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