IDWriteFont* CreateDWriteFontFromGDIFamilyName(IDWriteFactory* factory, const WCHAR* gdiFamilyName) { IDWriteGdiInterop* dwGdiInterop; HRESULT hr = factory->GetGdiInterop(&dwGdiInterop); if (SUCCEEDED(hr)) { LOGFONT lf = {}; wcscpy_s(lf.lfFaceName, gdiFamilyName); lf.lfHeight = -12; lf.lfWeight = FW_DONTCARE; lf.lfCharSet = DEFAULT_CHARSET; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = ANTIALIASED_QUALITY; lf.lfPitchAndFamily = VARIABLE_PITCH; IDWriteFont* dwFont; hr = dwGdiInterop->CreateFontFromLOGFONT(&lf, &dwFont); if (SUCCEEDED(hr)) { return dwFont; } dwGdiInterop->Release(); } return nullptr; }
bool gfxDWriteFontEntry::InitLogFont(IDWriteFont *aFont, LOGFONTW *aLogFont) { HRESULT hr; BOOL isInSystemCollection; IDWriteGdiInterop *gdi = gfxDWriteFontList::PlatformFontList()->GetGDIInterop(); hr = gdi->ConvertFontToLOGFONT(aFont, aLogFont, &isInSystemCollection); return (FAILED(hr) ? false : true); }
FX_BOOL CDWriteExt::DwCreateRenderingTarget(CFX_DIBitmap* pBitmap, void** renderTarget) { if (pBitmap->GetFormat() > FXDIB_Argb) { return FALSE; } IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory; IDWriteGdiInterop* pGdiInterop = NULL; IDWriteBitmapRenderTarget* pBitmapRenderTarget = NULL; IDWriteRenderingParams* pRenderingParams = NULL; HRESULT hr = S_OK; hr = pDwFactory->GetGdiInterop(&pGdiInterop); if (FAILED(hr)) { goto failed; } hr = pGdiInterop->CreateBitmapRenderTarget(NULL, pBitmap->GetWidth(), pBitmap->GetHeight(), &pBitmapRenderTarget); if (FAILED(hr)) { goto failed; } hr = pDwFactory->CreateCustomRenderingParams( 1.0f, 0.0f, 1.0f, DWRITE_PIXEL_GEOMETRY_RGB, DWRITE_RENDERING_MODE_DEFAULT, &pRenderingParams ); if (FAILED(hr)) { goto failed; } hr = pBitmapRenderTarget->SetPixelsPerDip(1.0f); if (FAILED(hr)) { goto failed; } *(CDwGdiTextRenderer**)renderTarget = FX_NEW CDwGdiTextRenderer(pBitmap, pBitmapRenderTarget, pRenderingParams); if (*(CDwGdiTextRenderer**)renderTarget == NULL) { goto failed; } SafeRelease(&pGdiInterop); SafeRelease(&pBitmapRenderTarget); SafeRelease(&pRenderingParams); return TRUE; failed: SafeRelease(&pGdiInterop); SafeRelease(&pBitmapRenderTarget); SafeRelease(&pRenderingParams); return FALSE; }
virtual HRESULT STDMETHODCALLTYPE ConvertFontToLOGFONT( IDWriteFont *font, LOGFONTW *logFont, WINBOOL *isSystemFont) { return orig_this->ConvertFontToLOGFONT(font, logFont, isSystemFont); }
/* IDWriteGdiInterop methods */ virtual HRESULT STDMETHODCALLTYPE CreateFontFromLOGFONT( LOGFONTW const *logFont, IDWriteFont **font) { OutputDebugString("delegate_dwrite_gdi_interop::CreateFontFromLOGFONT"); HRESULT result; UINT32 index; BOOL exists; result = mycoll_->FindFamilyName(logFont->lfFaceName, &index, &exists); if (SUCCEEDED(result)) { result = E_FAIL; if (exists != FALSE) { IDWriteFontFamily *family; result = mycoll_->GetFontFamily(index, &family); if (SUCCEEDED(result)) { result = family->GetFirstMatchingFont( (DWRITE_FONT_WEIGHT)logFont->lfWeight, DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, font); iunknown_release(family); } } } if (FAILED(result)) { OutputDebugString("delegate_dwrite_gdi_interop::CreateFontFromLOGFONT -> fallback"); result = orig_this->CreateFontFromLOGFONT(logFont, font); } return result; }
virtual HRESULT STDMETHODCALLTYPE CreateBitmapRenderTarget( HDC hdc, UINT32 width, UINT32 height, IDWriteBitmapRenderTarget **renderTarget) { return orig_this->CreateBitmapRenderTarget(hdc, width, height, renderTarget); }
void DWriteContext::DrawText(HDC hdc, const WCHAR* text, int len, int x, int y, int w, int h, int cellWidth, COLORREF color) { HRESULT hr = S_OK; IDWriteBitmapRenderTarget *bmpRT = NULL; // Skip when any fonts are not set. if (mTextFormat == NULL) return; // Check possibility of zero divided error. if (cellWidth == 0 || mDpiScaleX == 0.0f || mDpiScaleY == 0.0f) return; if (SUCCEEDED(hr)) hr = mGdiInterop->CreateBitmapRenderTarget(hdc, w, h, &bmpRT); if (SUCCEEDED(hr)) { IDWriteTextLayout *textLayout = NULL; HDC memdc = bmpRT->GetMemoryDC(); BitBlt(memdc, 0, 0, w, h, hdc, x, y, SRCCOPY); hr = mDWriteFactory->CreateGdiCompatibleTextLayout( text, len, mTextFormat, PixelsToDipsX(w), PixelsToDipsY(h), mDpiScaleX, NULL, TRUE, &textLayout); if (SUCCEEDED(hr)) { DWRITE_TEXT_RANGE textRange = { 0, (UINT32)len }; textLayout->SetFontWeight(mFontWeight, textRange); textLayout->SetFontStyle(mFontStyle, textRange); } if (SUCCEEDED(hr)) { GdiTextRenderer *renderer = new GdiTextRenderer(bmpRT, mRenderingParams); GdiTextRendererContext data = { color, PixelsToDipsX(cellWidth), 0.0f }; textLayout->Draw(&data, renderer, 0, 0); SafeRelease(&renderer); } BitBlt(hdc, x, y, w, h, memdc, 0, 0, SRCCOPY); SafeRelease(&textLayout); } SafeRelease(&bmpRT); }
HRESULT GdiTextRenderer::Initialize(HWND referenceHwnd, HDC referenceDC, UINT width, UINT height) { HRESULT hr; IDWriteGdiInterop* gdiInterop = NULL; hr = g_dwrite->GetGdiInterop(&gdiInterop); if (SUCCEEDED(hr)) { hr = gdiInterop->CreateBitmapRenderTarget(referenceDC, width, height, &m_renderTarget); } if (SUCCEEDED(hr)) { hr = g_dwrite->CreateMonitorRenderingParams( MonitorFromWindow(referenceHwnd, MONITOR_DEFAULTTONULL), &m_renderingParams); } SafeRelease(&gdiInterop); return hr; }
HRESULT DWriteContext::SetLOGFONT(const LOGFONTW &logFont, float fontSize) { // Most of this function is copy from: http://msdn.microsoft.com/en-us/library/windows/desktop/dd941783(v=vs.85).aspx HRESULT hr = S_OK; IDWriteFont *font = NULL; IDWriteFontFamily *fontFamily = NULL; IDWriteLocalizedStrings *localizedFamilyNames = NULL; if (SUCCEEDED(hr)) { hr = mGdiInterop->CreateFontFromLOGFONT(&logFont, &font); } // Get the font family to which this font belongs. if (SUCCEEDED(hr)) { hr = font->GetFontFamily(&fontFamily); } // Get the family names. This returns an object that encapsulates one or // more names with the same meaning but in different languages. if (SUCCEEDED(hr)) { hr = fontFamily->GetFamilyNames(&localizedFamilyNames); } // Get the family name at index zero. If we were going to display the name // we'd want to try to find one that matched the use locale, but for // purposes of creating a text format object any language will do. wchar_t familyName[100]; if (SUCCEEDED(hr)) { hr = localizedFamilyNames->GetString(0, familyName, ARRAYSIZE(familyName)); } if (SUCCEEDED(hr)) { // If no font size was passed in use the lfHeight of the LOGFONT. if (fontSize == 0) { // Convert from pixels to DIPs. fontSize = PixelsToDipsY(logFont.lfHeight); if (fontSize < 0) { // Negative lfHeight represents the size of the em unit. fontSize = -fontSize; } else { // Positive lfHeight represents the cell height (ascent + // descent). DWRITE_FONT_METRICS fontMetrics; font->GetMetrics(&fontMetrics); // Convert the cell height (ascent + descent) from design units // to ems. float cellHeight = static_cast<float>( fontMetrics.ascent + fontMetrics.descent) / fontMetrics.designUnitsPerEm; // Divide the font size by the cell height to get the font em // size. fontSize /= cellHeight; } } } // The text format includes a locale name. Ideally, this would be the // language of the text, which may or may not be the same as the primary // language of the user. However, for our purposes the user locale will do. wchar_t localeName[LOCALE_NAME_MAX_LENGTH]; if (SUCCEEDED(hr)) { if (GetUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH) == 0) hr = HRESULT_FROM_WIN32(GetLastError()); } if (SUCCEEDED(hr)) { // Create the text format object. hr = mDWriteFactory->CreateTextFormat( familyName, NULL, // no custom font collection font->GetWeight(), font->GetStyle(), font->GetStretch(), fontSize, localeName, &mTextFormat); } if (SUCCEEDED(hr)) { mFontWeight = static_cast<DWRITE_FONT_WEIGHT>(logFont.lfWeight); mFontStyle = logFont.lfItalic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL; } SafeRelease(&localizedFamilyNames); SafeRelease(&fontFamily); SafeRelease(&font); return hr; }
HRESULT DWriteRenderer::PrepareMagnifier(HDC hdc) { HRESULT hr = S_OK; if (!magnifier_.visible) { SafeRelease(&magnifierTarget_); return hr; } // Determine the size and scale factor for the magnifier render target. In vector // mode we render using a scale transform. In all other modes we render at normal // size and then scale up the pixels afterwards. SIZE targetSize = magnifier_.magnifierSize; int targetScale = magnifier_.scale; if (magnifier_.type != MagnifierInfo::Vector) { targetSize.cx /= targetScale; targetSize.cy /= targetScale; targetScale = 1; } // Create a separate render target for the magnifier if we haven't already. if (SUCCEEDED(hr) && magnifierTarget_ == NULL) { IDWriteGdiInterop* gdiInterop = NULL; if (SUCCEEDED(hr)) { hr = g_dwriteFactory->GetGdiInterop(&gdiInterop); } if (SUCCEEDED(hr)) { hr = gdiInterop->CreateBitmapRenderTarget(hdc, targetSize.cx, targetSize.cy, &magnifierTarget_); } SafeRelease(&gdiInterop); } DWRITE_MATRIX zoomTransform;; if (SUCCEEDED(hr)) { // Clear the background. HDC hdcMagnifier = magnifierTarget_->GetMemoryDC(); SelectObject(hdcMagnifier, GetSysColorBrush(COLOR_WINDOW)); PatBlt(hdcMagnifier, 0, 0, magnifier_.magnifierSize.cx, magnifier_.magnifierSize.cy, PATCOPY); // Create a transform that translates and scales the focus rect to the origin of the magnifier target. float focusLeft = PixelsToDipsX(magnifier_.focusPos.x); float focusTop = PixelsToDipsY(magnifier_.focusPos.y); zoomTransform.m11 = transform_.m11 * targetScale; zoomTransform.m12 = transform_.m12 * targetScale; zoomTransform.m21 = transform_.m21 * targetScale; zoomTransform.m22 = transform_.m22 * targetScale; zoomTransform.dx = (transform_.dx - focusLeft) * targetScale; zoomTransform.dy = (transform_.dy - focusTop) * targetScale; } if (SUCCEEDED(hr)) { hr = magnifierTarget_->SetCurrentTransform(&zoomTransform); } return hr; }
HRESULT DWriteRenderer::Draw(HDC hdc) { HRESULT hr = S_OK; // Create the bitmap render target if we don't already have it. if (renderTarget_ == NULL) { IDWriteGdiInterop* gdiInterop = NULL; if (SUCCEEDED(hr)) { hr = g_dwriteFactory->GetGdiInterop(&gdiInterop); } if (SUCCEEDED(hr)) { hr = gdiInterop->CreateBitmapRenderTarget(hdc, width_, height_, &renderTarget_); } if (SUCCEEDED(hr)) { hr = renderTarget_->SetPixelsPerDip(g_dpiY / 96.0f); } SafeRelease(&gdiInterop); } // Create the rendering params object if we haven't already. if (SUCCEEDED(hr) && renderingParams_ == NULL) { hr = g_dwriteFactory->CreateRenderingParams(&renderingParams_); } HDC hdcMem = NULL; if (SUCCEEDED(hr)) { // Clear the background. hdcMem = renderTarget_->GetMemoryDC(); SelectObject(hdcMem, GetSysColorBrush(COLOR_WINDOW)); PatBlt(hdcMem, 0, 0, width_, height_, PATCOPY); // Set the rendering transform. renderTarget_->SetCurrentTransform(&transform_); // Prepare the render target we use for the magnifier. PrepareMagnifier(hdc); } if (SUCCEEDED(hr)) { hr = InitializeTextLayout(); } if (SUCCEEDED(hr)) { // Render the text. The Draw method will call back to the IDWriteTextRenderer // methods implemented by this class. hr = textLayout_->Draw( NULL, // optional client drawing context this, // renderer callback textOriginX_, textOriginY_ ); } if (SUCCEEDED(hr)) { DrawMagnifier(); // Do the final BitBlt to the specified HDC. BitBlt(hdc, 0, 0, width_, height_, hdcMem, 0, 0, SRCCOPY | NOMIRRORBITMAP); } return hr; }
virtual HRESULT STDMETHODCALLTYPE CreateFontFaceFromHdc( HDC hdc, IDWriteFontFace **fontFace) { return orig_this->CreateFontFaceFromHdc(hdc, fontFace); }
virtual HRESULT STDMETHODCALLTYPE ConvertFontFaceToLOGFONT( IDWriteFontFace *font, LOGFONTW *logFont) { return orig_this->ConvertFontFaceToLOGFONT(font, logFont); }