[Libreoffice-commits] core.git: vcl/inc vcl/win

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Tue Apr 30 19:57:34 UTC 2019


 vcl/inc/win/DWriteTextRenderer.hxx |   11 +++++++----
 vcl/inc/win/winlayout.hxx          |    2 +-
 vcl/win/gdi/DWriteTextRenderer.cxx |   25 ++++++++++++++++++-------
 vcl/win/gdi/winlayout.cxx          |   16 +++++++++++-----
 4 files changed, 37 insertions(+), 17 deletions(-)

New commits:
commit f7453b956bcf83ec13c805d243f20cb209289179
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Tue Apr 30 17:38:14 2019 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue Apr 30 21:56:11 2019 +0200

    tdf#114209 vcl win DirectWrite: handle rotated text
    
    Commit a51b7a1c3a7e7cf7b0c733e1dec40288278c1884 (tdf#103831, tdf#100986:
    Force using GDI when needed, 2017-03-03) noted that the DirectWrite text
    renderer doesn't support vertical text, add initial support for this now
    by extending the DirectWrite transform matrix to do rotation as well.
    
    This is initial support, as it can be improved in two ways:
    
    - vertical text is not cached
    
    - only vertical Latin text is handled, which wants rotated glyphs (vs
      e.g. Japanese text that would not rotate the glyphs)
    
    With this, the "unreadable" text in the bugdoc's chart is on par with
    the the GDI rendering.
    
    Change-Id: I07af4de6cb437f83cc40546396ec8c8aac456bb3
    Reviewed-on: https://gerrit.libreoffice.org/71592
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/vcl/inc/win/DWriteTextRenderer.hxx b/vcl/inc/win/DWriteTextRenderer.hxx
index a84cf81b9b66..9011a951d277 100644
--- a/vcl/inc/win/DWriteTextRenderer.hxx
+++ b/vcl/inc/win/DWriteTextRenderer.hxx
@@ -81,12 +81,15 @@ private:
     D2DTextAntiAliasMode meTextAntiAliasMode;
 };
 
-/// Sets and unsets the needed DirectWrite transform to support the font's horizontal scaling.
-class WinFontStretchGuard
+/**
+ * Sets and unsets the needed DirectWrite transform to support the font's horizontal scaling and
+ * rotation.
+ */
+class WinFontTransformGuard
 {
 public:
-    WinFontStretchGuard(ID2D1RenderTarget* pRenderTarget, float fHScale);
-    ~WinFontStretchGuard();
+    WinFontTransformGuard(ID2D1RenderTarget* pRenderTarget, float fHScale, const GenericSalLayout& rLayout, const D2D1_POINT_2F& rBaseline);
+    ~WinFontTransformGuard();
 
 private:
     ID2D1RenderTarget* mpRenderTarget;
diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx
index 257c92e1a672..991c68f15b66 100644
--- a/vcl/inc/win/winlayout.hxx
+++ b/vcl/inc/win/winlayout.hxx
@@ -165,7 +165,7 @@ public:
 
     const WinFontFace * GetFontFace() const { return static_cast<const WinFontFace *>(LogicalFontInstance::GetFontFace()); }
 
-    bool CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, SalGraphics& rGraphics);
+    bool CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, SalGraphics& rGraphics, const GenericSalLayout& rLayout);
     OpenGLGlyphCache& GetOpenGLGlyphCache() { return maOpenGLGlyphCache; }
 
     bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const override;
diff --git a/vcl/win/gdi/DWriteTextRenderer.cxx b/vcl/win/gdi/DWriteTextRenderer.cxx
index dac6452a41a5..98daff12c4a4 100644
--- a/vcl/win/gdi/DWriteTextRenderer.cxx
+++ b/vcl/win/gdi/DWriteTextRenderer.cxx
@@ -234,7 +234,6 @@ bool D2DWriteTextOutRenderer::performRender(GenericSalLayout const & rLayout, Sa
 
     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);
@@ -266,6 +265,7 @@ bool D2DWriteTextOutRenderer::performRender(GenericSalLayout const & rLayout, Sa
             DWRITE_GLYPH_OFFSET glyphOffsets[] = { { 0.0f, 0.0f }, };
             D2D1_POINT_2F baseline = { static_cast<FLOAT>(aPos.X() - bounds.Left()) / fHScale,
                                        static_cast<FLOAT>(aPos.Y() - bounds.Top()) };
+            WinFontTransformGuard aTransformGuard(mpRT, fHScale, rLayout, baseline);
             DWRITE_GLYPH_RUN glyphs = {
                 mpFontFace,
                 mlfEmHeight,
@@ -384,18 +384,29 @@ bool D2DWriteTextOutRenderer::GetDWriteFaceFromHDC(HDC hDC, IDWriteFontFace ** p
     return succeeded;
 }
 
-WinFontStretchGuard::WinFontStretchGuard(ID2D1RenderTarget* pRenderTarget, float fHScale)
+WinFontTransformGuard::WinFontTransformGuard(ID2D1RenderTarget* pRenderTarget, float fHScale,
+                                             const GenericSalLayout& rLayout,
+                                             const D2D1_POINT_2F& rBaseline)
     : mpRenderTarget(pRenderTarget)
 {
     pRenderTarget->GetTransform(&maTransform);
-    if (fHScale == 1.0f)
-        return;
+    D2D1::Matrix3x2F aTransform = maTransform;
+    if (fHScale != 1.0f)
+    {
+        aTransform
+            = aTransform * D2D1::Matrix3x2F::Scale(D2D1::Size(fHScale, 1.0f), D2D1::Point2F(0, 0));
+    }
 
-    D2D1::Matrix3x2F aTransform
-        = maTransform * D2D1::Matrix3x2F::Scale(D2D1::Size(fHScale, 1.0f), D2D1::Point2F(0, 0));
+    if (rLayout.GetOrientation() != 0)
+    {
+        // DWrite angle is in clockwise degrees, our orientation is in counter-clockwise 10th
+        // degrees.
+        aTransform
+            = aTransform * D2D1::Matrix3x2F::Rotation(-rLayout.GetOrientation() / 10, rBaseline);
+    }
     mpRenderTarget->SetTransform(aTransform);
 }
 
-WinFontStretchGuard::~WinFontStretchGuard() { mpRenderTarget->SetTransform(maTransform); }
+WinFontTransformGuard::~WinFontTransformGuard() { 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 1d804fcd08d1..1f0af819f6a1 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -57,7 +57,8 @@ GlobalOpenGLGlyphCache * GlobalOpenGLGlyphCache::get()
     return data->m_pGlobalOpenGLGlyphCache.get();
 }
 
-bool WinFontInstance::CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, SalGraphics& rGraphics)
+bool WinFontInstance::CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex,
+                                        SalGraphics& rGraphics, const GenericSalLayout& rLayout)
 {
     OpenGLGlyphDrawElement aElement;
 
@@ -171,7 +172,7 @@ bool WinFontInstance::CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, S
         0
     };
 
-    WinFontStretchGuard aStretchGuard(pRT, fHScale);
+    WinFontTransformGuard aTransformGuard(pRT, fHScale, rLayout, baseline);
     pRT->BeginDraw();
     pRT->DrawGlyphRun(baseline, &glyphs, pBrush);
     HRESULT hResult = pRT->EndDraw();
@@ -400,6 +401,10 @@ bool WinSalGraphics::CacheGlyphs(const GenericSalLayout& rLayout)
     if (!bDoGlyphCaching)
         return false;
 
+    if (rLayout.GetOrientation())
+        // Our caching is incomplete, skip it for non-horizontal text.
+        return false;
+
     HDC hDC = getHDC();
     WinFontInstance& rFont = *static_cast<WinFontInstance*>(&rLayout.GetFont());
     HFONT hFONT = rFont.GetHFONT();
@@ -411,7 +416,7 @@ bool WinSalGraphics::CacheGlyphs(const GenericSalLayout& rLayout)
     {
         if (!rFont.GetOpenGLGlyphCache().IsGlyphCached(pGlyph->m_aGlyphId))
         {
-            if (!rFont.CacheGlyphToAtlas(hDC, hFONT, pGlyph->m_aGlyphId, *this))
+            if (!rFont.CacheGlyphToAtlas(hDC, hFONT, pGlyph->m_aGlyphId, *this, rLayout))
                 return false;
         }
     }
@@ -472,8 +477,9 @@ 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 text.
-    bool bForceGDI = rLayout.GetOrientation();
+    // Our DirectWrite renderer is incomplete, skip it for vertical text where glyphs are not
+    // rotated.
+    bool bForceGDI = rLayout.GetFont().GetFontSelectPattern().mbVertical;
 
     if (!bUseOpenGL)
     {


More information about the Libreoffice-commits mailing list