canvas/source/vcl/canvasfont.cxx |   32 ++++++++++----------------------
 canvas/source/vcl/canvasfont.hxx |    3 +++
 canvas/source/vcl/impltools.cxx  |   27 +++++++++++++++++++++++++++
 canvas/source/vcl/impltools.hxx  |    5 +++++
 canvas/source/vcl/textlayout.cxx |    8 ++++++++
 5 files changed, 53 insertions(+), 22 deletions(-)

New commits:
commit 2df481312ac949446684a5278a399ec178a89cf2
Author:     Khaled Hosny <kha...@libreofice.org>
AuthorDate: Mon Jul 10 13:40:28 2023 +0000
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Tue Jul 11 11:40:59 2023 +0200

    tdf#147999: Fix canvas font width for fallback fonts on Windows
    
    For some reason we are getting the wrong font width for fallback fonts, 
which
    results in rendering them squished. This happens only with VCL canvas, but 
not
    with DX one, so it shows when hardware acceleration is disabled (either
    explicitly or implicitly when Skia is enabled).
    
    Change-Id: I5a45b1c1d68f4c6e6dd6b43371602af3330a7cd3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154272
    Tested-by: Jenkins
    Reviewed-by: خالد حسني <kha...@libreoffice.org>
    (cherry picked from commit 199dbff478dacee0b1d65d521e5147ba88c96567)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154255
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/canvas/source/vcl/canvasfont.cxx b/canvas/source/vcl/canvasfont.cxx
index e7fab0492549..41b7da25016d 100644
--- a/canvas/source/vcl/canvasfont.cxx
+++ b/canvas/source/vcl/canvasfont.cxx
@@ -47,7 +47,8 @@ namespace vclcanvas
                       Size( 0, ::basegfx::fround(rFontRequest.CellSize) ) ) ),
         maFontRequest( rFontRequest ),
         mpRefDevice( &rDevice ),
-        mpOutDevProvider( rOutDevProvider )
+        mpOutDevProvider( rOutDevProvider ),
+        maFontMatrix( rFontMatrix )
     {
         maFont->SetAlignment( ALIGN_BASELINE );
         maFont->SetCharSet( 
(rFontRequest.FontDescription.IsSymbolFont==css::util::TriState_YES) ? 
RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE );
@@ -63,27 +64,7 @@ namespace vclcanvas
         maFont->SetLanguage( LanguageTag::convertToLanguageType( 
rFontRequest.Locale, false));
 
         // adjust to stretched/shrunk font
-        if( !::rtl::math::approxEqual( rFontMatrix.m00, rFontMatrix.m11) )
-        {
-            OutputDevice& rOutDev( rOutDevProvider->getOutDev() );
-
-            const bool bOldMapState( rOutDev.IsMapModeEnabled() );
-            rOutDev.EnableMapMode(false);
-
-            const Size aSize = rOutDev.GetFontMetric( *maFont ).GetFontSize();
-
-            const double fDividend( rFontMatrix.m10 + rFontMatrix.m11 );
-            double fStretch = rFontMatrix.m00 + rFontMatrix.m01;
-
-            if( !::basegfx::fTools::equalZero( fDividend) )
-                fStretch /= fDividend;
-
-            const ::tools::Long nNewWidth = ::basegfx::fround( aSize.Width() * 
fStretch );
-
-            maFont->SetAverageFontWidth( nNewWidth );
-
-            rOutDev.EnableMapMode(bOldMapState);
-        }
+        tools::setupFontWidth(rFontMatrix, maFont.get(), 
rOutDevProvider->getOutDev());
 
         sal_uInt32 nEmphasisMark = 0;
 
@@ -172,6 +153,13 @@ namespace vclcanvas
     {
         return *maFont;
     }
+
+    const css::geometry::Matrix2D& CanvasFont::getFontMatrix() const
+    {
+        SolarMutexGuard aGuard;
+
+        return maFontMatrix;
+    }
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/canvas/source/vcl/canvasfont.hxx b/canvas/source/vcl/canvasfont.hxx
index fdfa870f5ed3..834df756e0b7 100644
--- a/canvas/source/vcl/canvasfont.hxx
+++ b/canvas/source/vcl/canvasfont.hxx
@@ -75,11 +75,14 @@ namespace vclcanvas
 
         vcl::Font const & getVCLFont() const;
 
+        const css::geometry::Matrix2D& getFontMatrix() const;
+
     private:
         ::canvas::vcltools::VCLObject<vcl::Font>                          
maFont;
         css::rendering::FontRequest                                       
maFontRequest;
         css::uno::Reference< css::rendering::XGraphicDevice>              
mpRefDevice;
         OutDevProviderSharedPtr                                           
mpOutDevProvider;
+        css::geometry::Matrix2D                                           
maFontMatrix;
     };
 
 }
diff --git a/canvas/source/vcl/impltools.cxx b/canvas/source/vcl/impltools.cxx
index 5539a92d1734..0a44f22096f0 100644
--- a/canvas/source/vcl/impltools.cxx
+++ b/canvas/source/vcl/impltools.cxx
@@ -135,6 +135,33 @@ namespace vclcanvas::tools
             return true;
         }
 
+        void setupFontWidth(const css::geometry::Matrix2D& rFontMatrix,
+                            vcl::Font&                     rFont,
+                            OutputDevice&                  rOutDev)
+        {
+            rFont.SetFontSize(Size(0, rFont.GetFontHeight()));
+
+            if (!::rtl::math::approxEqual(rFontMatrix.m00, rFontMatrix.m11))
+            {
+                const bool bOldMapState(rOutDev.IsMapModeEnabled());
+                rOutDev.EnableMapMode(false);
+
+                const Size aSize = rOutDev.GetFontMetric(rFont).GetFontSize();
+
+                const double fDividend(rFontMatrix.m10 + rFontMatrix.m11);
+                double fStretch = rFontMatrix.m00 + rFontMatrix.m01;
+
+                if (!::basegfx::fTools::equalZero(fDividend))
+                    fStretch /= fDividend;
+
+                const ::tools::Long nNewWidth = 
::basegfx::fround(aSize.Width() * fStretch);
+
+                rFont.SetAverageFontWidth(nNewWidth);
+
+                rOutDev.EnableMapMode(bOldMapState);
+            }
+        }
+
         bool isRectangle( const ::tools::PolyPolygon& rPolyPoly )
         {
             // exclude some cheap cases first
diff --git a/canvas/source/vcl/impltools.hxx b/canvas/source/vcl/impltools.hxx
index f8a9db075227..030d5341b5b9 100644
--- a/canvas/source/vcl/impltools.hxx
+++ b/canvas/source/vcl/impltools.hxx
@@ -60,6 +60,7 @@ namespace com::sun::star::geometry
     struct RealPoint2D;
     struct RealSize2D;
     struct RealRectangle2D;
+    struct Matrix2D;
 }
 
 namespace com::sun::star::rendering
@@ -88,6 +89,10 @@ namespace vclcanvas
                                  const css::rendering::RenderState&    
renderState,
                                  ::OutputDevice const &                rOutDev 
);
 
+        void setupFontWidth(const css::geometry::Matrix2D& rFontMatrix,
+                            vcl::Font&                     rFont,
+                            OutputDevice&                  rOutDev);
+
         /** Predicate, to determine whether polygon is actually an 
axis-aligned rectangle
 
             @return true, if the polygon is a rectangle.
diff --git a/canvas/source/vcl/textlayout.cxx b/canvas/source/vcl/textlayout.cxx
index 689720e4570a..c31bf061319c 100644
--- a/canvas/source/vcl/textlayout.cxx
+++ b/canvas/source/vcl/textlayout.cxx
@@ -329,6 +329,14 @@ namespace vclcanvas
     {
         SolarMutexGuard aGuard;
 
+#ifdef _WIN32
+        // tdf#147999
+        // On Windows we get the wrong font width for fallback fonts unless we 
setup again here.
+        vcl::Font aFont(rOutDev.GetFont());
+        tools::setupFontWidth(mpFont->getFontMatrix(), aFont, rOutDev);
+        rOutDev.SetFont(aFont);
+#endif
+
         setupLayoutMode( rOutDev, mnTextDirection );
 
         if( maLogicalAdvancements.hasElements() )

Reply via email to