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 ++++-
 include/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx |    1 +
 include/drawinglayer/primitive2d/textprimitive2d.hxx          |    7 ++++++-
 svgio/source/svgreader/svgcharacternode.cxx                   |    1 +
 svx/source/svdraw/svdotextdecomposition.cxx                   |    4 +++-
 vcl/qa/cppunit/pdfexport/pdfexport2.cxx                       |    4 ++--
 11 files changed, 31 insertions(+), 8 deletions(-)

New commits:
commit 1c38d6646e93a7f282812563ff824db5980006e7
Author:     Khaled Hosny <[email protected]>
AuthorDate: Thu Sep 25 16:33:09 2025 +0300
Commit:     Xisco Fauli <[email protected]>
CommitDate: Mon Sep 29 17:44:27 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
    Signed-off-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191627
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191635

diff --git a/drawinglayer/source/primitive2d/textbreakuphelper.cxx 
b/drawinglayer/source/primitive2d/textbreakuphelper.cxx
index 121e44ec8759..be3887d18363 100644
--- a/drawinglayer/source/primitive2d/textbreakuphelper.cxx
+++ b/drawinglayer/source/primitive2d/textbreakuphelper.cxx
@@ -150,6 +150,7 @@ namespace drawinglayer::primitive2d
                         mrSource.getLocale(),
                         mrSource.getFontColor(),
                         mrSource.getTextFillColor(),
+                        mrSource.getLetterSpacing(),
 
                         pTextDecoratedPortionPrimitive2D->getOverlineColor(),
                         pTextDecoratedPortionPrimitive2D->getTextlineColor(),
@@ -180,7 +181,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 d08f729e3abf..09c4243a4ee5 100644
--- a/drawinglayer/source/primitive2d/textprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/textprimitive2d.cxx
@@ -206,7 +206,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)
@@ -217,6 +217,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 73e3d8adbac9..cdefe9095ad4 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -445,6 +445,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 3d9bef482860..6346777c67e8 100644
--- a/drawinglayer/source/tools/emfphelperdata.cxx
+++ b/drawinglayer/source/tools/emfphelperdata.cxx
@@ -1707,6 +1707,7 @@ namespace emfplushelper
                                             locale,
                                             color.getBColor(), // Font Color
                                             COL_TRANSPARENT,   // Fill Color
+                                            0,
                                             color.getBColor(), // OverlineColor
                                             color.getBColor(), // TextlineColor
                                             
drawinglayer::primitive2d::TEXT_LINE_NONE,
@@ -2221,6 +2222,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 c77c653d4ebd..00aff7114203 100644
--- a/drawinglayer/source/tools/wmfemfhelper.cxx
+++ b/drawinglayer/source/tools/wmfemfhelper.cxx
@@ -1128,6 +1128,7 @@ namespace wmfemfhelper
                     aLocale,
                     aFontColor,
                     aFillColor,
+                    rFont.GetFixKerning(),
 
                     // attributes for TextDecoratedPortionPrimitive2D
                     rProperty.getOverlineColorActive() ? 
rProperty.getOverlineColor() : aFontColor,
@@ -1155,7 +1156,9 @@ namespace wmfemfhelper
                     std::move(rKashidaArray),
                     std::move(aFontAttribute),
                     std::move(aLocale),
-                    aFontColor);
+                    aFontColor,
+                    aFillColor,
+                    rFont.GetFixKerning());
             }
         }
 
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 878ef9d8291c..60ae7a2723d3 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 4e7c8e4794c5..4e24576158b7 100644
--- a/svgio/source/svgreader/svgcharacternode.cxx
+++ b/svgio/source/svgreader/svgcharacternode.cxx
@@ -408,6 +408,7 @@ namespace svgio::svgreader
                         std::move(aLocale),
                         aFill,
                         COL_TRANSPARENT,
+                        0,
 
                         // extra props for decorated
                         aDecoColor,
diff --git a/svx/source/svdraw/svdotextdecomposition.cxx 
b/svx/source/svdraw/svdotextdecomposition.cxx
index 3fc554792f65..92776677a1d5 100644
--- a/svx/source/svdraw/svdotextdecomposition.cxx
+++ b/svx/source/svdraw/svdotextdecomposition.cxx
@@ -563,6 +563,7 @@ namespace
                 rInfo.mpLocale ? *rInfo.mpLocale : css::lang::Locale(),
                 aBFontColor,
                 aTextFillColor,
+                rInfo.mrFont.GetFixKerning(),
 
                 // attributes for TextDecoratedPortionPrimitive2D
                 aBOverlineColor,
@@ -591,7 +592,8 @@ namespace
                 rFontAttribute,
                 rInfo.mpLocale ? *rInfo.mpLocale : css::lang::Locale(),
                 aBFontColor,
-                aTextFillColor);
+                aTextFillColor,
+                rInfo.mrFont.GetFixKerning());
         }
 
         return pNewPrimitive;
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport2.cxx 
b/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
index fa07b33e549b..fb9817fbff8b 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
@@ -4152,9 +4152,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