sd/qa/unit/export-tests.cxx | 4 - svx/CppunitTest_svx_removewhichrange.mk | 1 svx/source/svdraw/svdpdf.cxx | 66 +++++++++++++++++++++++++++----- 3 files changed, 59 insertions(+), 12 deletions(-)
New commits: commit 070be7bf8b79b4a9a04f37de5f7431195440ab40 Author: Caolán McNamara <[email protected]> AuthorDate: Thu Sep 25 17:54:44 2025 +0100 Commit: Caolán McNamara <[email protected]> CommitDate: Tue Oct 14 17:15:28 2025 +0200 make extracted ligatures non-discretionary If they appear in the cmaps then they are used and we want them, so assume they are liga instead of dlig. Change-Id: Ic044cc4c98385a52849e64b081f0af8d60249858 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191514 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> (cherry picked from commit 49e9cd83908c69f293115723f8b738e4416666fd) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192339 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/sd/qa/unit/export-tests.cxx b/sd/qa/unit/export-tests.cxx index 0b63a7274a63..e0a823ca5247 100644 --- a/sd/qa/unit/export-tests.cxx +++ b/sd/qa/unit/export-tests.cxx @@ -1092,7 +1092,7 @@ CPPUNIT_TEST_FIXTURE(SdExportTest, testExplodedPdfFont) CPPUNIT_ASSERT_EQUAL(u"normal"_ustr, sItalic); // check that the others remain as expected OUString sFontName = getXPath(pXml, "//font[2]", "name"); - CPPUNIT_ASSERT_EQUAL(u"Liberation Serif:dlig"_ustr, sFontName); + CPPUNIT_ASSERT_EQUAL(u"Liberation Serif"_ustr, sFontName); int nFontHeight = getXPath(pXml, "//font[2]", "height").toInt32(); CPPUNIT_ASSERT_EQUAL(494, nFontHeight); } @@ -1104,7 +1104,7 @@ CPPUNIT_TEST_FIXTURE(SdExportTest, testExplodedPdfFont) CPPUNIT_ASSERT_EQUAL(u"bold"_ustr, sWeight); // check that the others remain as expected OUString sFontName = getXPath(pXml, "//font[4]", "name"); - CPPUNIT_ASSERT_EQUAL(u"Liberation Sans:dlig"_ustr, sFontName); + CPPUNIT_ASSERT_EQUAL(u"Liberation Sans"_ustr, sFontName); int nFontHeight = getXPath(pXml, "//font[4]", "height").toInt32(); CPPUNIT_ASSERT_EQUAL(564, nFontHeight); } diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx index 6232f0f32f8d..37db6b706166 100644 --- a/svx/source/svdraw/svdpdf.cxx +++ b/svx/source/svdraw/svdpdf.cxx @@ -1229,7 +1229,7 @@ static void buildCMapAndFeatures(const OUString& CMapUrl, const OUString& Featur SvFileStream Features(FeaturesUrl, StreamMode::READWRITE | StreamMode::TRUNC); Features.WriteLine("languagesystem DFLT dflt;"); - Features.WriteLine("feature dlig {"); + Features.WriteLine("feature liga {"); for (const auto& ligature : ligatureGlyphToChars) { sal_Int32 nLigatureGlyph = ligature.first; @@ -1244,7 +1244,7 @@ static void buildCMapAndFeatures(const OUString& CMapUrl, const OUString& Featur ligatureLine += " by \" + OString::number(nLigatureGlyph) + ";"; Features.WriteLine(ligatureLine); } - Features.WriteLine("} dlig;"); + Features.WriteLine("} liga;"); Features.Close(); bFeatures = true; @@ -1370,7 +1370,7 @@ static EmbeddedFontInfo mergeFontSubsets(const OUString& mergedFontUrl, { SvFileStream Features(mergedFeaturesUrl, StreamMode::READWRITE | StreamMode::TRUNC); Features.WriteLine("languagesystem DFLT dflt;"); - Features.WriteLine("feature dlig {"); + Features.WriteLine("feature liga {"); for (const auto& ligature : ligatureGlyphToChars) { sal_Int32 nLigatureGlyph = ligature.first; @@ -1385,7 +1385,7 @@ static EmbeddedFontInfo mergeFontSubsets(const OUString& mergedFontUrl, ligatureLine += " by \" + OString::number(nLigatureGlyph) + ";"; Features.WriteLine(ligatureLine); } - Features.WriteLine("} dlig;"); + Features.WriteLine("} liga;"); Features.Close(); } @@ -1498,10 +1498,7 @@ void ImpSdrPdfImport::ImportText(std::unique_ptr<vcl::pdf::PDFiumPageObject> con aFnt.SetFontSize(aFontSize); if (!sFontName.isEmpty()) - { - //TODO: any way to know if we need to force discretionally ligatures - aFnt.SetFamilyName(sFontName + ":dlig"); - } + aFnt.SetFamilyName(sFontName); const int italicAngle = pPageObject->getFontAngle(); aFnt.SetItalic(italicAngle == 0 ? ITALIC_NONE commit 0c5dafe056d6642d7a1bf93f1ce23dfb39d16787 Author: Caolán McNamara <[email protected]> AuthorDate: Thu Sep 25 17:53:28 2025 +0100 Commit: Caolán McNamara <[email protected]> CommitDate: Tue Oct 14 17:15:14 2025 +0200 Add in legacy unicode ligature decomposition mapping explictly Change-Id: I22978bd0e5a00c064bfafd36c7ff137744b62c48 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191513 Reviewed-by: Miklos Vajna <[email protected]> Tested-by: Jenkins CollaboraOffice <[email protected]> (cherry picked from commit 6856e4c93d97695cf5a1bbdb763272e947436484) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192338 Tested-by: Caolán McNamara <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> diff --git a/svx/CppunitTest_svx_removewhichrange.mk b/svx/CppunitTest_svx_removewhichrange.mk index 9fea95320f7b..e29e3744b9f8 100644 --- a/svx/CppunitTest_svx_removewhichrange.mk +++ b/svx/CppunitTest_svx_removewhichrange.mk @@ -15,6 +15,7 @@ $(eval $(call gb_CppunitTest_add_exception_objects,svx_removewhichrange, \ $(eval $(call gb_CppunitTest_use_externals,svx_removewhichrange, \ boost_headers \ + icuuc \ libxml2 \ )) diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx index ee414709cbe6..6232f0f32f8d 100644 --- a/svx/source/svdraw/svdpdf.cxx +++ b/svx/source/svdraw/svdpdf.cxx @@ -74,6 +74,7 @@ #include <o3tl/string_view.hxx> #include <osl/diagnose.h> #include <osl/file.hxx> +#include <unicode/normalizer2.h> using namespace com::sun::star; @@ -1074,6 +1075,40 @@ static bool toPfaCID(SubSetInfo& rSubSetInfo, const OUString& fileUrl, return true; } +static OString decomposeLegacyUnicodeLigature(UChar32 cUnicode) +{ + UErrorCode eCode(U_ZERO_ERROR); + + // Put in any legacy unicode ligature decompositions, which we detect as U_DT_COMPAT and + // a multi-character decomposition. + UDecompositionType decompType = static_cast<UDecompositionType>( + u_getIntPropertyValue(cUnicode, UCHAR_DECOMPOSITION_TYPE)); + if (decompType == UDecompositionType::U_DT_COMPAT) + { + const icu::Normalizer2* pInstance = icu::Normalizer2::getNFKDInstance(eCode); + + if (pInstance && eCode == U_ZERO_ERROR) + { + icu::UnicodeString sDecomposed; + pInstance->getRawDecomposition(cUnicode, sDecomposed); + if (sDecomposed.length() > 1) + { + OStringBuffer aBuffer; + for (int32_t i = 0, nLen = sDecomposed.length(); i < nLen; ++i) + { + OString sCodePoint = OString::number(sDecomposed[i], 16); + for (sal_Int32 j = sCodePoint.getLength(); j < 4; ++j) + aBuffer.append('0'); + aBuffer.append(sCodePoint); + } + return aBuffer.toString(); + } + } + } + + return OString(); +} + const char cmapprefix[] = "%!PS-Adobe-3.0 Resource-CMap " "/WMode 0 def " " " @@ -1146,6 +1181,8 @@ static void buildCMapAndFeatures(const OUString& CMapUrl, const OUString& Featur sal_Int32 nEnd = charline.indexOf('>', 1); assert(charline[nEnd] == '>'); sal_Int32 nGlyphIndex = o3tl::toInt32(charline.subView(1, nEnd - 1), 16); + if (bNameKeyed) + nGlyphIndex = nameIndexToGlyph[nGlyphIndex]; OString sChars(o3tl::trim(charline.subView(nEnd + 1))); assert(sChars[0] == '<' && sChars[sChars.getLength() - 1] == '>'); OString sContents = sChars.copy(1, sChars.getLength() - 2); @@ -1153,8 +1190,13 @@ static void buildCMapAndFeatures(const OUString& CMapUrl, const OUString& Featur sal_Int32 nCharsPerCode = sContents.getLength() / 4; if (nCharsPerCode > 1) ligatureGlyphToChars[nGlyphIndex] = sContents; - if (bNameKeyed) - nGlyphIndex = nameIndexToGlyph[nGlyphIndex]; + else + { + OString sLegacy + = decomposeLegacyUnicodeLigature(static_cast<UChar32>(sContents.toUInt32(16))); + if (!sLegacy.isEmpty()) + ligatureGlyphToChars[nGlyphIndex] = sLegacy; + } OString cidcharline = sChars + " " + OString::number(nGlyphIndex); glyphs.push_back(nGlyphIndex); rSubSetInfo.aComponents.back().glyphToChars[nGlyphIndex] = sContents; @@ -1304,6 +1346,13 @@ static EmbeddedFontInfo mergeFontSubsets(const OUString& mergedFontUrl, sal_Int32 nCharsPerCode = sCharContents.getLength() / 4; if (nCharsPerCode > 1) ligatureGlyphToChars[glyph] = sCharContents; + else + { + OString sLegacy = decomposeLegacyUnicodeLigature( + static_cast<UChar32>(sCharContents.toUInt32(16))); + if (!sLegacy.isEmpty()) + ligatureGlyphToChars[glyph] = sLegacy; + } charsToGlyph[entry.second] = glyph; mergedCMap.WriteLine(cidcharline);
