void DxFont::BuildFontSheetBitmap(Gdiplus::Font & font, Gdiplus::Graphics & charGraphics, Gdiplus::Bitmap & charBitmap, Gdiplus::Graphics & fontSheetGraphics) { WCHAR charString[ 2 ] = { ' ', 0 }; Gdiplus::SolidBrush whiteBrush( Gdiplus::Color( 255, 255, 255, 255 ) ); UINT fontSheetX = 0; UINT fontSheetY = 0; for( UINT i = 0; i < NumChars; ++i ) { charString[ 0 ] = static_cast<WCHAR>(StartChar + i); charGraphics.Clear(Gdiplus::Color(0, 0, 0, 0)); charGraphics.DrawString(charString, 1, &font, Gdiplus::PointF(0.0f, 0.0f), &whiteBrush); int minX = GetCharMinX(charBitmap); int maxX = GetCharMaxX(charBitmap); int charWidth = maxX - minX + 1; if(fontSheetX + charWidth >= TexWidth) { fontSheetX = 0; fontSheetY += static_cast<int>(CharHeight) + 1; } CharRects[i] = CD3D11_RECT(fontSheetX, fontSheetY, fontSheetX + charWidth, fontSheetY + CharHeight); fontSheetGraphics.DrawImage(&charBitmap, fontSheetX, fontSheetY, minX, 0, charWidth, CharHeight, Gdiplus::UnitPixel); fontSheetX += charWidth + 1; } }
//--------------------------------------------------------------------------- void CreateAndIndexAtlasBitmap(Gdiplus::Font& font, Gdiplus::Graphics& charGraphics, Gdiplus::Bitmap& charBitmap, Gdiplus::Graphics& fontSheetGraphics, FontAtlasSizeInfo* pSizeInfo, ScreenRect* pCharacterMap ) { using namespace Gdiplus; WCHAR charString[2] = {' ', 0}; SolidBrush whiteBrush(Color(255, 255, 255, 255)); UINT fontSheetX = 0; UINT fontSheetY = 0; for(UINT i = 0; i < s_NumChars; ++i) { charString[0] = static_cast<WCHAR>(s_StartChar + i); charGraphics.Clear(Color(0, 0, 0, 0)); charGraphics.DrawString(charString, 1, &font, PointF(0.0f, 0.0f), &whiteBrush); // Compute tight char horizontal bounds (ignoring empty space). int minX = GetCharMinX(charBitmap); int maxX = GetCharMaxX(charBitmap); int charWidth = maxX - minX + 1; // Move to next row of the font sheet? if(fontSheetX + charWidth >= pSizeInfo->atlasTextureWidth) { fontSheetX = 0; fontSheetY += static_cast<int>(pSizeInfo->characterRowHeight) + 1; } // Save the rectangle of this character on the texture atlas. pCharacterMap[i] = ScreenRect(fontSheetX, fontSheetY, fontSheetX + charWidth, fontSheetY + pSizeInfo->characterRowHeight); // The rectangle subset of the source image to copy. fontSheetGraphics.DrawImage(&charBitmap, fontSheetX, fontSheetY, minX, 0, charWidth, pSizeInfo->characterRowHeight, UnitPixel); // next char fontSheetX += charWidth + 1; } }
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); }
void CBtnRoundImg::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { CDC dc; dc.Attach(lpDrawItemStruct->hDC); //°´Å¥¿Ø¼þDC COLORREF clrBK = RGB(255,255,255); switch(m_nCtrlState) { case CTRL_NOFOCUS: clrBK = m_clrBKUnfocus; break; case CTRL_FOCUS: clrBK = m_clrBKFocus; break; case CTRL_SELECTED: clrBK = m_clrBKSelected; break; default: break; } if (IsWindowEnabled()==FALSE) { clrBK = m_clrBKDisable; } //draw background CRect rect(lpDrawItemStruct->rcItem); //dc.FillSolidRect(&rect,clrBK); DrawRoundRect(dc, 5,rect,clrBK); //draw image if (m_strPngPath != _T("")) { Gdiplus::Image imageBtn(m_strPngPath); if (imageBtn.GetLastStatus() != Ok) { ASSERT(FALSE); } ; HRGN hRgnOld = (HRGN)::SelectObject(lpDrawItemStruct->hDC, m_hRgnBtn); Gdiplus::Graphics * pGrp = Graphics::FromHDC(lpDrawItemStruct->hDC); pGrp->Clear(Color::White); CRect rectBtn; GetClientRect(&rectBtn); int startX = (rectBtn.Width() - imageBtn.GetWidth())/2; int startY = (rectBtn.Height() - imageBtn.GetHeight())/2; startX = 0; startY = 0; if (lpDrawItemStruct->itemState & ODS_SELECTED) //Ñ¡ÖÐ״̬£¬Í¼Æ¬Æ«ÒÆÒ»¸öÏñËØ { pGrp->DrawImage(&imageBtn, startX+1, startY+1, startX+imageBtn.GetWidth(), startY+imageBtn.GetHeight()); } else //ĬÈÏ״̬ { pGrp->DrawImage(&imageBtn, startX, startY, startX+imageBtn.GetWidth(), startY+imageBtn.GetHeight()); } delete pGrp; pGrp = NULL; ::SelectObject(lpDrawItemStruct->hDC, hRgnOld); } CFont* pOldFont; if (m_pFont) { pOldFont = dc.SelectObject(m_pFont); } COLORREF clrOld = dc.SetTextColor(m_clrFont); CString strText; GetWindowText(strText); if (strText != _T("")) { int test = 1; } int oldMode = dc.SetBkMode(TRANSPARENT); dc.DrawText(strText, -1, &lpDrawItemStruct->rcItem, DT_CENTER|DT_SINGLELINE|DT_VCENTER); dc.SetBkMode(oldMode); dc.SetTextColor(clrOld); if (m_pFont) { dc.SelectObject(pOldFont); } dc.Detach(); }
// // Draw overlay // PLUGIN_EXPORT void PluginUpdateOverlay() { if (!pRenderHelper) return; //SAFE_DELETE(pFPSNormalBrush); //pFPSNormalBrush = new Gdiplus::SolidBrush(Gdiplus::Color(255, 255, 255, 255)); if (bFirstAttach) { bFirstAttach = false; PC_StartRecording(); PC_DebugPrint(L"Triggered"); } else { PC_DebugPrint(L"Not Triggered"); } // lock overlay image auto pLock = pRenderHelper->BeginFrame(); if (!pLock) return; int w = pLock->dwWidth; int h = pLock->dwHeight; Gdiplus::Graphics *pGraphics = pRenderHelper->GetGraphics(); //----------------------------------------- // draw FPS counter // set options //pGraphics->SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); // clear back pGraphics->Clear(Gdiplus::Color(0, 0, 0, 0)); // draw fps { Gdiplus::RectF bound; //bound. int circleSize = 0; if (w < h) { circleSize = w; } else { circleSize = h; } if (PC_IsRecording()) { pGraphics->FillEllipse(pFPSRecordBrush, 0, 0, circleSize, circleSize); } else if (bShowWhenNotRecording) { pGraphics->FillEllipse(pFPSNormalBrush, 0, 0, circleSize, circleSize); } } // graphics.Flush(FlushIntentionSync); // fill overlay image pRenderHelper->EndFrame(); }
// // 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(); }
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; }
void CanvasGdiplus::Clear(const Color& color) { Gdiplus::Graphics* current = GetCurrentGraphics(); current->Clear(color.GetNativeColor()); }
void Graphics::Clear(const Color& col) { Gdiplus::Color gdiColor; ToGDIColor(col, gdiColor); Gdiplus::Graphics* g = reinterpret_cast<Gdiplus::Graphics*>(_private); g->Clear(gdiColor); }