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 f1e35b8ffd498b2d390f50ae9816fe0d9c904a49
Author:     Khaled Hosny <[email protected]>
AuthorDate: Thu Sep 25 16:33:09 2025 +0300
Commit:     Xisco Fauli <[email protected]>
CommitDate: Mon Sep 29 16:13:58 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

diff --git a/drawinglayer/source/primitive2d/textbreakuphelper.cxx 
b/drawinglayer/source/primitive2d/textbreakuphelper.cxx
index 7356d606cb92..8f3c8eaf22a8 100644
--- a/drawinglayer/source/primitive2d/textbreakuphelper.cxx
+++ b/drawinglayer/source/primitive2d/textbreakuphelper.cxx
@@ -148,6 +148,7 @@ namespace drawinglayer::primitive2d
                         mrSource.getLocale(),
                         mrSource.getFontColor(),
                         mrSource.getTextFillColor(),
+                        mrSource.getLetterSpacing(),
 
                         pTextDecoratedPortionPrimitive2D->getOverlineColor(),
                         pTextDecoratedPortionPrimitive2D->getTextlineColor(),
@@ -178,7 +179,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 fa2c2086b53c..43d27411ea68 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 05b0bba59c62..4dccd6d5e671 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/editeng/source/editeng/StripPortionsHelper.cxx 
b/editeng/source/editeng/StripPortionsHelper.cxx
index 2d9312710860..47b64ed189a0 100644
--- a/editeng/source/editeng/StripPortionsHelper.cxx
+++ b/editeng/source/editeng/StripPortionsHelper.cxx
@@ -270,6 +270,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,
@@ -282,7 +283,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 ccaefc14dd34..286b7ba5b9ac 100644
--- a/svgio/source/svgreader/svgcharacternode.cxx
+++ b/svgio/source/svgreader/svgcharacternode.cxx
@@ -409,6 +409,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 f22fb4806b0f..596b36906282 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
@@ -4192,9 +4192,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