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 51bcbfc88883596fceedfe019e841aab129425c9
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Apr 24 17:07:30 2019 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Apr 24 18:40:15 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.
    
    Change-Id: I8fe8e74d3edc0d71ed2f16fcce66c6f5009ed264
    Reviewed-on: https://gerrit.libreoffice.org/71245
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

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)
     {
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to