1 //========================================================================
5 // Copyright 1999-2003 Glyph & Cog, LLC
7 //========================================================================
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
20 #include "FoFiEncodings.h"
21 #include "FoFiType1C.h"
23 //------------------------------------------------------------------------
25 static char hexChars
[17] = "0123456789ABCDEF";
27 //------------------------------------------------------------------------
29 //------------------------------------------------------------------------
31 FoFiType1C
*FoFiType1C::make(char *fileA
, int lenA
) {
34 ff
= new FoFiType1C(fileA
, lenA
, gFalse
);
42 FoFiType1C
*FoFiType1C::load(char *fileName
) {
47 if (!(fileA
= FoFiBase::readFile(fileName
, &lenA
))) {
50 ff
= new FoFiType1C(fileA
, lenA
, gTrue
);
58 FoFiType1C::FoFiType1C(char *fileA
, int lenA
, GBool freeFileDataA
):
59 FoFiBase(fileA
, lenA
, freeFileDataA
)
68 FoFiType1C::~FoFiType1C() {
75 encoding
!= fofiType1StandardEncoding
&&
76 encoding
!= fofiType1ExpertEncoding
) {
77 for (i
= 0; i
< 256; ++i
) {
89 charset
!= fofiType1CISOAdobeCharset
&&
90 charset
!= fofiType1CExpertCharset
&&
91 charset
!= fofiType1CExpertSubsetCharset
) {
96 char *FoFiType1C::getName() {
97 return name
? name
->getCString() : (char *)NULL
;
100 char **FoFiType1C::getEncoding() {
104 Gushort
*FoFiType1C::getCIDToGIDMap(int *nCIDs
) {
108 // a CID font's top dict has ROS as the first operator
109 if (topDict
.firstOp
!= 0x0c1e) {
114 // in a CID font, the charset data is the GID-to-CID mapping, so all
115 // we have to do is reverse it
117 for (i
= 0; i
< nGlyphs
; ++i
) {
118 if (charset
[i
] > n
) {
123 map
= (Gushort
*)gmalloc(n
* sizeof(Gushort
));
124 memset(map
, 0, n
* sizeof(Gushort
));
125 for (i
= 0; i
< nGlyphs
; ++i
) {
132 void FoFiType1C::convertToType1(char **newEncoding
, GBool ascii
,
133 FoFiOutputFunc outputFunc
,
134 void *outputStream
) {
143 // write header and font dictionary, up to encoding
145 (*outputFunc
)(outputStream
, "%!FontType1-1.0: ", 17);
146 (*outputFunc
)(outputStream
, name
->getCString(), name
->getLength());
147 if (topDict
.versionSID
!= 0) {
148 getString(topDict
.versionSID
, buf
, &ok
);
149 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
151 (*outputFunc
)(outputStream
, "\n", 1);
152 // the dictionary needs room for 12 entries: the following 9, plus
153 // Private and CharStrings (in the eexec section) and FID (which is
154 // added by definefont)
155 (*outputFunc
)(outputStream
, "12 dict begin\n", 14);
156 (*outputFunc
)(outputStream
, "/FontInfo 10 dict dup begin\n", 28);
157 if (topDict
.versionSID
!= 0) {
158 (*outputFunc
)(outputStream
, "/version (", 10);
159 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
160 (*outputFunc
)(outputStream
, ") readonly def\n", 15);
162 if (topDict
.noticeSID
!= 0) {
163 getString(topDict
.noticeSID
, buf
, &ok
);
164 (*outputFunc
)(outputStream
, "/Notice (", 9);
165 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
166 (*outputFunc
)(outputStream
, ") readonly def\n", 15);
168 if (topDict
.copyrightSID
!= 0) {
169 getString(topDict
.copyrightSID
, buf
, &ok
);
170 (*outputFunc
)(outputStream
, "/Copyright (", 12);
171 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
172 (*outputFunc
)(outputStream
, ") readonly def\n", 15);
174 if (topDict
.fullNameSID
!= 0) {
175 getString(topDict
.fullNameSID
, buf
, &ok
);
176 (*outputFunc
)(outputStream
, "/FullName (", 11);
177 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
178 (*outputFunc
)(outputStream
, ") readonly def\n", 15);
180 if (topDict
.familyNameSID
!= 0) {
181 getString(topDict
.familyNameSID
, buf
, &ok
);
182 (*outputFunc
)(outputStream
, "/FamilyName (", 13);
183 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
184 (*outputFunc
)(outputStream
, ") readonly def\n", 15);
186 if (topDict
.weightSID
!= 0) {
187 getString(topDict
.weightSID
, buf
, &ok
);
188 (*outputFunc
)(outputStream
, "/Weight (", 9);
189 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
190 (*outputFunc
)(outputStream
, ") readonly def\n", 15);
192 if (topDict
.isFixedPitch
) {
193 (*outputFunc
)(outputStream
, "/isFixedPitch true def\n", 23);
195 (*outputFunc
)(outputStream
, "/isFixedPitch false def\n", 24);
197 sprintf(buf
, "/ItalicAngle %g def\n", topDict
.italicAngle
);
198 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
199 sprintf(buf
, "/UnderlinePosition %g def\n", topDict
.underlinePosition
);
200 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
201 sprintf(buf
, "/UnderlineThickness %g def\n", topDict
.underlineThickness
);
202 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
203 (*outputFunc
)(outputStream
, "end readonly def\n", 17);
204 (*outputFunc
)(outputStream
, "/FontName /", 11);
205 (*outputFunc
)(outputStream
, name
->getCString(), name
->getLength());
206 (*outputFunc
)(outputStream
, " def\n", 5);
207 sprintf(buf
, "/PaintType %d def\n", topDict
.paintType
);
208 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
209 (*outputFunc
)(outputStream
, "/FontType 1 def\n", 16);
210 sprintf(buf
, "/FontMatrix [%g %g %g %g %g %g] readonly def\n",
211 topDict
.fontMatrix
[0], topDict
.fontMatrix
[1], topDict
.fontMatrix
[2],
212 topDict
.fontMatrix
[3], topDict
.fontMatrix
[4], topDict
.fontMatrix
[5]);
213 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
214 sprintf(buf
, "/FontBBox [%g %g %g %g] readonly def\n",
215 topDict
.fontBBox
[0], topDict
.fontBBox
[1],
216 topDict
.fontBBox
[2], topDict
.fontBBox
[3]);
217 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
218 sprintf(buf
, "/StrokeWidth %g def\n", topDict
.strokeWidth
);
219 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
220 if (topDict
.uniqueID
!= 0) {
221 sprintf(buf
, "/UniqueID %d def\n", topDict
.uniqueID
);
222 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
225 // write the encoding
226 (*outputFunc
)(outputStream
, "/Encoding ", 10);
227 if (!newEncoding
&& encoding
== fofiType1StandardEncoding
) {
228 (*outputFunc
)(outputStream
, "StandardEncoding def\n", 21);
230 (*outputFunc
)(outputStream
, "256 array\n", 10);
231 (*outputFunc
)(outputStream
,
232 "0 1 255 {1 index exch /.notdef put} for\n", 40);
233 enc
= newEncoding
? newEncoding
: encoding
;
234 for (i
= 0; i
< 256; ++i
) {
236 sprintf(buf
, "dup %d /%s put\n", i
, enc
[i
]);
237 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
240 (*outputFunc
)(outputStream
, "readonly def\n", 13);
242 (*outputFunc
)(outputStream
, "currentdict end\n", 16);
244 // start the binary section
245 (*outputFunc
)(outputStream
, "currentfile eexec\n", 18);
246 eb
.outputFunc
= outputFunc
;
247 eb
.outputStream
= outputStream
;
252 // write the private dictionary
253 eexecWrite(&eb
, "\x83\xca\x73\xd5");
254 eexecWrite(&eb
, "dup /Private 32 dict dup begin\n");
255 eexecWrite(&eb
, "/RD {string currentfile exch readstring pop}"
256 " executeonly def\n");
257 eexecWrite(&eb
, "/ND {noaccess def} executeonly def\n");
258 eexecWrite(&eb
, "/NP {noaccess put} executeonly def\n");
259 eexecWrite(&eb
, "/MinFeature {16 16} def\n");
260 eexecWrite(&eb
, "/password 5839 def\n");
261 if (privateDicts
[0].nBlueValues
) {
262 eexecWrite(&eb
, "/BlueValues [");
263 for (i
= 0; i
< privateDicts
[0].nBlueValues
; ++i
) {
264 sprintf(buf
, "%s%d", i
> 0 ? " " : "", privateDicts
[0].blueValues
[i
]);
265 eexecWrite(&eb
, buf
);
267 eexecWrite(&eb
, "] def\n");
269 if (privateDicts
[0].nOtherBlues
) {
270 eexecWrite(&eb
, "/OtherBlues [");
271 for (i
= 0; i
< privateDicts
[0].nOtherBlues
; ++i
) {
272 sprintf(buf
, "%s%d", i
> 0 ? " " : "", privateDicts
[0].otherBlues
[i
]);
273 eexecWrite(&eb
, buf
);
275 eexecWrite(&eb
, "] def\n");
277 if (privateDicts
[0].nFamilyBlues
) {
278 eexecWrite(&eb
, "/FamilyBlues [");
279 for (i
= 0; i
< privateDicts
[0].nFamilyBlues
; ++i
) {
280 sprintf(buf
, "%s%d", i
> 0 ? " " : "", privateDicts
[0].familyBlues
[i
]);
281 eexecWrite(&eb
, buf
);
283 eexecWrite(&eb
, "] def\n");
285 if (privateDicts
[0].nFamilyOtherBlues
) {
286 eexecWrite(&eb
, "/FamilyOtherBlues [");
287 for (i
= 0; i
< privateDicts
[0].nFamilyOtherBlues
; ++i
) {
288 sprintf(buf
, "%s%d", i
> 0 ? " " : "",
289 privateDicts
[0].familyOtherBlues
[i
]);
290 eexecWrite(&eb
, buf
);
292 eexecWrite(&eb
, "] def\n");
294 if (privateDicts
[0].blueScale
!= 0.039625) {
295 sprintf(buf
, "/BlueScale %g def\n", privateDicts
[0].blueScale
);
296 eexecWrite(&eb
, buf
);
298 if (privateDicts
[0].blueShift
!= 7) {
299 sprintf(buf
, "/BlueShift %d def\n", privateDicts
[0].blueShift
);
300 eexecWrite(&eb
, buf
);
302 if (privateDicts
[0].blueFuzz
!= 1) {
303 sprintf(buf
, "/BlueFuzz %d def\n", privateDicts
[0].blueFuzz
);
304 eexecWrite(&eb
, buf
);
306 if (privateDicts
[0].hasStdHW
) {
307 sprintf(buf
, "/StdHW [%g] def\n", privateDicts
[0].stdHW
);
308 eexecWrite(&eb
, buf
);
310 if (privateDicts
[0].hasStdVW
) {
311 sprintf(buf
, "/StdVW [%g] def\n", privateDicts
[0].stdVW
);
312 eexecWrite(&eb
, buf
);
314 if (privateDicts
[0].nStemSnapH
) {
315 eexecWrite(&eb
, "/StemSnapH [");
316 for (i
= 0; i
< privateDicts
[0].nStemSnapH
; ++i
) {
317 sprintf(buf
, "%s%g", i
> 0 ? " " : "", privateDicts
[0].stemSnapH
[i
]);
318 eexecWrite(&eb
, buf
);
320 eexecWrite(&eb
, "] def\n");
322 if (privateDicts
[0].nStemSnapV
) {
323 eexecWrite(&eb
, "/StemSnapV [");
324 for (i
= 0; i
< privateDicts
[0].nStemSnapV
; ++i
) {
325 sprintf(buf
, "%s%g", i
> 0 ? " " : "", privateDicts
[0].stemSnapV
[i
]);
326 eexecWrite(&eb
, buf
);
328 eexecWrite(&eb
, "] def\n");
330 if (privateDicts
[0].hasForceBold
) {
331 sprintf(buf
, "/ForceBold %s def\n",
332 privateDicts
[0].forceBold
? "true" : "false");
333 eexecWrite(&eb
, buf
);
335 if (privateDicts
[0].forceBoldThreshold
!= 0) {
336 sprintf(buf
, "/ForceBoldThreshold %g def\n",
337 privateDicts
[0].forceBoldThreshold
);
338 eexecWrite(&eb
, buf
);
340 if (privateDicts
[0].languageGroup
!= 0) {
341 sprintf(buf
, "/LanguageGroup %d def\n", privateDicts
[0].languageGroup
);
342 eexecWrite(&eb
, buf
);
344 if (privateDicts
[0].expansionFactor
!= 0.06) {
345 sprintf(buf
, "/ExpansionFactor %g def\n", privateDicts
[0].expansionFactor
);
346 eexecWrite(&eb
, buf
);
349 // set up subroutines
351 getIndex(privateDicts
[0].subrsOffset
, &subrIdx
, &ok
);
356 // write the CharStrings
357 sprintf(buf
, "2 index /CharStrings %d dict dup begin\n", nGlyphs
);
358 eexecWrite(&eb
, buf
);
359 for (i
= 0; i
< nGlyphs
; ++i
) {
361 getIndexVal(&charStringsIdx
, i
, &val
, &ok
);
363 getString(charset
[i
], buf
, &ok
);
365 eexecCvtGlyph(&eb
, buf
, val
.pos
, val
.len
, &subrIdx
, &privateDicts
[0]);
369 eexecWrite(&eb
, "end\n");
370 eexecWrite(&eb
, "end\n");
371 eexecWrite(&eb
, "readonly put\n");
372 eexecWrite(&eb
, "noaccess put\n");
373 eexecWrite(&eb
, "dup /FontName get exch definefont pop\n");
374 eexecWrite(&eb
, "mark currentfile closefile\n");
377 if (ascii
&& eb
.line
> 0) {
378 (*outputFunc
)(outputStream
, "\n", 1);
380 for (i
= 0; i
< 8; ++i
) {
381 (*outputFunc
)(outputStream
, "0000000000000000000000000000000000000000000000000000000000000000\n", 65);
383 (*outputFunc
)(outputStream
, "cleartomark\n", 12);
386 void FoFiType1C::convertToCIDType0(char *psName
,
387 FoFiOutputFunc outputFunc
,
388 void *outputStream
) {
390 GString
*charStrings
;
391 int *charStringOffsets
;
395 char buf
[512], buf2
[512];
397 int gid
, offset
, n
, i
, j
, k
;
399 // compute the CID count and build the CID-to-GID mapping
401 for (i
= 0; i
< nGlyphs
; ++i
) {
402 if (charset
[i
] >= nCIDs
) {
403 nCIDs
= charset
[i
] + 1;
406 cidMap
= (int *)gmalloc(nCIDs
* sizeof(int));
407 for (i
= 0; i
< nCIDs
; ++i
) {
410 for (i
= 0; i
< nGlyphs
; ++i
) {
411 cidMap
[charset
[i
]] = i
;
414 // build the charstrings
415 charStrings
= new GString();
416 charStringOffsets
= (int *)gmalloc((nCIDs
+ 1) * sizeof(int));
417 for (i
= 0; i
< nCIDs
; ++i
) {
418 charStringOffsets
[i
] = charStrings
->getLength();
419 if ((gid
= cidMap
[i
]) >= 0) {
421 getIndexVal(&charStringsIdx
, gid
, &val
, &ok
);
423 getIndex(privateDicts
[fdSelect
[gid
]].subrsOffset
, &subrIdx
, &ok
);
427 cvtGlyph(val
.pos
, val
.len
, charStrings
,
428 &subrIdx
, &privateDicts
[fdSelect
[gid
]], gTrue
);
432 charStringOffsets
[nCIDs
] = charStrings
->getLength();
434 // compute gdBytes = number of bytes needed for charstring offsets
435 // (offset size needs to account for the charstring offset table,
436 // with a worst case of five bytes per entry, plus the charstrings
438 i
= (nCIDs
+ 1) * 5 + charStrings
->getLength();
441 } else if (i
< 0x10000) {
443 } else if (i
< 0x1000000) {
449 // begin the font dictionary
450 (*outputFunc
)(outputStream
, "/CIDInit /ProcSet findresource begin\n", 37);
451 (*outputFunc
)(outputStream
, "20 dict begin\n", 14);
452 (*outputFunc
)(outputStream
, "/CIDFontName /", 14);
453 (*outputFunc
)(outputStream
, psName
, strlen(psName
));
454 (*outputFunc
)(outputStream
, " def\n", 5);
455 (*outputFunc
)(outputStream
, "/CIDFontType 0 def\n", 19);
456 (*outputFunc
)(outputStream
, "/CIDSystemInfo 3 dict dup begin\n", 32);
457 if (topDict
.registrySID
> 0 && topDict
.orderingSID
> 0) {
459 getString(topDict
.registrySID
, buf
, &ok
);
461 (*outputFunc
)(outputStream
, " /Registry (", 13);
462 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
463 (*outputFunc
)(outputStream
, ") def\n", 6);
466 getString(topDict
.orderingSID
, buf
, &ok
);
468 (*outputFunc
)(outputStream
, " /Ordering (", 13);
469 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
470 (*outputFunc
)(outputStream
, ") def\n", 6);
473 (*outputFunc
)(outputStream
, " /Registry (Adobe) def\n", 24);
474 (*outputFunc
)(outputStream
, " /Ordering (Identity) def\n", 27);
476 sprintf(buf
, " /Supplement %d def\n", topDict
.supplement
);
477 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
478 (*outputFunc
)(outputStream
, "end def\n", 8);
479 sprintf(buf
, "/FontMatrix [%g %g %g %g %g %g] def\n",
480 topDict
.fontMatrix
[0], topDict
.fontMatrix
[1], topDict
.fontMatrix
[2],
481 topDict
.fontMatrix
[3], topDict
.fontMatrix
[4], topDict
.fontMatrix
[5]);
482 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
483 sprintf(buf
, "/FontBBox [%g %g %g %g] def\n",
484 topDict
.fontBBox
[0], topDict
.fontBBox
[1],
485 topDict
.fontBBox
[2], topDict
.fontBBox
[3]);
486 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
487 (*outputFunc
)(outputStream
, "/FontInfo 1 dict dup begin\n", 27);
488 (*outputFunc
)(outputStream
, " /FSType 8 def\n", 16);
489 (*outputFunc
)(outputStream
, "end def\n", 8);
491 // CIDFont-specific entries
492 sprintf(buf
, "/CIDCount %d def\n", nCIDs
);
493 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
494 (*outputFunc
)(outputStream
, "/FDBytes 1 def\n", 15);
495 sprintf(buf
, "/GDBytes %d def\n", gdBytes
);
496 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
497 (*outputFunc
)(outputStream
, "/CIDMapOffset 0 def\n", 20);
498 if (topDict
.paintType
!= 0) {
499 sprintf(buf
, "/PaintType %d def\n", topDict
.paintType
);
500 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
501 sprintf(buf
, "/StrokeWidth %g def\n", topDict
.strokeWidth
);
502 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
506 sprintf(buf
, "/FDArray %d array\n", nFDs
);
507 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
508 for (i
= 0; i
< nFDs
; ++i
) {
509 sprintf(buf
, "dup %d 10 dict begin\n", i
);
510 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
511 (*outputFunc
)(outputStream
, "/FontType 1 def\n", 16);
512 (*outputFunc
)(outputStream
, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
513 sprintf(buf
, "/PaintType %d def\n", topDict
.paintType
);
514 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
515 (*outputFunc
)(outputStream
, "/Private 32 dict begin\n", 23);
516 if (privateDicts
[i
].nBlueValues
) {
517 (*outputFunc
)(outputStream
, "/BlueValues [", 13);
518 for (j
= 0; j
< privateDicts
[i
].nBlueValues
; ++j
) {
519 sprintf(buf
, "%s%d", j
> 0 ? " " : "", privateDicts
[i
].blueValues
[j
]);
520 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
522 (*outputFunc
)(outputStream
, "] def\n", 6);
524 if (privateDicts
[i
].nOtherBlues
) {
525 (*outputFunc
)(outputStream
, "/OtherBlues [", 13);
526 for (j
= 0; j
< privateDicts
[i
].nOtherBlues
; ++j
) {
527 sprintf(buf
, "%s%d", j
> 0 ? " " : "", privateDicts
[i
].otherBlues
[j
]);
528 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
530 (*outputFunc
)(outputStream
, "] def\n", 6);
532 if (privateDicts
[i
].nFamilyBlues
) {
533 (*outputFunc
)(outputStream
, "/FamilyBlues [", 14);
534 for (j
= 0; j
< privateDicts
[i
].nFamilyBlues
; ++j
) {
535 sprintf(buf
, "%s%d", j
> 0 ? " " : "", privateDicts
[i
].familyBlues
[j
]);
536 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
538 (*outputFunc
)(outputStream
, "] def\n", 6);
540 if (privateDicts
[i
].nFamilyOtherBlues
) {
541 (*outputFunc
)(outputStream
, "/FamilyOtherBlues [", 19);
542 for (j
= 0; j
< privateDicts
[i
].nFamilyOtherBlues
; ++j
) {
543 sprintf(buf
, "%s%d", j
> 0 ? " " : "",
544 privateDicts
[i
].familyOtherBlues
[j
]);
545 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
547 (*outputFunc
)(outputStream
, "] def\n", 6);
549 if (privateDicts
[i
].blueScale
!= 0.039625) {
550 sprintf(buf
, "/BlueScale %g def\n", privateDicts
[i
].blueScale
);
551 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
553 if (privateDicts
[i
].blueShift
!= 7) {
554 sprintf(buf
, "/BlueShift %d def\n", privateDicts
[i
].blueShift
);
555 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
557 if (privateDicts
[i
].blueFuzz
!= 1) {
558 sprintf(buf
, "/BlueFuzz %d def\n", privateDicts
[i
].blueFuzz
);
559 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
561 if (privateDicts
[i
].hasStdHW
) {
562 sprintf(buf
, "/StdHW [%g] def\n", privateDicts
[i
].stdHW
);
563 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
565 if (privateDicts
[i
].hasStdVW
) {
566 sprintf(buf
, "/StdVW [%g] def\n", privateDicts
[i
].stdVW
);
567 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
569 if (privateDicts
[i
].nStemSnapH
) {
570 (*outputFunc
)(outputStream
, "/StemSnapH [", 12);
571 for (j
= 0; j
< privateDicts
[i
].nStemSnapH
; ++j
) {
572 sprintf(buf
, "%s%g", j
> 0 ? " " : "", privateDicts
[i
].stemSnapH
[j
]);
573 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
575 (*outputFunc
)(outputStream
, "] def\n", 6);
577 if (privateDicts
[i
].nStemSnapV
) {
578 (*outputFunc
)(outputStream
, "/StemSnapV [", 12);
579 for (j
= 0; j
< privateDicts
[i
].nStemSnapV
; ++j
) {
580 sprintf(buf
, "%s%g", j
> 0 ? " " : "", privateDicts
[i
].stemSnapV
[j
]);
581 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
583 (*outputFunc
)(outputStream
, "] def\n", 6);
585 if (privateDicts
[i
].hasForceBold
) {
586 sprintf(buf
, "/ForceBold %s def\n",
587 privateDicts
[i
].forceBold
? "true" : "false");
588 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
590 if (privateDicts
[i
].forceBoldThreshold
!= 0) {
591 sprintf(buf
, "/ForceBoldThreshold %g def\n",
592 privateDicts
[i
].forceBoldThreshold
);
593 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
595 if (privateDicts
[i
].languageGroup
!= 0) {
596 sprintf(buf
, "/LanguageGroup %d def\n", privateDicts
[i
].languageGroup
);
597 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
599 if (privateDicts
[i
].expansionFactor
!= 0.06) {
600 sprintf(buf
, "/ExpansionFactor %g def\n",
601 privateDicts
[i
].expansionFactor
);
602 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
604 (*outputFunc
)(outputStream
, "currentdict end def\n", 20);
605 (*outputFunc
)(outputStream
, "currentdict end put\n", 20);
607 (*outputFunc
)(outputStream
, "def\n", 4);
609 // start the binary section
610 offset
= (nCIDs
+ 1) * (1 + gdBytes
);
611 sprintf(buf
, "(Hex) %d StartData\n",
612 offset
+ charStrings
->getLength());
613 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
615 // write the charstring offset (CIDMap) table
616 for (i
= 0; i
<= nCIDs
; i
+= 6) {
617 for (j
= 0; j
< 6 && i
+j
<= nCIDs
; ++j
) {
618 if (i
+j
< nCIDs
&& cidMap
[i
+j
] >= 0) {
619 buf
[0] = (char)fdSelect
[cidMap
[i
+j
]];
623 n
= offset
+ charStringOffsets
[i
+j
];
624 for (k
= gdBytes
; k
>= 1; --k
) {
625 buf
[k
] = (char)(n
& 0xff);
628 for (k
= 0; k
<= gdBytes
; ++k
) {
629 sprintf(buf2
, "%02x", buf
[k
] & 0xff);
630 (*outputFunc
)(outputStream
, buf2
, 2);
633 (*outputFunc
)(outputStream
, "\n", 1);
636 // write the charstring data
637 n
= charStrings
->getLength();
638 for (i
= 0; i
< n
; i
+= 32) {
639 for (j
= 0; j
< 32 && i
+j
< n
; ++j
) {
640 sprintf(buf
, "%02x", charStrings
->getChar(i
+j
) & 0xff);
641 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
644 (*outputFunc
)(outputStream
, ">", 1);
646 (*outputFunc
)(outputStream
, "\n", 1);
649 gfree(charStringOffsets
);
654 void FoFiType1C::convertToType0(char *psName
,
655 FoFiOutputFunc outputFunc
,
656 void *outputStream
) {
666 // compute the CID count and build the CID-to-GID mapping
668 for (i
= 0; i
< nGlyphs
; ++i
) {
669 if (charset
[i
] >= nCIDs
) {
670 nCIDs
= charset
[i
] + 1;
673 cidMap
= (int *)gmalloc(nCIDs
* sizeof(int));
674 for (i
= 0; i
< nCIDs
; ++i
) {
677 for (i
= 0; i
< nGlyphs
; ++i
) {
678 cidMap
[charset
[i
]] = i
;
681 // write the descendant Type 1 fonts
682 for (i
= 0; i
< nCIDs
; i
+= 256) {
684 //~ this assumes that all CIDs in this block have the same FD --
685 //~ to handle multiple FDs correctly, need to somehow divide the
688 for (j
= 0; j
< 256 && i
+j
< nCIDs
; ++j
) {
689 if (cidMap
[i
+j
] >= 0) {
690 fd
= fdSelect
[cidMap
[i
+j
]];
695 // font dictionary (unencrypted section)
696 (*outputFunc
)(outputStream
, "16 dict begin\n", 14);
697 (*outputFunc
)(outputStream
, "/FontName /", 11);
698 (*outputFunc
)(outputStream
, psName
, strlen(psName
));
699 sprintf(buf
, "_%02x def\n", i
>> 8);
700 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
701 (*outputFunc
)(outputStream
, "/FontType 1 def\n", 16);
702 sprintf(buf
, "/FontMatrix [%g %g %g %g %g %g] def\n",
703 topDict
.fontMatrix
[0], topDict
.fontMatrix
[1],
704 topDict
.fontMatrix
[2], topDict
.fontMatrix
[3],
705 topDict
.fontMatrix
[4], topDict
.fontMatrix
[5]);
706 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
707 sprintf(buf
, "/FontBBox [%g %g %g %g] def\n",
708 topDict
.fontBBox
[0], topDict
.fontBBox
[1],
709 topDict
.fontBBox
[2], topDict
.fontBBox
[3]);
710 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
711 sprintf(buf
, "/PaintType %d def\n", topDict
.paintType
);
712 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
713 if (topDict
.paintType
!= 0) {
714 sprintf(buf
, "/StrokeWidth %g def\n", topDict
.strokeWidth
);
715 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
717 (*outputFunc
)(outputStream
, "/Encoding 256 array\n", 20);
718 for (j
= 0; j
< 256 && i
+j
< nCIDs
; ++j
) {
719 sprintf(buf
, "dup %d /c%02x put\n", j
, j
);
720 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
723 sprintf(buf
, "%d 1 255 { 1 index exch /.notdef put } for\n", j
);
724 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
726 (*outputFunc
)(outputStream
, "readonly def\n", 13);
727 (*outputFunc
)(outputStream
, "currentdict end\n", 16);
729 // start the binary section
730 (*outputFunc
)(outputStream
, "currentfile eexec\n", 18);
731 eb
.outputFunc
= outputFunc
;
732 eb
.outputStream
= outputStream
;
737 // start the private dictionary
738 eexecWrite(&eb
, "\x83\xca\x73\xd5");
739 eexecWrite(&eb
, "dup /Private 32 dict dup begin\n");
740 eexecWrite(&eb
, "/RD {string currentfile exch readstring pop}"
741 " executeonly def\n");
742 eexecWrite(&eb
, "/ND {noaccess def} executeonly def\n");
743 eexecWrite(&eb
, "/NP {noaccess put} executeonly def\n");
744 eexecWrite(&eb
, "/MinFeature {16 16} def\n");
745 eexecWrite(&eb
, "/password 5839 def\n");
746 if (privateDicts
[fd
].nBlueValues
) {
747 eexecWrite(&eb
, "/BlueValues [");
748 for (k
= 0; k
< privateDicts
[fd
].nBlueValues
; ++k
) {
749 sprintf(buf
, "%s%d", k
> 0 ? " " : "", privateDicts
[fd
].blueValues
[k
]);
750 eexecWrite(&eb
, buf
);
752 eexecWrite(&eb
, "] def\n");
754 if (privateDicts
[fd
].nOtherBlues
) {
755 eexecWrite(&eb
, "/OtherBlues [");
756 for (k
= 0; k
< privateDicts
[fd
].nOtherBlues
; ++k
) {
757 sprintf(buf
, "%s%d", k
> 0 ? " " : "", privateDicts
[fd
].otherBlues
[k
]);
758 eexecWrite(&eb
, buf
);
760 eexecWrite(&eb
, "] def\n");
762 if (privateDicts
[fd
].nFamilyBlues
) {
763 eexecWrite(&eb
, "/FamilyBlues [");
764 for (k
= 0; k
< privateDicts
[fd
].nFamilyBlues
; ++k
) {
765 sprintf(buf
, "%s%d", k
> 0 ? " " : "",
766 privateDicts
[fd
].familyBlues
[k
]);
767 eexecWrite(&eb
, buf
);
769 eexecWrite(&eb
, "] def\n");
771 if (privateDicts
[fd
].nFamilyOtherBlues
) {
772 eexecWrite(&eb
, "/FamilyOtherBlues [");
773 for (k
= 0; k
< privateDicts
[fd
].nFamilyOtherBlues
; ++k
) {
774 sprintf(buf
, "%s%d", k
> 0 ? " " : "",
775 privateDicts
[fd
].familyOtherBlues
[k
]);
776 eexecWrite(&eb
, buf
);
778 eexecWrite(&eb
, "] def\n");
780 if (privateDicts
[fd
].blueScale
!= 0.039625) {
781 sprintf(buf
, "/BlueScale %g def\n", privateDicts
[fd
].blueScale
);
782 eexecWrite(&eb
, buf
);
784 if (privateDicts
[fd
].blueShift
!= 7) {
785 sprintf(buf
, "/BlueShift %d def\n", privateDicts
[fd
].blueShift
);
786 eexecWrite(&eb
, buf
);
788 if (privateDicts
[fd
].blueFuzz
!= 1) {
789 sprintf(buf
, "/BlueFuzz %d def\n", privateDicts
[fd
].blueFuzz
);
790 eexecWrite(&eb
, buf
);
792 if (privateDicts
[fd
].hasStdHW
) {
793 sprintf(buf
, "/StdHW [%g] def\n", privateDicts
[fd
].stdHW
);
794 eexecWrite(&eb
, buf
);
796 if (privateDicts
[fd
].hasStdVW
) {
797 sprintf(buf
, "/StdVW [%g] def\n", privateDicts
[fd
].stdVW
);
798 eexecWrite(&eb
, buf
);
800 if (privateDicts
[fd
].nStemSnapH
) {
801 eexecWrite(&eb
, "/StemSnapH [");
802 for (k
= 0; k
< privateDicts
[fd
].nStemSnapH
; ++k
) {
803 sprintf(buf
, "%s%g", k
> 0 ? " " : "", privateDicts
[fd
].stemSnapH
[k
]);
804 eexecWrite(&eb
, buf
);
806 eexecWrite(&eb
, "] def\n");
808 if (privateDicts
[fd
].nStemSnapV
) {
809 eexecWrite(&eb
, "/StemSnapV [");
810 for (k
= 0; k
< privateDicts
[fd
].nStemSnapV
; ++k
) {
811 sprintf(buf
, "%s%g", k
> 0 ? " " : "", privateDicts
[fd
].stemSnapV
[k
]);
812 eexecWrite(&eb
, buf
);
814 eexecWrite(&eb
, "] def\n");
816 if (privateDicts
[fd
].hasForceBold
) {
817 sprintf(buf
, "/ForceBold %s def\n",
818 privateDicts
[fd
].forceBold
? "true" : "false");
819 eexecWrite(&eb
, buf
);
821 if (privateDicts
[fd
].forceBoldThreshold
!= 0) {
822 sprintf(buf
, "/ForceBoldThreshold %g def\n",
823 privateDicts
[fd
].forceBoldThreshold
);
824 eexecWrite(&eb
, buf
);
826 if (privateDicts
[fd
].languageGroup
!= 0) {
827 sprintf(buf
, "/LanguageGroup %d def\n", privateDicts
[fd
].languageGroup
);
828 eexecWrite(&eb
, buf
);
830 if (privateDicts
[fd
].expansionFactor
!= 0.06) {
831 sprintf(buf
, "/ExpansionFactor %g def\n",
832 privateDicts
[fd
].expansionFactor
);
833 eexecWrite(&eb
, buf
);
836 // set up the subroutines
838 getIndex(privateDicts
[fd
].subrsOffset
, &subrIdx
, &ok
);
843 // start the CharStrings
844 sprintf(buf
, "2 index /CharStrings 256 dict dup begin\n");
845 eexecWrite(&eb
, buf
);
847 // write the .notdef CharString
849 getIndexVal(&charStringsIdx
, 0, &val
, &ok
);
851 eexecCvtGlyph(&eb
, ".notdef", val
.pos
, val
.len
,
852 &subrIdx
, &privateDicts
[fd
]);
855 // write the CharStrings
856 for (j
= 0; j
< 256 && i
+j
< nCIDs
; ++j
) {
857 if (cidMap
[i
+j
] >= 0) {
859 getIndexVal(&charStringsIdx
, cidMap
[i
+j
], &val
, &ok
);
861 sprintf(buf
, "c%02x", j
);
862 eexecCvtGlyph(&eb
, buf
, val
.pos
, val
.len
,
863 &subrIdx
, &privateDicts
[fd
]);
867 eexecWrite(&eb
, "end\n");
868 eexecWrite(&eb
, "end\n");
869 eexecWrite(&eb
, "readonly put\n");
870 eexecWrite(&eb
, "noaccess put\n");
871 eexecWrite(&eb
, "dup /FontName get exch definefont pop\n");
872 eexecWrite(&eb
, "mark currentfile closefile\n");
876 (*outputFunc
)(outputStream
, "\n", 1);
878 for (j
= 0; j
< 8; ++j
) {
879 (*outputFunc
)(outputStream
, "0000000000000000000000000000000000000000000000000000000000000000\n", 65);
881 (*outputFunc
)(outputStream
, "cleartomark\n", 12);
884 // write the Type 0 parent font
885 (*outputFunc
)(outputStream
, "16 dict begin\n", 14);
886 (*outputFunc
)(outputStream
, "/FontName /", 11);
887 (*outputFunc
)(outputStream
, psName
, strlen(psName
));
888 (*outputFunc
)(outputStream
, " def\n", 5);
889 (*outputFunc
)(outputStream
, "/FontType 0 def\n", 16);
890 (*outputFunc
)(outputStream
, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
891 (*outputFunc
)(outputStream
, "/FMapType 2 def\n", 16);
892 (*outputFunc
)(outputStream
, "/Encoding [\n", 12);
893 for (i
= 0; i
< nCIDs
; i
+= 256) {
894 sprintf(buf
, "%d\n", i
>> 8);
895 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
897 (*outputFunc
)(outputStream
, "] def\n", 6);
898 (*outputFunc
)(outputStream
, "/FDepVector [\n", 14);
899 for (i
= 0; i
< nCIDs
; i
+= 256) {
900 (*outputFunc
)(outputStream
, "/", 1);
901 (*outputFunc
)(outputStream
, psName
, strlen(psName
));
902 sprintf(buf
, "_%02x findfont\n", i
>> 8);
903 (*outputFunc
)(outputStream
, buf
, strlen(buf
));
905 (*outputFunc
)(outputStream
, "] def\n", 6);
906 (*outputFunc
)(outputStream
, "FontName currentdict end definefont pop\n", 40);
911 void FoFiType1C::eexecCvtGlyph(Type1CEexecBuf
*eb
, char *glyphName
,
912 int offset
, int nBytes
,
913 Type1CIndex
*subrIdx
,
914 Type1CPrivateDict
*pDict
) {
918 // generate the charstring
919 charBuf
= new GString();
920 cvtGlyph(offset
, nBytes
, charBuf
, subrIdx
, pDict
, gTrue
);
922 sprintf(buf
, "/%s %d RD ", glyphName
, charBuf
->getLength());
924 eexecWriteCharstring(eb
, (Guchar
*)charBuf
->getCString(),
925 charBuf
->getLength());
926 eexecWrite(eb
, " ND\n");
931 void FoFiType1C::cvtGlyph(int offset
, int nBytes
, GString
*charBuf
,
932 Type1CIndex
*subrIdx
, Type1CPrivateDict
*pDict
,
939 int pos
, subrBias
, start
, i
, k
;
941 start
= charBuf
->getLength();
943 charBuf
->append((char)73);
944 charBuf
->append((char)58);
945 charBuf
->append((char)147);
946 charBuf
->append((char)134);
953 while (pos
< offset
+ nBytes
) {
955 pos
= getOp(pos
, gTrue
, &ok
);
959 if (!ops
[nOps
- 1].isNum
) {
960 --nOps
; // drop the operator
961 switch (ops
[nOps
].op
) {
962 case 0x0001: // hstem
964 cvtGlyphWidth(nOps
& 1, charBuf
, pDict
);
968 //~ error(-1, "Wrong number of args (%d) to Type 2 hstem", nOps);
972 for (k
= 0; k
< nOps
; k
+= 2) {
973 if (ops
[k
+1].num
< 0) {
974 d
+= ops
[k
].num
+ ops
[k
+1].num
;
975 dFP
|= ops
[k
].isFP
| ops
[k
+1].isFP
;
976 cvtNum(d
, dFP
, charBuf
);
977 cvtNum(-ops
[k
+1].num
, ops
[k
+1].isFP
, charBuf
);
981 cvtNum(d
, dFP
, charBuf
);
982 cvtNum(ops
[k
+1].num
, ops
[k
+1].isFP
, charBuf
);
984 dFP
|= ops
[k
+1].isFP
;
986 charBuf
->append((char)1);
991 case 0x0003: // vstem
993 cvtGlyphWidth(nOps
& 1, charBuf
, pDict
);
997 //~ error(-1, "Wrong number of args (%d) to Type 2 vstem", nOps);
1001 for (k
= 0; k
< nOps
; k
+= 2) {
1002 if (ops
[k
+1].num
< 0) {
1003 d
+= ops
[k
].num
+ ops
[k
+1].num
;
1004 dFP
|= ops
[k
].isFP
| ops
[k
+1].isFP
;
1005 cvtNum(d
, dFP
, charBuf
);
1006 cvtNum(-ops
[k
+1].num
, ops
[k
+1].isFP
, charBuf
);
1010 cvtNum(d
, dFP
, charBuf
);
1011 cvtNum(ops
[k
+1].num
, ops
[k
+1].isFP
, charBuf
);
1013 dFP
|= ops
[k
+1].isFP
;
1015 charBuf
->append((char)3);
1020 case 0x0004: // vmoveto
1022 cvtGlyphWidth(nOps
== 2, charBuf
, pDict
);
1026 //~ error(-1, "Wrong number of args (%d) to Type 2 vmoveto", nOps);
1028 cvtNum(ops
[0].num
, ops
[0].isFP
, charBuf
);
1029 charBuf
->append((char)4);
1032 case 0x0005: // rlineto
1033 if (nOps
< 2 || nOps
% 2 != 0) {
1034 //~ error(-1, "Wrong number of args (%d) to Type 2 rlineto", nOps);
1036 for (k
= 0; k
< nOps
; k
+= 2) {
1037 cvtNum(ops
[k
].num
, ops
[k
].isFP
, charBuf
);
1038 cvtNum(ops
[k
+1].num
, ops
[k
+1].isFP
, charBuf
);
1039 charBuf
->append((char)5);
1043 case 0x0006: // hlineto
1045 //~ error(-1, "Wrong number of args (%d) to Type 2 hlineto", nOps);
1047 for (k
= 0; k
< nOps
; ++k
) {
1048 cvtNum(ops
[k
].num
, ops
[k
].isFP
, charBuf
);
1049 charBuf
->append((char)((k
& 1) ? 7 : 6));
1053 case 0x0007: // vlineto
1055 //~ error(-1, "Wrong number of args (%d) to Type 2 vlineto", nOps);
1057 for (k
= 0; k
< nOps
; ++k
) {
1058 cvtNum(ops
[k
].num
, ops
[k
].isFP
, charBuf
);
1059 charBuf
->append((char)((k
& 1) ? 6 : 7));
1063 case 0x0008: // rrcurveto
1064 if (nOps
< 6 || nOps
% 6 != 0) {
1065 //~ error(-1, "Wrong number of args (%d) to Type 2 rrcurveto", nOps);
1067 for (k
= 0; k
< nOps
; k
+= 6) {
1068 cvtNum(ops
[k
].num
, ops
[k
].isFP
, charBuf
);
1069 cvtNum(ops
[k
+1].num
, ops
[k
+1].isFP
, charBuf
);
1070 cvtNum(ops
[k
+2].num
, ops
[k
+2].isFP
, charBuf
);
1071 cvtNum(ops
[k
+3].num
, ops
[k
+3].isFP
, charBuf
);
1072 cvtNum(ops
[k
+4].num
, ops
[k
+4].isFP
, charBuf
);
1073 cvtNum(ops
[k
+5].num
, ops
[k
+5].isFP
, charBuf
);
1074 charBuf
->append((char)8);
1078 case 0x000a: // callsubr
1080 subrBias
= (subrIdx
->len
< 1240)
1081 ? 107 : (subrIdx
->len
< 33900) ? 1131 : 32768;
1082 k
= subrBias
+ (int)ops
[nOps
- 1].num
;
1085 getIndexVal(subrIdx
, k
, &val
, &ok
);
1087 cvtGlyph(val
.pos
, val
.len
, charBuf
, subrIdx
, pDict
, gFalse
);
1090 //~ error(-1, "Too few args to Type 2 callsubr");
1092 // don't clear the stack
1094 case 0x000b: // return
1095 // don't clear the stack
1097 case 0x000e: // endchar / seac
1099 cvtGlyphWidth(nOps
== 1 || nOps
== 5, charBuf
, pDict
);
1103 cvtNum(0, gFalse
, charBuf
);
1104 cvtNum(ops
[0].num
, ops
[0].isFP
, charBuf
);
1105 cvtNum(ops
[1].num
, ops
[1].isFP
, charBuf
);
1106 cvtNum(ops
[2].num
, ops
[2].isFP
, charBuf
);
1107 cvtNum(ops
[3].num
, ops
[3].isFP
, charBuf
);
1108 charBuf
->append((char)12)->append((char)6);
1109 } else if (nOps
== 0) {
1110 charBuf
->append((char)14);
1112 //~ error(-1, "Wrong number of args (%d) to Type 2 endchar", nOps);
1116 case 0x000f: // (obsolete)
1117 // this op is ignored, but we need the glyph width
1119 cvtGlyphWidth(nOps
> 0, charBuf
, pDict
);
1124 case 0x0010: // blend
1125 //~ error(-1, "Unimplemented Type 2 charstring op: %d", file[i]);
1128 case 0x0012: // hstemhm
1131 cvtGlyphWidth(nOps
& 1, charBuf
, pDict
);
1135 //~ error(-1, "Wrong number of args (%d) to Type 2 hstemhm", nOps);
1140 case 0x0013: // hintmask
1143 cvtGlyphWidth(nOps
& 1, charBuf
, pDict
);
1148 //~ error(-1, "Wrong number of args (%d) to Type 2 hintmask/vstemhm",
1153 pos
+= (nHints
+ 7) >> 3;
1156 case 0x0014: // cntrmask
1159 cvtGlyphWidth(nOps
& 1, charBuf
, pDict
);
1164 //~ error(-1, "Wrong number of args (%d) to Type 2 cntrmask/vstemhm",
1169 pos
+= (nHints
+ 7) >> 3;
1172 case 0x0015: // rmoveto
1174 cvtGlyphWidth(nOps
== 3, charBuf
, pDict
);
1178 //~ error(-1, "Wrong number of args (%d) to Type 2 rmoveto", nOps);
1180 cvtNum(ops
[0].num
, ops
[0].isFP
, charBuf
);
1181 cvtNum(ops
[1].num
, ops
[1].isFP
, charBuf
);
1182 charBuf
->append((char)21);
1185 case 0x0016: // hmoveto
1187 cvtGlyphWidth(nOps
== 2, charBuf
, pDict
);
1191 //~ error(-1, "Wrong number of args (%d) to Type 2 hmoveto", nOps);
1193 cvtNum(ops
[0].num
, ops
[0].isFP
, charBuf
);
1194 charBuf
->append((char)22);
1197 case 0x0017: // vstemhm
1200 cvtGlyphWidth(nOps
& 1, charBuf
, pDict
);
1204 //~ error(-1, "Wrong number of args (%d) to Type 2 vstemhm", nOps);
1209 case 0x0018: // rcurveline
1210 if (nOps
< 8 || (nOps
- 2) % 6 != 0) {
1211 //~ error(-1, "Wrong number of args (%d) to Type 2 rcurveline", nOps);
1213 for (k
= 0; k
< nOps
- 2; k
+= 6) {
1214 cvtNum(ops
[k
].num
, ops
[k
].isFP
, charBuf
);
1215 cvtNum(ops
[k
+1].num
, ops
[k
+1].isFP
, charBuf
);
1216 cvtNum(ops
[k
+2].num
, ops
[k
+2].isFP
, charBuf
);
1217 cvtNum(ops
[k
+3].num
, ops
[k
+3].isFP
, charBuf
);
1218 cvtNum(ops
[k
+4].num
, ops
[k
+4].isFP
, charBuf
);
1219 cvtNum(ops
[k
+5].num
, ops
[k
+5].isFP
, charBuf
);
1220 charBuf
->append((char)8);
1222 cvtNum(ops
[k
].num
, ops
[k
].isFP
, charBuf
);
1223 cvtNum(ops
[k
+1].num
, ops
[k
].isFP
, charBuf
);
1224 charBuf
->append((char)5);
1227 case 0x0019: // rlinecurve
1228 if (nOps
< 8 || (nOps
- 6) % 2 != 0) {
1229 //~ error(-1, "Wrong number of args (%d) to Type 2 rlinecurve", nOps);
1231 for (k
= 0; k
< nOps
- 6; k
+= 2) {
1232 cvtNum(ops
[k
].num
, ops
[k
].isFP
, charBuf
);
1233 cvtNum(ops
[k
+1].num
, ops
[k
].isFP
, charBuf
);
1234 charBuf
->append((char)5);
1236 cvtNum(ops
[k
].num
, ops
[k
].isFP
, charBuf
);
1237 cvtNum(ops
[k
+1].num
, ops
[k
+1].isFP
, charBuf
);
1238 cvtNum(ops
[k
+2].num
, ops
[k
+2].isFP
, charBuf
);
1239 cvtNum(ops
[k
+3].num
, ops
[k
+3].isFP
, charBuf
);
1240 cvtNum(ops
[k
+4].num
, ops
[k
+4].isFP
, charBuf
);
1241 cvtNum(ops
[k
+5].num
, ops
[k
+5].isFP
, charBuf
);
1242 charBuf
->append((char)8);
1245 case 0x001a: // vvcurveto
1246 if (nOps
< 4 || !(nOps
% 4 == 0 || (nOps
-1) % 4 == 0)) {
1247 //~ error(-1, "Wrong number of args (%d) to Type 2 vvcurveto", nOps);
1249 if (nOps
% 2 == 1) {
1250 cvtNum(ops
[0].num
, ops
[0].isFP
, charBuf
);
1251 cvtNum(ops
[1].num
, ops
[1].isFP
, charBuf
);
1252 cvtNum(ops
[2].num
, ops
[2].isFP
, charBuf
);
1253 cvtNum(ops
[3].num
, ops
[3].isFP
, charBuf
);
1254 cvtNum(0, gFalse
, charBuf
);
1255 cvtNum(ops
[4].num
, ops
[4].isFP
, charBuf
);
1256 charBuf
->append((char)8);
1261 for (; k
< nOps
; k
+= 4) {
1262 cvtNum(0, gFalse
, charBuf
);
1263 cvtNum(ops
[k
].num
, ops
[k
].isFP
, charBuf
);
1264 cvtNum(ops
[k
+1].num
, ops
[k
+1].isFP
, charBuf
);
1265 cvtNum(ops
[k
+2].num
, ops
[k
+2].isFP
, charBuf
);
1266 cvtNum(0, gFalse
, charBuf
);
1267 cvtNum(ops
[k
+3].num
, ops
[k
+3].isFP
, charBuf
);
1268 charBuf
->append((char)8);
1272 case 0x001b: // hhcurveto
1273 if (nOps
< 4 || !(nOps
% 4 == 0 || (nOps
-1) % 4 == 0)) {
1274 //~ error(-1, "Wrong number of args (%d) to Type 2 hhcurveto", nOps);
1276 if (nOps
% 2 == 1) {
1277 cvtNum(ops
[1].num
, ops
[1].isFP
, charBuf
);
1278 cvtNum(ops
[0].num
, ops
[0].isFP
, charBuf
);
1279 cvtNum(ops
[2].num
, ops
[2].isFP
, charBuf
);
1280 cvtNum(ops
[3].num
, ops
[3].isFP
, charBuf
);
1281 cvtNum(ops
[4].num
, ops
[4].isFP
, charBuf
);
1282 cvtNum(0, gFalse
, charBuf
);
1283 charBuf
->append((char)8);
1288 for (; k
< nOps
; k
+= 4) {
1289 cvtNum(ops
[k
].num
, ops
[k
].isFP
, charBuf
);
1290 cvtNum(0, gFalse
, charBuf
);
1291 cvtNum(ops
[k
+1].num
, ops
[k
+1].isFP
, charBuf
);
1292 cvtNum(ops
[k
+2].num
, ops
[k
+2].isFP
, charBuf
);
1293 cvtNum(ops
[k
+3].num
, ops
[k
+3].isFP
, charBuf
);
1294 cvtNum(0, gFalse
, charBuf
);
1295 charBuf
->append((char)8);
1299 case 0x001d: // callgsubr
1301 k
= gsubrBias
+ (int)ops
[nOps
- 1].num
;
1304 getIndexVal(&gsubrIdx
, k
, &val
, &ok
);
1306 cvtGlyph(val
.pos
, val
.len
, charBuf
, subrIdx
, pDict
, gFalse
);
1309 //~ error(-1, "Too few args to Type 2 callgsubr");
1311 // don't clear the stack
1313 case 0x001e: // vhcurveto
1314 if (nOps
< 4 || !(nOps
% 4 == 0 || (nOps
-1) % 4 == 0)) {
1315 //~ error(-1, "Wrong number of args (%d) to Type 2 vhcurveto", nOps);
1317 for (k
= 0; k
< nOps
&& k
!= nOps
-5; k
+= 4) {
1319 cvtNum(ops
[k
].num
, ops
[k
].isFP
, charBuf
);
1320 cvtNum(ops
[k
+1].num
, ops
[k
+1].isFP
, charBuf
);
1321 cvtNum(ops
[k
+2].num
, ops
[k
+2].isFP
, charBuf
);
1322 cvtNum(ops
[k
+3].num
, ops
[k
+3].isFP
, charBuf
);
1323 charBuf
->append((char)30);
1325 cvtNum(ops
[k
].num
, ops
[k
].isFP
, charBuf
);
1326 cvtNum(ops
[k
+1].num
, ops
[k
+1].isFP
, charBuf
);
1327 cvtNum(ops
[k
+2].num
, ops
[k
+2].isFP
, charBuf
);
1328 cvtNum(ops
[k
+3].num
, ops
[k
+3].isFP
, charBuf
);
1329 charBuf
->append((char)31);
1334 cvtNum(0, gFalse
, charBuf
);
1335 cvtNum(ops
[k
].num
, ops
[k
].isFP
, charBuf
);
1336 cvtNum(ops
[k
+1].num
, ops
[k
+1].isFP
, charBuf
);
1337 cvtNum(ops
[k
+2].num
, ops
[k
+2].isFP
, charBuf
);
1338 cvtNum(ops
[k
+3].num
, ops
[k
+3].isFP
, charBuf
);
1339 cvtNum(ops
[k
+4].num
, ops
[k
+4].isFP
, charBuf
);
1341 cvtNum(ops
[k
].num
, ops
[k
].isFP
, charBuf
);
1342 cvtNum(0, gFalse
, charBuf
);
1343 cvtNum(ops
[k
+1].num
, ops
[k
+1].isFP
, charBuf
);
1344 cvtNum(ops
[k
+2].num
, ops
[k
+2].isFP
, charBuf
);
1345 cvtNum(ops
[k
+4].num
, ops
[k
+4].isFP
, charBuf
);
1346 cvtNum(ops
[k
+3].num
, ops
[k
+3].isFP
, charBuf
);
1348 charBuf
->append((char)8);
1352 case 0x001f: // hvcurveto
1353 if (nOps
< 4 || !(nOps
% 4 == 0 || (nOps
-1) % 4 == 0)) {
1354 //~ error(-1, "Wrong number of args (%d) to Type 2 hvcurveto", nOps);
1356 for (k
= 0; k
< nOps
&& k
!= nOps
-5; k
+= 4) {
1358 cvtNum(ops
[k
].num
, ops
[k
].isFP
, charBuf
);
1359 cvtNum(ops
[k
+1].num
, ops
[k
+1].isFP
, charBuf
);
1360 cvtNum(ops
[k
+2].num
, ops
[k
+2].isFP
, charBuf
);
1361 cvtNum(ops
[k
+3].num
, ops
[k
+3].isFP
, charBuf
);
1362 charBuf
->append((char)31);
1364 cvtNum(ops
[k
].num
, ops
[k
].isFP
, charBuf
);
1365 cvtNum(ops
[k
+1].num
, ops
[k
+1].isFP
, charBuf
);
1366 cvtNum(ops
[k
+2].num
, ops
[k
+2].isFP
, charBuf
);
1367 cvtNum(ops
[k
+3].num
, ops
[k
+3].isFP
, charBuf
);
1368 charBuf
->append((char)30);
1373 cvtNum(ops
[k
].num
, ops
[k
].isFP
, charBuf
);
1374 cvtNum(0, gFalse
, charBuf
);
1375 cvtNum(ops
[k
+1].num
, ops
[k
+1].isFP
, charBuf
);
1376 cvtNum(ops
[k
+2].num
, ops
[k
+2].isFP
, charBuf
);
1377 cvtNum(ops
[k
+4].num
, ops
[k
+4].isFP
, charBuf
);
1378 cvtNum(ops
[k
+3].num
, ops
[k
+3].isFP
, charBuf
);
1380 cvtNum(0, gFalse
, charBuf
);
1381 cvtNum(ops
[k
].num
, ops
[k
].isFP
, charBuf
);
1382 cvtNum(ops
[k
+1].num
, ops
[k
+1].isFP
, charBuf
);
1383 cvtNum(ops
[k
+2].num
, ops
[k
+2].isFP
, charBuf
);
1384 cvtNum(ops
[k
+3].num
, ops
[k
+3].isFP
, charBuf
);
1385 cvtNum(ops
[k
+4].num
, ops
[k
+4].isFP
, charBuf
);
1387 charBuf
->append((char)8);
1391 case 0x0c00: // dotsection (should be Type 1 only?)
1398 case 0x0c08: // store
1403 case 0x0c0d: // load
1406 case 0x0c12: // drop
1409 case 0x0c16: // ifelse
1410 case 0x0c17: // random
1412 case 0x0c1a: // sqrt
1414 case 0x0c1c: // exch
1415 case 0x0c1d: // index
1416 case 0x0c1e: // roll
1417 //~ error(-1, "Unimplemented Type 2 charstring op: 12.%d", file[i+1]);
1420 case 0x0c22: // hflex
1422 //~ error(-1, "Wrong number of args (%d) to Type 2 hflex", nOps);
1424 cvtNum(ops
[0].num
, ops
[0].isFP
, charBuf
);
1425 cvtNum(0, gFalse
, charBuf
);
1426 cvtNum(ops
[1].num
, ops
[1].isFP
, charBuf
);
1427 cvtNum(ops
[2].num
, ops
[2].isFP
, charBuf
);
1428 cvtNum(ops
[3].num
, ops
[3].isFP
, charBuf
);
1429 cvtNum(0, gFalse
, charBuf
);
1430 charBuf
->append((char)8);
1431 cvtNum(ops
[4].num
, ops
[4].isFP
, charBuf
);
1432 cvtNum(0, gFalse
, charBuf
);
1433 cvtNum(ops
[5].num
, ops
[5].isFP
, charBuf
);
1434 cvtNum(-ops
[2].num
, ops
[2].isFP
, charBuf
);
1435 cvtNum(ops
[6].num
, ops
[6].isFP
, charBuf
);
1436 cvtNum(0, gFalse
, charBuf
);
1437 charBuf
->append((char)8);
1440 case 0x0c23: // flex
1442 //~ error(-1, "Wrong number of args (%d) to Type 2 flex", nOps);
1444 cvtNum(ops
[0].num
, ops
[0].isFP
, charBuf
);
1445 cvtNum(ops
[1].num
, ops
[1].isFP
, charBuf
);
1446 cvtNum(ops
[2].num
, ops
[2].isFP
, charBuf
);
1447 cvtNum(ops
[3].num
, ops
[3].isFP
, charBuf
);
1448 cvtNum(ops
[4].num
, ops
[4].isFP
, charBuf
);
1449 cvtNum(ops
[5].num
, ops
[5].isFP
, charBuf
);
1450 charBuf
->append((char)8);
1451 cvtNum(ops
[6].num
, ops
[6].isFP
, charBuf
);
1452 cvtNum(ops
[7].num
, ops
[7].isFP
, charBuf
);
1453 cvtNum(ops
[8].num
, ops
[8].isFP
, charBuf
);
1454 cvtNum(ops
[9].num
, ops
[9].isFP
, charBuf
);
1455 cvtNum(ops
[10].num
, ops
[10].isFP
, charBuf
);
1456 cvtNum(ops
[11].num
, ops
[11].isFP
, charBuf
);
1457 charBuf
->append((char)8);
1460 case 0x0c24: // hflex1
1462 //~ error(-1, "Wrong number of args (%d) to Type 2 hflex1", nOps);
1464 cvtNum(ops
[0].num
, ops
[0].isFP
, charBuf
);
1465 cvtNum(ops
[1].num
, ops
[1].isFP
, charBuf
);
1466 cvtNum(ops
[2].num
, ops
[2].isFP
, charBuf
);
1467 cvtNum(ops
[3].num
, ops
[3].isFP
, charBuf
);
1468 cvtNum(ops
[4].num
, ops
[4].isFP
, charBuf
);
1469 cvtNum(0, gFalse
, charBuf
);
1470 charBuf
->append((char)8);
1471 cvtNum(ops
[5].num
, ops
[5].isFP
, charBuf
);
1472 cvtNum(0, gFalse
, charBuf
);
1473 cvtNum(ops
[6].num
, ops
[6].isFP
, charBuf
);
1474 cvtNum(ops
[7].num
, ops
[7].isFP
, charBuf
);
1475 cvtNum(ops
[8].num
, ops
[8].isFP
, charBuf
);
1476 cvtNum(-(ops
[1].num
+ ops
[3].num
+ ops
[7].num
),
1477 ops
[1].isFP
| ops
[3].isFP
| ops
[7].isFP
, charBuf
);
1478 charBuf
->append((char)8);
1481 case 0x0c25: // flex1
1483 //~ error(-1, "Wrong number of args (%d) to Type 2 flex1", nOps);
1485 cvtNum(ops
[0].num
, ops
[0].isFP
, charBuf
);
1486 cvtNum(ops
[1].num
, ops
[1].isFP
, charBuf
);
1487 cvtNum(ops
[2].num
, ops
[2].isFP
, charBuf
);
1488 cvtNum(ops
[3].num
, ops
[3].isFP
, charBuf
);
1489 cvtNum(ops
[4].num
, ops
[4].isFP
, charBuf
);
1490 cvtNum(ops
[5].num
, ops
[5].isFP
, charBuf
);
1491 charBuf
->append((char)8);
1492 cvtNum(ops
[6].num
, ops
[6].isFP
, charBuf
);
1493 cvtNum(ops
[7].num
, ops
[7].isFP
, charBuf
);
1494 cvtNum(ops
[8].num
, ops
[8].isFP
, charBuf
);
1495 cvtNum(ops
[9].num
, ops
[9].isFP
, charBuf
);
1496 dx
= ops
[0].num
+ ops
[2].num
+ ops
[4].num
+ ops
[6].num
+ ops
[8].num
;
1497 dy
= ops
[1].num
+ ops
[3].num
+ ops
[5].num
+ ops
[7].num
+ ops
[9].num
;
1498 if (fabs(dx
) > fabs(dy
)) {
1499 cvtNum(ops
[10].num
, ops
[10].isFP
, charBuf
);
1500 cvtNum(-dy
, ops
[1].isFP
| ops
[3].isFP
| ops
[5].isFP
|
1501 ops
[7].isFP
| ops
[9].isFP
, charBuf
);
1503 cvtNum(-dx
, ops
[0].isFP
| ops
[2].isFP
| ops
[4].isFP
|
1504 ops
[6].isFP
| ops
[8].isFP
, charBuf
);
1505 cvtNum(ops
[10].num
, ops
[10].isFP
, charBuf
);
1507 charBuf
->append((char)8);
1511 //~ error(-1, "Illegal Type 2 charstring op: %04x",
1519 // charstring encryption
1522 for (i
= start
; i
< charBuf
->getLength(); ++i
) {
1523 byte
= charBuf
->getChar(i
) ^ (r2
>> 8);
1524 charBuf
->setChar(i
, byte
);
1525 r2
= (byte
+ r2
) * 52845 + 22719;
1530 void FoFiType1C::cvtGlyphWidth(GBool useOp
, GString
*charBuf
,
1531 Type1CPrivateDict
*pDict
) {
1537 w
= pDict
->nominalWidthX
+ ops
[0].num
;
1538 wFP
= pDict
->nominalWidthXFP
| ops
[0].isFP
;
1539 for (i
= 1; i
< nOps
; ++i
) {
1544 w
= pDict
->defaultWidthX
;
1545 wFP
= pDict
->defaultWidthXFP
;
1547 cvtNum(0, gFalse
, charBuf
);
1548 cvtNum(w
, wFP
, charBuf
);
1549 charBuf
->append((char)13);
1552 void FoFiType1C::cvtNum(double x
, GBool isFP
, GString
*charBuf
) {
1558 if (x
>= -32768 && x
< 32768) {
1559 y
= (int)(x
* 256.0);
1561 buf
[1] = (Guchar
)(y
>> 24);
1562 buf
[2] = (Guchar
)(y
>> 16);
1563 buf
[3] = (Guchar
)(y
>> 8);
1574 //~ error(-1, "Type 2 fixed point constant out of range");
1578 if (y
>= -107 && y
<= 107) {
1579 buf
[0] = (Guchar
)(y
+ 139);
1581 } else if (y
> 107 && y
<= 1131) {
1583 buf
[0] = (Guchar
)((y
>> 8) + 247);
1584 buf
[1] = (Guchar
)(y
& 0xff);
1586 } else if (y
< -107 && y
>= -1131) {
1588 buf
[0] = (Guchar
)((y
>> 8) + 251);
1589 buf
[1] = (Guchar
)(y
& 0xff);
1593 buf
[1] = (Guchar
)(y
>> 24);
1594 buf
[2] = (Guchar
)(y
>> 16);
1595 buf
[3] = (Guchar
)(y
>> 8);
1600 charBuf
->append((char *)buf
, n
);
1603 void FoFiType1C::eexecWrite(Type1CEexecBuf
*eb
, char *s
) {
1607 for (p
= (Guchar
*)s
; *p
; ++p
) {
1608 x
= *p
^ (eb
->r1
>> 8);
1609 eb
->r1
= (x
+ eb
->r1
) * 52845 + 22719;
1611 (*eb
->outputFunc
)(eb
->outputStream
, &hexChars
[x
>> 4], 1);
1612 (*eb
->outputFunc
)(eb
->outputStream
, &hexChars
[x
& 0x0f], 1);
1614 if (eb
->line
== 64) {
1615 (*eb
->outputFunc
)(eb
->outputStream
, "\n", 1);
1619 (*eb
->outputFunc
)(eb
->outputStream
, (char *)&x
, 1);
1624 void FoFiType1C::eexecWriteCharstring(Type1CEexecBuf
*eb
,
1630 for (i
= 0; i
< n
; ++i
) {
1631 x
= s
[i
] ^ (eb
->r1
>> 8);
1632 eb
->r1
= (x
+ eb
->r1
) * 52845 + 22719;
1634 (*eb
->outputFunc
)(eb
->outputStream
, &hexChars
[x
>> 4], 1);
1635 (*eb
->outputFunc
)(eb
->outputStream
, &hexChars
[x
& 0x0f], 1);
1637 if (eb
->line
== 64) {
1638 (*eb
->outputFunc
)(eb
->outputStream
, "\n", 1);
1642 (*eb
->outputFunc
)(eb
->outputStream
, (char *)&x
, 1);
1647 GBool
FoFiType1C::parse() {
1654 // some tools embed Type 1C fonts with an extra whitespace char at
1656 if (len
> 0 && file
[0] != '\x01') {
1662 getIndex(getU8(2, &parsedOk
), &nameIdx
, &parsedOk
);
1663 getIndex(nameIdx
.endPos
, &topDictIdx
, &parsedOk
);
1664 getIndex(topDictIdx
.endPos
, &stringIdx
, &parsedOk
);
1665 getIndex(stringIdx
.endPos
, &gsubrIdx
, &parsedOk
);
1669 gsubrBias
= (gsubrIdx
.len
< 1240) ? 107
1670 : (gsubrIdx
.len
< 33900) ? 1131 : 32768;
1672 // read the first font name
1673 getIndexVal(&nameIdx
, 0, &val
, &parsedOk
);
1677 name
= new GString((char *)&file
[val
.pos
], val
.len
);
1679 // read the top dict for the first font
1682 // for CID fonts: read the FDArray dicts and private dicts
1683 if (topDict
.firstOp
== 0x0c1e) {
1684 if (topDict
.fdArrayOffset
== 0) {
1686 privateDicts
= (Type1CPrivateDict
*)gmalloc(sizeof(Type1CPrivateDict
));
1687 readPrivateDict(0, 0, &privateDicts
[0]);
1689 getIndex(topDict
.fdArrayOffset
, &fdIdx
, &parsedOk
);
1694 privateDicts
= (Type1CPrivateDict
*)
1695 gmalloc(nFDs
* sizeof(Type1CPrivateDict
));
1696 for (i
= 0; i
< nFDs
; ++i
) {
1697 getIndexVal(&fdIdx
, i
, &val
, &parsedOk
);
1701 readFD(val
.pos
, val
.len
, &privateDicts
[i
]);
1705 // for 8-bit fonts: read the private dict
1707 privateDicts
= (Type1CPrivateDict
*)gmalloc(sizeof(Type1CPrivateDict
));
1708 readPrivateDict(topDict
.privateOffset
, topDict
.privateSize
,
1712 // check for parse errors in the private dict(s)
1717 // get the charstrings index
1718 if (topDict
.charStringsOffset
<= 0) {
1722 getIndex(topDict
.charStringsOffset
, &charStringsIdx
, &parsedOk
);
1726 nGlyphs
= charStringsIdx
.len
;
1728 // for CID fonts: read the FDSelect table
1729 if (topDict
.firstOp
== 0x0c1e) {
1737 if (!readCharset()) {
1742 // for 8-bit fonts: build the encoding
1743 if (topDict
.firstOp
!= 0x0c14 && topDict
.firstOp
!= 0x0c1e) {
1753 void FoFiType1C::readTopDict() {
1754 Type1CIndexVal topDictPtr
;
1757 topDict
.firstOp
= -1;
1758 topDict
.versionSID
= 0;
1759 topDict
.noticeSID
= 0;
1760 topDict
.copyrightSID
= 0;
1761 topDict
.fullNameSID
= 0;
1762 topDict
.familyNameSID
= 0;
1763 topDict
.weightSID
= 0;
1764 topDict
.isFixedPitch
= 0;
1765 topDict
.italicAngle
= 0;
1766 topDict
.underlinePosition
= -100;
1767 topDict
.underlineThickness
= 50;
1768 topDict
.paintType
= 0;
1769 topDict
.charstringType
= 2;
1770 topDict
.fontMatrix
[0] = 0.001;
1771 topDict
.fontMatrix
[1] = 0;
1772 topDict
.fontMatrix
[2] = 0;
1773 topDict
.fontMatrix
[3] = 0.001;
1774 topDict
.fontMatrix
[4] = 0;
1775 topDict
.fontMatrix
[5] = 0;
1776 topDict
.uniqueID
= 0;
1777 topDict
.fontBBox
[0] = 0;
1778 topDict
.fontBBox
[1] = 0;
1779 topDict
.fontBBox
[2] = 0;
1780 topDict
.fontBBox
[3] = 0;
1781 topDict
.strokeWidth
= 0;
1782 topDict
.charsetOffset
= 0;
1783 topDict
.encodingOffset
= 0;
1784 topDict
.charStringsOffset
= 0;
1785 topDict
.privateSize
= 0;
1786 topDict
.privateOffset
= 0;
1787 topDict
.registrySID
= 0;
1788 topDict
.orderingSID
= 0;
1789 topDict
.supplement
= 0;
1790 topDict
.fdArrayOffset
= 0;
1791 topDict
.fdSelectOffset
= 0;
1793 getIndexVal(&topDictIdx
, 0, &topDictPtr
, &parsedOk
);
1794 pos
= topDictPtr
.pos
;
1796 while (pos
< topDictPtr
.pos
+ topDictPtr
.len
) {
1797 pos
= getOp(pos
, gFalse
, &parsedOk
);
1801 if (!ops
[nOps
- 1].isNum
) {
1802 --nOps
; // drop the operator
1803 if (topDict
.firstOp
< 0) {
1804 topDict
.firstOp
= ops
[nOps
].op
;
1806 switch (ops
[nOps
].op
) {
1807 case 0x0000: topDict
.versionSID
= (int)ops
[0].num
; break;
1808 case 0x0001: topDict
.noticeSID
= (int)ops
[0].num
; break;
1809 case 0x0c00: topDict
.copyrightSID
= (int)ops
[0].num
; break;
1810 case 0x0002: topDict
.fullNameSID
= (int)ops
[0].num
; break;
1811 case 0x0003: topDict
.familyNameSID
= (int)ops
[0].num
; break;
1812 case 0x0004: topDict
.weightSID
= (int)ops
[0].num
; break;
1813 case 0x0c01: topDict
.isFixedPitch
= (int)ops
[0].num
; break;
1814 case 0x0c02: topDict
.italicAngle
= ops
[0].num
; break;
1815 case 0x0c03: topDict
.underlinePosition
= ops
[0].num
; break;
1816 case 0x0c04: topDict
.underlineThickness
= ops
[0].num
; break;
1817 case 0x0c05: topDict
.paintType
= (int)ops
[0].num
; break;
1818 case 0x0c06: topDict
.charstringType
= (int)ops
[0].num
; break;
1819 case 0x0c07: topDict
.fontMatrix
[0] = ops
[0].num
;
1820 topDict
.fontMatrix
[1] = ops
[1].num
;
1821 topDict
.fontMatrix
[2] = ops
[2].num
;
1822 topDict
.fontMatrix
[3] = ops
[3].num
;
1823 topDict
.fontMatrix
[4] = ops
[4].num
;
1824 topDict
.fontMatrix
[5] = ops
[5].num
; break;
1825 case 0x000d: topDict
.uniqueID
= (int)ops
[0].num
; break;
1826 case 0x0005: topDict
.fontBBox
[0] = ops
[0].num
;
1827 topDict
.fontBBox
[1] = ops
[1].num
;
1828 topDict
.fontBBox
[2] = ops
[2].num
;
1829 topDict
.fontBBox
[3] = ops
[3].num
; break;
1830 case 0x0c08: topDict
.strokeWidth
= ops
[0].num
; break;
1831 case 0x000f: topDict
.charsetOffset
= (int)ops
[0].num
; break;
1832 case 0x0010: topDict
.encodingOffset
= (int)ops
[0].num
; break;
1833 case 0x0011: topDict
.charStringsOffset
= (int)ops
[0].num
; break;
1834 case 0x0012: topDict
.privateSize
= (int)ops
[0].num
;
1835 topDict
.privateOffset
= (int)ops
[1].num
; break;
1836 case 0x0c1e: topDict
.registrySID
= (int)ops
[0].num
;
1837 topDict
.orderingSID
= (int)ops
[1].num
;
1838 topDict
.supplement
= (int)ops
[2].num
; break;
1839 case 0x0c24: topDict
.fdArrayOffset
= (int)ops
[0].num
; break;
1840 case 0x0c25: topDict
.fdSelectOffset
= (int)ops
[0].num
; break;
1847 // Read a CID font dict (FD) - this pulls out the private dict
1848 // pointer, and reads the private dict.
1849 void FoFiType1C::readFD(int offset
, int length
, Type1CPrivateDict
*pDict
) {
1850 int pos
, pSize
, pOffset
;
1852 pSize
= pOffset
= 0;
1855 while (pos
< offset
+ length
) {
1856 pos
= getOp(pos
, gFalse
, &parsedOk
);
1860 if (!ops
[nOps
- 1].isNum
) {
1861 if (ops
[nOps
- 1].op
== 0x0012) {
1866 pSize
= (int)ops
[0].num
;
1867 pOffset
= (int)ops
[1].num
;
1873 readPrivateDict(pOffset
, pSize
, pDict
);
1876 void FoFiType1C::readPrivateDict(int offset
, int length
,
1877 Type1CPrivateDict
*pDict
) {
1880 pDict
->nBlueValues
= 0;
1881 pDict
->nOtherBlues
= 0;
1882 pDict
->nFamilyBlues
= 0;
1883 pDict
->nFamilyOtherBlues
= 0;
1884 pDict
->blueScale
= 0.039625;
1885 pDict
->blueShift
= 7;
1886 pDict
->blueFuzz
= 1;
1887 pDict
->hasStdHW
= gFalse
;
1888 pDict
->hasStdVW
= gFalse
;
1889 pDict
->nStemSnapH
= 0;
1890 pDict
->nStemSnapV
= 0;
1891 pDict
->hasForceBold
= gFalse
;
1892 pDict
->forceBoldThreshold
= 0;
1893 pDict
->languageGroup
= 0;
1894 pDict
->expansionFactor
= 0.06;
1895 pDict
->initialRandomSeed
= 0;
1896 pDict
->subrsOffset
= 0;
1897 pDict
->defaultWidthX
= 0;
1898 pDict
->defaultWidthXFP
= 0;
1899 pDict
->nominalWidthX
= 0;
1900 pDict
->nominalWidthXFP
= 0;
1903 if (offset
== 0 || length
== 0) {
1909 while (pos
< offset
+ length
) {
1910 pos
= getOp(pos
, gFalse
, &parsedOk
);
1914 if (!ops
[nOps
- 1].isNum
) {
1915 --nOps
; // drop the operator
1916 switch (ops
[nOps
].op
) {
1918 pDict
->nBlueValues
= getDeltaIntArray(pDict
->blueValues
,
1919 type1CMaxBlueValues
);
1922 pDict
->nOtherBlues
= getDeltaIntArray(pDict
->otherBlues
,
1923 type1CMaxOtherBlues
);
1926 pDict
->nFamilyBlues
= getDeltaIntArray(pDict
->familyBlues
,
1927 type1CMaxBlueValues
);
1930 pDict
->nFamilyOtherBlues
= getDeltaIntArray(pDict
->familyOtherBlues
,
1931 type1CMaxOtherBlues
);
1934 pDict
->blueScale
= ops
[0].num
;
1937 pDict
->blueShift
= (int)ops
[0].num
;
1940 pDict
->blueFuzz
= (int)ops
[0].num
;
1943 pDict
->stdHW
= ops
[0].num
;
1944 pDict
->hasStdHW
= gTrue
;
1947 pDict
->stdVW
= ops
[0].num
;
1948 pDict
->hasStdVW
= gTrue
;
1951 pDict
->nStemSnapH
= getDeltaFPArray(pDict
->stemSnapH
,
1955 pDict
->nStemSnapV
= getDeltaFPArray(pDict
->stemSnapV
,
1959 pDict
->forceBold
= ops
[0].num
!= 0;
1960 pDict
->hasForceBold
= gTrue
;
1963 pDict
->forceBoldThreshold
= ops
[0].num
;
1966 pDict
->languageGroup
= (int)ops
[0].num
;
1969 pDict
->expansionFactor
= ops
[0].num
;
1972 pDict
->initialRandomSeed
= (int)ops
[0].num
;
1975 pDict
->subrsOffset
= offset
+ (int)ops
[0].num
;
1978 pDict
->defaultWidthX
= ops
[0].num
;
1981 pDict
->nominalWidthX
= ops
[0].num
;
1989 void FoFiType1C::readFDSelect() {
1990 int fdSelectFmt
, pos
, nRanges
, gid0
, gid1
, fd
, i
, j
;
1992 fdSelect
= (Guchar
*)gmalloc(nGlyphs
);
1993 if (topDict
.fdSelectOffset
== 0) {
1994 for (i
= 0; i
< nGlyphs
; ++i
) {
1998 pos
= topDict
.fdSelectOffset
;
1999 fdSelectFmt
= getU8(pos
++, &parsedOk
);
2003 if (fdSelectFmt
== 0) {
2004 if (!checkRegion(pos
, nGlyphs
)) {
2008 memcpy(fdSelect
, file
+ pos
, nGlyphs
);
2009 } else if (fdSelectFmt
== 3) {
2010 nRanges
= getU16BE(pos
, &parsedOk
);
2012 gid0
= getU16BE(pos
, &parsedOk
);
2014 for (i
= 1; i
<= nRanges
; ++i
) {
2015 fd
= getU8(pos
++, &parsedOk
);
2016 gid1
= getU16BE(pos
, &parsedOk
);
2021 if (gid0
> gid1
|| gid1
> nGlyphs
) {
2022 //~ error(-1, "Bad FDSelect table in CID font");
2026 for (j
= gid0
; j
< gid1
; ++j
) {
2032 //~ error(-1, "Unknown FDSelect table format in CID font");
2033 for (i
= 0; i
< nGlyphs
; ++i
) {
2040 void FoFiType1C::buildEncoding() {
2042 int nCodes
, nRanges
, encFormat
;
2043 int pos
, c
, sid
, nLeft
, nSups
, i
, j
;
2045 if (topDict
.encodingOffset
== 0) {
2046 encoding
= fofiType1StandardEncoding
;
2048 } else if (topDict
.encodingOffset
== 1) {
2049 encoding
= fofiType1ExpertEncoding
;
2052 encoding
= (char **)gmalloc(256 * sizeof(char *));
2053 for (i
= 0; i
< 256; ++i
) {
2056 pos
= topDict
.encodingOffset
;
2057 encFormat
= getU8(pos
++, &parsedOk
);
2061 if ((encFormat
& 0x7f) == 0) {
2062 nCodes
= 1 + getU8(pos
++, &parsedOk
);
2066 if (nCodes
> nGlyphs
) {
2069 for (i
= 1; i
< nCodes
; ++i
) {
2070 c
= getU8(pos
++, &parsedOk
);
2077 encoding
[c
] = copyString(getString(charset
[i
], buf
, &parsedOk
));
2079 } else if ((encFormat
& 0x7f) == 1) {
2080 nRanges
= getU8(pos
++, &parsedOk
);
2085 for (i
= 0; i
< nRanges
; ++i
) {
2086 c
= getU8(pos
++, &parsedOk
);
2087 nLeft
= getU8(pos
++, &parsedOk
);
2091 for (j
= 0; j
<= nLeft
&& nCodes
< nGlyphs
; ++j
) {
2096 encoding
[c
] = copyString(getString(charset
[nCodes
], buf
,
2104 if (encFormat
& 0x80) {
2105 nSups
= getU8(pos
++, &parsedOk
);
2109 for (i
= 0; i
< nSups
; ++i
) {
2110 c
= getU8(pos
++, &parsedOk
);;
2114 sid
= getU16BE(pos
, &parsedOk
);
2122 encoding
[c
] = copyString(getString(sid
, buf
, &parsedOk
));
2128 GBool
FoFiType1C::readCharset() {
2129 int charsetFormat
, c
, pos
;
2132 if (topDict
.charsetOffset
== 0) {
2133 charset
= fofiType1CISOAdobeCharset
;
2134 } else if (topDict
.charsetOffset
== 1) {
2135 charset
= fofiType1CExpertCharset
;
2136 } else if (topDict
.charsetOffset
== 2) {
2137 charset
= fofiType1CExpertSubsetCharset
;
2139 charset
= (Gushort
*)gmalloc(nGlyphs
* sizeof(Gushort
));
2140 for (i
= 0; i
< nGlyphs
; ++i
) {
2143 pos
= topDict
.charsetOffset
;
2144 charsetFormat
= getU8(pos
++, &parsedOk
);
2145 if (charsetFormat
== 0) {
2146 for (i
= 1; i
< nGlyphs
; ++i
) {
2147 charset
[i
] = (Gushort
)getU16BE(pos
, &parsedOk
);
2153 } else if (charsetFormat
== 1) {
2155 while (i
< nGlyphs
) {
2156 c
= getU16BE(pos
, &parsedOk
);
2158 nLeft
= getU8(pos
++, &parsedOk
);
2162 for (j
= 0; j
<= nLeft
&& i
< nGlyphs
; ++j
) {
2163 charset
[i
++] = (Gushort
)c
++;
2166 } else if (charsetFormat
== 2) {
2168 while (i
< nGlyphs
) {
2169 c
= getU16BE(pos
, &parsedOk
);
2171 nLeft
= getU16BE(pos
, &parsedOk
);
2176 for (j
= 0; j
<= nLeft
&& i
< nGlyphs
; ++j
) {
2177 charset
[i
++] = (Gushort
)c
++;
2190 int FoFiType1C::getOp(int pos
, GBool charstring
, GBool
*ok
) {
2191 static char nybChars
[16] = "0123456789.ee -";
2194 int b0
, b1
, nyb0
, nyb1
, x
, i
;
2196 b0
= getU8(pos
++, ok
);
2201 x
= getU8(pos
++, ok
);
2202 x
= (x
<< 8) | getU8(pos
++, ok
);
2208 } else if (!charstring
&& b0
== 29) {
2209 x
= getU8(pos
++, ok
);
2210 x
= (x
<< 8) | getU8(pos
++, ok
);
2211 x
= (x
<< 8) | getU8(pos
++, ok
);
2212 x
= (x
<< 8) | getU8(pos
++, ok
);
2213 if (x
& 0x80000000) {
2218 } else if (!charstring
&& b0
== 30) {
2221 b1
= getU8(pos
++, ok
);
2227 buf
[i
++] = nybChars
[nyb0
];
2240 buf
[i
++] = nybChars
[nyb1
];
2252 } else if (b0
>= 32 && b0
<= 246) {
2255 } else if (b0
>= 247 && b0
<= 250) {
2256 op
.num
= ((b0
- 247) << 8) + getU8(pos
++, ok
) + 108;
2258 } else if (b0
>= 251 && b0
<= 254) {
2259 op
.num
= -((b0
- 251) << 8) - getU8(pos
++, ok
) - 108;
2261 } else if (charstring
&& b0
== 255) {
2262 x
= getU8(pos
++, ok
);
2263 x
= (x
<< 8) | getU8(pos
++, ok
);
2264 x
= (x
<< 8) | getU8(pos
++, ok
);
2265 x
= (x
<< 8) | getU8(pos
++, ok
);
2266 if (x
& 0x80000000) {
2269 op
.num
= (double)x
/ 65536.0;
2272 } else if (b0
== 12) {
2274 op
.op
= 0x0c00 + getU8(pos
++, ok
);
2288 // Convert the delta-encoded ops array to an array of ints.
2289 int FoFiType1C::getDeltaIntArray(int *arr
, int maxLen
) {
2293 if ((n
= nOps
) > maxLen
) {
2297 for (i
= 0; i
< n
; ++i
) {
2298 x
+= (int)ops
[i
].num
;
2304 // Convert the delta-encoded ops array to an array of doubles.
2305 int FoFiType1C::getDeltaFPArray(double *arr
, int maxLen
) {
2309 if ((n
= nOps
) > maxLen
) {
2313 for (i
= 0; i
< n
; ++i
) {
2320 void FoFiType1C::getIndex(int pos
, Type1CIndex
*idx
, GBool
*ok
) {
2322 idx
->len
= getU16BE(pos
, ok
);
2323 if (idx
->len
== 0) {
2324 // empty indexes are legal
2326 idx
->startPos
= idx
->endPos
= 0;
2328 idx
->offSize
= getU8(pos
+ 2, ok
);
2329 if (idx
->offSize
< 1 || idx
->offSize
> 4) {
2332 idx
->startPos
= pos
+ 3 + (idx
->len
+ 1) * idx
->offSize
- 1;
2333 if (idx
->startPos
< 0 || idx
->startPos
>= len
) {
2336 idx
->endPos
= idx
->startPos
+ getUVarBE(pos
+ 3 + idx
->len
* idx
->offSize
,
2338 if (idx
->endPos
< idx
->startPos
|| idx
->endPos
> len
) {
2344 void FoFiType1C::getIndexVal(Type1CIndex
*idx
, int i
,
2345 Type1CIndexVal
*val
, GBool
*ok
) {
2348 if (i
< 0 || i
>= idx
->len
) {
2352 pos0
= idx
->startPos
+ getUVarBE(idx
->pos
+ 3 + i
* idx
->offSize
,
2354 pos1
= idx
->startPos
+ getUVarBE(idx
->pos
+ 3 + (i
+ 1) * idx
->offSize
,
2356 if (pos0
< idx
->startPos
|| pos0
>= idx
->endPos
||
2357 pos1
<= idx
->startPos
|| pos1
> idx
->endPos
||
2362 val
->len
= pos1
- pos0
;
2365 char *FoFiType1C::getString(int sid
, char *buf
, GBool
*ok
) {
2370 strcpy(buf
, fofiType1CStdStrings
[sid
]);
2373 getIndexVal(&stringIdx
, sid
, &val
, ok
);
2375 if ((n
= val
.len
) > 255) {
2378 strncpy(buf
, (char *)&file
[val
.pos
], n
);