diff options
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/win/DWriteTextRenderer.hxx | 12 | ||||
-rw-r--r-- | vcl/inc/win/winlayout.hxx | 1 | ||||
-rw-r--r-- | vcl/win/gdi/DWriteTextRenderer.cxx | 21 | ||||
-rw-r--r-- | vcl/win/gdi/winlayout.cxx | 19 |
4 files changed, 47 insertions, 6 deletions
diff --git a/vcl/inc/win/DWriteTextRenderer.hxx b/vcl/inc/win/DWriteTextRenderer.hxx index 92e0825bb8b3..a84cf81b9b66 100644 --- a/vcl/inc/win/DWriteTextRenderer.hxx +++ b/vcl/inc/win/DWriteTextRenderer.hxx @@ -81,6 +81,18 @@ private: D2DTextAntiAliasMode meTextAntiAliasMode; }; +/// Sets and unsets the needed DirectWrite transform to support the font's horizontal scaling. +class WinFontStretchGuard +{ +public: + WinFontStretchGuard(ID2D1RenderTarget* pRenderTarget, float fHScale); + ~WinFontStretchGuard(); + +private: + ID2D1RenderTarget* mpRenderTarget; + D2D1::Matrix3x2F maTransform; +}; + #endif // INCLUDED_VCL_INC_WIN_DWRITERENDERER_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx index 279c155b0a97..257c92e1a672 100644 --- a/vcl/inc/win/winlayout.hxx +++ b/vcl/inc/win/winlayout.hxx @@ -151,6 +151,7 @@ public: ~WinFontInstance() override; bool hasHScale() const; + float getHScale() const; void SetGraphics(WinSalGraphics*); WinSalGraphics* GetGraphics() const { return m_pGraphics; } diff --git a/vcl/win/gdi/DWriteTextRenderer.cxx b/vcl/win/gdi/DWriteTextRenderer.cxx index 117b35989b1c..dac6452a41a5 100644 --- a/vcl/win/gdi/DWriteTextRenderer.cxx +++ b/vcl/win/gdi/DWriteTextRenderer.cxx @@ -232,6 +232,10 @@ bool D2DWriteTextOutRenderer::performRender(GenericSalLayout const & rLayout, Sa if (!GetDWriteFaceFromHDC(hDC, &mpFontFace, &mlfEmHeight)) return false; + const WinFontInstance& rWinFont = static_cast<const WinFontInstance&>(rLayout.GetFont()); + float fHScale = rWinFont.getHScale(); + WinFontStretchGuard aStretchGuard(mpRT, fHScale); + tools::Rectangle bounds; bool succeeded = rLayout.GetBoundRect(bounds); if (succeeded) @@ -258,9 +262,10 @@ bool D2DWriteTextOutRenderer::performRender(GenericSalLayout const & rLayout, Sa while (rLayout.GetNextGlyph(&pGlyph, aPos, nStart)) { UINT16 glyphIndices[] = { pGlyph->m_aGlyphId }; - FLOAT glyphAdvances[] = { static_cast<FLOAT>(pGlyph->m_nNewWidth) }; + FLOAT glyphAdvances[] = { static_cast<FLOAT>(pGlyph->m_nNewWidth) / fHScale }; DWRITE_GLYPH_OFFSET glyphOffsets[] = { { 0.0f, 0.0f }, }; - D2D1_POINT_2F baseline = { static_cast<FLOAT>(aPos.X() - bounds.Left()), static_cast<FLOAT>(aPos.Y() - bounds.Top()) }; + D2D1_POINT_2F baseline = { static_cast<FLOAT>(aPos.X() - bounds.Left()) / fHScale, + static_cast<FLOAT>(aPos.Y() - bounds.Top()) }; DWRITE_GLYPH_RUN glyphs = { mpFontFace, mlfEmHeight, @@ -379,6 +384,18 @@ bool D2DWriteTextOutRenderer::GetDWriteFaceFromHDC(HDC hDC, IDWriteFontFace ** p return succeeded; } +WinFontStretchGuard::WinFontStretchGuard(ID2D1RenderTarget* pRenderTarget, float fHScale) + : mpRenderTarget(pRenderTarget) +{ + pRenderTarget->GetTransform(&maTransform); + if (fHScale == 1.0f) + return; + + D2D1::Matrix3x2F aTransform + = maTransform * D2D1::Matrix3x2F::Scale(D2D1::Size(fHScale, 1.0f), D2D1::Point2F(0, 0)); + mpRenderTarget->SetTransform(aTransform); +} +WinFontStretchGuard::~WinFontStretchGuard() { mpRenderTarget->SetTransform(maTransform); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx index b3fe0132b7df..1d804fcd08d1 100644 --- a/vcl/win/gdi/winlayout.cxx +++ b/vcl/win/gdi/winlayout.cxx @@ -116,10 +116,11 @@ bool WinFontInstance::CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, S std::vector<float> aGlyphAdv(1); // offsets between glyphs std::vector<DWRITE_GLYPH_OFFSET> aGlyphOffset(1, {0.0f, 0.0f}); std::vector<int> aEnds(1); // end of each glyph box + float fHScale = getHScale(); float totWidth = 0; { int overhang = aInkBoxes[0].Left(); - int blackWidth = aInkBoxes[0].getWidth(); // width of non-AA pixels + int blackWidth = aInkBoxes[0].getWidth() * fHScale; // width of non-AA pixels aElement.maLeftOverhangs = overhang; aGlyphAdv[0] = blackWidth + aElement.getExtraSpace(); @@ -170,6 +171,7 @@ bool WinFontInstance::CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, S 0 }; + WinFontStretchGuard aStretchGuard(pRT, fHScale); pRT->BeginDraw(); pRT->DrawGlyphRun(baseline, &glyphs, pBrush); HRESULT hResult = pRT->EndDraw(); @@ -314,6 +316,16 @@ bool WinFontInstance::hasHScale() const return nWidth != nHeight; } +float WinFontInstance::getHScale() const +{ + const FontSelectPattern& rPattern = GetFontSelectPattern(); + int nHeight(rPattern.mnHeight); + if (!nHeight) + return 1.0; + float nWidth(rPattern.mnWidth ? rPattern.mnWidth * GetAverageWidthFactor() : nHeight); + return nWidth / nHeight; +} + static hb_blob_t* getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pUserData) { sal_uLong nLength = 0; @@ -460,9 +472,8 @@ void WinSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout) const HFONT hLayoutFont = pWinFont->GetHFONT(); bool bUseOpenGL = OpenGLHelper::isVCLOpenGLEnabled() && !mbPrinter; - // Our DirectWrite renderer is incomplete, skip it for non-horizontal or - // stretched text. - bool bForceGDI = rLayout.GetOrientation() || (pWinFont->hasHScale() && !bUseOpenGL); + // Our DirectWrite renderer is incomplete, skip it for non-horizontal text. + bool bForceGDI = rLayout.GetOrientation(); if (!bUseOpenGL) { |