32typedef sal_uInt16
U16;
39 ".notdef",
"space",
"exclam",
"quotedbl",
40 "numbersign",
"dollar",
"percent",
"ampersand",
41 "quoteright",
"parenleft",
"parenright",
"asterisk",
42 "plus",
"comma",
"hyphen",
"period",
43 "slash",
"zero",
"one",
"two",
44 "three",
"four",
"five",
"six",
45 "seven",
"eight",
"nine",
"colon",
46 "semicolon",
"less",
"equal",
"greater",
47 "question",
"at",
"A",
"B",
54 "bracketleft",
"backslash",
"bracketright",
"asciicircum",
55 "underscore",
"quoteleft",
"a",
"b",
62 "braceleft",
"bar",
"braceright",
"asciitilde",
63 "exclamdown",
"cent",
"sterlin",
"fraction",
64 "yen",
"florin",
"section",
"currency",
65 "quotesingle",
"quotedblleft",
"guillemotleft",
"guilsinglleft",
66 "guilsinglright",
"fi",
"fl",
"endash",
67 "dagger",
"daggerdbl",
"periodcentered",
"paragraph",
68 "bullet",
"quotesinglbase",
"quotedblbase",
"quotedblright",
69 "guillemotright",
"ellipsis",
"perthousand",
"questiondown",
70 "grave",
"acute",
"circumflex",
"tilde",
71 "macron",
"breve",
"dotaccent",
"dieresis",
72 "ring",
"cedilla",
"hungarumlaut",
"ogonek",
73 "caron",
"emdash",
"AE",
"ordfeminine",
74 "Lslash",
"Oslash",
"OE",
"ordmasculine",
75 "ae",
"dotlessi",
"lslash",
"oslash",
76 "oe",
"germandbls",
"onesuperior",
"logicalnot",
77 "mu",
"trademark",
"Eth",
"onehalf",
78 "plusminus",
"Thorn",
"onequarter",
"divide",
79 "brokenbar",
"degree",
"thorn",
"threequarters",
80 "twosuperior",
"registered",
"minus",
"eth",
81 "multiply",
"threesuperior",
"copyright",
"Aacute",
82 "Acircumflex",
"Adieresis",
"Agrave",
"Aring",
83 "Atilde",
"Ccedilla",
"Eacute",
"Ecircumflex",
84 "Edieresis",
"Egrave",
"Iacute",
"Icircumflex",
85 "Idieresis",
"Igrave",
"Ntilde",
"Oacute",
86 "Ocircumflex",
"Odieresis",
"Ograve",
"Otilde",
87 "Scaron",
"Uacute",
"Ucircumflex",
"Udieresis",
88 "Ugrave",
"Yacute",
"Ydieresis",
"Zcaron",
89 "aacute",
"acircumflex",
"adieresis",
"agrave",
90 "aring",
"atilde",
"ccedilla",
"eacute",
91 "ecircumflex",
"edieresis",
"egrave",
"iacute",
92 "icircumflex",
"idieresis",
"igrave",
"ntilde",
93 "oacute",
"ocircumflex",
"odieresis",
"ograve",
94 "otilde",
"scaron",
"uacute",
"ucircumflex",
95 "udieresis",
"ugrave",
"yacute",
"ydieresis",
96 "zcaron",
"exclamsmall",
"Hungarumlautsmall",
"dollaroldstyle",
97 "dollarsuperior",
"ampersandsmall",
"Acutesmall",
"parenleftsuperior",
98 "parenrightsuperior",
"twodotenleader",
"onedotenleader",
"zerooldstyle",
99 "oneoldstyle",
"twooldstyle",
"threeoldstyle",
"fouroldstyle",
100 "fiveoldstyle",
"sixoldstyle",
"sevenoldstyle",
"eightoldstyle",
101 "nineoldstile",
"commasuperior",
"threequartersemdash",
"periodsuperior",
102 "questionsmall",
"asuperior",
"bsuperior",
"centsuperior",
103 "dsuperior",
"esuperior",
"isuperior",
"lsuperior",
104 "msuperior",
"nsuperior",
"osuperior",
"rsuperior",
105 "ssuperior",
"tsuperior",
"ff",
"ffi",
106 "ffl",
"parenleftinferior",
"parenrightinferior",
"Circumflexsmall",
107 "hyphensuperior",
"Gravesmall",
"Asmall",
"Bsmall",
108 "Csmall",
"Dsmall",
"Esmall",
"Fsmall",
109 "Gsmall",
"Hsmall",
"Ismall",
"Jsmall",
110 "Ksmall",
"Lsmall",
"Msmall",
"Nsmall",
111 "Osmall",
"Psmall",
"Qsmall",
"Rsmall",
112 "Ssmall",
"Tsmall",
"Usmall",
"Vsmall",
113 "Wsmall",
"Xsmall",
"Ysmall",
"Zsmall",
114 "colonmonetary",
"onefitted",
"rupia",
"Tildesmall",
115 "exclamdownsmall",
"centoldstyle",
"Lslashsmall",
"Scaronsmall",
116 "Zcaronsmall",
"Dieresissmall",
"Brevesmall",
"Caronsmall",
117 "Dotaccentsmall",
"Macronsmall",
"figuredash",
"hypheninferior",
118 "Ogoneksmall",
"Ringsmall",
"Cedillasmall",
"questiondownsmall",
119 "oneeight",
"threeeights",
"fiveeights",
"seveneights",
120 "onethird",
"twothirds",
"zerosuperior",
"foursuperior",
121 "fivesuperior",
"sixsuperior",
"sevensuperior",
"eightsuperior",
122 "ninesuperior",
"zeroinferior",
"oneinferior",
"twoinferior",
123 "threeinferior",
"fourinferior",
"fiveinferior",
"sixinferior",
124 "seveninferior",
"eightinferior",
"nineinferior",
"centinferior",
125 "dollarinferior",
"periodinferior",
"commainferior",
"Agravesmall",
126 "Aacutesmall",
"Acircumflexsmall",
"Atildesmall",
"Adieresissmall",
127 "Aringsmall",
"AEsmall",
"Ccedillasmall",
"Egravesmall",
128 "Eacutesmall",
"Ecircumflexsmall",
"Edieresissmall",
"Igravesmall",
129 "Iacutesmall",
"Icircumflexsmall",
"Idieresissmall",
"Ethsmall",
130 "Ntildesmall",
"Ogravesmall",
"Oacutesmall",
"Ocircumflexsmall",
131 "Otildesmall",
"Odieressissmall",
"OEsmall",
"Oslashsmall",
132 "Ugravesmall",
"Uacutesmall",
"Ucircumflexsmall",
"Udieresissmall",
133 "Yacutesmall",
"Thornsmall",
"Ydieresissmall",
"001.000",
134 "001.001",
"001.002",
"001.003",
"Black",
135 "Bold",
"Book",
"Light",
"Medium",
136 "Regular",
"Roman",
"Semibold"
141 "sVersion",
"sNotice",
"sFullName",
"sFamilyName",
142 "sWeight",
"aFontBBox",
"dBlueValues",
"dOtherBlues",
143 "dFamilyBlues",
"dFamilyOtherBlues",
"nStdHW",
"nStdVW",
144 "xESC",
"nUniqueID",
"aXUID",
"nCharset",
145 "nEncoding",
"nCharStrings",
"PPrivate",
"nSubrs",
146 "nDefaultWidthX",
"nNominalWidthX",
nullptr,
nullptr,
147 nullptr,
nullptr,
nullptr,
nullptr,
148 "shortint",
"longint",
"BCD",
nullptr
153 "sCopyright",
"bIsFixedPitch",
"nItalicAngle",
"nUnderlinePosition",
154 "nUnderlineThickness",
"nPaintType",
"tCharstringType",
"aFontMatrix",
155 "nStrokeWidth",
"nBlueScale",
"nBlueShift",
"nBlueFuzz",
156 "dStemSnapH",
"dStemSnapV",
"bForceBold",
nullptr,
157 nullptr,
"nLanguageGroup",
"nExpansionFactor",
"nInitialRandomSeed",
158 "nSyntheticBase",
"sPostScript",
"sBaseFontName",
"dBaseFontBlend",
159 nullptr,
nullptr,
nullptr,
nullptr,
160 nullptr,
nullptr,
"rROS",
"nCIDFontVersion",
161 "nCIDFontRevision",
"nCIDFontType",
"nCIDCount",
"nUIDBase",
162 "nFDArray",
"nFDSelect",
"sFontName"
171 HSTEM=1, VSTEM=3, VMOVETO=4, RLINETO=5,
172 HLINETO=6, VLINETO=7, RCURVETO=8, CLOSEPATH=9,
173 CALLSUBR=10,
RETURN=11, T1ESC=12, HSBW=13,
174 ENDCHAR=14, RMOVETO=21, HMOVETO=22, VHCURVETO=30,
180 DOTSECTION=0, VSTEM3=1, HSTEM3=2, SEAC=6,
181 SBW=7, ABS=9,
ADD=10,
SUB=11,
182 DIV=12, CALLOTHERSUBR=16,
POP=17, SETCURRENTPOINT=33
190 HSTEM=1, VSTEM=3, VMOVETO=4, RLINETO=5,
191 HLINETO=6, VLINETO=7, RCURVETO=8, CALLSUBR=10,
192 RETURN=11, T2ESC=12, ENDCHAR=14, HSTEMHM=18,
193 HINTMASK=19, CNTRMASK=20, RMOVETO=21, HMOVETO=22,
194 VSTEMHM=23, RCURVELINE=24, RLINECURVE=25, VVCURVETO=26,
195 HHCURVETO=27, SHORTINT=28, CALLGSUBR=29, VHCURVETO=30,
205 DUP=27, EXCH=28,
INDEX=29, ROLL=30,
206 HFLEX=34, FLEX=35, HFLEX1=36, FLEX1=37
212 explicit CffGlobal();
220 int mnGlobalSubrBase;
221 int mnGlobalSubrCount;
222 int mnGlobalSubrBias;
227 std::vector<ValType> maFontBBox;
228 std::vector<ValType> maFontMatrix;
250 std::vector<ValType> maStemSnapH;
251 std::vector<ValType> maStemSnapV;
252 std::vector<ValType> maBlueValues;
253 std::vector<ValType> maOtherBlues;
254 std::vector<ValType> maFamilyBlues;
255 std::vector<ValType> maFamilyOtherBlues;
264class CffSubsetterContext
268 static const int NMAXSTACK = 48;
269 static const int NMAXHINTS = 2*96;
270 static const int NMAXTRANS = 32;
272 explicit CffSubsetterContext(
const U8* pBasePtr,
int nBaseLen);
274 bool initialCffRead();
275 void emitAsType1(
class Type1Emitter&,
280 int convert2Type1Ops( CffLocal*,
const U8* pType2Ops,
int nType2Len,
U8* pType1Ops);
281 void convertOneTypeOp();
282 void convertOneTypeEsc();
283 void callType2Subr(
bool bGlobal,
int nSubrNumber);
284 sal_Int32 getReadOfs()
const {
return static_cast<sal_Int32
>(mpReadPtr - mpBasePtr);}
295 sal_Int32 mnCntrMask;
297 int seekIndexData(
int nIndexBase,
int nDataIndex);
298 void seekIndexEnd(
int nIndexBase);
300 CffLocal maCffLocal[256];
301 CffLocal* mpCffLocal;
306 int getFDSelect(
int nGlyphIndex)
const;
307 int getGlyphSID(
int nGlyphIndex)
const;
308 const char* getGlyphName(
int nGlyphIndex);
312 void writeTypeOp(
int nTypeOp);
313 void writeTypeEsc(
int nTypeOp);
314 void writeCurveTo(
int nStackPos,
int nIX1,
int nIY1,
int nIX2,
int nIY2,
int nIX3,
int nIY3);
315 void pop2MultiWrite(
int nArgsPerTypo,
int nTypeOp,
int nTypeXor=0);
316 void popAll2Write(
int nTypeOp);
321 void push(
ValType nVal) { mnValStack[ mnStackIdx++] = nVal;}
322 ValType popVal() {
return ((mnStackIdx>0) ? mnValStack[ --mnStackIdx] : 0);}
323 ValType getVal(
int nIndex)
const {
return mnValStack[
nIndex];}
325 int size()
const {
return mnStackIdx;}
326 void clear() { mnStackIdx = 0;}
329 void addHints(
bool bVerticalHints);
332 void updateWidth(
bool bUseFirstVal);
337 ValType mnValStack[ NMAXSTACK+4];
338 ValType mnTransVals[ NMAXTRANS];
342 ValType mnHintStack[ NMAXHINTS];
349CffSubsetterContext::CffSubsetterContext(
const U8* pBasePtr,
int nBaseLen)
350 : mpBasePtr( pBasePtr)
351 , mpBaseEnd( pBasePtr+nBaseLen)
354 , mpWritePtr(nullptr)
356 , mbIgnoreHints(false)
368 mpCffLocal = &maCffLocal[0];
371inline int CffSubsetterContext::popInt()
374 const int nInt =
static_cast<int>(aVal);
375 assert( nInt == aVal);
379inline void CffSubsetterContext::updateWidth(
bool bUseFirstVal)
386 maCharWidth = mpCffLocal->maNominalWidth + mnValStack[0];
389 for(
int i = 0;
i < mnStackIdx; ++
i)
390 mnValStack[ i] = mnValStack[ i+1];
392 maCharWidth = mpCffLocal->maDefaultWidth;
396void CffSubsetterContext::addHints(
bool bVerticalHints)
399 updateWidth( (mnStackIdx & 1) != 0);
406 if( mnStackIdx & 1) --mnStackIdx;
409 assert( (mnHintSize + mnStackIdx) <= 2*NMAXHINTS);
412 for(
int i = 0;
i < mnStackIdx; ++
i) {
413 nHintOfs += mnValStack[
i ];
414 mnHintStack[ mnHintSize++] = nHintOfs;
418 mnHorzHintSize = mnHintSize;
424void CffSubsetterContext::readDictOp()
426 const U8 c = *mpReadPtr;
428 int nOpId = *(mpReadPtr++);
429 const char* pCmdName =
nullptr;
433 const U8 nExtId = *(mpReadPtr++);
436 nOpId = 900 + nExtId;
445 default:
SAL_WARN(
"vcl.fonts",
"unsupported DictOp.type='" << *pCmdName <<
"'.");
break;
449 case 915: mpCffLocal->mbForceBold = nInt;
break;
455 nInt =
static_cast<int>(nVal);
457 case 10: mpCffLocal->maStemStdHW = nVal;
break;
458 case 11: mpCffLocal->maStemStdVW = nVal;
break;
459 case 15: mnCharsetBase = nInt;
break;
461 case 17: mnCharStrBase = nInt;
break;
462 case 19: mpCffLocal->mnLocalSubrOffs = nInt;
break;
463 case 20: mpCffLocal->maDefaultWidth = nVal;
break;
464 case 21: mpCffLocal->maNominalWidth = nVal;
break;
465 case 909: mpCffLocal->mfBlueScale = nVal;
break;
466 case 910: mpCffLocal->mfBlueShift = nVal;
break;
467 case 911: mpCffLocal->mfBlueFuzz = nVal;
break;
468 case 912: mpCffLocal->mfExpFactor = nVal;
break;
469 case 917: mpCffLocal->mnLangGroup = nInt;
break;
470 case 936: mnFontDictBase = nInt;
break;
471 case 937: mnFDSelectBase = nInt;
break;
477 case 5: maFontBBox.clear();
break;
478 case 907: maFontMatrix.clear();
break;
481 for(
int i = 0;
i <
size(); ++
i ) {
484 case 5: maFontBBox.push_back( nVal);
break;
485 case 907: maFontMatrix.push_back( nVal);
break;
493 for(
int i = 0;
i <
size(); ++
i ) {
496 case 6: mpCffLocal->maBlueValues.push_back( nVal);
break;
497 case 7: mpCffLocal->maOtherBlues.push_back( nVal);
break;
498 case 8: mpCffLocal->maFamilyBlues.push_back( nVal);
break;
499 case 9: mpCffLocal->maFamilyOtherBlues.push_back( nVal);
break;
500 case 912: mpCffLocal->maStemSnapH.push_back( nVal);
break;
501 case 913: mpCffLocal->maStemSnapV.push_back( nVal);
break;
510 case 2: mnFullNameSID = nInt;
break;
512 case 938: mnFontNameSID = nInt;
break;
517 mpCffLocal->mnPrivDictBase = popInt();
518 mpCffLocal->mnPrivDictSize = popInt();
530 }
else if( (c >= 32) || (c == 28) ) {
533 }
else if( c == 29 ) {
535 sal_Int32 nS32 = mpReadPtr[0] << 24;
536 nS32 += mpReadPtr[1] << 16;
537 nS32 += mpReadPtr[2] << 8;
538 nS32 += mpReadPtr[3] << 0;
542 }
else if( c == 30) {
544 const RealType fReal = readRealVal();
551void CffSubsetterContext::read2push()
555 const U8*&
p = mpReadPtr;
558 sal_Int16 nS16 = (
p[1] << 8) + p[2];
561 }
else if( c <= 246 ) {
562 aVal =
static_cast<ValType>(
p[0] - 139);
564 }
else if( c <= 250 ) {
565 aVal =
static_cast<ValType>(((
p[0] << 8) + p[1]) - 63124);
567 }
else if( c <= 254 ) {
568 aVal =
static_cast<ValType>(64148 - ((
p[0] << 8) + p[1]));
571 int nS32 = (
p[1] << 24) + (p[2] << 16) + (
p[3] << 8) + p[4];
572 if( (
sizeof(nS32) != 2) && (nS32 & (1U<<31)))
574 aVal =
static_cast<ValType>(nS32 * (1.0 / 0x10000));
581void CffSubsetterContext::writeType1Val(
ValType aVal)
585 int nInt =
static_cast<int>(aVal);
586 if( (nInt >= -107) && (nInt <= +107)) {
587 *(
pOut++) =
static_cast<U8>(nInt + 139);
588 }
else if( (nInt >= -1131) && (nInt <= +1131)) {
593 *(
pOut++) =
static_cast<U8>(nInt >> 8);
594 *(
pOut++) =
static_cast<U8>(nInt);
598 *(
pOut++) =
static_cast<U8>(nInt >> 24);
599 *(
pOut++) =
static_cast<U8>(nInt >> 16);
600 *(
pOut++) =
static_cast<U8>(nInt >> 8);
601 *(
pOut++) =
static_cast<U8>(nInt);
607inline void CffSubsetterContext::writeTypeOp(
int nTypeOp)
609 *(mpWritePtr++) =
static_cast<U8>(nTypeOp);
612inline void CffSubsetterContext::writeTypeEsc(
int nTypeEsc)
614 *(mpWritePtr++) = TYPE1OP::T1ESC;
615 *(mpWritePtr++) =
static_cast<U8>(nTypeEsc);
618void CffSubsetterContext::pop2MultiWrite(
int nArgsPerTypo,
int nTypeOp,
int nTypeXor)
620 for(
int i = 0;
i < mnStackIdx;) {
621 for(
int j = 0; j < nArgsPerTypo; ++j) {
622 const ValType aVal = mnValStack[
i+j];
623 writeType1Val( aVal);
626 writeTypeOp( nTypeOp);
632void CffSubsetterContext::popAll2Write(
int nTypeOp)
635 for(
int i = 0;
i < mnStackIdx; ++
i) {
637 writeType1Val( aVal);
640 writeTypeOp( nTypeOp);
643void CffSubsetterContext::writeCurveTo(
int nStackPos,
644 int nIX1,
int nIY1,
int nIX2,
int nIY2,
int nIX3,
int nIY3)
647 const ValType nDX1 = nIX1 ? mnValStack[ nStackPos+nIX1 ] : 0;
648 const ValType nDY1 = nIY1 ? mnValStack[ nStackPos+nIY1 ] : 0;
649 const ValType nDX2 = nIX2 ? mnValStack[ nStackPos+nIX2 ] : 0;
650 const ValType nDY2 = nIY2 ? mnValStack[ nStackPos+nIY2 ] : 0;
651 const ValType nDX3 = nIX3 ? mnValStack[ nStackPos+nIX3 ] : 0;
652 const ValType nDY3 = nIY3 ? mnValStack[ nStackPos+nIY3 ] : 0;
657 writeType1Val( nDX1 );
658 writeType1Val( nDY1 );
659 writeType1Val( nDX2 );
660 writeType1Val( nDY2 );
661 writeType1Val( nDX3 );
662 writeType1Val( nDY3 );
663 writeTypeOp( TYPE1OP::RCURVETO );
666void CffSubsetterContext::convertOneTypeOp()
668 const int nType2Op = *(mpReadPtr++);
678 addHints( nType2Op == TYPE2OP::VSTEM );
679 for( i = 0;
i < mnHintSize;
i+=2 ) {
680 writeType1Val( mnHintStack[i]);
681 writeType1Val( mnHintStack[i+1] - mnHintStack[i]);
682 writeTypeOp( nType2Op );
685 case TYPE2OP::HSTEMHM:
686 case TYPE2OP::VSTEMHM:
687 addHints( nType2Op == TYPE2OP::VSTEMHM);
689 case TYPE2OP::CNTRMASK:
695 for( i = 0; i < mnHintSize; i+=2, nMaskBit>>=1) {
697 nMaskByte = *(mpReadPtr++);
700 if( !(nMaskByte & nMaskBit))
702 if( i >= 8*
int(
sizeof(mnCntrMask)))
703 mbIgnoreHints =
true;
706 mnCntrMask |= (1U <<
i);
710 case TYPE2OP::HINTMASK:
713 sal_Int32 nHintMask = 0;
714 int nCntrBits[2] = {0,0};
717 int const MASK_BITS = 8*
sizeof(nHintMask);
718 for( i = 0; i < mnHintSize; i+=2, nMaskBit>>=1) {
720 nMaskByte = *(mpReadPtr++);
723 if( !(nMaskByte & nMaskBit))
726 mbIgnoreHints =
true;
729 nHintMask |= (1U <<
i);
730 nCntrBits[
i < mnHorzHintSize] += (mnCntrMask >>
i) & 1;
733 mbIgnoreHints |= (nCntrBits[0] && (nCntrBits[0] != 3));
734 mbIgnoreHints |= (nCntrBits[1] && (nCntrBits[1] != 3));
738 for( i = 0;
i < mnHintSize;
i+=2) {
739 if(i >= MASK_BITS || !(nHintMask & (1U << i)))
741 writeType1Val( mnHintStack[i]);
742 writeType1Val( mnHintStack[i+1] - mnHintStack[i]);
743 const bool bHorz = (
i < mnHorzHintSize);
744 if( !nCntrBits[ bHorz])
745 writeTypeOp( bHorz ? TYPE1OP::HSTEM : TYPE1OP::VSTEM);
746 else if( !--nCntrBits[ bHorz])
747 writeTypeEsc( bHorz ? TYPE1OP::HSTEM3 : TYPE1OP::VSTEM3);
751 case TYPE2OP::CALLSUBR:
752 case TYPE2OP::CALLGSUBR:
755 const bool bGlobal = (nType2Op == TYPE2OP::CALLGSUBR);
756 callType2Subr( bGlobal, nInt);
759 case TYPE2OP::RETURN:
762 case TYPE2OP::VMOVETO:
763 case TYPE2OP::HMOVETO:
765 writeTypeOp( TYPE1OP::CLOSEPATH);
767 updateWidth(
size() > 1);
769 pop2MultiWrite( 1, nType2Op);
771 case TYPE2OP::VLINETO:
772 case TYPE2OP::HLINETO:
773 pop2MultiWrite( 1, nType2Op,
774 TYPE1OP::VLINETO ^ TYPE1OP::HLINETO);
776 case TYPE2OP::RMOVETO:
779 writeTypeOp( TYPE1OP::CLOSEPATH);
781 updateWidth(
size() > 2);
783 pop2MultiWrite( 2, nType2Op);
785 case TYPE2OP::RLINETO:
787 pop2MultiWrite( 2, nType2Op);
789 case TYPE2OP::RCURVETO:
791 pop2MultiWrite( 6, nType2Op);
793 case TYPE2OP::RCURVELINE:
795 while( (i += 6) <= mnStackIdx)
796 writeCurveTo( i, -6, -5, -4, -3, -2, -1 );
798 while( (i += 2) <= mnStackIdx) {
799 writeType1Val( mnValStack[i-2]);
800 writeType1Val( mnValStack[i-1]);
801 writeTypeOp( TYPE2OP::RLINETO);
805 case TYPE2OP::RLINECURVE:
807 while( (i += 2) <= mnStackIdx-6) {
808 writeType1Val( mnValStack[i-2]);
809 writeType1Val( mnValStack[i-1]);
810 writeTypeOp( TYPE2OP::RLINETO);
813 while( (i += 6) <= mnStackIdx)
814 writeCurveTo( i, -6, -5, -4, -3, -2, -1 );
817 case TYPE2OP::VHCURVETO:
818 case TYPE2OP::HVCURVETO:
820 bool bVert = (nType2Op == TYPE2OP::VHCURVETO);
824 nInt =
static_cast<int>(mnValStack[ --mnStackIdx ]);
825 while( (i += 4) <= mnStackIdx) {
827 if( bVert ) writeType1Val( 0 );
828 writeType1Val( mnValStack[i-4] );
829 if( !bVert ) writeType1Val( 0);
830 writeType1Val( mnValStack[i-3] );
831 writeType1Val( mnValStack[i-2] );
832 if( !bVert ) writeType1Val(
static_cast<ValType>((i==mnStackIdx) ? nInt : 0) );
833 writeType1Val( mnValStack[i-1] );
834 if( bVert ) writeType1Val(
static_cast<ValType>((i==mnStackIdx) ? nInt : 0) );
836 writeTypeOp( TYPE2OP::RCURVETO);
841 case TYPE2OP::HHCURVETO:
842 i = (mnStackIdx & 1);
843 while( (i += 4) <= mnStackIdx) {
845 writeCurveTo( i, -4, 0, -3, -2, -1, 0);
847 writeCurveTo( i, -4, -5, -3, -2, -1, 0);
851 case TYPE2OP::VVCURVETO:
852 i = (mnStackIdx & 1);
853 while( (i += 4) <= mnStackIdx) {
855 writeCurveTo( i, 0, -4, -3, -2, 0, -1);
857 writeCurveTo( i, -5, -4, -3, -2, 0, -1);
861 case TYPE2OP::ENDCHAR:
863 writeTypeOp( TYPE1OP::CLOSEPATH);
865 updateWidth(
size() >= 1);
867 writeTypeOp( TYPE1OP::ENDCHAR);
870 if( ((nType2Op >= 32) && (nType2Op <= 255)) || (nType2Op == 28)) {
874 popAll2Write( nType2Op);
875 assert(
false &&
"TODO?");
881void CffSubsetterContext::convertOneTypeEsc()
883 const int nType2Esc = *(mpReadPtr++);
884 ValType* pTop = &mnValStack[ mnStackIdx-1];
888 assert( mnStackIdx >= 2 );
889 pTop[0] =
static_cast<ValType>(
static_cast<int>(pTop[0]) &
static_cast<int>(pTop[-1]));
893 assert( mnStackIdx >= 2 );
894 pTop[0] =
static_cast<ValType>(
static_cast<int>(pTop[0]) |
static_cast<int>(pTop[-1]));
898 assert( mnStackIdx >= 1 );
899 pTop[0] =
ValType(pTop[0] == 0);
902 assert( mnStackIdx >= 1 );
907 assert( mnStackIdx >= 1 );
911 assert( mnStackIdx >= 2 );
916 assert( mnStackIdx >= 2 );
921 assert( mnStackIdx >= 2 );
927 assert( mnStackIdx >= 2 );
933 assert( mnStackIdx >= 2 );
934 pTop[0] =
ValType(pTop[0] == pTop[-1]);
938 assert( mnStackIdx >= 1 );
942 assert( mnStackIdx >= 2 );
943 const int nIdx =
static_cast<int>(pTop[0]);
945 assert( nIdx < NMAXTRANS );
946 mnTransVals[ nIdx] = pTop[-1];
951 assert( mnStackIdx >= 1 );
952 const int nIdx =
static_cast<int>(pTop[0]);
954 assert( nIdx < NMAXTRANS );
955 pTop[0] = mnTransVals[ nIdx ];
958 case TYPE2OP::IFELSE: {
959 assert( mnStackIdx >= 4 );
960 if( pTop[-1] > pTop[0] )
965 case TYPE2OP::RANDOM:
973 assert( mnStackIdx >= 1 );
977 case TYPE2OP::EXCH: {
978 assert( mnStackIdx >= 2 );
984 case TYPE2OP::INDEX: {
985 assert( mnStackIdx >= 1 );
986 const int nVal =
static_cast<int>(pTop[0]);
988 assert( nVal < mnStackIdx-1 );
989 pTop[0] = pTop[-1-nVal];
992 case TYPE2OP::ROLL: {
993 assert( mnStackIdx >= 1 );
994 const int nNum =
static_cast<int>(pTop[0]);
996 assert( nNum < mnStackIdx-2 );
1002 case TYPE2OP::HFLEX1: {
1003 assert( mnStackIdx == 9);
1005 writeCurveTo( mnStackIdx, -9, -8, -7, -6, -5, 0);
1006 writeCurveTo( mnStackIdx, -4, 0, -3, -2, -1, 0);
1012 case TYPE2OP::HFLEX: {
1013 assert( mnStackIdx == 7);
1014 ValType* pX = &mnValStack[ mnStackIdx];
1017 writeCurveTo( mnStackIdx, -7, 0, -6, -5, -4, 0);
1018 writeCurveTo( mnStackIdx, -3, 0, -2, +1, -1, 0);
1024 case TYPE2OP::FLEX: {
1025 assert( mnStackIdx == 13 );
1026 writeCurveTo( mnStackIdx, -13, -12, -11, -10, -9, -8 );
1027 writeCurveTo( mnStackIdx, -7, -6, -5, -4, -3, -2 );
1032 case TYPE2OP::FLEX1: {
1033 assert( mnStackIdx == 11 );
1035 writeCurveTo( mnStackIdx, -11, -10, -9, -8, -7, -6 );
1038 const int i = mnStackIdx;
1039 ValType nDeltaX = mnValStack[
i-11] + mnValStack[
i-9] + mnValStack[
i-7] + mnValStack[
i-5] + mnValStack[
i-3];
1040 if( nDeltaX < 0 ) nDeltaX = -nDeltaX;
1041 ValType nDeltaY = mnValStack[
i-10] + mnValStack[
i-8] + mnValStack[
i-6] + mnValStack[
i-4] + mnValStack[
i-2];
1042 if( nDeltaY < 0 ) nDeltaY = -nDeltaY;
1043 const bool bVertD6 = (nDeltaY > nDeltaX);
1047 writeCurveTo( mnStackIdx, -5, -4, -3, -2, -1, 0);
1049 writeCurveTo( mnStackIdx, -5, -4, -3, -2, 0, -1);
1054 SAL_WARN(
"vcl.fonts",
"unhandled type2esc " << nType2Esc);
1060void CffSubsetterContext::callType2Subr(
bool bGlobal,
int nSubrNumber)
1062 const U8*
const pOldReadPtr = mpReadPtr;
1063 const U8*
const pOldReadEnd = mpReadEnd;
1066 nSubrNumber += mnGlobalSubrBias;
1067 seekIndexData( mnGlobalSubrBase, nSubrNumber);
1069 nSubrNumber += mpCffLocal->mnLocalSubrBias;
1070 seekIndexData( mpCffLocal->mnLocalSubrBase, nSubrNumber);
1073 while( mpReadPtr < mpReadEnd)
1076 mpReadPtr = pOldReadPtr;
1077 mpReadEnd = pOldReadEnd;
1082int CffSubsetterContext::convert2Type1Ops( CffLocal* pCffLocal,
const U8*
const pT2Ops,
int nT2Len,
U8*
const pT1Ops)
1084 mpCffLocal = pCffLocal;
1087 mpWritePtr = pT1Ops;
1090 mpWritePtr = aType1Ops;
1091 *
const_cast<U8**
>(&pT1Ops) = mpWritePtr;
1094 *(mpWritePtr++) = 0x48;
1095 *(mpWritePtr++) = 0x44;
1096 *(mpWritePtr++) = 0x55;
1097 *(mpWritePtr++) =
' ';
1101 mpReadEnd = pT2Ops + nT2Len;
1105 U8* pCharWidthPtr=mpWritePtr;
1108 *(mpWritePtr++) = 255;
1109 *(mpWritePtr++) =
static_cast<U8>(0);
1110 *(mpWritePtr++) =
static_cast<U8>(0);
1111 *(mpWritePtr++) =
static_cast<U8>(250);
1112 *(mpWritePtr++) =
static_cast<U8>(124);
1113 writeTypeOp(TYPE1OP::HSBW);
1114 mbNeedClose =
false;
1115 mbIgnoreHints =
false;
1116 mnHintSize=mnHorzHintSize=mnStackIdx=0; maCharWidth=-1;
1118 while( mpReadPtr < mpReadEnd)
1120 if( maCharWidth != -1 )
1125 const int nInt =
static_cast<int>(maCharWidth);
1126 *(pCharWidthPtr++) = 255;
1127 *(pCharWidthPtr++) =
static_cast<U8>(nInt >> 24);
1128 *(pCharWidthPtr++) =
static_cast<U8>(nInt >> 16);
1129 *(pCharWidthPtr++) =
static_cast<U8>(nInt >> 8);
1130 *(pCharWidthPtr++) =
static_cast<U8>(nInt);
1133 const int nType1Len = mpWritePtr - pT1Ops;
1136 unsigned nRDCryptR = 4330;
1137 for(
U8*
p = pT1Ops;
p < mpWritePtr; ++
p) {
1138 *
p ^= (nRDCryptR >> 8);
1139 nRDCryptR = (*
p + nRDCryptR) * 52845 + 22719;
1145RealType CffSubsetterContext::readRealVal()
1148 bool bComma =
false;
1154 const U8 c = *(mpReadPtr++);
1156 const U8 nH = c >> 4U;
1158 nNumber = nNumber * 10 + nH;
1160 }
else if( nH == 10) {
1163 }
else if( nH == 11) {
1167 }
else if( nH == 12) {
1171 }
else if( nH == 13) {
1173 }
else if( nH == 14)
1178 const U8 nL = c & 0x0F;
1180 nNumber = nNumber * 10 + nL;
1182 }
else if( nL == 10) {
1185 }
else if( nL == 11) {
1189 }
else if( nL == 12) {
1193 }
else if( nL == 13) {
1195 }
else if( nL == 14)
1204 if( !nExpSign) { fReal *= nNumber;}
1205 else if( nExpSign > 0) { nExpVal +=
static_cast<int>(nNumber);}
1206 else if( nExpSign < 0) { nExpVal -=
static_cast<int>(nNumber);}
1210 else if( nExpVal > 0) {
while( --nExpVal >= 0) fReal *= 10.0;}
1211 else if( nExpVal < 0) {
while( ++nExpVal <= 0) fReal /= 10.0;}
1216int CffSubsetterContext::seekIndexData(
int nIndexBase,
int nDataIndex)
1218 assert( (nIndexBase > 0) && (mpBasePtr + nIndexBase + 3 <= mpBaseEnd));
1221 mpReadPtr = mpBasePtr + nIndexBase;
1222 const int nDataCount = (mpReadPtr[0]<<8) + mpReadPtr[1];
1223 if( nDataIndex >= nDataCount)
1225 const int nDataOfsSz = mpReadPtr[2];
1226 mpReadPtr += 3 + (nDataOfsSz * nDataIndex);
1228 switch( nDataOfsSz) {
1229 default:
SAL_WARN(
"vcl.fonts",
"\tINVALID nDataOfsSz=" << nDataOfsSz);
return -1;
1230 case 1: nOfs1 = mpReadPtr[0];
break;
1231 case 2: nOfs1 = (mpReadPtr[0]<<8) + mpReadPtr[1];
break;
1232 case 3: nOfs1 = (mpReadPtr[0]<<16) + (mpReadPtr[1]<<8) + mpReadPtr[2];
break;
1233 case 4: nOfs1 = (mpReadPtr[0]<<24) + (mpReadPtr[1]<<16) + (mpReadPtr[2]<<8) + mpReadPtr[3];
break;
1235 mpReadPtr += nDataOfsSz;
1238 switch( nDataOfsSz) {
1239 case 1: nOfs2 = mpReadPtr[0];
break;
1240 case 2: nOfs2 = (mpReadPtr[0]<<8) + mpReadPtr[1];
break;
1241 case 3: nOfs2 = (mpReadPtr[0]<<16) + (mpReadPtr[1]<<8) + mpReadPtr[2];
break;
1242 case 4: nOfs2 = (mpReadPtr[0]<<24) + (mpReadPtr[1]<<16) + (mpReadPtr[2]<<8) + mpReadPtr[3];
break;
1245 mpReadPtr = mpBasePtr + (nIndexBase + 2) + nDataOfsSz * (nDataCount + 1) + nOfs1;
1246 mpReadEnd = mpReadPtr + (nOfs2 - nOfs1);
1247 assert( nOfs1 >= 0);
1248 assert( nOfs2 >= nOfs1);
1249 assert( mpReadPtr <= mpBaseEnd);
1250 assert( mpReadEnd <= mpBaseEnd);
1251 return (nOfs2 - nOfs1);
1255void CffSubsetterContext::seekIndexEnd(
int nIndexBase)
1257 assert( (nIndexBase > 0) && (mpBasePtr + nIndexBase + 3 <= mpBaseEnd));
1258 mpReadPtr = mpBasePtr + nIndexBase;
1259 const int nDataCount = (mpReadPtr[0]<<8) + mpReadPtr[1];
1260 const int nDataOfsSz = mpReadPtr[2];
1261 mpReadPtr += 3 + nDataOfsSz * nDataCount;
1262 assert( mpReadPtr <= mpBaseEnd);
1264 switch( nDataOfsSz) {
1265 default:
SAL_WARN(
"vcl.fonts",
"\tINVALID nDataOfsSz=" << nDataOfsSz);
return;
1266 case 1: nEndOfs = mpReadPtr[0];
break;
1267 case 2: nEndOfs = (mpReadPtr[0]<<8) + mpReadPtr[1];
break;
1268 case 3: nEndOfs = (mpReadPtr[0]<<16) + (mpReadPtr[1]<<8) + mpReadPtr[2];
break;
1269 case 4: nEndOfs = (mpReadPtr[0]<<24) + (mpReadPtr[1]<<16) + (mpReadPtr[2]<<8) + mpReadPtr[3];
break;
1271 mpReadPtr += nDataOfsSz;
1272 mpReadPtr += nEndOfs - 1;
1273 mpReadEnd = mpBaseEnd;
1274 assert( nEndOfs >= 0);
1275 assert( mpReadEnd <= mpBaseEnd);
1282, mnLocalSubrOffs( 0)
1283, mnLocalSubrBase( 0)
1284, mnLocalSubrBias( 0)
1294, mbForceBold( false)
1298CffGlobal::CffGlobal()
1300, mnStringIdxBase( 0)
1305, mnGlobalSubrBase( 0)
1306, mnGlobalSubrCount( 0)
1307, mnGlobalSubrBias( 0)
1316bool CffSubsetterContext::initialCffRead()
1319 mpReadPtr = mpBasePtr;
1320 const U8 nVerMajor = *(mpReadPtr++);
1321 const U8 nVerMinor = *(mpReadPtr++);
1322 const U8 nHeaderSize = *(mpReadPtr++);
1323 const U8 nOffsetSize = *(mpReadPtr++);
1325 assert( (nVerMajor == 1) && (nVerMinor == 0));
1326 (void)(nVerMajor + nVerMinor + nOffsetSize);
1329 mnNameIdxBase = nHeaderSize;
1330 mpReadPtr = mpBasePtr + nHeaderSize;
1331 seekIndexEnd( mnNameIdxBase);
1334 const sal_Int32 nTopDictBase = getReadOfs();
1335 const int nTopDictCount = (mpReadPtr[0]<<8) + mpReadPtr[1];
1336 if( nTopDictCount) {
1337 for(
int i = 0;
i < nTopDictCount; ++
i) {
1338 seekIndexData( nTopDictBase, i);
1339 while( mpReadPtr < mpReadEnd)
1341 assert( mpReadPtr == mpReadEnd);
1346 mnStringIdxBase = getReadOfs();
1347 seekIndexEnd( mnStringIdxBase);
1350 mnGlobalSubrBase = getReadOfs();
1351 mnGlobalSubrCount = (mpReadPtr[0]<<8) + mpReadPtr[1];
1352 mnGlobalSubrBias = (mnGlobalSubrCount<1240)?107:(mnGlobalSubrCount<33900)?1131:32768;
1363 mpReadPtr = mpBasePtr + mnCharStrBase;
1364 mnCharStrCount = (mpReadPtr[0]<<8) + mpReadPtr[1];
1370 mpReadPtr = mpBasePtr + mnFontDictBase;
1371 mnFDAryCount = (mpReadPtr[0]<<8) + mpReadPtr[1];
1374 SAL_INFO(
"vcl.fonts",
"CffSubsetterContext: too many CFF in font");
1379 for(
int i = 0;
i < mnFDAryCount; ++
i) {
1380 mpCffLocal = &maCffLocal[
i];
1381 seekIndexData( mnFontDictBase, i);
1382 while( mpReadPtr < mpReadEnd)
1384 assert( mpReadPtr == mpReadEnd);
1388 for(
int i = 0;
i < mnFDAryCount; ++
i) {
1389 mpCffLocal = &maCffLocal[
i];
1393 if( mpCffLocal->mnPrivDictSize != 0) {
1394 assert( mpCffLocal->mnPrivDictSize > 0);
1396 mpReadPtr = mpBasePtr + mpCffLocal->mnPrivDictBase;
1397 mpReadEnd = mpReadPtr + mpCffLocal->mnPrivDictSize;
1398 assert( mpReadEnd <= mpBaseEnd);
1400 while( mpReadPtr < mpReadEnd)
1405 if( mpCffLocal->mnLocalSubrOffs) {
1407 mpCffLocal->mnLocalSubrBase = mpCffLocal->mnPrivDictBase + mpCffLocal->mnLocalSubrOffs;
1408 mpReadPtr = mpBasePtr + mpCffLocal->mnLocalSubrBase;
1409 const int nSubrCount = (mpReadPtr[0] << 8) + mpReadPtr[1];
1410 mpCffLocal->mnLocalSubrBias = (nSubrCount<1240)?107:(nSubrCount<33900)?1131:32768;
1421const char* CffSubsetterContext::getString(
int nStringID)
1425 if( (nStringID >= 0) && (nStringID < nStdStrings))
1429 const U8* pReadPtr = mpReadPtr;
1430 const U8* pReadEnd = mpReadEnd;
1431 nStringID -= nStdStrings;
1432 int nLen = seekIndexData( mnStringIdxBase, nStringID);
1436 static char aNameBuf[ 2560];
1438 sprintf( aNameBuf,
"name[%d].notfound!", nStringID);
1440 const int nMaxLen =
sizeof(aNameBuf) - 1;
1441 if( nLen >= nMaxLen)
1443 for(
int i = 0;
i < nLen; ++
i)
1444 aNameBuf[i] = *(mpReadPtr++);
1445 aNameBuf[ nLen] =
'\0';
1447 mpReadPtr = pReadPtr;
1448 mpReadEnd = pReadEnd;
1453int CffSubsetterContext::getFDSelect(
int nGlyphIndex)
const
1455 assert( nGlyphIndex >= 0);
1456 assert( nGlyphIndex < mnCharStrCount);
1460 const U8* pReadPtr = mpBasePtr + mnFDSelectBase;
1461 const U8 nFDSelFormat = *(pReadPtr++);
1462 switch( nFDSelFormat) {
1464 pReadPtr += nGlyphIndex;
1465 const U8 nFDIdx = *(pReadPtr++);
1469 const U16 nRangeCount = (pReadPtr[0]<<8) + pReadPtr[1];
1470 assert( nRangeCount > 0);
1471 assert( nRangeCount <= mnCharStrCount);
1472 U16 nPrev = (pReadPtr[2]<<8) + pReadPtr[3];
1473 assert( nPrev == 0);
1477 for(
int i = 0;
i < nRangeCount; ++
i) {
1478 const U8 nFDIdx = pReadPtr[0];
1479 const U16 nNext = (pReadPtr[1]<<8) + pReadPtr[2];
1480 assert( nPrev < nNext);
1481 if( nGlyphIndex < nNext)
1488 SAL_WARN(
"vcl.fonts",
"invalid CFF.FdselType=" << nFDSelFormat);
1496int CffSubsetterContext::getGlyphSID(
int nGlyphIndex)
const
1498 if( nGlyphIndex == 0)
1500 assert( nGlyphIndex >= 0);
1501 assert( nGlyphIndex < mnCharStrCount);
1502 if( (nGlyphIndex < 0) || (nGlyphIndex >= mnCharStrCount))
1506 const U8* pReadPtr = mpBasePtr + mnCharsetBase;
1507 const U8 nCSetFormat = *(pReadPtr++);
1508 int nGlyphsToSkip = nGlyphIndex - 1;
1509 switch( nCSetFormat) {
1511 pReadPtr += 2 * nGlyphsToSkip;
1515 while( nGlyphsToSkip >= 0) {
1516 const int nLeft = pReadPtr[2];
1517 if( nGlyphsToSkip <= nLeft)
1519 nGlyphsToSkip -= nLeft + 1;
1524 while( nGlyphsToSkip >= 0) {
1525 const int nLeft = (pReadPtr[2]<<8) + pReadPtr[3];
1526 if( nGlyphsToSkip <= nLeft)
1528 nGlyphsToSkip -= nLeft + 1;
1533 SAL_WARN(
"vcl.fonts",
"ILLEGAL CFF-Charset format " << nCSetFormat);
1537 int nSID = (pReadPtr[0]<<8) + pReadPtr[1];
1538 nSID += nGlyphsToSkip;
1544const char* CffSubsetterContext::getGlyphName(
int nGlyphIndex)
1547 const char* pGlyphName =
".notdef";
1548 if( nGlyphIndex == 0)
1553 static char aDefaultGlyphName[64];
1554 pGlyphName = aDefaultGlyphName;
1557 const int nSID = getGlyphSID( nGlyphIndex);
1559 sprintf( aDefaultGlyphName,
"gly%03d", nGlyphIndex);
1561 sprintf( aDefaultGlyphName,
"cid%03d", nSID);
1563 const char* pSidName =
getString( nSID);
1566 const char*
p = pSidName;
1567 while( (*p >=
'0') && (*p <=
'z')) ++
p;
1568 if( (p >= pSidName+1) && (*p ==
'\0'))
1569 pGlyphName = pSidName;
1572 if( pGlyphName != pSidName)
1573 sprintf( aDefaultGlyphName,
"bad%03d", nSID);
1584 explicit Type1Emitter( FILE* pOutFile,
bool bPfbSubset);
1586 void setSubsetName(
const char* );
1588 size_t emitRawData(
const char* pData,
size_t nLength)
const;
1591 void emitAllCrypted();
1592 int tellPos()
const;
1593 void updateLen(
int nTellPos,
size_t nLength);
1594 void emitValVector(
const char* pLineHead,
const char* pLineTail,
const std::vector<ValType>&);
1598 unsigned mnEECryptR;
1602 char maSubsetName[256];
1609Type1Emitter::Type1Emitter( FILE* pOutFile,
bool bPfbSubset)
1610: mpFileOut( pOutFile)
1614, mbPfbSubset( bPfbSubset)
1617 maSubsetName[0] =
'\0';
1620Type1Emitter::~Type1Emitter()
1624 mpFileOut =
nullptr;
1627void Type1Emitter::setSubsetName(
const char* pSubsetName)
1629 maSubsetName[0] =
'\0';
1631 strncpy( maSubsetName, pSubsetName,
sizeof(maSubsetName) - 1);
1632 maSubsetName[
sizeof(maSubsetName)-1] =
'\0';
1635int Type1Emitter::tellPos()
const
1637 int nTellPos = ftell( mpFileOut);
1641void Type1Emitter::updateLen(
int nTellPos,
size_t nLength)
1645 cData[0] =
static_cast<U8>(
nLength >> 0);
1646 cData[1] =
static_cast<U8>(
nLength >> 8);
1647 cData[2] =
static_cast<U8>(
nLength >> 16);
1648 cData[3] =
static_cast<U8>(
nLength >> 24);
1652 if (fseek( mpFileOut, nTellPos, SEEK_SET) != 0)
1654 fwrite(cData, 1,
sizeof(cData), mpFileOut);
1655 (void)fseek(mpFileOut, nCurrPos, SEEK_SET);
1658inline size_t Type1Emitter::emitRawData(
const char* pData,
size_t nLength)
const
1660 return fwrite( pData, 1, nLength, mpFileOut);
1663inline void Type1Emitter::emitAllRaw()
1666 assert( (mpPtr - maBuffer) <
int(
sizeof(maBuffer)));
1667 emitRawData( maBuffer, mpPtr - maBuffer);
1672inline void Type1Emitter::emitAllHex()
1674 assert( (mpPtr - maBuffer) <
int(
sizeof(maBuffer)));
1675 for(
const char* p = maBuffer;
p < mpPtr;) {
1677 char aHexBuf[0x4000];
1678 char*
pOut = aHexBuf;
1679 while( (p < mpPtr) && (pOut < aHexBuf+
sizeof(aHexBuf)-4)) {
1681 char cNibble = (
static_cast<unsigned char>(*p) >> 4) & 0x0F;
1682 cNibble += (cNibble < 10) ?
'0' :
'A'-10;
1683 *(
pOut++) = cNibble;
1684 cNibble = *(
p++) & 0x0F;
1685 cNibble += (cNibble < 10) ?
'0' :
'A'-10;
1686 *(
pOut++) = cNibble;
1688 if( (++mnHexLineCol & 0x3F) == 0)
1692 emitRawData( aHexBuf, pOut-aHexBuf);
1698void Type1Emitter::emitAllCrypted()
1701 for(
char* p = maBuffer;
p < mpPtr; ++
p) {
1702 *
p ^= (mnEECryptR >> 8);
1703 mnEECryptR = (*
reinterpret_cast<U8*
>(
p) + mnEECryptR) * 52845 + 22719;
1722void Type1Emitter::emitValVector(
const char* pLineHead,
const char* pLineTail,
1723 const std::vector<ValType>& rVector)
1726 if( rVector.empty())
1730 mpPtr += sprintf( mpPtr,
"%s", pLineHead);
1732 std::vector<ValType>::value_type aVal = 0;
1733 for( std::vector<ValType>::const_iterator it = rVector.begin();;) {
1735 if( ++it == rVector.end() )
1737 mpPtr +=
dbl2str( mpPtr, aVal);
1741 mpPtr +=
dbl2str( mpPtr, aVal);
1743 mpPtr += sprintf( mpPtr,
"%s", pLineTail);
1746void CffSubsetterContext::emitAsType1( Type1Emitter& rEmitter,
1748 sal_Int32* pGlyphWidths,
int nGlyphCount,
FontSubsetInfo& rFSInfo)
1751 static const int nUniqueIdBase = 4100000;
1752 static int nUniqueId = nUniqueIdBase;
1755 char* pFontName = rEmitter.maSubsetName;
1757 if( mnFontNameSID) {
1759 strncpy( pFontName,
getString( mnFontNameSID),
sizeof(rEmitter.maSubsetName) - 1);
1760 pFontName[
sizeof(rEmitter.maSubsetName) - 1] = 0;
1761 }
else if( mnFullNameSID) {
1763 const char* pI =
getString( mnFullNameSID);
1764 char* pO = pFontName;
1765 const char* pLimit = pFontName +
sizeof(rEmitter.maSubsetName) - 1;
1766 while( pO < pLimit) {
1767 const char c = *(pI++);
1776 strncpy( pFontName,
"DummyName",
sizeof(rEmitter.maSubsetName));
1779 const char* pFullName = pFontName;
1780 const char* pFamilyName = pFontName;
1782 char*&
pOut = rEmitter.mpPtr;
1785 if( rEmitter.mbPfbSubset ) {
1786 static const char aPfbHeader[] =
"\x80\x01\x00\x00\x00\x00";
1787 rEmitter.emitRawData( aPfbHeader,
sizeof(aPfbHeader)-1);
1790 pOut += sprintf( pOut,
"%%!FontType1-1.0: %s 001.003\n", rEmitter.maSubsetName);
1792 pOut += sprintf( pOut,
1795 "/PaintType 0 def\n");
1796 pOut += sprintf( pOut,
"/FontName /%s def\n", rEmitter.maSubsetName);
1797 pOut += sprintf( pOut,
"/UniqueID %d def\n", nUniqueId);
1799 if( maFontMatrix.size() == 6)
1800 rEmitter.emitValVector(
"/FontMatrix [",
"]readonly def\n", maFontMatrix);
1802 pOut += sprintf( pOut,
"/FontMatrix [0.001 0 0 0.001 0 0]readonly def\n");
1804 if( maFontBBox.size() == 4)
1805 rEmitter.emitValVector(
"/FontBBox {",
"}readonly def\n", maFontBBox);
1807 pOut += sprintf( pOut,
"/FontBBox {0 0 999 999}readonly def\n");
1809 pOut += sprintf( pOut,
1810 "/FontInfo 2 dict dup begin\n"
1811 " /FullName (%s) readonly def\n"
1812 " /FamilyName (%s) readonly def\n"
1813 "end readonly def\n",
1814 pFullName, pFamilyName);
1816 pOut += sprintf( pOut,
1817 "/Encoding 256 array\n"
1818 "0 1 255 {1 index exch /.notdef put} for\n");
1819 for(
int i = 1; (
i < nGlyphCount) && (i < 256); ++
i) {
1820 const char* pGlyphName = getGlyphName( pReqGlyphIds[i]);
1821 pOut += sprintf( pOut,
"dup %d /%s put\n", pReqEncoding[i], pGlyphName);
1823 pOut += sprintf( pOut,
"readonly def\n");
1824 pOut += sprintf( pOut,
1827 "currentfile eexec\n");
1830 rEmitter.emitAllRaw();
1831 if( rEmitter.mbPfbSubset) {
1833 const int nPfbHeaderLen = rEmitter.tellPos() - 6;
1834 rEmitter.updateLen( 2, nPfbHeaderLen);
1837 rEmitter.emitRawData(
"\x80\x02\x00\x00\x00\x00", 6);
1839 const int nEExecSegTell = rEmitter.tellPos();
1843 int nPrivEntryCount = 9;
1845 nPrivEntryCount +=
int(!mpCffLocal->maOtherBlues.empty());
1846 nPrivEntryCount +=
int(!mpCffLocal->maFamilyBlues.empty());
1847 nPrivEntryCount +=
int(!mpCffLocal->maFamilyOtherBlues.empty());
1848 nPrivEntryCount +=
int(mpCffLocal->mfBlueScale != 0.0);
1849 nPrivEntryCount +=
int(mpCffLocal->mfBlueShift != 0.0);
1850 nPrivEntryCount +=
int(mpCffLocal->mfBlueFuzz != 0.0);
1852 nPrivEntryCount +=
int(mpCffLocal->maStemStdHW != 0);
1853 nPrivEntryCount +=
int(mpCffLocal->maStemStdVW != 0);
1854 nPrivEntryCount +=
int(!mpCffLocal->maStemSnapH.empty());
1855 nPrivEntryCount +=
int(!mpCffLocal->maStemSnapV.empty());
1857 nPrivEntryCount +=
int(mpCffLocal->mfExpFactor != 0.0);
1858 nPrivEntryCount +=
int(mpCffLocal->mnLangGroup != 0);
1859 nPrivEntryCount +=
int(mpCffLocal->mnLangGroup == 1);
1860 nPrivEntryCount +=
int(mpCffLocal->mbForceBold);
1862 pOut += sprintf( pOut,
1864 "dup\n/Private %d dict dup begin\n"
1865 "/RD{string currentfile exch readstring pop}executeonly def\n"
1866 "/ND{noaccess def}executeonly def\n"
1867 "/NP{noaccess put}executeonly def\n"
1868 "/MinFeature{16 16}ND\n"
1869 "/password 5839 def\n",
1873 if( !mpCffLocal->maBlueValues.empty())
1874 rEmitter.emitValVector(
"/BlueValues [",
"]ND\n", mpCffLocal->maBlueValues);
1876 pOut += sprintf( pOut,
"/BlueValues []ND\n");
1877 rEmitter.emitValVector(
"/OtherBlues [",
"]ND\n", mpCffLocal->maOtherBlues);
1878 rEmitter.emitValVector(
"/FamilyBlues [",
"]ND\n", mpCffLocal->maFamilyBlues);
1879 rEmitter.emitValVector(
"/FamilyOtherBlues [",
"]ND\n", mpCffLocal->maFamilyOtherBlues);
1881 if( mpCffLocal->mfBlueScale) {
1882 pOut += sprintf( pOut,
"/BlueScale ");
1884 pOut += sprintf( pOut,
" def\n");
1886 if( mpCffLocal->mfBlueShift) {
1887 pOut += sprintf( pOut,
"/BlueShift ");
1889 pOut += sprintf( pOut,
" def\n");
1891 if( mpCffLocal->mfBlueFuzz) {
1892 pOut += sprintf( pOut,
"/BlueFuzz ");
1894 pOut += sprintf( pOut,
" def\n");
1898 if( mpCffLocal->maStemStdHW) {
1899 pOut += sprintf( pOut,
"/StdHW [");
1901 pOut += sprintf( pOut,
"] def\n");
1903 if( mpCffLocal->maStemStdVW) {
1904 pOut += sprintf( pOut,
"/StdVW [");
1906 pOut += sprintf( pOut,
"] def\n");
1908 rEmitter.emitValVector(
"/StemSnapH [",
"]ND\n", mpCffLocal->maStemSnapH);
1909 rEmitter.emitValVector(
"/StemSnapV [",
"]ND\n", mpCffLocal->maStemSnapV);
1912 if( mpCffLocal->mbForceBold)
1913 pOut += sprintf( pOut,
"/ForceBold true def\n");
1914 if( mpCffLocal->mnLangGroup != 0)
1915 pOut += sprintf( pOut,
"/LanguageGroup %d def\n", mpCffLocal->mnLangGroup);
1916 if( mpCffLocal->mnLangGroup == 1)
1917 pOut += sprintf( pOut,
"/RndStemUp false def\n");
1918 if( mpCffLocal->mfExpFactor) {
1919 pOut += sprintf( pOut,
"/ExpansionFactor ");
1921 pOut += sprintf( pOut,
" def\n");
1925 pOut += sprintf( pOut,
"/UniqueID %d def\n", nUniqueId);
1928 static const char aOtherSubrs[] =
1930 "% Dummy code for faking flex hints\n"
1931 "[ {} {} {} {systemdict /internaldict known not {pop 3}\n"
1932 "{1183615869 systemdict /internaldict get exec\n"
1933 "dup /startlock known\n"
1934 "{/startlock get exec}\n"
1935 "{dup /strtlck known\n"
1936 "{/strtlck get exec}\n"
1937 "{pop 3}\nifelse}\nifelse}\nifelse\n} executeonly\n"
1939 memcpy( pOut, aOtherSubrs,
sizeof(aOtherSubrs)-1);
1940 pOut +=
sizeof(aOtherSubrs)-1;
1945 static const char aSubrs[] =
1947 "dup 0 15 RD \x5F\x3D\x6B\xAC\x3C\xBD\x74\x3D\x3E\x17\xA0\x86\x58\x08\x85 NP\n"
1948 "dup 1 9 RD \x5F\x3D\x6B\xD8\xA6\xB5\x68\xB6\xA2 NP\n"
1949 "dup 2 9 RD \x5F\x3D\x6B\xAC\x39\x46\xB9\x43\xF9 NP\n"
1950 "dup 3 5 RD \x5F\x3D\x6B\xAC\xB9 NP\n"
1951 "dup 4 12 RD \x5F\x3D\x6B\xAC\x3E\x5D\x48\x54\x62\x76\x39\x03 NP\n"
1953 memcpy( pOut, aSubrs,
sizeof(aSubrs)-1);
1954 pOut +=
sizeof(aSubrs)-1;
1960 pOut += sprintf( pOut,
1961 "2 index /CharStrings %d dict dup begin\n", nGlyphCount);
1962 rEmitter.emitAllCrypted();
1963 for(
int i = 0;
i < nGlyphCount; ++
i) {
1964 const int nCffGlyphId = pReqGlyphIds[
i];
1965 assert( (nCffGlyphId >= 0) && (nCffGlyphId < mnCharStrCount));
1967 const int nFDSelect = getFDSelect( nCffGlyphId);
1970 mpCffLocal = &maCffLocal[ nFDSelect];
1972 const int nT2Len = seekIndexData( mnCharStrBase, nCffGlyphId);
1973 assert( nT2Len > 0);
1975 const int nT1Len = convert2Type1Ops( mpCffLocal, mpReadPtr, nT2Len, aType1Ops);
1977 const char* pGlyphName = getGlyphName( nCffGlyphId);
1979 pOut += sprintf( pOut,
"/%s %d RD ", pGlyphName, nT1Len);
1980 memcpy( pOut, aType1Ops, nT1Len);
1982 pOut += sprintf( pOut,
" ND\n");
1983 rEmitter.emitAllCrypted();
1985 if( pGlyphWidths ) {
1986 ValType aCharWidth = maCharWidth;
1987 if( maFontMatrix.size() >= 4)
1988 aCharWidth *= 1000.0F * maFontMatrix[0];
1989 pGlyphWidths[
i] =
static_cast<sal_Int32
>(aCharWidth);
1992 pOut += sprintf( pOut,
"end end\nreadonly put\nput\n");
1993 pOut += sprintf( pOut,
"dup/FontName get exch definefont pop\n");
1994 pOut += sprintf( pOut,
"mark currentfile closefile\n");
1995 rEmitter.emitAllCrypted();
1998 if( rEmitter.mbPfbSubset) {
1999 const int nEExecLen = rEmitter.tellPos() - nEExecSegTell;
2000 rEmitter.updateLen( nEExecSegTell-4, nEExecLen);
2004 static const char aPfxFooter[] =
"\x80\x01\x14\x02\x00\x00\n"
2005 "0000000000000000000000000000000000000000000000000000000000000000\n"
2006 "0000000000000000000000000000000000000000000000000000000000000000\n"
2007 "0000000000000000000000000000000000000000000000000000000000000000\n"
2008 "0000000000000000000000000000000000000000000000000000000000000000\n"
2009 "0000000000000000000000000000000000000000000000000000000000000000\n"
2010 "0000000000000000000000000000000000000000000000000000000000000000\n"
2011 "0000000000000000000000000000000000000000000000000000000000000000\n"
2012 "0000000000000000000000000000000000000000000000000000000000000000\n"
2015 if( rEmitter.mbPfbSubset)
2016 rEmitter.emitRawData( aPfxFooter,
sizeof(aPfxFooter)-1);
2018 rEmitter.emitRawData( aPfxFooter+6,
sizeof(aPfxFooter)-9);
2025 if( maFontMatrix.size() >= 4) {
2026 fXFactor = 1000.0F * maFontMatrix[0];
2027 fYFactor = 1000.0F * maFontMatrix[3];
2030 static_cast<sal_Int32
>(maFontBBox[1] * fYFactor) ),
2031 Point(
static_cast<sal_Int32
>(maFontBBox[2] * fXFactor),
2032 static_cast<sal_Int32
>(maFontBBox[3] * fYFactor) ) );
2040 rFSInfo.
m_aPSName = OUString( rEmitter.maSubsetName, strlen(rEmitter.maSubsetName), RTL_TEXTENCODING_UTF8 );
2046 bool bRC = aCff.initialCffRead();
2053 Type1Emitter aType1Emitter(
mpOutFile, bPfbSubset);
2055 aCff.emitAsType1( aType1Emitter,
static const char * pDictOps[]
static const char * pStringIds[]
static int dbl2str(char *pOut, double fVal)
static const char * pDictEscs[]
tools::Rectangle m_aFontBBox
const char * mpReqFontName
FontType m_nFontType
font-type of subset result
unsigned const char * mpInFontBytes
const sal_GlyphId * mpReqGlyphIds
const sal_uInt8 * mpReqEncodedIds
FontType mnReqFontTypeMask
allowed subset-target font types
bool CreateFontSubsetFromCff(sal_Int32 *pOutGlyphWidths)
int m_nAscent
all metrics in PS font units
@ TYPE1_PFB
PSType1 Postscript Font Binary.
@ TYPE1_PFA
PSType1 Postscript Font Ascii.
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
#define SAL_N_ELEMENTS(arr)
OUString getString(const Any &_rAny)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
int getValueOfDouble(char *pBuffer, double f, int nPrecision=0)
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int