diff options
Diffstat (limited to 'vcl/source/fontsubset/cff.cxx')
-rw-r--r-- | vcl/source/fontsubset/cff.cxx | 188 |
1 files changed, 46 insertions, 142 deletions
diff --git a/vcl/source/fontsubset/cff.cxx b/vcl/source/fontsubset/cff.cxx index 39964f635c9c..620ca64f44d9 100644 --- a/vcl/source/fontsubset/cff.cxx +++ b/vcl/source/fontsubset/cff.cxx @@ -33,6 +33,7 @@ #include <assert.h> #include <vcl/fontsubset.hxx> +#include <vcl/strhelper.hxx> //#define IGNORE_HINTS @@ -391,11 +392,9 @@ public: // used by charstring converter void setCharStringType( int); void fakeLocalSubrCount( int nLocalSubrs ) { maCffLocal[0].mnLocalSubrCount=nLocalSubrs;} - void readCharString( const U8* pTypeOps, int nTypeLen); protected: int convert2Type1Ops( CffLocal*, const U8* pType2Ops, int nType2Len, U8* pType1Ops); private: - void readTypeOp( CffSubsetterContext&); void convertOneTypeOp( void); void convertOneTypeEsc( void); void callType2Subr( bool bGlobal, int nSubrNumber); @@ -431,7 +430,6 @@ private: int getGlyphSID( int nGlyphIndex) const; const char* getGlyphName( int nGlyphIndex); - void readTypeOp( void); void read2push( void); void pop2write( void); void writeType1Val( ValType); @@ -611,25 +609,6 @@ void CffSubsetterContext::setCharStringType( int nVal) // -------------------------------------------------------------------- -void CffSubsetterContext::readCharString( const U8* pTypeOps, int nTypeLen) -{ - mnStackIdx = 0; - mnHintSize = 0; - mnHorzHintSize = 0; - maCharWidth = -1; - - assert( nTypeLen >= 0); -// assert( nEnd <= getLength()); - mpReadPtr = pTypeOps; - mpReadEnd = mpReadPtr + nTypeLen; - // reset the execution context - while( mpReadPtr < mpReadEnd) - readTypeOp(); -//### assert( tellRel() == nEnd); -} - -// -------------------------------------------------------------------- - void CffSubsetterContext::readDictOp( void) { ValType nVal = 0; @@ -765,112 +744,6 @@ void CffSubsetterContext::readDictOp( void) // -------------------------------------------------------------------- -void CffSubsetterContext::readTypeOp( void) -{ - int nVal = 0; - const U8 c = *mpReadPtr; - if( (c <= 31) && (c != 28) ) { - const int nOpId = *(mpReadPtr++); - const char* pCmdName; - if( nOpId != 12) - pCmdName = mpCharStringOps[ nOpId]; - else { - const int nExtId = *(mpReadPtr++); - pCmdName = mpCharStringEscs[ nExtId]; - } - - if( !pCmdName ) - pCmdName = ".NULL"; - // handle typeop parameters - int nMinStack = -1, nMaxStack = -1; - switch( *pCmdName) { - default: fprintf( stderr, "unsupported TypeOp.type=\'%c\'\n", *pCmdName); break; - case '.': nMinStack = 0; nMaxStack = 999; break; - case '0': nMinStack = nMaxStack = 0; break; - case '1': nMinStack = nMaxStack = 1; break; - case '2': nMinStack = nMaxStack = 2; break; - case '4': nMinStack = nMaxStack = 4; break; - case '5': nMinStack = nMaxStack = 5; break; // not used for Type2 ops - case '6': nMinStack = nMaxStack = 6; break; - case '7': nMinStack = nMaxStack = 7; break; - case '9': nMinStack = nMaxStack = 9; break; - case 'f': nMinStack = nMaxStack = 11; break; - case 'F': nMinStack = nMaxStack = 13; break; - case 'A': nMinStack = 2; nMaxStack = 999; break; - case 'C': nMinStack = 6; nMaxStack = 999; break; - case 'E': nMinStack = 1; nMaxStack = 999; break; - case 'G': nMinStack = 1; nMaxStack = 999; // global subr - nVal = peekInt(); - // TODO global subr - break; - case 'L': // local subr - nMinStack = 1; nMaxStack = 999; - nVal = peekInt(); - // TODO local subr - break; - case 'I': // operands for "index" -#if 0 - nMinStack = nValStack[ nStackIdx-1]; - if( nMinStack < 0) nMinStack = 0; - nMinStack += 1; -#else - fprintf( stderr, "TODO: Iindex op\n"); -#endif - break; - case 'R': // operands for "rol" -#if 0 - nMinStack = nValStack[ nStackIdx-2]; -#else - fprintf( stderr, "TODO: Rrol op\n"); -#endif - case 'X': // operands for "return" - nMinStack = 0; - nMaxStack = /*### (!bInSubrs)? 0 :###*/999; - break; - case 'H': // "hstemhm" - case 'h': // "hstem" - addHints( false); - nMinStack = nMaxStack = 0; - break; - case 'V': // "vstemhm" - case 'v': // "vstem" - addHints( true); - nMinStack = nMaxStack = 0; - break; - case 'K': // "hintmask" or "cntrmask" - addHints( true); // implicit vstemhm - nMinStack = nMaxStack = 0; - break; - case 'e': // endchar - updateWidth( (size() >= 1) && (size() != 4)); - nMinStack = nMaxStack = 0; - if( size() == 4) - fprintf( stderr,"Deprecated SEAC-like endchar is not supported for CFF subsetting!\n"); // TODO: handle deprecated op - break; - case 'm': // hmoveto or vmoveto - updateWidth( size() > 1); - nMinStack = 1; - nMaxStack = nMinStack; - break; - case 'M': // rmoveto - updateWidth( size() > 2); - nMinStack = 2; - nMaxStack = nMinStack; - break; - } - - clear(); - return; - } - - if( (c >= 32) || (c == 28)) { -// --mpReadPtr; - read2push(); - } -} - -// -------------------------------------------------------------------- - void CffSubsetterContext::read2push() { ValType aVal = 0; @@ -2155,6 +2028,17 @@ void Type1Emitter::emitAllCrypted( void) // -------------------------------------------------------------------- +// #i110387# quick-and-dirty double->ascii conversion +// needed because sprintf/ecvt/etc. alone are too localized (LC_NUMERIC) +// also strip off trailing zeros in fraction while we are at it +inline int dbl2str( char* pOut, double fVal, int nPrecision=6) +{ + const int nLen = psp::getValueOfDouble( pOut, fVal, nPrecision); + return nLen; +} + +// -------------------------------------------------------------------- + void Type1Emitter::emitValVector( const char* pLineHead, const char* pLineTail, const ValVector& rVector) { @@ -2170,10 +2054,11 @@ void Type1Emitter::emitValVector( const char* pLineHead, const char* pLineTail, aVal = *it; if( ++it == rVector.end() ) break; - mpPtr += sprintf( mpPtr, "%g ", aVal); + mpPtr += dbl2str( mpPtr, aVal); + *(mpPtr++) = ' '; } // emit the last value - mpPtr += sprintf( mpPtr, "%g", aVal); + mpPtr += dbl2str( mpPtr, aVal); // emit the line tail mpPtr += sprintf( mpPtr, pLineTail); } @@ -2330,18 +2215,33 @@ bool CffSubsetterContext::emitAsType1( Type1Emitter& rEmitter, rEmitter.emitValVector( "/FamilyBlues [", "]ND\n", mpCffLocal->maFamilyBlues); rEmitter.emitValVector( "/FamilyOtherBlues [", "]ND\n", mpCffLocal->maFamilyOtherBlues); - if( mpCffLocal->mfBlueScale) - pOut += sprintf( pOut, "/BlueScale %.6f def\n", mpCffLocal->mfBlueScale); - if( mpCffLocal->mfBlueShift) // default BlueShift==7 - pOut += sprintf( pOut, "/BlueShift %.1f def\n", mpCffLocal->mfBlueShift); - if( mpCffLocal->mfBlueFuzz) // default BlueFuzz==1 - pOut += sprintf( pOut, "/BlueFuzz %.1f def\n", mpCffLocal->mfBlueFuzz); + if( mpCffLocal->mfBlueScale) { + pOut += sprintf( pOut, "/BlueScale "); + pOut += dbl2str( pOut, mpCffLocal->mfBlueScale, 6); + pOut += sprintf( pOut, " def\n"); + } + if( mpCffLocal->mfBlueShift) { // default BlueShift==7 + pOut += sprintf( pOut, "/BlueShift "); + pOut += dbl2str( pOut, mpCffLocal->mfBlueShift); + pOut += sprintf( pOut, " def\n"); + } + if( mpCffLocal->mfBlueFuzz) { // default BlueFuzz==1 + pOut += sprintf( pOut, "/BlueFuzz "); + pOut += dbl2str( pOut, mpCffLocal->mfBlueFuzz); + pOut += sprintf( pOut, " def\n"); + } // emit stem hint related privdict entries - if( mpCffLocal->maStemStdHW) - pOut += sprintf( pOut, "/StdHW [%g] def\n", mpCffLocal->maStemStdHW); - if( mpCffLocal->maStemStdVW) - pOut += sprintf( pOut, "/StdVW [%g] def\n", mpCffLocal->maStemStdVW); + if( mpCffLocal->maStemStdHW) { + pOut += sprintf( pOut, "/StdHW ["); + pOut += dbl2str( pOut, mpCffLocal->maStemStdHW); + pOut += sprintf( pOut, "] def\n"); + } + if( mpCffLocal->maStemStdVW) { + pOut += sprintf( pOut, "/StdVW ["); + pOut += dbl2str( pOut, mpCffLocal->maStemStdVW); + pOut += sprintf( pOut, "] def\n"); + } rEmitter.emitValVector( "/StemSnapH [", "]ND\n", mpCffLocal->maStemSnapH); rEmitter.emitValVector( "/StemSnapV [", "]ND\n", mpCffLocal->maStemSnapV); @@ -2352,8 +2252,11 @@ bool CffSubsetterContext::emitAsType1( Type1Emitter& rEmitter, pOut += sprintf( pOut, "/LanguageGroup %d def\n", mpCffLocal->mnLangGroup); if( mpCffLocal->mnLangGroup == 1) // compatibility with ancient printers pOut += sprintf( pOut, "/RndStemUp false def\n"); - if( mpCffLocal->mfExpFactor) - pOut += sprintf( pOut, "/ExpansionFactor %.2f def\n", mpCffLocal->mfExpFactor); + if( mpCffLocal->mfExpFactor) { + pOut += sprintf( pOut, "/ExpansionFactor "); + pOut += dbl2str( pOut, mpCffLocal->mfExpFactor); + pOut += sprintf( pOut, " def\n"); + } #endif // IGNORE_HINTS // emit remaining privdict entries @@ -2376,6 +2279,7 @@ bool CffSubsetterContext::emitAsType1( Type1Emitter& rEmitter, // emit used GlobalSubr charstrings // these are the just the default subrs + // TODO: do we need them as the flex hints are resolved differently? static const char aSubrs[] = "/Subrs 5 array\n" "dup 0 15 RD \x5F\x3D\x6B\xAC\x3C\xBD\x74\x3D\x3E\x17\xA0\x86\x58\x08\x85 NP\n" |