drawinglayer/source/primitive2d/textbreakuphelper.cxx         |    5 ++++-
 drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx  |    4 +++-
 drawinglayer/source/primitive2d/textprimitive2d.cxx           |    3 ++-
 drawinglayer/source/processor2d/vclprocessor2d.cxx            |    3 +++
 drawinglayer/source/tools/emfphelperdata.cxx                  |    2 ++
 drawinglayer/source/tools/wmfemfhelper.cxx                    |    5 ++++-
 editeng/source/editeng/StripPortionsHelper.cxx                |    4 +++-
 include/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx |    1 +
 include/drawinglayer/primitive2d/textprimitive2d.hxx          |    7 ++++++-
 svgio/source/svgreader/svgcharacternode.cxx                   |    1 +
 vcl/qa/cppunit/pdfexport/pdfexport2.cxx                       |    4 ++--
 11 files changed, 31 insertions(+), 8 deletions(-)

New commits:
commit 1bdf1e2d52a7fae3e1a58ddf15a7657df3d47004
Author:     Khaled Hosny <[email protected]>
AuthorDate: Thu Sep 25 16:33:09 2025 +0300
Commit:     Khaled Hosny <[email protected]>
CommitDate: Thu Sep 25 18:52:49 2025 +0200

    tdf#168371: Disable ligatures in Impress/Draw with character spacing
    
    This is follow up to commit:
    
    commit b9f0caad5d9e628f82d5148dfc7d2436d32817e2
    Author: Khaled Hosny <[email protected]>
    Date:   Tue Aug 23 04:13:28 2022 +0200
    
        tdf#66819: Disable ligatures with character spacing
    
    Even though editengine was applying letter spacing, when drawing with
    drawinglayer, letter spacing was not propagated which caused VCL to not
    disable the ligature features.
    
    Change-Id: Ia8bf2231478720262484a757e16fe5afec3cd28e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191512
    Reviewed-by: Khaled Hosny <[email protected]>
    Tested-by: Jenkins

diff --git a/drawinglayer/source/primitive2d/textbreakuphelper.cxx 
b/drawinglayer/source/primitive2d/textbreakuphelper.cxx
index eac53589a7ff..b27268fc25c5 100644
--- a/drawinglayer/source/primitive2d/textbreakuphelper.cxx
+++ b/drawinglayer/source/primitive2d/textbreakuphelper.cxx
@@ -147,6 +147,7 @@ namespace drawinglayer::primitive2d
                         mrSource.getLocale(),
                         mrSource.getFontColor(),
                         mrSource.getTextFillColor(),
+                        mrSource.getLetterSpacing(),
 
                         pTextDecoratedPortionPrimitive2D->getOverlineColor(),
                         pTextDecoratedPortionPrimitive2D->getTextlineColor(),
@@ -177,7 +178,9 @@ namespace drawinglayer::primitive2d
                         std::move(aNewKashidaArray),
                         mrSource.getFontAttribute(),
                         mrSource.getLocale(),
-                        mrSource.getFontColor()));
+                        mrSource.getFontColor(),
+                        mrSource.getTextFillColor(),
+                        mrSource.getLetterSpacing()));
             }
         }
 
diff --git a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx 
b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
index bfa5ebbb7eea..f3abbe41f4a2 100644
--- a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
@@ -463,6 +463,7 @@ namespace drawinglayer::primitive2d
             const css::lang::Locale& rLocale,
             const basegfx::BColor& rFontColor,
             const Color& rFillColor,
+            short nLetterSpacing,
 
             // local parameters
             const basegfx::BColor& rOverlineColor,
@@ -487,7 +488,8 @@ namespace drawinglayer::primitive2d
                 rFontAttribute,
                 rLocale,
                 rFontColor,
-                rFillColor),
+                rFillColor,
+                nLetterSpacing),
             maBufferedBrokenUpText(),
             maBufferedDecorationGeometry(),
             maOverlineColor(rOverlineColor),
diff --git a/drawinglayer/source/primitive2d/textprimitive2d.cxx 
b/drawinglayer/source/primitive2d/textprimitive2d.cxx
index 973ea3aa95fb..ae1b049db574 100644
--- a/drawinglayer/source/primitive2d/textprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/textprimitive2d.cxx
@@ -205,7 +205,7 @@ TextSimplePortionPrimitive2D::TextSimplePortionPrimitive2D(
     basegfx::B2DHomMatrix rNewTransform, OUString rText, sal_Int32 
nTextPosition,
     sal_Int32 nTextLength, std::vector<double>&& rDXArray, 
std::vector<sal_Bool>&& rKashidaArray,
     attribute::FontAttribute aFontAttribute, css::lang::Locale aLocale,
-    const basegfx::BColor& rFontColor, const Color& rTextFillColor)
+    const basegfx::BColor& rFontColor, const Color& rTextFillColor, short 
nLetterSpacing)
     : maTextTransform(std::move(rNewTransform))
     , maText(std::move(rText))
     , mnTextPosition(nTextPosition)
@@ -216,6 +216,7 @@ TextSimplePortionPrimitive2D::TextSimplePortionPrimitive2D(
     , maLocale(std::move(aLocale))
     , maFontColor(rFontColor)
     , maTextFillColor(rTextFillColor)
+    , mnLetterSpacing(nLetterSpacing)
 {
 #if OSL_DEBUG_LEVEL > 0
     const sal_Int32 aStringLength(getText().getLength());
diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx 
b/drawinglayer/source/processor2d/vclprocessor2d.cxx
index 4d089830a9db..eebb5a99f9b0 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -442,6 +442,9 @@ void 
VclProcessor2D::RenderTextSimpleOrDecoratedPortionPrimitive2D(
                                     basegfx::fround<tools::Long>(aPointY));
             }
 
+            // tdf#168371 set letter spacing so that VCL knows it has to 
disable ligatures
+            aFont.SetFixKerning(rTextCandidate.getLetterSpacing());
+
             // tdf#152990 set the font after the MapMode is (potentially) set 
so canvas uses the desired
             // font size
             mpOutputDevice->SetFont(aFont);
diff --git a/drawinglayer/source/tools/emfphelperdata.cxx 
b/drawinglayer/source/tools/emfphelperdata.cxx
index ea1f6c34ef1f..143eeec8ac72 100644
--- a/drawinglayer/source/tools/emfphelperdata.cxx
+++ b/drawinglayer/source/tools/emfphelperdata.cxx
@@ -1705,6 +1705,7 @@ namespace emfplushelper
                                             locale,
                                             color.getBColor(), // Font Color
                                             COL_TRANSPARENT,   // Fill Color
+                                            0,
                                             color.getBColor(), // OverlineColor
                                             color.getBColor(), // TextlineColor
                                             
drawinglayer::primitive2d::TEXT_LINE_NONE,
@@ -2219,6 +2220,7 @@ namespace emfplushelper
                                                     
Application::GetSettings().GetLanguageTag().getLocale(),
                                                     color.getBColor(),
                                                     COL_TRANSPARENT,
+                                                    0,
                                                     color.getBColor(),
                                                     color.getBColor(),
                                                     
drawinglayer::primitive2d::TEXT_LINE_NONE,
diff --git a/drawinglayer/source/tools/wmfemfhelper.cxx 
b/drawinglayer/source/tools/wmfemfhelper.cxx
index 18889567001f..e58c21ce5a53 100644
--- a/drawinglayer/source/tools/wmfemfhelper.cxx
+++ b/drawinglayer/source/tools/wmfemfhelper.cxx
@@ -1125,6 +1125,7 @@ namespace wmfemfhelper
                     aLocale,
                     aFontColor,
                     aFillColor,
+                    rFont.GetFixKerning(),
 
                     // attributes for TextDecoratedPortionPrimitive2D
                     rProperty.getOverlineColorActive() ? 
rProperty.getOverlineColor() : aFontColor,
@@ -1152,7 +1153,9 @@ namespace wmfemfhelper
                     std::move(rKashidaArray),
                     std::move(aFontAttribute),
                     std::move(aLocale),
-                    aFontColor);
+                    aFontColor,
+                    aFillColor,
+                    rFont.GetFixKerning());
             }
         }
 
diff --git a/editeng/source/editeng/StripPortionsHelper.cxx 
b/editeng/source/editeng/StripPortionsHelper.cxx
index 71391194734b..6447575919af 100644
--- a/editeng/source/editeng/StripPortionsHelper.cxx
+++ b/editeng/source/editeng/StripPortionsHelper.cxx
@@ -200,6 +200,7 @@ buildTextPortionPrimitive(const DrawPortionInfo& rInfo, 
const OUString& rText,
             rNewTransform, rText, rInfo.mnTextStart, rInfo.mnTextLen, 
std::vector(rDXArray),
             std::move(aKashidaArray), rFontAttribute,
             rInfo.mpLocale ? *rInfo.mpLocale : css::lang::Locale(), 
aBFontColor, aTextFillColor,
+            rInfo.mrFont.GetFixKerning(),
 
             // attributes for TextDecoratedPortionPrimitive2D
             aBOverlineColor, aBUnderlineColor, eFontOverline, eFontLineStyle, 
bUnderlineAbove,
@@ -212,7 +213,8 @@ buildTextPortionPrimitive(const DrawPortionInfo& rInfo, 
const OUString& rText,
         pNewPrimitive = new 
drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
             rNewTransform, rText, rInfo.mnTextStart, rInfo.mnTextLen, 
std::vector(rDXArray),
             std::move(aKashidaArray), rFontAttribute,
-            rInfo.mpLocale ? *rInfo.mpLocale : css::lang::Locale(), 
aBFontColor, aTextFillColor);
+            rInfo.mpLocale ? *rInfo.mpLocale : css::lang::Locale(), 
aBFontColor, aTextFillColor,
+            rInfo.mrFont.GetFixKerning());
     }
 
     return pNewPrimitive;
diff --git a/include/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx 
b/include/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx
index 07b780b24922..c635dc93ecfe 100644
--- a/include/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx
@@ -89,6 +89,7 @@ namespace drawinglayer::primitive2d
                 const css::lang::Locale& rLocale,
                 const basegfx::BColor& rFontColor,
                 const Color& rFillColor,
+                short nLetterSpacing,
 
                 /// local parameters
                 const basegfx::BColor& rOverlineColor,
diff --git a/include/drawinglayer/primitive2d/textprimitive2d.hxx 
b/include/drawinglayer/primitive2d/textprimitive2d.hxx
index 0dfb6bae0b2c..d898db236cae 100644
--- a/include/drawinglayer/primitive2d/textprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/textprimitive2d.hxx
@@ -136,6 +136,9 @@ private:
     /// #i96669# internal: add simple range buffering for this primitive
     basegfx::B2DRange maB2DRange;
 
+    /// Letter spacing
+    short mnLetterSpacing;
+
 protected:
     /// local decomposition.
     virtual Primitive2DReference
@@ -155,7 +158,8 @@ public:
                                  std::vector<sal_Bool>&& rKashidaArray,
                                  attribute::FontAttribute aFontAttribute, 
css::lang::Locale aLocale,
                                  const basegfx::BColor& rFontColor,
-                                 const Color& rTextFillColor = 
COL_TRANSPARENT);
+                                 const Color& rTextFillColor = COL_TRANSPARENT,
+                                 short nLetterSpacing = 0);
 
     /** get text outlines as polygons and their according 
ObjectTransformation. Handles all
         the necessary VCL outline extractions, scaling adaptations and other 
stuff.
@@ -174,6 +178,7 @@ public:
     const css::lang::Locale& getLocale() const { return maLocale; }
     const basegfx::BColor& getFontColor() const { return maFontColor; }
     const Color& getTextFillColor() const { return maTextFillColor; }
+    short getLetterSpacing() const { return mnLetterSpacing; }
 
     /// helpers for determining various decoration states
     virtual bool hasTextRelief() const;
diff --git a/svgio/source/svgreader/svgcharacternode.cxx 
b/svgio/source/svgreader/svgcharacternode.cxx
index 99998b0863e7..eb5d16f0573c 100644
--- a/svgio/source/svgreader/svgcharacternode.cxx
+++ b/svgio/source/svgreader/svgcharacternode.cxx
@@ -413,6 +413,7 @@ namespace svgio::svgreader
                     std::move(aLocale),
                     aFill,
                     COL_TRANSPARENT,
+                    0,
 
                     // extra props for decorated
                     aDecoColor,
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport2.cxx 
b/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
index c237a6b3a27f..12a4ddbb6058 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
@@ -4181,9 +4181,9 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest2, testTdf145873)
     int nPageObjectCount = pPdfPage->getObjectCount();
 
     // tdf#145873: Without the fix #1 in place, this test would have failed 
with
-    // - Expected: 66
+    // - Expected: 107
     // - Actual  : 3
-    CPPUNIT_ASSERT_EQUAL(66, nPageObjectCount);
+    CPPUNIT_ASSERT_EQUAL(107, nPageObjectCount);
 
     auto pObject = pPdfPage->getObject(4);
     CPPUNIT_ASSERT_MESSAGE("no object", pObject != nullptr);

Reply via email to