[Libreoffice-commits] core.git: Branch 'libreoffice-6-2' - vcl/inc vcl/win

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Mon Apr 29 09:49:10 UTC 2019


 vcl/inc/win/DWriteTextRenderer.hxx |   12 ++++++++++++
 vcl/inc/win/winlayout.hxx          |    1 +
 vcl/win/gdi/DWriteTextRenderer.cxx |   21 +++++++++++++++++++--
 vcl/win/gdi/winlayout.cxx          |   19 +++++++++++++++----
 4 files changed, 47 insertions(+), 6 deletions(-)

New commits:
commit 4266020a78e98d7271e7dca8f5727cd7a419afc6
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Wed Apr 24 17:07:30 2019 +0200
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Mon Apr 29 11:48:31 2019 +0200

    Related: tdf#113076 vcl win DirectWrite: handle stretched text
    
    Commit a51b7a1c3a7e7cf7b0c733e1dec40288278c1884 (tdf#103831, tdf#100986:
    Force using GDI when needed, 2017-03-03) noted that the DirectWrite text
    renderer doesn't support stretched text, add support for this now by
    setting a DirectWrite transform matrix that only does horizontal
    scaling.
    
    With this, tdf#113076 is kept fixed, but at the same time manually
    stretched text keeps working. Previously the glyphs of the text had the
    correct size and position, but the glyphs themselves where not streched,
    but simply aligned to the left.
    
    (cherry picked from commit 51bcbfc88883596fceedfe019e841aab129425c9)
    
    Change-Id: I8fe8e74d3edc0d71ed2f16fcce66c6f5009ed264
    Reviewed-on: https://gerrit.libreoffice.org/71289
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lunak at collabora.com>

diff --git a/vcl/inc/win/DWriteTextRenderer.hxx b/vcl/inc/win/DWriteTextRenderer.hxx
index 0e81b67167d1..270c4772716f 100644
--- a/vcl/inc/win/DWriteTextRenderer.hxx
+++ b/vcl/inc/win/DWriteTextRenderer.hxx
@@ -95,6 +95,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 042e30e9f299..2bbd87a12206 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 6dbfdbf403c3..50ec50897c80 100644
--- a/vcl/win/gdi/DWriteTextRenderer.cxx
+++ b/vcl/win/gdi/DWriteTextRenderer.cxx
@@ -271,6 +271,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)
@@ -297,9 +301,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,
@@ -418,6 +423,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 3aa8133be598..b9453f7b96d1 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -117,10 +117,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, DWRITE_GLYPH_OFFSET{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();
@@ -171,6 +172,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();
@@ -320,6 +322,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;
@@ -467,9 +479,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)
     {


More information about the Libreoffice-commits mailing list