void CStartupView::DrawTitleText(Gdiplus::Graphics &graphics) { Gdiplus::Rect gdipRcLeftButtons; CalculateLeftButtonsRegion(gdipRcLeftButtons); Gdiplus::SolidBrush blackBrush(Gdiplus::Color(255, 0, 0, 0)); Gdiplus::Font titleFont(m_csFontFamily, m_iTitleFontSize, Gdiplus::FontStyleBold, Gdiplus::UnitPixel); Gdiplus::Font subTitleFont(m_csFontFamily, m_iNormalFontSize, Gdiplus::FontStyleBold, Gdiplus::UnitPixel); CString csRecord1; csRecord1.LoadString(IDS_RECORD); INT x = gdipRcLeftButtons.X; INT y = gdipRcLeftButtons.Y + 2*BUTTON_TITLE_HEIGHT; Gdiplus::PointF textOrigin(x/*gdipRcLeftButtons.X*/, y/*(gdipRcLeftButtons.Y + gdipRcLeftButtons.Height)*/ ); graphics.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAliasGridFit); graphics.DrawString(csRecord1, csRecord1.GetLength(), &titleFont, textOrigin, &blackBrush); x = gdipRcLeftButtons.X; y = gdipRcLeftButtons.Y + BUTTON_TITLE_HEIGHT + 2*BUTTON_SUBTITLE_HEIGHT + 2*(BUTTON_HEIGHT1 + 10) + SEPARATOR_HEIGHT + 5; //Gdiplus::PointF textOrigin(x/*gdipRcLeftButtons.X*/, y/*(gdipRcLeftButtons.Y + gdipRcLeftButtons.Height)*/ ); textOrigin.X = x; textOrigin.Y = y; CString csWelcome; //csWelcome.LoadStringW(IDS_WELCOME); csWelcome.LoadStringW(ID_MENU_NEW); graphics.DrawString(csWelcome, csWelcome.GetLength(), &titleFont, textOrigin, &blackBrush); textOrigin.Y += BUTTON_TITLE_HEIGHT; Gdiplus::Rect gdipRcRightButtons; CalculateRightButtonsRegion(gdipRcRightButtons); textOrigin.X = gdipRcRightButtons.X ; textOrigin.Y = gdipRcRightButtons.Y + BUTTON_TITLE_HEIGHT + BUTTON_HEIGHT;; CString csRecord; //csRecord.LoadStringW(IDS_RECORD); csRecord.LoadStringW(ID_MENU_OPEN); graphics.DrawString(csRecord, csRecord.GetLength(), &titleFont, textOrigin, &blackBrush); /*textOrigin.X = gdipRcRightButtons.X ; textOrigin.Y += 3*BUTTON_HEIGHT; CString csRecent; csRecent.LoadStringW(IDS_RECENTLY_OPENED_PROJECTS); graphics.DrawString(csRecent, csRecent.GetLength(), &titleFont, textOrigin, &blackBrush); */ }
bool PngOutlineText::DrawString( Gdiplus::Graphics* pGraphics, Gdiplus::FontFamily* pFontFamily, Gdiplus::FontStyle fontStyle, int nfontSize, const wchar_t*pszText, Gdiplus::Rect rtDraw, Gdiplus::StringFormat* pStrFormat) { if(!pGraphics) return false; if(m_bEnableShadow&&m_pBkgdBitmap&&m_pFontBodyShadow&&m_pShadowStrategy&&m_pShadowStrategyMask) { Gdiplus::Graphics* pGraphicsMask=NULL; Gdiplus::Bitmap* pBmpMask=NULL; Gdiplus::Graphics* pGraphicsDrawn=NULL; Gdiplus::Bitmap* pBmpDrawn=NULL; bool b = RenderTransShadowA( pGraphics, &pGraphicsMask, &pBmpMask, &pGraphicsDrawn, &pBmpDrawn); if(!b) return false; b = RenderFontShadow( pGraphicsDrawn, pGraphicsMask, pBmpDrawn, pBmpMask, pFontFamily, fontStyle, nfontSize, pszText, Gdiplus::Rect(rtDraw.X+m_ptShadowOffset.X, rtDraw.Y+m_ptShadowOffset.Y,rtDraw.Width,rtDraw.Height), pStrFormat); if(!b) { delete pGraphicsMask; delete pGraphicsDrawn; delete pBmpDrawn; return false; } b = RenderTransShadowB( pGraphics, pGraphicsMask, pBmpMask, pGraphicsDrawn, pBmpDrawn); delete pGraphicsMask; delete pGraphicsDrawn; delete pBmpDrawn; if(!b) return false; } if(m_pTextStrategy&&m_pTextStrategyMask) { Gdiplus::Graphics* pGraphicsPng = new Gdiplus::Graphics((Gdiplus::Image*)(m_pPngBitmap)); pGraphicsPng->SetCompositingMode(pGraphics->GetCompositingMode()); pGraphicsPng->SetCompositingQuality(pGraphics->GetCompositingQuality()); pGraphicsPng->SetInterpolationMode(pGraphics->GetInterpolationMode()); pGraphicsPng->SetSmoothingMode(pGraphics->GetSmoothingMode()); pGraphicsPng->SetTextRenderingHint(pGraphics->GetTextRenderingHint()); pGraphicsPng->SetPageUnit(pGraphics->GetPageUnit()); pGraphicsPng->SetPageScale(pGraphics->GetPageScale()); bool b = m_pTextStrategy->DrawString( pGraphicsPng, pFontFamily, fontStyle, nfontSize, pszText, rtDraw, pStrFormat); delete pGraphicsPng; if(!b) return false; } //pGraphics->DrawImage(m_pPngBitmap,0,0,m_pPngBitmap->GetWidth(),m_pPngBitmap->GetHeight()); return true; }
bool PngOutlineText::RenderFontShadow( Gdiplus::Graphics* pGraphicsDrawn, Gdiplus::Graphics* pGraphicsMask, Gdiplus::Bitmap* pBitmapDrawn, Gdiplus::Bitmap* pBitmapMask, Gdiplus::FontFamily* pFontFamily, Gdiplus::FontStyle fontStyle, int nfontSize, const wchar_t*pszText, Gdiplus::Rect rtDraw, Gdiplus::StringFormat* pStrFormat) { if(!pGraphicsDrawn||!pGraphicsMask||!pBitmapDrawn||!pBitmapMask) return false; Gdiplus::Bitmap* pBitmapShadowMask = m_pPngBitmap->Clone(0, 0, m_pPngBitmap->GetWidth(), m_pPngBitmap->GetHeight(), PixelFormat32bppARGB); Gdiplus::Graphics* pGraphicsShadowMask = new Gdiplus::Graphics((Gdiplus::Image*)(pBitmapShadowMask)); Gdiplus::SolidBrush brushBlack(Gdiplus::Color(0,0,0)); pGraphicsShadowMask->FillRectangle(&brushBlack, 0, 0, m_pPngBitmap->GetWidth(), m_pPngBitmap->GetHeight() ); pGraphicsShadowMask->SetCompositingMode(pGraphicsDrawn->GetCompositingMode()); pGraphicsShadowMask->SetCompositingQuality(pGraphicsDrawn->GetCompositingQuality()); pGraphicsShadowMask->SetInterpolationMode(pGraphicsDrawn->GetInterpolationMode()); pGraphicsShadowMask->SetSmoothingMode(pGraphicsDrawn->GetSmoothingMode()); pGraphicsShadowMask->SetTextRenderingHint(pGraphicsDrawn->GetTextRenderingHint()); pGraphicsShadowMask->SetPageUnit(pGraphicsDrawn->GetPageUnit()); pGraphicsShadowMask->SetPageScale(pGraphicsDrawn->GetPageScale()); bool b = false; b = m_pFontBodyShadowMask->DrawString( pGraphicsMask, pFontFamily, fontStyle, nfontSize, pszText, rtDraw, pStrFormat); if(!b) return false; b = m_pShadowStrategyMask->DrawString( pGraphicsShadowMask, pFontFamily, fontStyle, nfontSize, pszText, rtDraw, pStrFormat); if(!b) return false; b = m_pFontBodyShadow->DrawString( pGraphicsDrawn, pFontFamily, fontStyle, nfontSize, pszText, rtDraw, pStrFormat); if(!b) return false; b = m_pShadowStrategy->DrawString( pGraphicsDrawn, pFontFamily, fontStyle, nfontSize, pszText, rtDraw, pStrFormat); if(!b) return false; UINT* pixelsDest = NULL; UINT* pixelsMask = NULL; UINT* pixelsShadowMask = NULL; using namespace Gdiplus; BitmapData bitmapDataDest; BitmapData bitmapDataMask; BitmapData bitmapDataShadowMask; Rect rect(0, 0, m_pBkgdBitmap->GetWidth(), m_pBkgdBitmap->GetHeight() ); pBitmapDrawn->LockBits( &rect, ImageLockModeWrite, PixelFormat32bppARGB, &bitmapDataDest ); pBitmapMask->LockBits( &rect, ImageLockModeWrite, PixelFormat32bppARGB, &bitmapDataMask ); pBitmapShadowMask->LockBits( &rect, ImageLockModeWrite, PixelFormat32bppARGB, &bitmapDataShadowMask ); pixelsDest = (UINT*)bitmapDataDest.Scan0; pixelsMask = (UINT*)bitmapDataMask.Scan0; pixelsShadowMask = (UINT*)bitmapDataShadowMask.Scan0; if( !pixelsDest || !pixelsMask || !pixelsShadowMask ) return false; UINT col = 0; int stride = bitmapDataDest.Stride >> 2; for(UINT row = 0; row < bitmapDataDest.Height; ++row) { for(col = 0; col < bitmapDataDest.Width; ++col) { using namespace Gdiplus; UINT index = row * stride + col; BYTE nAlpha = pixelsMask[index] & 0xff; BYTE nAlphaShadow = pixelsShadowMask[index] & 0xff; if(nAlpha>0&&nAlpha>nAlphaShadow) { pixelsDest[index] = nAlpha << 24 | m_clrShadow.GetR()<<16 | m_clrShadow.GetG()<<8 | m_clrShadow.GetB(); } else if(nAlphaShadow>0) { pixelsDest[index] = nAlphaShadow << 24 | m_clrShadow.GetR()<<16 | m_clrShadow.GetG()<<8 | m_clrShadow.GetB(); pixelsMask[index] = pixelsShadowMask[index]; } } } pBitmapShadowMask->UnlockBits(&bitmapDataShadowMask); pBitmapMask->UnlockBits(&bitmapDataMask); pBitmapDrawn->UnlockBits(&bitmapDataDest); if(pGraphicsShadowMask) { delete pGraphicsShadowMask; pGraphicsShadowMask = NULL; } if(pBitmapShadowMask) { delete pBitmapShadowMask; pBitmapShadowMask = NULL; } return true; }
void InitTextStyles(Gdiplus::Graphics& gfx, Gdiplus::StringFormat& format, const Style& style) { gfx.SetTextRenderingHint(AntialiasingFromStyleString(style.Get(L"antialiasing", L"default"))); format.SetTrimming(StringTrimmingFromStyleString(style.Get(L"trimming", L"default"))); }
static Image *ReadEMFImage(const ImageInfo *image_info, ExceptionInfo *exception) { Gdiplus::Bitmap *bitmap; Gdiplus::BitmapData bitmap_data; Gdiplus::GdiplusStartupInput startup_input; Gdiplus::Graphics *graphics; Gdiplus::Image *source; Gdiplus::Rect rect; GeometryInfo geometry_info; Image *image; MagickStatusType flags; register Quantum *q; register ssize_t x; ssize_t y; ULONG_PTR token; unsigned char *p; wchar_t fileName[MagickPathExtent]; assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); image=AcquireImage(image_info,exception); if (Gdiplus::GdiplusStartup(&token,&startup_input,NULL) != Gdiplus::Status::Ok) ThrowReaderException(CoderError, "GdiplusStartupFailed"); MultiByteToWideChar(CP_UTF8,0,image->filename,-1,fileName,MagickPathExtent); source=Gdiplus::Image::FromFile(fileName); if (source == (Gdiplus::Image *) NULL) { Gdiplus::GdiplusShutdown(token); ThrowReaderException(FileOpenError,"UnableToOpenFile"); } image->resolution.x=source->GetHorizontalResolution(); image->resolution.y=source->GetVerticalResolution(); image->columns=(size_t) source->GetWidth(); image->rows=(size_t) source->GetHeight(); if (image_info->density != (char *) NULL) { flags=ParseGeometry(image_info->density,&geometry_info); image->resolution.x=geometry_info.rho; image->resolution.y=geometry_info.sigma; if ((flags & SigmaValue) == 0) image->resolution.y=image->resolution.x; if ((image->resolution.x > 0.0) && (image->resolution.y > 0.0)) { image->columns=(size_t) floor((Gdiplus::REAL) source->GetWidth() / source->GetHorizontalResolution() * image->resolution.x + 0.5); image->rows=(size_t)floor((Gdiplus::REAL) source->GetHeight() / source->GetVerticalResolution() * image->resolution.y + 0.5); } } bitmap=new Gdiplus::Bitmap((INT) image->columns,(INT) image->rows, PixelFormat32bppARGB); graphics=Gdiplus::Graphics::FromImage(bitmap); graphics->SetInterpolationMode(Gdiplus::InterpolationModeHighQualityBicubic); graphics->SetSmoothingMode(Gdiplus::SmoothingModeHighQuality); graphics->SetTextRenderingHint(Gdiplus::TextRenderingHintClearTypeGridFit); graphics->Clear(Gdiplus::Color((BYTE) ScaleQuantumToChar( image->background_color.alpha),(BYTE) ScaleQuantumToChar( image->background_color.red),(BYTE) ScaleQuantumToChar( image->background_color.green),(BYTE) ScaleQuantumToChar( image->background_color.blue))); graphics->DrawImage(source,0,0,(INT) image->columns,(INT) image->rows); delete graphics; delete source; rect=Gdiplus::Rect(0,0,(INT) image->columns,(INT) image->rows); if (bitmap->LockBits(&rect,Gdiplus::ImageLockModeRead,PixelFormat32bppARGB, &bitmap_data) != Gdiplus::Ok) { delete bitmap; Gdiplus::GdiplusShutdown(token); ThrowReaderException(FileOpenError,"UnableToReadImageData"); } image->alpha_trait=BlendPixelTrait; for (y=0; y < (ssize_t) image->rows; y++) { p=(unsigned char *) bitmap_data.Scan0+(y*abs(bitmap_data.Stride)); if (bitmap_data.Stride < 0) q=GetAuthenticPixels(image,0,image->rows-y-1,image->columns,1,exception); else q=GetAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (Quantum *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelBlue(image,ScaleCharToQuantum(*p++),q); SetPixelGreen(image,ScaleCharToQuantum(*p++),q); SetPixelRed(image,ScaleCharToQuantum(*p++),q); SetPixelAlpha(image,ScaleCharToQuantum(*p++),q); q+=GetPixelChannels(image); } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } bitmap->UnlockBits(&bitmap_data); delete bitmap; Gdiplus::GdiplusShutdown(token); return(image); }
// // Draw overlay // PLUGIN_EXPORT void PluginUpdateOverlay() { if (!pRenderHelper) return; // lock overlay image auto pLock = pRenderHelper->BeginFrame(); if (!pLock) return; int w = pLock->dwWidth; int h = pLock->dwHeight; Gdiplus::Graphics *pGraphics = pRenderHelper->GetGraphics(); //----------------------------------------- // draw Text Overlay // set options pGraphics->SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); // clear back pGraphics->Clear(Gdiplus::Color(0, 0, 0, 0)); WCHAR s[128]; _itow_s(PC_GetConfirmedProcessID(), s, 10); if (PathFileExists(pFileName)) { string textContents = ""; WIN32_FILE_ATTRIBUTE_DATA attribs; GetFileAttributesExW(pFileName, GetFileExInfoStandard, &attribs); FILETIME modifyTime = attribs.ftLastWriteTime; if (CompareFileTime(&modifyTime, &oldModifyTime) > 0) { oldModifyTime = modifyTime; string line; ifstream myfile; myfile.open(pFileName); if (myfile.is_open()) { while (getline(myfile, line)) { textContents += line; } myfile.close(); } textLength = textContents.length(); wcTextContents[textLength] = 0; std::copy(textContents.begin(), textContents.end(), wcTextContents); } } // draw back if required if (bShowBackground) { Gdiplus::RectF bound; pRenderHelper->GetTextExtent(wcTextContents, pFont, &bound); pGraphics->FillRectangle(pBackBrush, bound); } // draw text Gdiplus::RectF bound; pRenderHelper->GetTextExtent(wcTextContents, pFont, &bound); if (bound.Width > w) { wchar_t wcNewTextContents[256]; wcNewTextContents[textLength * 2 + 5] = 0; swprintf_s(wcNewTextContents, L"%s %s", wcTextContents, wcTextContents); Gdiplus::RectF newbound; pRenderHelper->GetTextExtent(wcNewTextContents, pFont, &newbound); pRenderHelper->DrawString(wcNewTextContents, pFont, Gdiplus::Point(0 - scroll, 0), pTextBrush, pBackBrush); scroll += 2; if (scroll > newbound.Width - bound.Width) scroll = 0; } else { pRenderHelper->DrawString(wcTextContents, pFont, Gdiplus::Point(0, 0), pTextBrush, pBackBrush); } // fill overlay image pRenderHelper->EndFrame(); }
void CSimplePanelDlg::DrawEmpty(Gdiplus::Graphics& gr, CRect& rc) { //每次先刷新背景 Gdiplus::Color cl = Gdiplus::Color::White; Gdiplus::SolidBrush brush(cl); gr.FillRectangle(&brush, 0, 0, rc.Width(), rc.Height()); //显示线路号背景 Gdiplus::PointF pointLineBK(60, 0); gr.DrawImage(m_pImLineBK, pointLineBK); int nWidth = m_pImLineBK->GetWidth(); int nHeight = m_pImLineBK->GetHeight(); //显示-- CString strLineNum = "--"; Gdiplus::SolidBrush brushLineNum(Gdiplus::Color::White); WCHAR wcLineNum[6] = {0}; MultiByteToWideChar(CP_ACP, 0, (char*)(LPCTSTR)strLineNum, strLineNum.GetLength(), wcLineNum, sizeof(wcLineNum)); Gdiplus::PointF pointLineNum = pointLineBK; Gdiplus::RectF rectLineNum(pointLineNum, Gdiplus::SizeF(nWidth, nHeight)); Gdiplus::Font fontLineNum(L"helvetica", 42 , Gdiplus::FontStyleBold, Gdiplus::UnitPixel); Gdiplus::StringFormat stringFormatLineNum; stringFormatLineNum.SetAlignment(Gdiplus::StringAlignmentCenter); stringFormatLineNum.SetLineAlignment(Gdiplus::StringAlignmentCenter); gr.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); gr.DrawString(wcLineNum, wcslen(wcLineNum), &fontLineNum, rectLineNum, &stringFormatLineNum, &brushLineNum); //显示路 std::wstring str = L"路"; Gdiplus::SolidBrush brushLu(Gdiplus::Color::White); Gdiplus::PointF pointWord = pointLineBK; pointWord.X += 0.75 * nWidth; Gdiplus::RectF rectWord(pointWord, Gdiplus::SizeF(40, nHeight - 5)); Gdiplus::Font fontLu(L"方正兰亭黑简体", 24 , Gdiplus::FontStyleRegular, Gdiplus::UnitPixel); Gdiplus::StringFormat stringFormatWord; stringFormatWord.SetAlignment(Gdiplus::StringAlignmentNear); stringFormatWord.SetLineAlignment(Gdiplus::StringAlignmentFar); gr.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); gr.DrawString(str.c_str(), str.size(), &fontLu, rectWord, &stringFormatWord, &brushLu); //第一辆车距离站 if(1) { CString strNum = "- -"; Gdiplus::SolidBrush brushNum(Gdiplus::Color(149,158,168)); WCHAR wcNum[6] = {0}; MultiByteToWideChar(CP_ACP, 0, (char*)(LPCTSTR)strNum, strNum.GetLength(), wcNum, sizeof(wcNum)); Gdiplus::PointF pointNum(60 + nWidth, 0); Gdiplus::RectF rectNum(pointNum, Gdiplus::SizeF(145, nHeight)); Gdiplus::Font fontNum(L"helvetica", 42 , Gdiplus::FontStyleBold, Gdiplus::UnitPixel); Gdiplus::StringFormat stringFormatNum; stringFormatNum.SetAlignment(Gdiplus::StringAlignmentCenter); stringFormatNum.SetLineAlignment(Gdiplus::StringAlignmentCenter); gr.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); gr.DrawString(wcNum, wcslen(wcNum), &fontNum, rectNum, &stringFormatNum, &brushNum); std::wstring wstr = L"站"; Gdiplus::SolidBrush brushZhan(Gdiplus::Color(149,158,168)); Gdiplus::PointF pointZhan(60 + nWidth + 0.7 * 145, 0); Gdiplus::RectF rectZhan(pointZhan, Gdiplus::SizeF(40, nHeight - 5)); Gdiplus::Font fontZhan(L"方正兰亭黑简体", 24 , Gdiplus::FontStyleRegular, Gdiplus::UnitPixel); Gdiplus::StringFormat stringFormatZhan; stringFormatZhan.SetAlignment(Gdiplus::StringAlignmentNear); stringFormatZhan.SetLineAlignment(Gdiplus::StringAlignmentFar); gr.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); gr.DrawString(wstr.c_str(), wstr.size(), &fontZhan, rectZhan, &stringFormatZhan, &brushZhan); } if(1) { //第二辆车距离站 CString strNum = "- -"; Gdiplus::SolidBrush brushNum(Gdiplus::Color(149,158,168)); WCHAR wcNum[6] = {0}; MultiByteToWideChar(CP_ACP, 0, (char*)(LPCTSTR)strNum, strNum.GetLength(), wcNum, sizeof(wcNum)); Gdiplus::PointF pointNum(60 + nWidth + 145, 0); Gdiplus::RectF rectNum(pointNum, Gdiplus::SizeF(145, nHeight)); Gdiplus::Font fontNum(L"helvetica", 42 , Gdiplus::FontStyleBold, Gdiplus::UnitPixel); Gdiplus::StringFormat stringFormatNum; stringFormatNum.SetAlignment(Gdiplus::StringAlignmentCenter); stringFormatNum.SetLineAlignment(Gdiplus::StringAlignmentCenter); gr.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); gr.DrawString(wcNum, wcslen(wcNum), &fontNum, rectNum, &stringFormatNum, &brushNum); std::wstring wstr = L"站"; Gdiplus::SolidBrush brushZhan(Gdiplus::Color(149,158,168)); Gdiplus::PointF pointZhan(60 + nWidth + 0.7 * 145 + 145, 0); Gdiplus::RectF rectZhan(pointZhan, Gdiplus::SizeF(40, nHeight - 5)); Gdiplus::Font fontZhan(L"方正兰亭黑简体", 24 , Gdiplus::FontStyleRegular, Gdiplus::UnitPixel); Gdiplus::StringFormat stringFormatZhan; stringFormatZhan.SetAlignment(Gdiplus::StringAlignmentNear); stringFormatZhan.SetLineAlignment(Gdiplus::StringAlignmentFar); gr.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); gr.DrawString(wstr.c_str(), wstr.size(), &fontZhan, rectZhan, &stringFormatZhan, &brushZhan); } }
void CSimplePanelDlg::DrawArrive(Gdiplus::Graphics& gr, vector<BusArrivalInfo>& vecArrival, CRect& rc, CData* pData) { //每次先刷新背景 Gdiplus::Color cl = Gdiplus::Color::White; Gdiplus::SolidBrush brush(cl); gr.FillRectangle(&brush, 0, 0, rc.Width(), rc.Height()); //显示线路号背景 Gdiplus::PointF pointLineBK(60, 0); gr.DrawImage(m_pImLineBK, pointLineBK); int nWidth = m_pImLineBK->GetWidth(); int nHeight = m_pImLineBK->GetHeight(); //显示线路号 CString strLineNum = pData->GetLineNumber(); Gdiplus::SolidBrush brushLineNum(Gdiplus::Color::White); WCHAR wcLineNum[6] = {0}; MultiByteToWideChar(CP_ACP, 0, (char*)(LPCTSTR)strLineNum, strLineNum.GetLength(), wcLineNum, sizeof(wcLineNum)); Gdiplus::PointF pointLineNum = pointLineBK; Gdiplus::RectF rectLineNum(pointLineNum, Gdiplus::SizeF(nWidth, nHeight)); Gdiplus::Font fontLineNum(L"helvetica", 42 , Gdiplus::FontStyleBold, Gdiplus::UnitPixel); Gdiplus::StringFormat stringFormatLineNum; stringFormatLineNum.SetAlignment(Gdiplus::StringAlignmentCenter); stringFormatLineNum.SetLineAlignment(Gdiplus::StringAlignmentCenter); gr.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); gr.DrawString(wcLineNum, wcslen(wcLineNum), &fontLineNum, rectLineNum, &stringFormatLineNum, &brushLineNum); //显示路 std::wstring str = L"路"; Gdiplus::SolidBrush brushLu(Gdiplus::Color::White); Gdiplus::PointF pointWord = pointLineBK; pointWord.X += 0.75 * nWidth; Gdiplus::RectF rectWord(pointWord, Gdiplus::SizeF(40, nHeight - 5)); Gdiplus::Font fontLu(L"方正兰亭黑简体", 24 , Gdiplus::FontStyleRegular, Gdiplus::UnitPixel); Gdiplus::StringFormat stringFormatWord; stringFormatWord.SetAlignment(Gdiplus::StringAlignmentNear); stringFormatWord.SetLineAlignment(Gdiplus::StringAlignmentFar); gr.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); gr.DrawString(str.c_str(), str.size(), &fontLu, rectWord, &stringFormatWord, &brushLu); if(0 < vecArrival.size()) { //显示第一辆车到站 BusArrivalInfo& stArrive = vecArrival[0]; if(stArrive.iNum > 0) { //距离站 CString strNum; strNum.Format("%d", stArrive.iNum); Gdiplus::SolidBrush brushNum(Gdiplus::Color(23,117,231)); WCHAR wcNum[6] = {0}; MultiByteToWideChar(CP_ACP, 0, (char*)(LPCTSTR)strNum, strNum.GetLength(), wcNum, sizeof(wcNum)); Gdiplus::PointF pointNum(60 + nWidth, 0); Gdiplus::RectF rectNum(pointNum, Gdiplus::SizeF(145, nHeight)); Gdiplus::Font fontNum(L"helvetica", 42 , Gdiplus::FontStyleBold, Gdiplus::UnitPixel); Gdiplus::StringFormat stringFormatNum; stringFormatNum.SetAlignment(Gdiplus::StringAlignmentCenter); stringFormatNum.SetLineAlignment(Gdiplus::StringAlignmentCenter); gr.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); gr.DrawString(wcNum, wcslen(wcNum), &fontNum, rectNum, &stringFormatNum, &brushNum); std::wstring wstr = L"站"; Gdiplus::SolidBrush brushZhan(Gdiplus::Color(149,158,168)); Gdiplus::PointF pointZhan(60 + nWidth + 145 - 32, 0); Gdiplus::RectF rectZhan(pointZhan, Gdiplus::SizeF(40, nHeight - 5)); Gdiplus::Font fontZhan(L"方正兰亭黑简体", 24 , Gdiplus::FontStyleRegular, Gdiplus::UnitPixel); Gdiplus::StringFormat stringFormatZhan; stringFormatZhan.SetAlignment(Gdiplus::StringAlignmentNear); stringFormatZhan.SetLineAlignment(Gdiplus::StringAlignmentFar); gr.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); gr.DrawString(wstr.c_str(), wstr.size(), &fontZhan, rectZhan, &stringFormatZhan, &brushZhan); } else if(stArrive.iNum == 0) { if(stArrive.iDistance <= 50) { std::wstring wstr = L"已经进站"; Gdiplus::SolidBrush brushZhan(Gdiplus::Color(23,117,231)); Gdiplus::PointF pointZhan(60 + nWidth, 0); Gdiplus::RectF rectZhan(pointZhan, Gdiplus::SizeF(145, nHeight - 5)); Gdiplus::Font fontZhan(L"方正兰亭黑简体", 24 , Gdiplus::FontStyleRegular, Gdiplus::UnitPixel); Gdiplus::StringFormat stringFormatZhan; stringFormatZhan.SetAlignment(Gdiplus::StringAlignmentFar); stringFormatZhan.SetLineAlignment(Gdiplus::StringAlignmentFar); gr.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); gr.DrawString(wstr.c_str(), wstr.size(), &fontZhan, rectZhan, &stringFormatZhan, &brushZhan); } else { std::wstring wstr = L"即将到站"; Gdiplus::SolidBrush brushZhan(Gdiplus::Color(23,117,231)); Gdiplus::PointF pointZhan(60 + nWidth, 0); Gdiplus::RectF rectZhan(pointZhan, Gdiplus::SizeF(145, nHeight - 5)); Gdiplus::Font fontZhan(L"方正兰亭黑简体", 24 , Gdiplus::FontStyleRegular, Gdiplus::UnitPixel); Gdiplus::StringFormat stringFormatZhan; stringFormatZhan.SetAlignment(Gdiplus::StringAlignmentFar); stringFormatZhan.SetLineAlignment(Gdiplus::StringAlignmentFar); gr.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); gr.DrawString(wstr.c_str(), wstr.size(), &fontZhan, rectZhan, &stringFormatZhan, &brushZhan); } } } else { std::wstring wstr = L"待发"; Gdiplus::SolidBrush brushZhan(Gdiplus::Color(23,117,231)); Gdiplus::PointF pointZhan(60 + nWidth, 0); Gdiplus::RectF rectZhan(pointZhan, Gdiplus::SizeF(145, nHeight - 5)); Gdiplus::Font fontZhan(L"方正兰亭黑简体", 24 , Gdiplus::FontStyleRegular, Gdiplus::UnitPixel); Gdiplus::StringFormat stringFormatZhan; stringFormatZhan.SetAlignment(Gdiplus::StringAlignmentFar); stringFormatZhan.SetLineAlignment(Gdiplus::StringAlignmentFar); gr.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); gr.DrawString(wstr.c_str(), wstr.size(), &fontZhan, rectZhan, &stringFormatZhan, &brushZhan); } if(1 < vecArrival.size()) { //显示第二辆车到站 BusArrivalInfo& stArrive = vecArrival[1]; if(stArrive.iNum > 0) { //距离站 CString strNum; strNum.Format("%d", stArrive.iNum); Gdiplus::SolidBrush brushNum(Gdiplus::Color(23,117,231)); WCHAR wcNum[6] = {0}; MultiByteToWideChar(CP_ACP, 0, (char*)(LPCTSTR)strNum, strNum.GetLength(), wcNum, sizeof(wcNum)); Gdiplus::PointF pointNum(60 + nWidth + 145, 0); Gdiplus::RectF rectNum(pointNum, Gdiplus::SizeF(145, nHeight)); Gdiplus::Font fontNum(L"helvetica", 42 , Gdiplus::FontStyleBold, Gdiplus::UnitPixel); Gdiplus::StringFormat stringFormatNum; stringFormatNum.SetAlignment(Gdiplus::StringAlignmentCenter); stringFormatNum.SetLineAlignment(Gdiplus::StringAlignmentCenter); gr.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); gr.DrawString(wcNum, wcslen(wcNum), &fontNum, rectNum, &stringFormatNum, &brushNum); std::wstring wstr = L"站"; Gdiplus::SolidBrush brushZhan(Gdiplus::Color(149,158,168)); Gdiplus::PointF pointZhan(60 + nWidth + 145 + 145 - 32, 0); Gdiplus::RectF rectZhan(pointZhan, Gdiplus::SizeF(40, nHeight - 5)); Gdiplus::Font fontZhan(L"方正兰亭黑简体", 24 , Gdiplus::FontStyleRegular, Gdiplus::UnitPixel); Gdiplus::StringFormat stringFormatZhan; stringFormatZhan.SetAlignment(Gdiplus::StringAlignmentNear); stringFormatZhan.SetLineAlignment(Gdiplus::StringAlignmentFar); gr.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); gr.DrawString(wstr.c_str(), wstr.size(), &fontZhan, rectZhan, &stringFormatZhan, &brushZhan); } else if(stArrive.iNum == 0) { if(stArrive.iDistance <= 50) { std::wstring wstr = L"已经进站"; Gdiplus::SolidBrush brushZhan(Gdiplus::Color(23,117,231)); Gdiplus::PointF pointZhan(60 + nWidth + 145, 0); Gdiplus::RectF rectZhan(pointZhan, Gdiplus::SizeF(145, nHeight - 5)); Gdiplus::Font fontZhan(L"方正兰亭黑简体", 24 , Gdiplus::FontStyleRegular, Gdiplus::UnitPixel); Gdiplus::StringFormat stringFormatZhan; stringFormatZhan.SetAlignment(Gdiplus::StringAlignmentFar); stringFormatZhan.SetLineAlignment(Gdiplus::StringAlignmentFar); gr.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); gr.DrawString(wstr.c_str(), wstr.size(), &fontZhan, rectZhan, &stringFormatZhan, &brushZhan); } else { std::wstring wstr = L"即将到站"; Gdiplus::SolidBrush brushZhan(Gdiplus::Color(23,117,231)); Gdiplus::PointF pointZhan(60 + nWidth + 145, 0); Gdiplus::RectF rectZhan(pointZhan, Gdiplus::SizeF(145, nHeight - 5)); Gdiplus::Font fontZhan(L"方正兰亭黑简体", 24 , Gdiplus::FontStyleRegular, Gdiplus::UnitPixel); Gdiplus::StringFormat stringFormatZhan; stringFormatZhan.SetAlignment(Gdiplus::StringAlignmentFar); stringFormatZhan.SetLineAlignment(Gdiplus::StringAlignmentFar); gr.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); gr.DrawString(wstr.c_str(), wstr.size(), &fontZhan, rectZhan, &stringFormatZhan, &brushZhan); } } } else { std::wstring wstr = L"待发"; Gdiplus::SolidBrush brushZhan(Gdiplus::Color(23,117,231)); Gdiplus::PointF pointZhan(60 + nWidth + 145, 0); Gdiplus::RectF rectZhan(pointZhan, Gdiplus::SizeF(145, nHeight - 5)); Gdiplus::Font fontZhan(L"方正兰亭黑简体", 24 , Gdiplus::FontStyleRegular, Gdiplus::UnitPixel); Gdiplus::StringFormat stringFormatZhan; stringFormatZhan.SetAlignment(Gdiplus::StringAlignmentFar); stringFormatZhan.SetLineAlignment(Gdiplus::StringAlignmentFar); gr.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); gr.DrawString(wstr.c_str(), wstr.size(), &fontZhan, rectZhan, &stringFormatZhan, &brushZhan); } }
Surface renderString( const std::string &str, const Font &font, const ColorA &color, float *baselineOffset ) { Line line; line.addRun( Run( str, font, color ) ); line.mJustification = Line::LEFT; line.mLeadingOffset = 0; line.calcExtents(); float totalWidth = line.mWidth; float totalHeight = line.mHeight; int pixelWidth = (int)math<float>::ceil( totalWidth ); int pixelHeight = (int)math<float>::ceil( totalHeight ); // Odd failure - return a NULL Surface if( ( pixelWidth < 0 ) || ( pixelHeight < 0 ) ) return Surface(); #if defined( CINDER_MAC ) Surface result( pixelWidth, pixelHeight, true, SurfaceChannelOrder::RGBA ); CGContextRef cgContext = cocoa::createCgBitmapContext( result ); ip::fill( &result, ColorA( 0, 0, 0, 0 ) ); float currentY = totalHeight + 1.0f; currentY -= line.mAscent + line.mLeadingOffset; line.render( cgContext, currentY, (float)0, pixelWidth ); // force all the rendering to finish and release the context ::CGContextFlush( cgContext ); ::CGContextRelease( cgContext ); ip::unpremultiply( &result ); #elif defined( CINDER_MSW ) // I don't have a great explanation for this other than it seems to be necessary pixelHeight += 1; // prep our GDI and GDI+ resources ::HDC dc = TextManager::instance()->getDc(); Surface result( pixelWidth, pixelHeight, true, SurfaceConstraintsGdiPlus() ); Gdiplus::Bitmap *offscreenBitmap = msw::createGdiplusBitmap( result, false ); //Gdiplus::Bitmap *offscreenBitmap = new Gdiplus::Bitmap( pixelWidth, pixelHeight, (premultiplied) ? PixelFormat32bppPARGB : PixelFormat32bppARGB ); Gdiplus::Graphics *offscreenGraphics = Gdiplus::Graphics::FromImage( offscreenBitmap ); // high quality text rendering offscreenGraphics->SetTextRenderingHint( Gdiplus::TextRenderingHintAntiAlias ); // fill the surface with the background color offscreenGraphics->Clear( Gdiplus::Color( (BYTE)(0), (BYTE)(0), (BYTE)(0), (BYTE)(0) ) ); // walk the lines and render them, advancing our Y offset along the way float currentY = 0; currentY += line.mLeadingOffset + line.mLeading; line.render( offscreenGraphics, currentY, (float)0, (float)pixelWidth ); ::GdiFlush(); delete offscreenBitmap; delete offscreenGraphics; #elif defined( CINDER_LINUX ) Surface result( pixelWidth, pixelHeight, true, SurfaceChannelOrder::RGBA ); #endif if( baselineOffset ) *baselineOffset = line.mDescent; return result; }
Surface TextLayout::render( bool useAlpha, bool premultiplied ) { Surface result; // determine the extents for all the lines and the result surface float totalHeight = 0, maxWidth = 0; for( deque<shared_ptr<Line> >::iterator lineIt = mLines.begin(); lineIt != mLines.end(); ++lineIt ) { (*lineIt)->calcExtents(); totalHeight = std::max( totalHeight, totalHeight + (*lineIt)->mHeight + (*lineIt)->mLeadingOffset ); if( (*lineIt)->mWidth > maxWidth ) maxWidth = (*lineIt)->mWidth; } // for the last line, instead of using the font info, we'll use the true height /* if( ! mLines.empty() ) { totalHeight = currentY - (mLines.back()->mAscent - mLines.back()->mDescent - mLines.back()->mLeadingOffset - mLines.back()->mLeading ); totalHeight += mLines.back()->mHeight; }*/ // round up from the floating point sizes to get the number of pixels we'll need int pixelWidth = (int)math<float>::ceil( maxWidth ) + mHorizontalBorder * 2; int pixelHeight = (int)math<float>::ceil( totalHeight ) + mVerticalBorder * 2; // Odd failure - return a NULL Surface if( ( pixelWidth < 0 ) || ( pixelHeight < 0 ) ) return Surface(); // allocate the surface based on our collective extents #if defined( CINDER_MAC ) result = Surface( pixelWidth, pixelHeight, useAlpha, (useAlpha)?SurfaceChannelOrder::RGBA:SurfaceChannelOrder::RGBX ); CGContextRef cgContext = cocoa::createCgBitmapContext( result ); ip::fill( &result, mBackgroundColor.premultiplied() ); float currentY = totalHeight + 1.0f + mVerticalBorder; for( deque<shared_ptr<Line> >::iterator lineIt = mLines.begin(); lineIt != mLines.end(); ++lineIt ) { // these are negated from Cinder's normal pixel coordinate system currentY -= (*lineIt)->mAscent + (*lineIt)->mLeadingOffset; (*lineIt)->render( cgContext, currentY, (float)mHorizontalBorder, pixelWidth ); currentY -= (*lineIt)->mDescent + (*lineIt)->mLeading; } // force all the rendering to finish and release the context CGContextFlush( cgContext ); CGContextRelease( cgContext ); // since CGContextBitmaps are always premultiplied, if the caller didn't want that we'll have to undo it if( ! premultiplied ) ip::unpremultiply( &result ); #elif defined( CINDER_MSW ) // I don't have a great explanation for this other than it seems to be necessary pixelHeight += 1; // prep our GDI and GDI+ resources HDC dc = TextManager::instance()->getDc(); result = Surface8u( pixelWidth, pixelHeight, useAlpha, SurfaceConstraintsGdiPlus() ); Gdiplus::Bitmap *offscreenBitmap = msw::createGdiplusBitmap( result, premultiplied ); //Gdiplus::Bitmap *offscreenBitmap = new Gdiplus::Bitmap( pixelWidth, pixelHeight, (premultiplied) ? PixelFormat32bppPARGB : PixelFormat32bppARGB ); Gdiplus::Graphics *offscreenGraphics = Gdiplus::Graphics::FromImage( offscreenBitmap ); // high quality text rendering offscreenGraphics->SetTextRenderingHint( Gdiplus::TextRenderingHintAntiAlias ); // fill the surface with the background color offscreenGraphics->Clear( Gdiplus::Color( (BYTE)(mBackgroundColor.a * 255), (BYTE)(mBackgroundColor.r * 255), (BYTE)(mBackgroundColor.g * 255), (BYTE)(mBackgroundColor.b * 255) ) ); // walk the lines and render them, advancing our Y offset along the way float currentY = (float)mVerticalBorder; for( deque<shared_ptr<Line> >::iterator lineIt = mLines.begin(); lineIt != mLines.end(); ++lineIt ) { //currentY += (*lineIt)->mLeadingOffset + (*lineIt)->mAscent; currentY += (*lineIt)->mLeadingOffset + (*lineIt)->mLeading; (*lineIt)->render( offscreenGraphics, currentY, (float)mHorizontalBorder, (float)pixelWidth ); //currentY += (*lineIt)->mDescent + (*lineIt)->mLeading; currentY += (*lineIt)->mAscent + (*lineIt)->mDescent; } GdiFlush(); delete offscreenBitmap; delete offscreenGraphics; #endif return result; }