tdf#113048: Fix PDF ascender and descender of some fonts
Use the same ascender and descender calculation for fonts with CFF
table as fonts without CFF table.
This also provides a better fix for tdf#138325 and tdf#151039.
Change-Id: I416a123199e94401fa557fce95013eb8b0590e33
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143683
Tested-by: خالد حسني <khaled@aliftype.com>
Reviewed-by: خالد حسني <khaled@aliftype.com>
diff --git a/vcl/inc/fontsubset.hxx b/vcl/inc/fontsubset.hxx
index d7e5318..a1ba31aa 100644
--- a/vcl/inc/fontsubset.hxx
+++ b/vcl/inc/fontsubset.hxx
@@ -70,6 +70,7 @@ public: // TODO: make subsetter results private and provide accessor methods ins
int m_nCapHeight;
tools::Rectangle m_aFontBBox;
FontType m_nFontType; ///< font-type of subset result
bool m_bFilled;
private:
// input-font-specific details
diff --git a/vcl/inc/sft.hxx b/vcl/inc/sft.hxx
index 29f282a..52d9c3d 100644
--- a/vcl/inc/sft.hxx
+++ b/vcl/inc/sft.hxx
@@ -616,7 +616,6 @@ class TrueTypeFont;
VCL_DLLPUBLIC bool CreateCFFfontSubset(const unsigned char* pFontBytes,
int nByteLength,
std::vector<sal_uInt8>& rOutBuffer,
const OUString& rPSName,
const sal_GlyphId* pGlyphIds,
const sal_uInt8* pEncoding,
int nGlyphCount, FontSubsetInfo& rInfo);
diff --git a/vcl/source/font/PhysicalFontFace.cxx b/vcl/source/font/PhysicalFontFace.cxx
index 682113c..72c0a86 100644
--- a/vcl/source/font/PhysicalFontFace.cxx
+++ b/vcl/source/font/PhysicalFontFace.cxx
@@ -358,13 +358,6 @@ bool PhysicalFontFace::CreateFontSubset(std::vector<sal_uInt8>& rOutBuffer,
const sal_GlyphId* pGlyphIds, const sal_uInt8* pEncoding,
const int nGlyphCount, FontSubsetInfo& rInfo) const
{
// Shortcut for CFF-subsetting.
auto aData = GetRawFontData(T_CFF);
if (!aData.empty())
return CreateCFFfontSubset(aData.data(), aData.size(), rOutBuffer,
GetName(NAME_ID_POSTSCRIPT_NAME), pGlyphIds, pEncoding,
nGlyphCount, rInfo);
// Prepare data for font subsetter.
TrueTypeFace aSftFont(RawFace(GetHbFace()), GetFontCharMap());
if (aSftFont.initialize() != SFErrCodes::Ok)
@@ -373,6 +366,12 @@ bool PhysicalFontFace::CreateFontSubset(std::vector<sal_uInt8>& rOutBuffer,
// Get details about the subset font.
FillFontSubsetInfo(&aSftFont, rInfo);
// Shortcut for CFF-subsetting.
auto aData = GetRawFontData(T_CFF);
if (!aData.empty())
return CreateCFFfontSubset(aData.data(), aData.size(), rOutBuffer, pGlyphIds, pEncoding,
nGlyphCount, rInfo);
// write subset into destination file
return CreateTTFfontSubset(aSftFont, rOutBuffer, pGlyphIds, pEncoding, nGlyphCount);
}
diff --git a/vcl/source/fontsubset/cff.cxx b/vcl/source/fontsubset/cff.cxx
index 45a8b78..76a77ec 100644
--- a/vcl/source/fontsubset/cff.cxx
+++ b/vcl/source/fontsubset/cff.cxx
@@ -2361,9 +2361,22 @@ void CffSubsetterContext::emitAsType1( Type1Emitter& rEmitter,
rEmitter.emitValVector( "/FontMatrix [", "]readonly def\n", maFontMatrix);
else // emit default FontMatrix if needed
rEmitter.maBuffer.append( "/FontMatrix [0.001 0 0 0.001 0 0]readonly def\n");
// emit FontBBox
ValType fXFactor = 1.0;
ValType fYFactor = 1.0;
if( maFontMatrix.size() >= 4) {
fXFactor = 1000.0F * maFontMatrix[0];
fYFactor = 1000.0F * maFontMatrix[3];
}
auto aFontBBox = maFontBBox;
if (aFontBBox.size() != 4)
if (rFSInfo.m_bFilled)
aFontBBox = {
rFSInfo.m_aFontBBox.Left() / fXFactor, rFSInfo.m_aFontBBox.Top() / fYFactor,
rFSInfo.m_aFontBBox.Right() / fXFactor, (rFSInfo.m_aFontBBox.Bottom() + 1) / fYFactor
};
else if (aFontBBox.size() != 4)
aFontBBox = { 0, 0, 999, 999 }; // emit default FontBBox if needed
rEmitter.emitValVector( "/FontBBox {", "}readonly def\n", aFontBBox);
// emit FONTINFO into TOPDICT
@@ -2572,12 +2585,12 @@ void CffSubsetterContext::emitAsType1( Type1Emitter& rEmitter,
// provide details to the subset requesters, TODO: move into own method?
// note: Top and Bottom are flipped between Type1 and VCL
// note: the rest of VCL expects the details below to be scaled like for an emUnits==1000 font
ValType fXFactor = 1.0;
ValType fYFactor = 1.0;
if( maFontMatrix.size() >= 4) {
fXFactor = 1000.0F * maFontMatrix[0];
fYFactor = 1000.0F * maFontMatrix[3];
}
rFSInfo.m_nFontType = rEmitter.mbPfbSubset ? FontType::TYPE1_PFB : FontType::TYPE1_PFA;
if (rFSInfo.m_bFilled)
return;
rFSInfo.m_aFontBBox = { Point(static_cast<sal_Int32>(aFontBBox[0] * fXFactor),
static_cast<sal_Int32>(aFontBBox[1] * fYFactor)),
Point(static_cast<sal_Int32>(aFontBBox[2] * fXFactor),
@@ -2588,7 +2601,6 @@ void CffSubsetterContext::emitAsType1( Type1Emitter& rEmitter,
rFSInfo.m_nDescent = -rFSInfo.m_aFontBBox.Top(); // for all letters
rFSInfo.m_nCapHeight = rFSInfo.m_nAscent; // for top-flat capital letters
rFSInfo.m_nFontType = rEmitter.mbPfbSubset ? FontType::TYPE1_PFB : FontType::TYPE1_PFA;
rFSInfo.m_aPSName = OUString( rEmitter.maSubsetName, strlen(rEmitter.maSubsetName), RTL_TEXTENCODING_UTF8 );
}
diff --git a/vcl/source/fontsubset/fontsubset.cxx b/vcl/source/fontsubset/fontsubset.cxx
index 1e3daa4..4e6e03c 100644
--- a/vcl/source/fontsubset/fontsubset.cxx
+++ b/vcl/source/fontsubset/fontsubset.cxx
@@ -29,6 +29,7 @@ FontSubsetInfo::FontSubsetInfo()
, m_nDescent( 0)
, m_nCapHeight( 0)
, m_nFontType( FontType::NO_FONT)
, m_bFilled(false)
, mpInFontBytes( nullptr)
, mnInByteLength( 0)
, meInFontType( FontType::NO_FONT)
diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index b0518a0..205be4f 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1868,16 +1868,15 @@ bool CreateTTFfontSubset(vcl::AbstractTrueTypeFont& rTTF, std::vector<sal_uInt8>
}
bool CreateCFFfontSubset(const unsigned char* pFontBytes, int nByteLength,
std::vector<sal_uInt8>& rOutBuffer, const OUString& rPSName,
const sal_GlyphId* pGlyphIds, const sal_uInt8* pEncoding, int nGlyphCount,
FontSubsetInfo& rInfo)
std::vector<sal_uInt8>& rOutBuffer, const sal_GlyphId* pGlyphIds,
const sal_uInt8* pEncoding, int nGlyphCount, FontSubsetInfo& rInfo)
{
utl::TempFileFast aTempFile;
SvStream* pStream = aTempFile.GetStream(StreamMode::READWRITE);
rInfo.LoadFont(FontType::CFF_FONT, pFontBytes, nByteLength);
bool bRet = rInfo.CreateFontSubset(FontType::TYPE1_PFB, pStream, rPSName.toUtf8().getStr(),
pGlyphIds, pEncoding, nGlyphCount);
bool bRet = rInfo.CreateFontSubset(FontType::TYPE1_PFB, pStream, nullptr, pGlyphIds, pEncoding,
nGlyphCount);
if (bRet)
{
@@ -2269,6 +2268,8 @@ void FillFontSubsetInfo(AbstractTrueTypeFont *ttf, FontSubsetInfo& rInfo)
rInfo.m_nDescent = +aTTInfo.typoDescender;
if (!rInfo.m_nDescent)
rInfo.m_nDescent = -aTTInfo.descender;
rInfo.m_bFilled = true;
}
std::unique_ptr<GlyphData> GetTTRawGlyphData(AbstractTrueTypeFont *ttf, sal_uInt32 glyphID)