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);
