[Libreoffice-commits] core.git: Branch 'feature/drop-findcmap' - vcl/inc vcl/qt5 vcl/quartz vcl/source vcl/win

Jan-Marek Glogowski (via logerrit) logerrit at kemper.freedesktop.org
Sun Sep 13 14:19:08 UTC 2020


Rebased ref, commits from common ancestor:
commit 32deea4278d1b149f442854a24c55038eef75a95
Author:     Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Sun Sep 13 15:01:22 2020 +0200
Commit:     Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Sun Sep 13 16:18:00 2020 +0200

    WIN OSX Qt5 unify CreateFontSubset code
    
    This is basically just some refactoring. Mots interestingly the
    MacOS used to work with 257 glyphs. I couldn't find any
    explaination for the 256 glyph limit. Sadly the PrintFontManager
    is out of scope. That needs more inspection.
    
    Change-Id: Ibfa0e905f5efeb7d4a609884d64b4ed2615a9d3d

diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx
index 9d86421e4e10..08e1187d9cfe 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -622,6 +622,11 @@ protected:
     static void GetGlyphWidths(const vcl::AbstractTrueTypeFont& rTTF,
                                const PhysicalFontFace& rFontFace, bool bVertical,
                                std::vector<sal_Int32>& rWidths, Ucs2UIntMap& rUnicodeEnc);
+
+    static bool CreateFontSubset(vcl::AbstractTrueTypeFont& aTTF, const OString& rSysPath,
+                                 const bool bVertical, const sal_GlyphId* pGlyphIds,
+                                 const sal_uInt8* pEncoding, sal_Int32* pGlyphWidths,
+                                 int nGlyphCount);
 };
 
 bool SalGraphics::IsNativeControlSupported(ControlType eType, ControlPart ePart)
diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx
index 26b09b8bdc26..0eb31aba3252 100644
--- a/vcl/qt5/Qt5Graphics_Text.cxx
+++ b/vcl/qt5/Qt5Graphics_Text.cxx
@@ -219,7 +219,6 @@ bool Qt5Graphics::CreateFontSubset(const OUString& rToFile, const PhysicalFontFa
                                    const sal_GlyphId* pGlyphIds, const sal_uInt8* pEncoding,
                                    sal_Int32* pGlyphWidths, int nGlyphCount, FontSubsetInfo& rInfo)
 {
-    // prepare the requested file name for writing the font-subset file
     OUString aSysPath;
     if (osl_File_E_None != osl_getSystemPathFromFileURL(rToFile.pData, &aSysPath.pData))
         return false;
@@ -229,8 +228,6 @@ bool Qt5Graphics::CreateFontSubset(const OUString& rToFile, const PhysicalFontFa
     const QFont aFont = pQt5FontFace->CreateFont();
     const QRawFont aRawFont(QRawFont::fromFont(aFont));
     const QFontInfo aFontInfo(aFont);
-    const OString aToFile(OUStringToOString(aSysPath, osl_getThreadTextEncoding()));
-    const int nOrigGlyphCount = nGlyphCount;
 
     // get details about the subsetted font
     rInfo.m_nFontType = FontType::SFNT_TTF;
@@ -245,49 +242,9 @@ bool Qt5Graphics::CreateFontSubset(const OUString& rToFile, const PhysicalFontFa
     if (GetTTGlobalFontHeadInfo(&aTTF, nXmin, nYmin, nXmax, nYmax, nMacStyleFlags))
         rInfo.m_aFontBBox = tools::Rectangle(Point(nXmin, nYmin), Point(nXmax, nYmax));
 
-    sal_uInt16 aShortIDs[nGlyphCount + 1];
-    sal_uInt8 aTempEncs[nGlyphCount + 1];
-
-    int nNotDef = -1;
-
-    for (int i = 0; i < nGlyphCount; ++i)
-    {
-        aTempEncs[i] = pEncoding[i];
-
-        sal_GlyphId aGlyphId(pGlyphIds[i]);
-        aShortIDs[i] = static_cast<sal_uInt16>(aGlyphId);
-        if (!aGlyphId && nNotDef < 0)
-            nNotDef = i; // first NotDef glyph found
-    }
-
-    if (nNotDef != 0)
-    {
-        // add fake NotDef glyph if needed
-        if (nNotDef < 0)
-            nNotDef = nGlyphCount++;
-        // NotDef glyph must be in pos 0 => swap glyphids
-        aShortIDs[nNotDef] = aShortIDs[0];
-        aTempEncs[nNotDef] = aTempEncs[0];
-        aShortIDs[0] = 0;
-        aTempEncs[0] = 0;
-    }
-
-    std::unique_ptr<sal_uInt16[]> pGlyphMetrics
-        = GetTTSimpleGlyphMetrics(&aTTF, aShortIDs, nGlyphCount, false);
-    if (!pGlyphMetrics)
-        return false;
-
-    sal_uInt16 nNotDefAdv = pGlyphMetrics[0];
-    pGlyphMetrics[0] = pGlyphMetrics[nNotDef];
-    pGlyphMetrics[nNotDef] = nNotDefAdv;
-
-    for (int i = 0; i < nOrigGlyphCount; ++i)
-        pGlyphWidths[i] = pGlyphMetrics[i];
-
-    // write subset into destination file
-    vcl::SFErrCodes nRC
-        = vcl::CreateTTFromTTGlyphs(&aTTF, aToFile.getStr(), aShortIDs, aTempEncs, nGlyphCount);
-    return (nRC == vcl::SFErrCodes::Ok);
+    const OString aToFile(OUStringToOString(aSysPath, osl_getThreadTextEncoding()));
+    return SalGraphics::CreateFontSubset(aTTF, aToFile, false /* use FontSelectPattern? */,
+                                         pGlyphIds, pEncoding, pGlyphWidths, nGlyphCount);
 }
 
 const void* Qt5Graphics::GetEmbedFontData(const PhysicalFontFace*, long* /*pDataLen*/)
diff --git a/vcl/quartz/salgdicommon.cxx b/vcl/quartz/salgdicommon.cxx
index c72e8ee5cabd..5283d2cd2b85 100644
--- a/vcl/quartz/salgdicommon.cxx
+++ b/vcl/quartz/salgdicommon.cxx
@@ -145,7 +145,7 @@ static void AddPolyPolygonToPath( CGMutablePathRef xPath,
 bool AquaSalGraphics::CreateFontSubset( const OUString& rToFile,
                                         const PhysicalFontFace* pFontData,
                                         const sal_GlyphId* pGlyphIds, const sal_uInt8* pEncoding,
-                                        sal_Int32* pGlyphWidths, int nGlyphCount,
+                                        sal_Int32* pGlyphWidths, const int nGlyphCount,
                                         FontSubsetInfo& rInfo )
 {
     // TODO: move more of the functionality here into the generic subsetter code
@@ -153,17 +153,13 @@ bool AquaSalGraphics::CreateFontSubset( const OUString& rToFile,
     // prepare the requested file name for writing the font-subset file
     OUString aSysPath;
     if( osl_File_E_None != osl_getSystemPathFromFileURL( rToFile.pData, &aSysPath.pData ) )
-    {
         return false;
-    }
 
     // get the raw-bytes from the font to be subset
     std::vector<unsigned char> aBuffer;
     bool bCffOnly = false;
     if( !GetRawFontData( pFontData, aBuffer, &bCffOnly ) )
-    {
         return false;
-    }
     const OString aToFile( OUStringToOString( aSysPath,
                                               osl_getThreadTextEncoding()));
 
@@ -190,11 +186,10 @@ bool AquaSalGraphics::CreateFontSubset( const OUString& rToFile,
 
     // prepare data for psprint's font subsetter
     TrueTypeFont* pSftFont = nullptr;
-    SFErrCodes nRC = ::OpenTTFontBuffer( static_cast<void*>(aBuffer.data()), aBuffer.size(), 0, &pSftFont);
-    if( nRC != SFErrCodes::Ok )
-    {
+    if (::OpenTTFontBuffer( static_cast<void*>(aBuffer.data()), aBuffer.size(), 0, &pSftFont)
+            != SFErrCodes::Ok)
         return false;
-    }
+
     // get details about the subsetted font
     TTGlobalFontInfo aTTInfo;
     ::GetTTGlobalFontInfo( pSftFont, &aTTInfo );
@@ -206,86 +201,23 @@ bool AquaSalGraphics::CreateFontSubset( const OUString& rToFile,
     rInfo.m_nCapHeight = aTTInfo.yMax; // Well ...
     rInfo.m_nAscent = aTTInfo.winAscent;
     rInfo.m_nDescent = aTTInfo.winDescent;
+
     // mac fonts usually do not have an OS2-table
     // => get valid ascent/descent values from other tables
     if( !rInfo.m_nAscent )
-    {
         rInfo.m_nAscent = +aTTInfo.typoAscender;
-    }
     if( !rInfo.m_nAscent )
-    {
         rInfo.m_nAscent = +aTTInfo.ascender;
-    }
     if( !rInfo.m_nDescent )
-    {
         rInfo.m_nDescent = +aTTInfo.typoDescender;
-    }
     if( !rInfo.m_nDescent )
-    {
         rInfo.m_nDescent = -aTTInfo.descender;
-    }
-
-    // subset glyphs and get their properties
-    // take care that subset fonts require the NotDef glyph in pos 0
-    int nOrigCount = nGlyphCount;
-    sal_uInt16 aShortIDs[ 257 ];
-    sal_uInt8 aTempEncs[ 257 ];
-    int nNotDef = -1;
-
-    assert( (nGlyphCount <= 256 && "too many glyphs for subsetting" ));
-
-    for( int i = 0; i < nGlyphCount; ++i )
-    {
-        aTempEncs[i] = pEncoding[i];
-
-        sal_GlyphId aGlyphId(pGlyphIds[i]);
-        aShortIDs[i] = static_cast<sal_uInt16>( aGlyphId );
-        if( !aGlyphId && nNotDef < 0 )
-        {
-            nNotDef = i; // first NotDef glyph found
-        }
-    }
-
-    if( nNotDef != 0 )
-    {
-        // add fake NotDef glyph if needed
-        if( nNotDef < 0 )
-        {
-            nNotDef = nGlyphCount++;
-        }
-        // NotDef glyph must be in pos 0 => swap glyphids
-        aShortIDs[ nNotDef ] = aShortIDs[0];
-        aTempEncs[ nNotDef ] = aTempEncs[0];
-        aShortIDs[0] = 0;
-        aTempEncs[0] = 0;
-    }
-
-    // TODO: where to get bVertical?
-    const bool bVertical = false;
-
-    // fill the pGlyphWidths array
-    // while making sure that the NotDef glyph is at index==0
-    std::unique_ptr<sal_uInt16[]> pGlyphMetrics = ::GetTTSimpleGlyphMetrics( pSftFont, aShortIDs,
-                                                                     nGlyphCount, bVertical );
-    if( !pGlyphMetrics )
-    {
-        return false;
-    }
-
-    sal_uInt16 nNotDefAdv = pGlyphMetrics[0];
-    pGlyphMetrics[0] = pGlyphMetrics[nNotDef];
-    pGlyphMetrics[nNotDef]  = nNotDefAdv;
-    for( int i = 0; i < nOrigCount; ++i )
-    {
-        pGlyphWidths[i] = pGlyphMetrics[i];
-    }
-    pGlyphMetrics.reset();
 
     // write subset into destination file
-    nRC = ::CreateTTFromTTGlyphs( pSftFont, aToFile.getStr(), aShortIDs,
-                                  aTempEncs, nGlyphCount );
+    bool bRet = SalGraphics::CreateFontSubset(*pSftFont, aToFile, false /* use FontSelectPattern? */,
+                                              pGlyphIds, pEncoding, pGlyphWidths, nGlyphCount);
     ::CloseTTFont(pSftFont);
-    return (nRC == SFErrCodes::Ok);
+    return bRet;
 }
 
 static void alignLinePoint( const SalPoint* i_pIn, float& o_fX, float& o_fY )
diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx
index 777b2b1115e4..76f33fdbd44e 100644
--- a/vcl/source/gdi/salgdilayout.cxx
+++ b/vcl/source/gdi/salgdilayout.cxx
@@ -942,4 +942,75 @@ void SalGraphics::GetGlyphWidths(const vcl::AbstractTrueTypeFont& rTTF,
     }
 }
 
+bool SalGraphics::CreateFontSubset(vcl::AbstractTrueTypeFont& rTTF, const OString& rSysPath,
+                                   const bool bVertical, const sal_GlyphId* pGlyphIds,
+                                   const sal_uInt8* pEncoding, sal_Int32* pGlyphWidths,
+                                   const int nOrigGlyphCount)
+{
+    // Multiple questions:
+    // - Why is there a glyph limit?
+    //   MacOS used to handle 257 glyphs...
+    //   Also the much more complex PrintFontManager variant has this limit.
+    //   Also the very first implementation has the limit in
+    //   commit 8789ed701e98031f2a1657ea0dfd6f7a0b050992
+    // - Why doesn't the PrintFontManager care about the fake glpyh? It
+    //   is used on all unx platforms to create the subset font.
+    // - Should the SAL_WARN actually be asserts, like on MacOS?
+    if (nOrigGlyphCount > 256)
+    {
+        SAL_WARN("vcl.fonts", "too many glyphs for subsetting");
+        return false;
+    }
+
+    int nGlyphCount = nOrigGlyphCount;
+    sal_uInt16 aShortIDs[256];
+    sal_uInt8 aTempEncs[256];
+
+    // handle the undefined / first font glyph
+    int nNotDef = -1, i;
+    for (i = 0; i < nGlyphCount; ++i)
+    {
+        aTempEncs[i] = pEncoding[i];
+        aShortIDs[i] = static_cast<sal_uInt16>(pGlyphIds[i]);
+        if (!aShortIDs[i])
+            if (nNotDef < 0)
+                nNotDef = i;
+    }
+
+    // nNotDef glyph must be in pos 0 => swap glyphids
+    if (nNotDef != 0)
+    {
+        if (nNotDef < 0)
+        {
+            if (nGlyphCount == 256)
+            {
+                SAL_WARN("vcl.fonts", "too many glyphs for subsetting");
+                return false;
+            }
+            nNotDef = nGlyphCount++;
+        }
+
+        aShortIDs[nNotDef] = aShortIDs[0];
+        aTempEncs[nNotDef] = aTempEncs[0];
+        aShortIDs[0] = 0;
+        aTempEncs[0] = 0;
+    }
+
+    std::unique_ptr<sal_uInt16[]> pMetrics
+        = GetTTSimpleGlyphMetrics(&rTTF, aShortIDs, nGlyphCount, bVertical);
+    if (!pMetrics)
+        return false;
+
+    sal_uInt16 nNotDefAdv = pMetrics[0];
+    pMetrics[0] = pMetrics[nNotDef];
+    pMetrics[nNotDef] = nNotDefAdv;
+    for (i = 0; i < nOrigGlyphCount; ++i)
+        pGlyphWidths[i] = pMetrics[i];
+    pMetrics.reset();
+
+    // write subset into destination file
+    return (CreateTTFromTTGlyphs(&rTTF, rSysPath.getStr(), aShortIDs, aTempEncs, nGlyphCount)
+            == vcl::SFErrCodes::Ok);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index bc7f83b8b6f2..ba3104f80319 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -1643,52 +1643,9 @@ bool WinSalGraphics::CreateFontSubset( const OUString& rToFile,
                                     Point( aTTInfo.xMax, aTTInfo.yMax ) );
     rInfo.m_nCapHeight  = aTTInfo.yMax; // Well ...
 
-    // subset TTF-glyphs and get their properties
-    // take care that subset fonts require the NotDef glyph in pos 0
-    int nOrigCount = nGlyphCount;
-    sal_uInt16    aShortIDs[ 256 ];
-    sal_uInt8 aTempEncs[ 256 ];
-
-    int nNotDef=-1, i;
-    for( i = 0; i < nGlyphCount; ++i )
-    {
-        aTempEncs[i] = pEncoding[i];
-        aShortIDs[i] = static_cast<sal_uInt16>(pGlyphIds[i]);
-        if (!aShortIDs[i])
-            if( nNotDef < 0 )
-                nNotDef = i; // first NotDef glyph found
-    }
-
-    if( nNotDef != 0 )
-    {
-        // add fake NotDef glyph if needed
-        if( nNotDef < 0 )
-            nNotDef = nGlyphCount++;
-
-        // NotDef glyph must be in pos 0 => swap glyphids
-        aShortIDs[ nNotDef ] = aShortIDs[0];
-        aTempEncs[ nNotDef ] = aTempEncs[0];
-        aShortIDs[0] = 0;
-        aTempEncs[0] = 0;
-    }
-    SAL_WARN_IF( nGlyphCount >= 257, "vcl", "too many glyphs for subsetting" );
-
-    // fill pWidth array
-    std::unique_ptr<sal_uInt16[]> pMetrics =
-        ::GetTTSimpleGlyphMetrics( aSftTTF.get(), aShortIDs, nGlyphCount, aIFSD.mbVertical );
-    if( !pMetrics )
-        return false;
-    sal_uInt16 nNotDefAdv = pMetrics[0];
-    pMetrics[0]         = pMetrics[nNotDef];
-    pMetrics[nNotDef]   = nNotDefAdv;
-    for( i = 0; i < nOrigCount; ++i )
-        pGlyphWidths[i] = pMetrics[i];
-    pMetrics.reset();
-
     // write subset into destination file
-    nRC = ::CreateTTFromTTGlyphs( aSftTTF.get(), aToFile.getStr(), aShortIDs,
-            aTempEncs, nGlyphCount );
-    return (nRC == SFErrCodes::Ok);
+    return SalGraphics::CreateFontSubset(*aSftTTF.get(), aToFile, aIFSD.mbVertical, pGlyphIds, pEncoding,
+                                         pGlyphWidths, nGlyphCount);
 }
 
 const void* WinSalGraphics::GetEmbedFontData(const PhysicalFontFace* pFont, long* pDataLen)


More information about the Libreoffice-commits mailing list