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); }
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; }
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 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; }