Rebased ref, commits from common ancestor: commit 32deea4278d1b149f442854a24c55038eef75a95 Author: Jan-Marek Glogowski <glo...@fbihome.de> AuthorDate: Sun Sep 13 15:01:22 2020 +0200 Commit: Jan-Marek Glogowski <glo...@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) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits