diff options
-rwxr-xr-x | vcl/inc/win/DWriteTextRenderer.hxx | 13 | ||||
-rwxr-xr-x | vcl/win/gdi/DWriteTextRenderer.cxx | 106 | ||||
-rw-r--r-- | vcl/win/gdi/winlayout.cxx | 3 |
3 files changed, 84 insertions, 38 deletions
diff --git a/vcl/inc/win/DWriteTextRenderer.hxx b/vcl/inc/win/DWriteTextRenderer.hxx index 611a134396f7..e87ef5fe977b 100755 --- a/vcl/inc/win/DWriteTextRenderer.hxx +++ b/vcl/inc/win/DWriteTextRenderer.hxx @@ -29,8 +29,9 @@ enum class D2DTextAntiAliasMode { Default, - ClearType, + Aliased, AntiAliased, + ClearType, }; class D2DWriteTextOutRenderer : public TextOutRenderer @@ -55,7 +56,7 @@ public: SalGraphics &rGraphics, HDC hDC) override; - bool BindDC(HDC hDC, tools::Rectangle const & rRect = tools::Rectangle(0, 0, 1, 1)); + HRESULT BindDC(HDC hDC, tools::Rectangle const & rRect = tools::Rectangle(0, 0, 1, 1)); bool BindFont(HDC hDC) /*override*/; bool ReleaseFont() /*override*/; @@ -70,10 +71,8 @@ public: bool Ready() const; void applyTextAntiAliasMode(); - void setTextAntiAliasMode(D2DTextAntiAliasMode eMode) - { - meTextAntiAliasMode = eMode; - } + void changeTextAntiAliasMode(D2DTextAntiAliasMode eMode); + private: static void CleanupModules(); @@ -82,6 +81,7 @@ private: D2DWriteTextOutRenderer & operator = (const D2DWriteTextOutRenderer &) = delete; bool GetDWriteFaceFromHDC(HDC hDC, IDWriteFontFace ** ppFontFace, float * lfSize) const; + bool performRender(CommonSalLayout const &rLayout, SalGraphics &rGraphics, HDC hDC, bool& bRetry); ID2D1Factory * mpD2DFactory; IDWriteFactory * mpDWriteFactory; @@ -93,7 +93,6 @@ private: float mlfEmHeight; HDC mhDC; D2DTextAntiAliasMode meTextAntiAliasMode; - IDWriteRenderingParams* mpRenderingParameters; }; #endif // INCLUDED_VCL_INC_WIN_DWRITERENDERER_HXX diff --git a/vcl/win/gdi/DWriteTextRenderer.cxx b/vcl/win/gdi/DWriteTextRenderer.cxx index f876f368e882..11469aadb597 100755 --- a/vcl/win/gdi/DWriteTextRenderer.cxx +++ b/vcl/win/gdi/DWriteTextRenderer.cxx @@ -80,12 +80,15 @@ D2DTextAntiAliasMode lclGetSystemTextAntiAliasMode() if (bFontSmoothing) { - UINT nType; - if (!SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &nType, 0)) - return eMode; + eMode = D2DTextAntiAliasMode::AntiAliased; - eMode = (nType == FE_FONTSMOOTHINGCLEARTYPE) ? D2DTextAntiAliasMode::ClearType - : D2DTextAntiAliasMode::AntiAliased; + UINT nType; + if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &nType, 0) && nType == FE_FONTSMOOTHINGCLEARTYPE) + eMode = D2DTextAntiAliasMode::ClearType; + } + else + { + eMode = D2DTextAntiAliasMode::Aliased; } return eMode; @@ -150,7 +153,6 @@ D2DWriteTextOutRenderer::D2DWriteTextOutRenderer() hr = CreateRenderTarget(); } meTextAntiAliasMode = lclGetSystemTextAntiAliasMode(); - mpRenderingParameters = lclSetRenderingMode(mpDWriteFactory, DWRITE_RENDERING_MODE_GDI_CLASSIC); } D2DWriteTextOutRenderer::~D2DWriteTextOutRenderer() @@ -169,23 +171,31 @@ D2DWriteTextOutRenderer::~D2DWriteTextOutRenderer() void D2DWriteTextOutRenderer::applyTextAntiAliasMode() { - D2D1_TEXT_ANTIALIAS_MODE eMode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT; + D2D1_TEXT_ANTIALIAS_MODE eTextAAMode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT; + DWRITE_RENDERING_MODE eRenderingMode = DWRITE_RENDERING_MODE_DEFAULT; switch (meTextAntiAliasMode) { case D2DTextAntiAliasMode::Default: - eMode = D2D1_TEXT_ANTIALIAS_MODE_ALIASED; + eRenderingMode = DWRITE_RENDERING_MODE_DEFAULT; + eTextAAMode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT; + break; + case D2DTextAntiAliasMode::Aliased: + eRenderingMode = DWRITE_RENDERING_MODE_ALIASED; + eTextAAMode = D2D1_TEXT_ANTIALIAS_MODE_ALIASED; break; case D2DTextAntiAliasMode::AntiAliased: - eMode = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE; + eRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC; + eTextAAMode = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE; break; case D2DTextAntiAliasMode::ClearType: - eMode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE; + eRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC; + eTextAAMode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE; break; default: break; } - mpRT->SetTextAntialiasMode(eMode); - mpRT->SetTextRenderingParams(mpRenderingParameters); + mpRT->SetTextRenderingParams(lclSetRenderingMode(mpDWriteFactory, eRenderingMode)); + mpRT->SetTextAntialiasMode(eTextAAMode); } HRESULT D2DWriteTextOutRenderer::CreateRenderTarget() @@ -195,7 +205,19 @@ HRESULT D2DWriteTextOutRenderer::CreateRenderTarget() mpRT->Release(); mpRT = nullptr; } - return CHECKHR(mpD2DFactory->CreateDCRenderTarget(&mRTProps, &mpRT)); + HRESULT hr = CHECKHR(mpD2DFactory->CreateDCRenderTarget(&mRTProps, &mpRT)); + if (SUCCEEDED(hr)) + applyTextAntiAliasMode(); + return hr; +} + +void D2DWriteTextOutRenderer::changeTextAntiAliasMode(D2DTextAntiAliasMode eMode) +{ + if (meTextAntiAliasMode != eMode) + { + meTextAntiAliasMode = eMode; + applyTextAntiAliasMode(); + } } bool D2DWriteTextOutRenderer::Ready() const @@ -203,41 +225,64 @@ bool D2DWriteTextOutRenderer::Ready() const return mpGdiInterop && mpRT; } -bool D2DWriteTextOutRenderer::BindDC(HDC hDC, tools::Rectangle const & rRect) +HRESULT D2DWriteTextOutRenderer::BindDC(HDC hDC, tools::Rectangle const & rRect) { - if (rRect.GetWidth() == 0 || rRect.GetHeight() == 0) - return false; RECT const rc = { rRect.Left(), rRect.Top(), rRect.Right(), rRect.Bottom() }; - return SUCCEEDED(CHECKHR(mpRT->BindDC(hDC, &rc))); + return CHECKHR(mpRT->BindDC(hDC, &rc)); +} + +bool D2DWriteTextOutRenderer::operator ()(CommonSalLayout const & rLayout, SalGraphics& rGraphics, HDC hDC) +{ + bool bRetry = false; + bool bResult = false; + int nCount = 0; + do + { + bRetry = false; + bResult = performRender(rLayout, rGraphics, hDC, bRetry); + nCount++; + } while (bRetry && nCount < 3); + return bResult; } -bool D2DWriteTextOutRenderer::operator ()(CommonSalLayout const &rLayout, - SalGraphics &rGraphics, - HDC hDC) +bool D2DWriteTextOutRenderer::performRender(CommonSalLayout const & rLayout, SalGraphics& rGraphics, HDC hDC, bool& bRetry) { if (!Ready()) return false; - if (!BindFont(hDC)) + HRESULT hr = S_OK; + hr = BindDC(hDC); + + if (hr == D2DERR_RECREATE_TARGET) { - // If for any reason we can't bind fallback to legacy APIs. - return ExTextOutRenderer()(rLayout, rGraphics, hDC); + CreateRenderTarget(); + bRetry = true; + return false; } + mlfEmHeight = 0; + if (!GetDWriteFaceFromHDC(hDC, &mpFontFace, &mlfEmHeight)) + return false; + tools::Rectangle bounds; bool succeeded = rLayout.GetBoundRect(rGraphics, bounds); - succeeded &= BindDC(hDC, bounds); // Update the bounding rect. + if (succeeded) + { + hr = BindDC(hDC, bounds); // Update the bounding rect. + succeeded &= SUCCEEDED(hr); + } ID2D1SolidColorBrush* pBrush = nullptr; - COLORREF bgrTextColor = GetTextColor(mhDC); - D2D1::ColorF aD2DColor(GetRValue(bgrTextColor) / 255.0f, GetGValue(bgrTextColor) / 255.0f, GetBValue(bgrTextColor) / 255.0f); - succeeded &= SUCCEEDED(CHECKHR(mpRT->CreateSolidColorBrush(aD2DColor, &pBrush))); + if (succeeded) + { + COLORREF bgrTextColor = GetTextColor(hDC); + D2D1::ColorF aD2DColor(GetRValue(bgrTextColor) / 255.0f, GetGValue(bgrTextColor) / 255.0f, GetBValue(bgrTextColor) / 255.0f); + succeeded &= SUCCEEDED(CHECKHR(mpRT->CreateSolidColorBrush(aD2DColor, &pBrush))); + } - HRESULT hr = S_OK; if (succeeded) { mpRT->BeginDraw(); - applyTextAntiAliasMode(); int nStart = 0; Point aPos(0, 0); @@ -271,7 +316,10 @@ bool D2DWriteTextOutRenderer::operator ()(CommonSalLayout const &rLayout, ReleaseFont(); if (hr == D2DERR_RECREATE_TARGET) + { CreateRenderTarget(); + bRetry = true; + } return succeeded; } diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx index facaf82ad93c..df3db65362ab 100644 --- a/vcl/win/gdi/winlayout.cxx +++ b/vcl/win/gdi/winlayout.cxx @@ -79,7 +79,7 @@ bool WinFontInstance::CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, S if (!pTxt) return false; - pTxt->setTextAntiAliasMode(D2DTextAntiAliasMode::AntiAliased); + pTxt->changeTextAntiAliasMode(D2DTextAntiAliasMode::AntiAliased); if (!pTxt->BindFont(aHDC.get())) { @@ -180,7 +180,6 @@ bool WinFontInstance::CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, S }; pRT->BeginDraw(); - pTxt->applyTextAntiAliasMode(); pRT->DrawGlyphRun(baseline, &glyphs, pBrush); HRESULT hResult = pRT->EndDraw(); |