include/vcl/filter/PDFiumLibrary.hxx        |    1 
 sd/qa/unit/data/pdf/differentfonts.pdf      |binary
 sd/qa/unit/export-tests.cxx                 |   24 ++++
 svx/source/svdraw/svdpdf.cxx                |   17 +--
 vcl/inc/sft.hxx                             |    2 
 vcl/source/fontsubset/sft.cxx               |  139 ++++++++++++++++++++++++++++
 vcl/source/pdf/PDFiumLibrary.cxx            |    9 +
 vcl/unx/generic/fontmanager/fontmanager.cxx |  138 ---------------------------
 8 files changed, 184 insertions(+), 146 deletions(-)

New commits:
commit 1f489500415ebea22722da57851dd63782452ee2
Author:     Caolán McNamara <[email protected]>
AuthorDate: Tue Aug 12 13:24:10 2025 +0100
Commit:     Caolán McNamara <[email protected]>
CommitDate: Sat Oct 4 11:24:20 2025 +0200

    move convertSfntName from fontmanager to sft
    
    Change-Id: I67327fdef59538fcafe92f0c6d42f94d9aca06bc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191160
    Reviewed-by: Miklos Vajna <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191819
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/vcl/inc/sft.hxx b/vcl/inc/sft.hxx
index c02f383c5680..259bfbbe44db 100644
--- a/vcl/inc/sft.hxx
+++ b/vcl/inc/sft.hxx
@@ -146,6 +146,8 @@ namespace vcl
         std::vector<sal_uInt8> sptr;            /**< string data (not 
zero-terminated!)          */
     };
 
+    OUString convertSfntName(const NameRecord& rNameRecord);
+
 /** Return value of GetTTGlobalFontInfo() */
 
     typedef struct TTGlobalFontInfo_ {
diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index cfee9552ed0e..dab5aff157ec 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -42,11 +42,13 @@
 #include <tools/fix16.hxx>
 #endif
 #include "ttcr.hxx"
+#include <i18nlangtag/applelangid.hxx>
 #include <rtl/crc.h>
 #include <rtl/ustring.hxx>
 #include <rtl/ustrbuf.hxx>
 #include <sal/log.hxx>
 #include <o3tl/safeint.hxx>
+#include <o3tl/string_view.hxx>
 #include <osl/endian.h>
 #include <osl/thread.h>
 #include <unotools/tempfile.hxx>
@@ -1797,6 +1799,143 @@ bool getTTCoverage(
     return bRet;
 }
 
+/*
+ *  static helpers
+ */
+static sal_uInt16 getUInt16BE( const sal_uInt8*& pBuffer )
+{
+    sal_uInt16 nRet = static_cast<sal_uInt16>(pBuffer[1]) |
+        (static_cast<sal_uInt16>(pBuffer[0]) << 8);
+    pBuffer+=2;
+    return nRet;
+}
+
+OUString convertSfntName( const NameRecord& rNameRecord )
+{
+    OUString aValue;
+    if(
+       ( rNameRecord.platformID == 3 && ( rNameRecord.encodingID == 0 || 
rNameRecord.encodingID == 1 ) )  // MS, Unicode
+       ||
+       ( rNameRecord.platformID == 0 ) // Apple, Unicode
+       )
+    {
+        OUStringBuffer aName( rNameRecord.sptr.size()/2 );
+        const sal_uInt8* pNameBuffer = rNameRecord.sptr.data();
+        for(size_t n = 0; n < rNameRecord.sptr.size()/2; n++ )
+            aName.append( static_cast<sal_Unicode>(getUInt16BE( pNameBuffer )) 
);
+        aValue = aName.makeStringAndClear();
+    }
+    else if( rNameRecord.platformID == 3 )
+    {
+        if( rNameRecord.encodingID >= 2 && rNameRecord.encodingID <= 6 )
+        {
+            /*
+             *  and now for a special kind of madness:
+             *  some fonts encode their byte value string as BE uint16
+             *  (leading to stray zero bytes in the string)
+             *  while others code two bytes as a uint16 and swap to BE
+             */
+            OStringBuffer aName;
+            const sal_uInt8* pNameBuffer = rNameRecord.sptr.data();
+            for(size_t n = 0; n < rNameRecord.sptr.size()/2; n++ )
+            {
+                sal_Unicode aCode = static_cast<sal_Unicode>(getUInt16BE( 
pNameBuffer ));
+                char aChar = aCode >> 8;
+                if( aChar )
+                    aName.append( aChar );
+                aChar = aCode & 0x00ff;
+                if( aChar )
+                    aName.append( aChar );
+            }
+            switch( rNameRecord.encodingID )
+            {
+                case 2:
+                    aValue = OStringToOUString( aName, RTL_TEXTENCODING_MS_932 
);
+                    break;
+                case 3:
+                    aValue = OStringToOUString( aName, RTL_TEXTENCODING_MS_936 
);
+                    break;
+                case 4:
+                    aValue = OStringToOUString( aName, RTL_TEXTENCODING_MS_950 
);
+                    break;
+                case 5:
+                    aValue = OStringToOUString( aName, RTL_TEXTENCODING_MS_949 
);
+                    break;
+                case 6:
+                    aValue = OStringToOUString( aName, 
RTL_TEXTENCODING_MS_1361 );
+                    break;
+            }
+        }
+    }
+    else if( rNameRecord.platformID == 1 )
+    {
+        std::string_view aName(reinterpret_cast<const 
char*>(rNameRecord.sptr.data()), rNameRecord.sptr.size());
+        rtl_TextEncoding eEncoding = RTL_TEXTENCODING_DONTKNOW;
+        switch (rNameRecord.encodingID)
+        {
+            case 0:
+                eEncoding = RTL_TEXTENCODING_APPLE_ROMAN;
+                break;
+            case 1:
+                eEncoding = RTL_TEXTENCODING_APPLE_JAPANESE;
+                break;
+            case 2:
+                eEncoding = RTL_TEXTENCODING_APPLE_CHINTRAD;
+                break;
+            case 3:
+                eEncoding = RTL_TEXTENCODING_APPLE_KOREAN;
+                break;
+            case 4:
+                eEncoding = RTL_TEXTENCODING_APPLE_ARABIC;
+                break;
+            case 5:
+                eEncoding = RTL_TEXTENCODING_APPLE_HEBREW;
+                break;
+            case 6:
+                eEncoding = RTL_TEXTENCODING_APPLE_GREEK;
+                break;
+            case 7:
+                eEncoding = RTL_TEXTENCODING_APPLE_CYRILLIC;
+                break;
+            case 9:
+                eEncoding = RTL_TEXTENCODING_APPLE_DEVANAGARI;
+                break;
+            case 10:
+                eEncoding = RTL_TEXTENCODING_APPLE_GURMUKHI;
+                break;
+            case 11:
+                eEncoding = RTL_TEXTENCODING_APPLE_GUJARATI;
+                break;
+            case 21:
+                eEncoding = RTL_TEXTENCODING_APPLE_THAI;
+                break;
+            case 25:
+                eEncoding = RTL_TEXTENCODING_APPLE_CHINSIMP;
+                break;
+            case 29:
+                eEncoding = RTL_TEXTENCODING_APPLE_CENTEURO;
+                break;
+            case 32:    //Uninterpreted
+                eEncoding = RTL_TEXTENCODING_UTF8;
+                break;
+            default:
+                if (o3tl::starts_with(aName, "Khmer OS") || // encoding '20' 
(Khmer) isn't implemented
+                    o3tl::starts_with(aName, "YoavKtav")) // tdf#152278
+                {
+                    eEncoding = RTL_TEXTENCODING_UTF8;
+                }
+                SAL_WARN_IF(eEncoding == RTL_TEXTENCODING_DONTKNOW, 
"vcl.fonts", "mac encoding " <<
+                            rNameRecord.encodingID << " in font '" << aName << 
"'" <<
+                            (rNameRecord.encodingID > 32 ? " is invalid" : " 
has unimplemented conversion"));
+                break;
+        }
+        if (eEncoding != RTL_TEXTENCODING_DONTKNOW)
+            aValue = OStringToOUString(aName, eEncoding);
+    }
+
+    return aValue;
+}
+
 } // namespace vcl
 
 int TestFontSubset(const void* data, sal_uInt32 size)
diff --git a/vcl/unx/generic/fontmanager/fontmanager.cxx 
b/vcl/unx/generic/fontmanager/fontmanager.cxx
index d755f317362a..fd2b1dbad382 100644
--- a/vcl/unx/generic/fontmanager/fontmanager.cxx
+++ b/vcl/unx/generic/fontmanager/fontmanager.cxx
@@ -62,18 +62,6 @@ using namespace psp;
 using namespace com::sun::star::uno;
 using namespace com::sun::star::lang;
 
-/*
- *  static helpers
- */
-
-static sal_uInt16 getUInt16BE( const sal_uInt8*& pBuffer )
-{
-    sal_uInt16 nRet = static_cast<sal_uInt16>(pBuffer[1]) |
-        (static_cast<sal_uInt16>(pBuffer[0]) << 8);
-    pBuffer+=2;
-    return nRet;
-}
-
 /*
  *  PrintFont implementations
  */
@@ -311,132 +299,6 @@ std::vector<fontID> PrintFontManager::findFontFileIDs( 
int nDirID, const OString
 
 namespace {
 
-OUString convertSfntName( const NameRecord& rNameRecord )
-{
-    OUString aValue;
-    if(
-       ( rNameRecord.platformID == 3 && ( rNameRecord.encodingID == 0 || 
rNameRecord.encodingID == 1 ) )  // MS, Unicode
-       ||
-       ( rNameRecord.platformID == 0 ) // Apple, Unicode
-       )
-    {
-        OUStringBuffer aName( rNameRecord.sptr.size()/2 );
-        const sal_uInt8* pNameBuffer = rNameRecord.sptr.data();
-        for(size_t n = 0; n < rNameRecord.sptr.size()/2; n++ )
-            aName.append( static_cast<sal_Unicode>(getUInt16BE( pNameBuffer )) 
);
-        aValue = aName.makeStringAndClear();
-    }
-    else if( rNameRecord.platformID == 3 )
-    {
-        if( rNameRecord.encodingID >= 2 && rNameRecord.encodingID <= 6 )
-        {
-            /*
-             *  and now for a special kind of madness:
-             *  some fonts encode their byte value string as BE uint16
-             *  (leading to stray zero bytes in the string)
-             *  while others code two bytes as a uint16 and swap to BE
-             */
-            OStringBuffer aName;
-            const sal_uInt8* pNameBuffer = rNameRecord.sptr.data();
-            for(size_t n = 0; n < rNameRecord.sptr.size()/2; n++ )
-            {
-                sal_Unicode aCode = static_cast<sal_Unicode>(getUInt16BE( 
pNameBuffer ));
-                char aChar = aCode >> 8;
-                if( aChar )
-                    aName.append( aChar );
-                aChar = aCode & 0x00ff;
-                if( aChar )
-                    aName.append( aChar );
-            }
-            switch( rNameRecord.encodingID )
-            {
-                case 2:
-                    aValue = OStringToOUString( aName, RTL_TEXTENCODING_MS_932 
);
-                    break;
-                case 3:
-                    aValue = OStringToOUString( aName, RTL_TEXTENCODING_MS_936 
);
-                    break;
-                case 4:
-                    aValue = OStringToOUString( aName, RTL_TEXTENCODING_MS_950 
);
-                    break;
-                case 5:
-                    aValue = OStringToOUString( aName, RTL_TEXTENCODING_MS_949 
);
-                    break;
-                case 6:
-                    aValue = OStringToOUString( aName, 
RTL_TEXTENCODING_MS_1361 );
-                    break;
-            }
-        }
-    }
-    else if( rNameRecord.platformID == 1 )
-    {
-        std::string_view aName(reinterpret_cast<const 
char*>(rNameRecord.sptr.data()), rNameRecord.sptr.size());
-        rtl_TextEncoding eEncoding = RTL_TEXTENCODING_DONTKNOW;
-        switch (rNameRecord.encodingID)
-        {
-            case 0:
-                eEncoding = RTL_TEXTENCODING_APPLE_ROMAN;
-                break;
-            case 1:
-                eEncoding = RTL_TEXTENCODING_APPLE_JAPANESE;
-                break;
-            case 2:
-                eEncoding = RTL_TEXTENCODING_APPLE_CHINTRAD;
-                break;
-            case 3:
-                eEncoding = RTL_TEXTENCODING_APPLE_KOREAN;
-                break;
-            case 4:
-                eEncoding = RTL_TEXTENCODING_APPLE_ARABIC;
-                break;
-            case 5:
-                eEncoding = RTL_TEXTENCODING_APPLE_HEBREW;
-                break;
-            case 6:
-                eEncoding = RTL_TEXTENCODING_APPLE_GREEK;
-                break;
-            case 7:
-                eEncoding = RTL_TEXTENCODING_APPLE_CYRILLIC;
-                break;
-            case 9:
-                eEncoding = RTL_TEXTENCODING_APPLE_DEVANAGARI;
-                break;
-            case 10:
-                eEncoding = RTL_TEXTENCODING_APPLE_GURMUKHI;
-                break;
-            case 11:
-                eEncoding = RTL_TEXTENCODING_APPLE_GUJARATI;
-                break;
-            case 21:
-                eEncoding = RTL_TEXTENCODING_APPLE_THAI;
-                break;
-            case 25:
-                eEncoding = RTL_TEXTENCODING_APPLE_CHINSIMP;
-                break;
-            case 29:
-                eEncoding = RTL_TEXTENCODING_APPLE_CENTEURO;
-                break;
-            case 32:    //Uninterpreted
-                eEncoding = RTL_TEXTENCODING_UTF8;
-                break;
-            default:
-                if (o3tl::starts_with(aName, "Khmer OS") || // encoding '20' 
(Khmer) isn't implemented
-                    o3tl::starts_with(aName, "YoavKtav")) // tdf#152278
-                {
-                    eEncoding = RTL_TEXTENCODING_UTF8;
-                }
-                SAL_WARN_IF(eEncoding == RTL_TEXTENCODING_DONTKNOW, 
"vcl.fonts", "mac encoding " <<
-                            rNameRecord.encodingID << " in font '" << aName << 
"'" <<
-                            (rNameRecord.encodingID > 32 ? " is invalid" : " 
has unimplemented conversion"));
-                break;
-        }
-        if (eEncoding != RTL_TEXTENCODING_DONTKNOW)
-            aValue = OStringToOUString(aName, eEncoding);
-    }
-
-    return aValue;
-}
-
 OUString analyzeSfntFamilyName(void const * pTTFont)
 {
     OUString aFamily;
commit ebe962007e39df9010aa1a641ef66cee0dbcb54c
Author:     Caolán McNamara <[email protected]>
AuthorDate: Tue Aug 12 12:51:23 2025 +0100
Commit:     Caolán McNamara <[email protected]>
CommitDate: Sat Oct 4 11:24:11 2025 +0200

    extract italic/oblique info about font
    
    Change-Id: Idf9943cede5b63e98e13265f99fcde9d649987ac
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190994
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Miklos Vajna <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191818
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/include/vcl/filter/PDFiumLibrary.hxx 
b/include/vcl/filter/PDFiumLibrary.hxx
index c91c0cef6a77..f41eebcf4daa 100644
--- a/include/vcl/filter/PDFiumLibrary.hxx
+++ b/include/vcl/filter/PDFiumLibrary.hxx
@@ -154,6 +154,7 @@ public:
     virtual basegfx::B2DRectangle getBounds() = 0;
     virtual double getFontSize() = 0;
     virtual OUString getFontName() = 0;
+    virtual int getFontAngle() = 0;
     virtual PDFTextRenderMode getTextRenderMode() = 0;
     virtual Color getFillColor() = 0;
     virtual Color getStrokeColor() = 0;
diff --git a/sd/qa/unit/data/pdf/differentfonts.pdf 
b/sd/qa/unit/data/pdf/differentfonts.pdf
new file mode 100644
index 000000000000..9b5582716328
Binary files /dev/null and b/sd/qa/unit/data/pdf/differentfonts.pdf differ
diff --git a/sd/qa/unit/export-tests.cxx b/sd/qa/unit/export-tests.cxx
index 443ee00b4431..dd50ebbdb170 100644
--- a/sd/qa/unit/export-tests.cxx
+++ b/sd/qa/unit/export-tests.cxx
@@ -1072,6 +1072,30 @@ CPPUNIT_TEST_FIXTURE(SdExportTest, 
testExplodedPdfTextPos)
     CPPUNIT_ASSERT_DOUBLES_EQUAL(3063, y, 0);
 }
 
+CPPUNIT_TEST_FIXTURE(SdExportTest, testExplodedPdfFont)
+{
+    auto pPdfium = vcl::pdf::PDFiumLibrary::get();
+    if (!pPdfium)
+        return;
+    UsePdfium aGuard;
+
+    loadFromFile(u"pdf/differentfonts.pdf");
+
+    
setFilterOptions("{\"DecomposePDF\":{\"type\":\"boolean\",\"value\":\"true\"}}");
+    setImportFilterName(u"OpenDocument Drawing Flat XML"_ustr);
+    saveAndReload(u"OpenDocument Drawing Flat XML"_ustr);
+
+    xmlDocUniquePtr pXml = parseLayout();
+    OUString sItalic = getXPath(pXml, "//font[2]", "italic");
+    // was "none" before
+    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"_ustr, sFontName);
+    int nFontHeight = getXPath(pXml, "//font[2]", "height").toInt32();
+    CPPUNIT_ASSERT_EQUAL(494, nFontHeight);
+}
+
 CPPUNIT_TEST_FIXTURE(SdExportTest, testEmbeddedText)
 {
     createSdDrawDoc("objectwithtext.fodg");
diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index 3d9de5d5c151..b2bbb8e94350 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -733,17 +733,18 @@ void 
ImpSdrPdfImport::ImportText(std::unique_ptr<vcl::pdf::PDFiumPageObject> con
 
     const Size aFontSize(dFontSizeH, dFontSizeV);
     vcl::Font aFnt = mpVD->GetFont();
-    if (aFontSize != aFnt.GetFontSize())
-    {
-        aFnt.SetFontSize(aFontSize);
-        mpVD->SetFont(aFnt);
-        mbFntDirty = true;
-    }
+    aFnt.SetFontSize(aFontSize);
 
     OUString sFontName = pPageObject->getFontName();
-    if (!sFontName.isEmpty() && sFontName != aFnt.GetFamilyName())
-    {
+    if (!sFontName.isEmpty())
         aFnt.SetFamilyName(sFontName);
+
+    const int italicAngle = pPageObject->getFontAngle();
+    aFnt.SetItalic(italicAngle == 0 ? ITALIC_NONE
+                                    : (italicAngle < 0 ? ITALIC_NORMAL : 
ITALIC_OBLIQUE));
+
+    if (aFnt != mpVD->GetFont())
+    {
         mpVD->SetFont(aFnt);
         mbFntDirty = true;
     }
diff --git a/vcl/source/pdf/PDFiumLibrary.cxx b/vcl/source/pdf/PDFiumLibrary.cxx
index 13d6eedec9f1..40a95382f4c0 100644
--- a/vcl/source/pdf/PDFiumLibrary.cxx
+++ b/vcl/source/pdf/PDFiumLibrary.cxx
@@ -414,6 +414,7 @@ public:
     basegfx::B2DRectangle getBounds() override;
     double getFontSize() override;
     OUString getFontName() override;
+    int getFontAngle() override;
     PDFTextRenderMode getTextRenderMode() override;
     Color getFillColor() override;
     Color getStrokeColor() override;
@@ -1150,6 +1151,14 @@ OUString PDFiumPageObjectImpl::getFontName()
     return sFamilyName;
 }
 
+int PDFiumPageObjectImpl::getFontAngle()
+{
+    int nFontAngle(0);
+    FPDF_FONT pFontObject = FPDFTextObj_GetFont(mpPageObject);
+    FPDFFont_GetItalicAngle(pFontObject, &nFontAngle);
+    return nFontAngle;
+}
+
 PDFTextRenderMode PDFiumPageObjectImpl::getTextRenderMode()
 {
     return 
static_cast<PDFTextRenderMode>(FPDFTextObj_GetTextRenderMode(mpPageObject));

Reply via email to