Kaydet (Commit) 6907cbd0 authored tarafından Thorsten Behrens's avatar Thorsten Behrens

tdf#113448 fix type1 font subsetter

This fixes verapdf A-1 validation error '6.2.11.5-1 glyph width in
dict and font file inconsistent'

Previous code was writing hard-coded '1000' as glyph width for any
type1 font subsetting - since actual type2 width info only became
available during subsequent convertOneTypeOp() parsing.

Catch was, that loop sometimes already modifies the output buffer
(whenever glyph path info was given), so we fix that by first padding
out 5 bytes for the width (size of integers are sadly variable), then
parsing Type2 glyph code, and in the end putting in the actual width
value we then know.

Can't put hsbw type1 op last, since standard requires that to be first
(and can only be given _once_)...

Could be re-done nicer by buffering Type2 glyph data, then writing it.
Left as an exercise for the reader.

Change-Id: I64ffaa32ded2f0a7c06311d1e0426cf358308a0a
Reviewed-on: https://gerrit.libreoffice.org/69293
Tested-by: Jenkins
Reviewed-by: 's avatarThorsten Behrens <Thorsten.Behrens@CIB.de>
üst b4d5e95b
...@@ -1099,16 +1099,34 @@ int CffSubsetterContext::convert2Type1Ops( CffLocal* pCffLocal, const U8* const ...@@ -1099,16 +1099,34 @@ int CffSubsetterContext::convert2Type1Ops( CffLocal* pCffLocal, const U8* const
mpReadEnd = pT2Ops + nT2Len; mpReadEnd = pT2Ops + nT2Len;
// prepend "hsbw" or "sbw" // prepend "hsbw" or "sbw"
// TODO: only emit hsbw when charwidth is known // TODO: only emit hsbw when charwidth is known
// TODO: remove charwidth from T2 stack writeType1Val(0); // TODO: aSubsetterContext.getLeftSideBearing();
writeType1Val( 0); // TODO: aSubsetterContext.getLeftSideBearing(); U8* pCharWidthPtr=mpWritePtr; // need to overwrite that later
writeType1Val( 1000/*###getCharWidth()###*/); // pad out 5 bytes for the char width with default val 1000 (to be
writeTypeOp( TYPE1OP::HSBW); // filled with the actual value below)
*(mpWritePtr++) = 255;
*(mpWritePtr++) = static_cast<U8>(0);
*(mpWritePtr++) = static_cast<U8>(0);
*(mpWritePtr++) = static_cast<U8>(250);
*(mpWritePtr++) = static_cast<U8>(124);
writeTypeOp(TYPE1OP::HSBW);
mbNeedClose = false; mbNeedClose = false;
mbIgnoreHints = false; mbIgnoreHints = false;
mnHintSize=mnHorzHintSize=mnStackIdx=0; maCharWidth=-1;//####### mnHintSize=mnHorzHintSize=mnStackIdx=0; maCharWidth=-1;//#######
mnCntrMask = 0; mnCntrMask = 0;
while( mpReadPtr < mpReadEnd) while( mpReadPtr < mpReadEnd)
convertOneTypeOp(); convertOneTypeOp();
if( maCharWidth != -1 )
{
// overwrite earlier charWidth value, which we only now have
// parsed out of mpReadPtr buffer (by way of
// convertOneTypeOp()s above)
const int nInt = static_cast<int>(maCharWidth);
*(pCharWidthPtr++) = 255;
*(pCharWidthPtr++) = static_cast<U8>(nInt >> 24);
*(pCharWidthPtr++) = static_cast<U8>(nInt >> 16);
*(pCharWidthPtr++) = static_cast<U8>(nInt >> 8);
*(pCharWidthPtr++) = static_cast<U8>(nInt);
}
const int nType1Len = mpWritePtr - pT1Ops; const int nType1Len = mpWritePtr - pT1Ops;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment