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 *)gmallocn(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;
235 fprintf(stderr, "convertToType1: Warning: No Encoding\n");
237 for (i = 0; i < 256; ++i) {
239 sprintf(buf, "dup %d /%s put\n", i, enc[i]);
240 (*outputFunc)(outputStream, buf, strlen(buf));
243 (*outputFunc)(outputStream, "readonly def\n", 13);
245 (*outputFunc)(outputStream, "currentdict end\n", 16);
247 // start the binary section
248 (*outputFunc)(outputStream, "currentfile eexec\n", 18);
249 eb.outputFunc = outputFunc;
250 eb.outputStream = outputStream;
255 // write the private dictionary
256 eexecWrite(&eb, "\x83\xca\x73\xd5");
257 eexecWrite(&eb, "dup /Private 32 dict dup begin\n");
258 eexecWrite(&eb, "/RD {string currentfile exch readstring pop}"
259 " executeonly def\n");
260 eexecWrite(&eb, "/ND {noaccess def} executeonly def\n");
261 eexecWrite(&eb, "/NP {noaccess put} executeonly def\n");
262 eexecWrite(&eb, "/MinFeature {16 16} def\n");
263 eexecWrite(&eb, "/password 5839 def\n");
264 if (privateDicts[0].nBlueValues) {
265 eexecWrite(&eb, "/BlueValues [");
266 for (i = 0; i < privateDicts[0].nBlueValues; ++i) {
267 sprintf(buf, "%s%d", i > 0 ? " " : "", privateDicts[0].blueValues[i]);
268 eexecWrite(&eb, buf);
270 eexecWrite(&eb, "] def\n");
272 if (privateDicts[0].nOtherBlues) {
273 eexecWrite(&eb, "/OtherBlues [");
274 for (i = 0; i < privateDicts[0].nOtherBlues; ++i) {
275 sprintf(buf, "%s%d", i > 0 ? " " : "", privateDicts[0].otherBlues[i]);
276 eexecWrite(&eb, buf);
278 eexecWrite(&eb, "] def\n");
280 if (privateDicts[0].nFamilyBlues) {
281 eexecWrite(&eb, "/FamilyBlues [");
282 for (i = 0; i < privateDicts[0].nFamilyBlues; ++i) {
283 sprintf(buf, "%s%d", i > 0 ? " " : "", privateDicts[0].familyBlues[i]);
284 eexecWrite(&eb, buf);
286 eexecWrite(&eb, "] def\n");
288 if (privateDicts[0].nFamilyOtherBlues) {
289 eexecWrite(&eb, "/FamilyOtherBlues [");
290 for (i = 0; i < privateDicts[0].nFamilyOtherBlues; ++i) {
291 sprintf(buf, "%s%d", i > 0 ? " " : "",
292 privateDicts[0].familyOtherBlues[i]);
293 eexecWrite(&eb, buf);
295 eexecWrite(&eb, "] def\n");
297 if (privateDicts[0].blueScale != 0.039625) {
298 sprintf(buf, "/BlueScale %g def\n", privateDicts[0].blueScale);
299 eexecWrite(&eb, buf);
301 if (privateDicts[0].blueShift != 7) {
302 sprintf(buf, "/BlueShift %d def\n", privateDicts[0].blueShift);
303 eexecWrite(&eb, buf);
305 if (privateDicts[0].blueFuzz != 1) {
306 sprintf(buf, "/BlueFuzz %d def\n", privateDicts[0].blueFuzz);
307 eexecWrite(&eb, buf);
309 if (privateDicts[0].hasStdHW) {
310 sprintf(buf, "/StdHW [%g] def\n", privateDicts[0].stdHW);
311 eexecWrite(&eb, buf);
313 if (privateDicts[0].hasStdVW) {
314 sprintf(buf, "/StdVW [%g] def\n", privateDicts[0].stdVW);
315 eexecWrite(&eb, buf);
317 if (privateDicts[0].nStemSnapH) {
318 eexecWrite(&eb, "/StemSnapH [");
319 for (i = 0; i < privateDicts[0].nStemSnapH; ++i) {
320 sprintf(buf, "%s%g", i > 0 ? " " : "", privateDicts[0].stemSnapH[i]);
321 eexecWrite(&eb, buf);
323 eexecWrite(&eb, "] def\n");
325 if (privateDicts[0].nStemSnapV) {
326 eexecWrite(&eb, "/StemSnapV [");
327 for (i = 0; i < privateDicts[0].nStemSnapV; ++i) {
328 sprintf(buf, "%s%g", i > 0 ? " " : "", privateDicts[0].stemSnapV[i]);
329 eexecWrite(&eb, buf);
331 eexecWrite(&eb, "] def\n");
333 if (privateDicts[0].hasForceBold) {
334 sprintf(buf, "/ForceBold %s def\n",
335 privateDicts[0].forceBold ? "true" : "false");
336 eexecWrite(&eb, buf);
338 if (privateDicts[0].forceBoldThreshold != 0) {
339 sprintf(buf, "/ForceBoldThreshold %g def\n",
340 privateDicts[0].forceBoldThreshold);
341 eexecWrite(&eb, buf);
343 if (privateDicts[0].languageGroup != 0) {
344 sprintf(buf, "/LanguageGroup %d def\n", privateDicts[0].languageGroup);
345 eexecWrite(&eb, buf);
347 if (privateDicts[0].expansionFactor != 0.06) {
348 sprintf(buf, "/ExpansionFactor %g def\n", privateDicts[0].expansionFactor);
349 eexecWrite(&eb, buf);
352 // set up subroutines
354 getIndex(privateDicts[0].subrsOffset, &subrIdx, &ok);
359 // write the CharStrings
360 sprintf(buf, "2 index /CharStrings %d dict dup begin\n", nGlyphs);
361 eexecWrite(&eb, buf);
362 for (i = 0; i < nGlyphs; ++i) {
364 getIndexVal(&charStringsIdx, i, &val, &ok);
366 getString(charset[i], buf, &ok);
368 eexecCvtGlyph(&eb, buf, val.pos, val.len, &subrIdx, &privateDicts[0]);
372 eexecWrite(&eb, "end\n");
373 eexecWrite(&eb, "end\n");
374 eexecWrite(&eb, "readonly put\n");
375 eexecWrite(&eb, "noaccess put\n");
376 eexecWrite(&eb, "dup /FontName get exch definefont pop\n");
377 eexecWrite(&eb, "mark currentfile closefile\n");
380 if (ascii && eb.line > 0) {
381 (*outputFunc)(outputStream, "\n", 1);
383 for (i = 0; i < 8; ++i) {
384 (*outputFunc)(outputStream, "0000000000000000000000000000000000000000000000000000000000000000\n", 65);
386 (*outputFunc)(outputStream, "cleartomark\n", 12);
389 void FoFiType1C::convertToCIDType0(char *psName,
390 FoFiOutputFunc outputFunc,
391 void *outputStream) {
393 GString *charStrings;
394 int *charStringOffsets;
398 char buf[512], buf2[512];
400 int gid, offset, n, i, j, k;
402 // compute the CID count and build the CID-to-GID mapping
404 for (i = 0; i < nGlyphs; ++i) {
405 if (charset[i] >= nCIDs) {
406 nCIDs = charset[i] + 1;
409 cidMap = (int *)gmallocn(nCIDs, sizeof(int));
410 for (i = 0; i < nCIDs; ++i) {
413 for (i = 0; i < nGlyphs; ++i) {
414 cidMap[charset[i]] = i;
417 // build the charstrings
418 charStrings = new GString();
419 charStringOffsets = (int *)gmallocn(nCIDs + 1, sizeof(int));
420 for (i = 0; i < nCIDs; ++i) {
421 charStringOffsets[i] = charStrings->getLength();
422 if ((gid = cidMap[i]) >= 0) {
424 getIndexVal(&charStringsIdx, gid, &val, &ok);
426 getIndex(privateDicts[fdSelect[gid]].subrsOffset, &subrIdx, &ok);
430 cvtGlyph(val.pos, val.len, charStrings,
431 &subrIdx, &privateDicts[fdSelect[gid]], gTrue);
435 charStringOffsets[nCIDs] = charStrings->getLength();
437 // compute gdBytes = number of bytes needed for charstring offsets
438 // (offset size needs to account for the charstring offset table,
439 // with a worst case of five bytes per entry, plus the charstrings
441 i = (nCIDs + 1) * 5 + charStrings->getLength();
444 } else if (i < 0x10000) {
446 } else if (i < 0x1000000) {
452 // begin the font dictionary
453 (*outputFunc)(outputStream, "/CIDInit /ProcSet findresource begin\n", 37);
454 (*outputFunc)(outputStream, "20 dict begin\n", 14);
455 (*outputFunc)(outputStream, "/CIDFontName /", 14);
456 (*outputFunc)(outputStream, psName, strlen(psName));
457 (*outputFunc)(outputStream, " def\n", 5);
458 (*outputFunc)(outputStream, "/CIDFontType 0 def\n", 19);
459 (*outputFunc)(outputStream, "/CIDSystemInfo 3 dict dup begin\n", 32);
460 if (topDict.registrySID > 0 && topDict.orderingSID > 0) {
462 getString(topDict.registrySID, buf, &ok);
464 (*outputFunc)(outputStream, " /Registry (", 13);
465 (*outputFunc)(outputStream, buf, strlen(buf));
466 (*outputFunc)(outputStream, ") def\n", 6);
469 getString(topDict.orderingSID, buf, &ok);
471 (*outputFunc)(outputStream, " /Ordering (", 13);
472 (*outputFunc)(outputStream, buf, strlen(buf));
473 (*outputFunc)(outputStream, ") def\n", 6);
476 (*outputFunc)(outputStream, " /Registry (Adobe) def\n", 24);
477 (*outputFunc)(outputStream, " /Ordering (Identity) def\n", 27);
479 sprintf(buf, " /Supplement %d def\n", topDict.supplement);
480 (*outputFunc)(outputStream, buf, strlen(buf));
481 (*outputFunc)(outputStream, "end def\n", 8);
482 if (topDict.hasFontMatrix) {
483 sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n",
484 topDict.fontMatrix[0], topDict.fontMatrix[1],
485 topDict.fontMatrix[2], topDict.fontMatrix[3],
486 topDict.fontMatrix[4], topDict.fontMatrix[5]);
487 (*outputFunc)(outputStream, buf, strlen(buf));
488 } else if (privateDicts[0].hasFontMatrix) {
489 (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
491 (*outputFunc)(outputStream,
492 "/FontMatrix [0.001 0 0 0.001 0 0] def\n", 38);
494 sprintf(buf, "/FontBBox [%g %g %g %g] def\n",
495 topDict.fontBBox[0], topDict.fontBBox[1],
496 topDict.fontBBox[2], topDict.fontBBox[3]);
497 (*outputFunc)(outputStream, buf, strlen(buf));
498 (*outputFunc)(outputStream, "/FontInfo 1 dict dup begin\n", 27);
499 (*outputFunc)(outputStream, " /FSType 8 def\n", 16);
500 (*outputFunc)(outputStream, "end def\n", 8);
502 // CIDFont-specific entries
503 sprintf(buf, "/CIDCount %d def\n", nCIDs);
504 (*outputFunc)(outputStream, buf, strlen(buf));
505 (*outputFunc)(outputStream, "/FDBytes 1 def\n", 15);
506 sprintf(buf, "/GDBytes %d def\n", gdBytes);
507 (*outputFunc)(outputStream, buf, strlen(buf));
508 (*outputFunc)(outputStream, "/CIDMapOffset 0 def\n", 20);
509 if (topDict.paintType != 0) {
510 sprintf(buf, "/PaintType %d def\n", topDict.paintType);
511 (*outputFunc)(outputStream, buf, strlen(buf));
512 sprintf(buf, "/StrokeWidth %g def\n", topDict.strokeWidth);
513 (*outputFunc)(outputStream, buf, strlen(buf));
517 sprintf(buf, "/FDArray %d array\n", nFDs);
518 (*outputFunc)(outputStream, buf, strlen(buf));
519 for (i = 0; i < nFDs; ++i) {
520 sprintf(buf, "dup %d 10 dict begin\n", i);
521 (*outputFunc)(outputStream, buf, strlen(buf));
522 (*outputFunc)(outputStream, "/FontType 1 def\n", 16);
523 if (privateDicts[i].hasFontMatrix) {
524 sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n",
525 privateDicts[i].fontMatrix[0],
526 privateDicts[i].fontMatrix[1],
527 privateDicts[i].fontMatrix[2],
528 privateDicts[i].fontMatrix[3],
529 privateDicts[i].fontMatrix[4],
530 privateDicts[i].fontMatrix[5]);
531 (*outputFunc)(outputStream, buf, strlen(buf));
533 (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
535 sprintf(buf, "/PaintType %d def\n", topDict.paintType);
536 (*outputFunc)(outputStream, buf, strlen(buf));
537 (*outputFunc)(outputStream, "/Private 32 dict begin\n", 23);
538 if (privateDicts[i].nBlueValues) {
539 (*outputFunc)(outputStream, "/BlueValues [", 13);
540 for (j = 0; j < privateDicts[i].nBlueValues; ++j) {
541 sprintf(buf, "%s%d", j > 0 ? " " : "", privateDicts[i].blueValues[j]);
542 (*outputFunc)(outputStream, buf, strlen(buf));
544 (*outputFunc)(outputStream, "] def\n", 6);
546 if (privateDicts[i].nOtherBlues) {
547 (*outputFunc)(outputStream, "/OtherBlues [", 13);
548 for (j = 0; j < privateDicts[i].nOtherBlues; ++j) {
549 sprintf(buf, "%s%d", j > 0 ? " " : "", privateDicts[i].otherBlues[j]);
550 (*outputFunc)(outputStream, buf, strlen(buf));
552 (*outputFunc)(outputStream, "] def\n", 6);
554 if (privateDicts[i].nFamilyBlues) {
555 (*outputFunc)(outputStream, "/FamilyBlues [", 14);
556 for (j = 0; j < privateDicts[i].nFamilyBlues; ++j) {
557 sprintf(buf, "%s%d", j > 0 ? " " : "", privateDicts[i].familyBlues[j]);
558 (*outputFunc)(outputStream, buf, strlen(buf));
560 (*outputFunc)(outputStream, "] def\n", 6);
562 if (privateDicts[i].nFamilyOtherBlues) {
563 (*outputFunc)(outputStream, "/FamilyOtherBlues [", 19);
564 for (j = 0; j < privateDicts[i].nFamilyOtherBlues; ++j) {
565 sprintf(buf, "%s%d", j > 0 ? " " : "",
566 privateDicts[i].familyOtherBlues[j]);
567 (*outputFunc)(outputStream, buf, strlen(buf));
569 (*outputFunc)(outputStream, "] def\n", 6);
571 if (privateDicts[i].blueScale != 0.039625) {
572 sprintf(buf, "/BlueScale %g def\n", privateDicts[i].blueScale);
573 (*outputFunc)(outputStream, buf, strlen(buf));
575 if (privateDicts[i].blueShift != 7) {
576 sprintf(buf, "/BlueShift %d def\n", privateDicts[i].blueShift);
577 (*outputFunc)(outputStream, buf, strlen(buf));
579 if (privateDicts[i].blueFuzz != 1) {
580 sprintf(buf, "/BlueFuzz %d def\n", privateDicts[i].blueFuzz);
581 (*outputFunc)(outputStream, buf, strlen(buf));
583 if (privateDicts[i].hasStdHW) {
584 sprintf(buf, "/StdHW [%g] def\n", privateDicts[i].stdHW);
585 (*outputFunc)(outputStream, buf, strlen(buf));
587 if (privateDicts[i].hasStdVW) {
588 sprintf(buf, "/StdVW [%g] def\n", privateDicts[i].stdVW);
589 (*outputFunc)(outputStream, buf, strlen(buf));
591 if (privateDicts[i].nStemSnapH) {
592 (*outputFunc)(outputStream, "/StemSnapH [", 12);
593 for (j = 0; j < privateDicts[i].nStemSnapH; ++j) {
594 sprintf(buf, "%s%g", j > 0 ? " " : "", privateDicts[i].stemSnapH[j]);
595 (*outputFunc)(outputStream, buf, strlen(buf));
597 (*outputFunc)(outputStream, "] def\n", 6);
599 if (privateDicts[i].nStemSnapV) {
600 (*outputFunc)(outputStream, "/StemSnapV [", 12);
601 for (j = 0; j < privateDicts[i].nStemSnapV; ++j) {
602 sprintf(buf, "%s%g", j > 0 ? " " : "", privateDicts[i].stemSnapV[j]);
603 (*outputFunc)(outputStream, buf, strlen(buf));
605 (*outputFunc)(outputStream, "] def\n", 6);
607 if (privateDicts[i].hasForceBold) {
608 sprintf(buf, "/ForceBold %s def\n",
609 privateDicts[i].forceBold ? "true" : "false");
610 (*outputFunc)(outputStream, buf, strlen(buf));
612 if (privateDicts[i].forceBoldThreshold != 0) {
613 sprintf(buf, "/ForceBoldThreshold %g def\n",
614 privateDicts[i].forceBoldThreshold);
615 (*outputFunc)(outputStream, buf, strlen(buf));
617 if (privateDicts[i].languageGroup != 0) {
618 sprintf(buf, "/LanguageGroup %d def\n", privateDicts[i].languageGroup);
619 (*outputFunc)(outputStream, buf, strlen(buf));
621 if (privateDicts[i].expansionFactor != 0.06) {
622 sprintf(buf, "/ExpansionFactor %g def\n",
623 privateDicts[i].expansionFactor);
624 (*outputFunc)(outputStream, buf, strlen(buf));
626 (*outputFunc)(outputStream, "currentdict end def\n", 20);
627 (*outputFunc)(outputStream, "currentdict end put\n", 20);
629 (*outputFunc)(outputStream, "def\n", 4);
631 // start the binary section
632 offset = (nCIDs + 1) * (1 + gdBytes);
633 sprintf(buf, "(Hex) %d StartData\n",
634 offset + charStrings->getLength());
635 (*outputFunc)(outputStream, buf, strlen(buf));
637 // write the charstring offset (CIDMap) table
638 for (i = 0; i <= nCIDs; i += 6) {
639 for (j = 0; j < 6 && i+j <= nCIDs; ++j) {
640 if (i+j < nCIDs && cidMap[i+j] >= 0) {
641 buf[0] = (char)fdSelect[cidMap[i+j]];
645 n = offset + charStringOffsets[i+j];
646 for (k = gdBytes; k >= 1; --k) {
647 buf[k] = (char)(n & 0xff);
650 for (k = 0; k <= gdBytes; ++k) {
651 sprintf(buf2, "%02x", buf[k] & 0xff);
652 (*outputFunc)(outputStream, buf2, 2);
655 (*outputFunc)(outputStream, "\n", 1);
658 // write the charstring data
659 n = charStrings->getLength();
660 for (i = 0; i < n; i += 32) {
661 for (j = 0; j < 32 && i+j < n; ++j) {
662 sprintf(buf, "%02x", charStrings->getChar(i+j) & 0xff);
663 (*outputFunc)(outputStream, buf, strlen(buf));
666 (*outputFunc)(outputStream, ">", 1);
668 (*outputFunc)(outputStream, "\n", 1);
671 gfree(charStringOffsets);
676 void FoFiType1C::convertToType0(char *psName,
677 FoFiOutputFunc outputFunc,
678 void *outputStream) {
688 // compute the CID count and build the CID-to-GID mapping
690 for (i = 0; i < nGlyphs; ++i) {
691 if (charset[i] >= nCIDs) {
692 nCIDs = charset[i] + 1;
695 cidMap = (int *)gmallocn(nCIDs, sizeof(int));
696 for (i = 0; i < nCIDs; ++i) {
699 for (i = 0; i < nGlyphs; ++i) {
700 cidMap[charset[i]] = i;
703 // write the descendant Type 1 fonts
704 for (i = 0; i < nCIDs; i += 256) {
706 //~ this assumes that all CIDs in this block have the same FD --
707 //~ to handle multiple FDs correctly, need to somehow divide the
710 for (j = 0; j < 256 && i+j < nCIDs; ++j) {
711 if (cidMap[i+j] >= 0) {
712 fd = fdSelect[cidMap[i+j]];
717 // font dictionary (unencrypted section)
718 (*outputFunc)(outputStream, "16 dict begin\n", 14);
719 (*outputFunc)(outputStream, "/FontName /", 11);
720 (*outputFunc)(outputStream, psName, strlen(psName));
721 sprintf(buf, "_%02x def\n", i >> 8);
722 (*outputFunc)(outputStream, buf, strlen(buf));
723 (*outputFunc)(outputStream, "/FontType 1 def\n", 16);
724 if (privateDicts[fd].hasFontMatrix) {
725 sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n",
726 privateDicts[fd].fontMatrix[0],
727 privateDicts[fd].fontMatrix[1],
728 privateDicts[fd].fontMatrix[2],
729 privateDicts[fd].fontMatrix[3],
730 privateDicts[fd].fontMatrix[4],
731 privateDicts[fd].fontMatrix[5]);
732 (*outputFunc)(outputStream, buf, strlen(buf));
733 } else if (topDict.hasFontMatrix) {
734 (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
736 (*outputFunc)(outputStream,
737 "/FontMatrix [0.001 0 0 0.001 0 0] def\n", 38);
739 sprintf(buf, "/FontBBox [%g %g %g %g] def\n",
740 topDict.fontBBox[0], topDict.fontBBox[1],
741 topDict.fontBBox[2], topDict.fontBBox[3]);
742 (*outputFunc)(outputStream, buf, strlen(buf));
743 sprintf(buf, "/PaintType %d def\n", topDict.paintType);
744 (*outputFunc)(outputStream, buf, strlen(buf));
745 if (topDict.paintType != 0) {
746 sprintf(buf, "/StrokeWidth %g def\n", topDict.strokeWidth);
747 (*outputFunc)(outputStream, buf, strlen(buf));
749 (*outputFunc)(outputStream, "/Encoding 256 array\n", 20);
750 for (j = 0; j < 256 && i+j < nCIDs; ++j) {
751 sprintf(buf, "dup %d /c%02x put\n", j, j);
752 (*outputFunc)(outputStream, buf, strlen(buf));
755 sprintf(buf, "%d 1 255 { 1 index exch /.notdef put } for\n", j);
756 (*outputFunc)(outputStream, buf, strlen(buf));
758 (*outputFunc)(outputStream, "readonly def\n", 13);
759 (*outputFunc)(outputStream, "currentdict end\n", 16);
761 // start the binary section
762 (*outputFunc)(outputStream, "currentfile eexec\n", 18);
763 eb.outputFunc = outputFunc;
764 eb.outputStream = outputStream;
769 // start the private dictionary
770 eexecWrite(&eb, "\x83\xca\x73\xd5");
771 eexecWrite(&eb, "dup /Private 32 dict dup begin\n");
772 eexecWrite(&eb, "/RD {string currentfile exch readstring pop}"
773 " executeonly def\n");
774 eexecWrite(&eb, "/ND {noaccess def} executeonly def\n");
775 eexecWrite(&eb, "/NP {noaccess put} executeonly def\n");
776 eexecWrite(&eb, "/MinFeature {16 16} def\n");
777 eexecWrite(&eb, "/password 5839 def\n");
778 if (privateDicts[fd].nBlueValues) {
779 eexecWrite(&eb, "/BlueValues [");
780 for (k = 0; k < privateDicts[fd].nBlueValues; ++k) {
781 sprintf(buf, "%s%d", k > 0 ? " " : "", privateDicts[fd].blueValues[k]);
782 eexecWrite(&eb, buf);
784 eexecWrite(&eb, "] def\n");
786 if (privateDicts[fd].nOtherBlues) {
787 eexecWrite(&eb, "/OtherBlues [");
788 for (k = 0; k < privateDicts[fd].nOtherBlues; ++k) {
789 sprintf(buf, "%s%d", k > 0 ? " " : "", privateDicts[fd].otherBlues[k]);
790 eexecWrite(&eb, buf);
792 eexecWrite(&eb, "] def\n");
794 if (privateDicts[fd].nFamilyBlues) {
795 eexecWrite(&eb, "/FamilyBlues [");
796 for (k = 0; k < privateDicts[fd].nFamilyBlues; ++k) {
797 sprintf(buf, "%s%d", k > 0 ? " " : "",
798 privateDicts[fd].familyBlues[k]);
799 eexecWrite(&eb, buf);
801 eexecWrite(&eb, "] def\n");
803 if (privateDicts[fd].nFamilyOtherBlues) {
804 eexecWrite(&eb, "/FamilyOtherBlues [");
805 for (k = 0; k < privateDicts[fd].nFamilyOtherBlues; ++k) {
806 sprintf(buf, "%s%d", k > 0 ? " " : "",
807 privateDicts[fd].familyOtherBlues[k]);
808 eexecWrite(&eb, buf);
810 eexecWrite(&eb, "] def\n");
812 if (privateDicts[fd].blueScale != 0.039625) {
813 sprintf(buf, "/BlueScale %g def\n", privateDicts[fd].blueScale);
814 eexecWrite(&eb, buf);
816 if (privateDicts[fd].blueShift != 7) {
817 sprintf(buf, "/BlueShift %d def\n", privateDicts[fd].blueShift);
818 eexecWrite(&eb, buf);
820 if (privateDicts[fd].blueFuzz != 1) {
821 sprintf(buf, "/BlueFuzz %d def\n", privateDicts[fd].blueFuzz);
822 eexecWrite(&eb, buf);
824 if (privateDicts[fd].hasStdHW) {
825 sprintf(buf, "/StdHW [%g] def\n", privateDicts[fd].stdHW);
826 eexecWrite(&eb, buf);
828 if (privateDicts[fd].hasStdVW) {
829 sprintf(buf, "/StdVW [%g] def\n", privateDicts[fd].stdVW);
830 eexecWrite(&eb, buf);
832 if (privateDicts[fd].nStemSnapH) {
833 eexecWrite(&eb, "/StemSnapH [");
834 for (k = 0; k < privateDicts[fd].nStemSnapH; ++k) {
835 sprintf(buf, "%s%g", k > 0 ? " " : "", privateDicts[fd].stemSnapH[k]);
836 eexecWrite(&eb, buf);
838 eexecWrite(&eb, "] def\n");
840 if (privateDicts[fd].nStemSnapV) {
841 eexecWrite(&eb, "/StemSnapV [");
842 for (k = 0; k < privateDicts[fd].nStemSnapV; ++k) {
843 sprintf(buf, "%s%g", k > 0 ? " " : "", privateDicts[fd].stemSnapV[k]);
844 eexecWrite(&eb, buf);
846 eexecWrite(&eb, "] def\n");
848 if (privateDicts[fd].hasForceBold) {
849 sprintf(buf, "/ForceBold %s def\n",
850 privateDicts[fd].forceBold ? "true" : "false");
851 eexecWrite(&eb, buf);
853 if (privateDicts[fd].forceBoldThreshold != 0) {
854 sprintf(buf, "/ForceBoldThreshold %g def\n",
855 privateDicts[fd].forceBoldThreshold);
856 eexecWrite(&eb, buf);
858 if (privateDicts[fd].languageGroup != 0) {
859 sprintf(buf, "/LanguageGroup %d def\n", privateDicts[fd].languageGroup);
860 eexecWrite(&eb, buf);
862 if (privateDicts[fd].expansionFactor != 0.06) {
863 sprintf(buf, "/ExpansionFactor %g def\n",
864 privateDicts[fd].expansionFactor);
865 eexecWrite(&eb, buf);
868 // set up the subroutines
870 getIndex(privateDicts[fd].subrsOffset, &subrIdx, &ok);
875 // start the CharStrings
876 sprintf(buf, "2 index /CharStrings 256 dict dup begin\n");
877 eexecWrite(&eb, buf);
879 // write the .notdef CharString
881 getIndexVal(&charStringsIdx, 0, &val, &ok);
883 eexecCvtGlyph(&eb, ".notdef", val.pos, val.len,
884 &subrIdx, &privateDicts[fd]);
887 // write the CharStrings
888 for (j = 0; j < 256 && i+j < nCIDs; ++j) {
889 if (cidMap[i+j] >= 0) {
891 getIndexVal(&charStringsIdx, cidMap[i+j], &val, &ok);
893 sprintf(buf, "c%02x", j);
894 eexecCvtGlyph(&eb, buf, val.pos, val.len,
895 &subrIdx, &privateDicts[fd]);
899 eexecWrite(&eb, "end\n");
900 eexecWrite(&eb, "end\n");
901 eexecWrite(&eb, "readonly put\n");
902 eexecWrite(&eb, "noaccess put\n");
903 eexecWrite(&eb, "dup /FontName get exch definefont pop\n");
904 eexecWrite(&eb, "mark currentfile closefile\n");
908 (*outputFunc)(outputStream, "\n", 1);
910 for (j = 0; j < 8; ++j) {
911 (*outputFunc)(outputStream, "0000000000000000000000000000000000000000000000000000000000000000\n", 65);
913 (*outputFunc)(outputStream, "cleartomark\n", 12);
916 // write the Type 0 parent font
917 (*outputFunc)(outputStream, "16 dict begin\n", 14);
918 (*outputFunc)(outputStream, "/FontName /", 11);
919 (*outputFunc)(outputStream, psName, strlen(psName));
920 (*outputFunc)(outputStream, " def\n", 5);
921 (*outputFunc)(outputStream, "/FontType 0 def\n", 16);
922 if (topDict.hasFontMatrix) {
923 sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n",
924 topDict.fontMatrix[0], topDict.fontMatrix[1],
925 topDict.fontMatrix[2], topDict.fontMatrix[3],
926 topDict.fontMatrix[4], topDict.fontMatrix[5]);
927 (*outputFunc)(outputStream, buf, strlen(buf));
929 (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
931 (*outputFunc)(outputStream, "/FMapType 2 def\n", 16);
932 (*outputFunc)(outputStream, "/Encoding [\n", 12);
933 for (i = 0; i < nCIDs; i += 256) {
934 sprintf(buf, "%d\n", i >> 8);
935 (*outputFunc)(outputStream, buf, strlen(buf));
937 (*outputFunc)(outputStream, "] def\n", 6);
938 (*outputFunc)(outputStream, "/FDepVector [\n", 14);
939 for (i = 0; i < nCIDs; i += 256) {
940 (*outputFunc)(outputStream, "/", 1);
941 (*outputFunc)(outputStream, psName, strlen(psName));
942 sprintf(buf, "_%02x findfont\n", i >> 8);
943 (*outputFunc)(outputStream, buf, strlen(buf));
945 (*outputFunc)(outputStream, "] def\n", 6);
946 (*outputFunc)(outputStream, "FontName currentdict end definefont pop\n", 40);
951 void FoFiType1C::eexecCvtGlyph(Type1CEexecBuf *eb, char *glyphName,
952 int offset, int nBytes,
953 Type1CIndex *subrIdx,
954 Type1CPrivateDict *pDict) {
958 // generate the charstring
959 charBuf = new GString();
960 cvtGlyph(offset, nBytes, charBuf, subrIdx, pDict, gTrue);
962 sprintf(buf, "/%s %d RD ", glyphName, charBuf->getLength());
964 eexecWriteCharstring(eb, (Guchar *)charBuf->getCString(),
965 charBuf->getLength());
966 eexecWrite(eb, " ND\n");
971 void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
972 Type1CIndex *subrIdx, Type1CPrivateDict *pDict,
979 int pos, subrBias, start, i, k;
981 start = charBuf->getLength();
983 charBuf->append((char)73);
984 charBuf->append((char)58);
985 charBuf->append((char)147);
986 charBuf->append((char)134);
994 while (pos < offset + nBytes) {
996 pos = getOp(pos, gTrue, &ok);
1000 if (!ops[nOps - 1].isNum) {
1001 --nOps; // drop the operator
1002 switch (ops[nOps].op) {
1003 case 0x0001: // hstem
1005 cvtGlyphWidth(nOps & 1, charBuf, pDict);
1009 //~ error(-1, "Wrong number of args (%d) to Type 2 hstem", nOps);
1013 for (k = 0; k < nOps; k += 2) {
1014 // convert Type 2 edge hints (-20 or -21) to Type 1 ghost hints
1015 if (ops[k+1].num < 0) {
1016 d += ops[k].num + ops[k+1].num;
1017 dFP |= ops[k].isFP | ops[k+1].isFP;
1018 cvtNum(d, dFP, charBuf);
1019 cvtNum(-ops[k+1].num, ops[k+1].isFP, charBuf);
1023 cvtNum(d, dFP, charBuf);
1024 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1026 dFP |= ops[k+1].isFP;
1028 charBuf->append((char)1);
1033 case 0x0003: // vstem
1035 cvtGlyphWidth(nOps & 1, charBuf, pDict);
1039 //~ error(-1, "Wrong number of args (%d) to Type 2 vstem", nOps);
1043 for (k = 0; k < nOps; k += 2) {
1044 // convert Type 2 edge hints (-20 or -21) to Type 1 ghost hints
1045 if (ops[k+1].num < 0) {
1046 d += ops[k].num + ops[k+1].num;
1047 dFP |= ops[k].isFP | ops[k+1].isFP;
1048 cvtNum(d, dFP, charBuf);
1049 cvtNum(-ops[k+1].num, ops[k+1].isFP, charBuf);
1053 cvtNum(d, dFP, charBuf);
1054 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1056 dFP |= ops[k+1].isFP;
1058 charBuf->append((char)3);
1063 case 0x0004: // vmoveto
1065 cvtGlyphWidth(nOps == 2, charBuf, pDict);
1069 charBuf->append((char)9);
1073 //~ error(-1, "Wrong number of args (%d) to Type 2 vmoveto", nOps);
1075 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1076 charBuf->append((char)4);
1079 case 0x0005: // rlineto
1080 if (nOps < 2 || nOps % 2 != 0) {
1081 //~ error(-1, "Wrong number of args (%d) to Type 2 rlineto", nOps);
1083 for (k = 0; k < nOps; k += 2) {
1084 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1085 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1086 charBuf->append((char)5);
1091 case 0x0006: // hlineto
1093 //~ error(-1, "Wrong number of args (%d) to Type 2 hlineto", nOps);
1095 for (k = 0; k < nOps; ++k) {
1096 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1097 charBuf->append((char)((k & 1) ? 7 : 6));
1102 case 0x0007: // vlineto
1104 //~ error(-1, "Wrong number of args (%d) to Type 2 vlineto", nOps);
1106 for (k = 0; k < nOps; ++k) {
1107 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1108 charBuf->append((char)((k & 1) ? 6 : 7));
1113 case 0x0008: // rrcurveto
1114 if (nOps < 6 || nOps % 6 != 0) {
1115 //~ error(-1, "Wrong number of args (%d) to Type 2 rrcurveto", nOps);
1117 for (k = 0; k < nOps; k += 6) {
1118 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1119 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1120 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1121 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1122 cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
1123 cvtNum(ops[k+5].num, ops[k+5].isFP, charBuf);
1124 charBuf->append((char)8);
1129 case 0x000a: // callsubr
1131 subrBias = (subrIdx->len < 1240)
1132 ? 107 : (subrIdx->len < 33900) ? 1131 : 32768;
1133 k = subrBias + (int)ops[nOps - 1].num;
1136 getIndexVal(subrIdx, k, &val, &ok);
1138 cvtGlyph(val.pos, val.len, charBuf, subrIdx, pDict, gFalse);
1141 //~ error(-1, "Too few args to Type 2 callsubr");
1143 // don't clear the stack
1145 case 0x000b: // return
1146 // don't clear the stack
1148 case 0x000e: // endchar / seac
1150 cvtGlyphWidth(nOps == 1 || nOps == 5, charBuf, pDict);
1154 charBuf->append((char)9);
1158 cvtNum(0, gFalse, charBuf);
1159 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1160 cvtNum(ops[1].num, ops[1].isFP, charBuf);
1161 cvtNum(ops[2].num, ops[2].isFP, charBuf);
1162 cvtNum(ops[3].num, ops[3].isFP, charBuf);
1163 charBuf->append((char)12)->append((char)6);
1164 } else if (nOps == 0) {
1165 charBuf->append((char)14);
1167 //~ error(-1, "Wrong number of args (%d) to Type 2 endchar", nOps);
1171 case 0x000f: // (obsolete)
1172 // this op is ignored, but we need the glyph width
1174 cvtGlyphWidth(nOps > 0, charBuf, pDict);
1179 case 0x0010: // blend
1180 //~ error(-1, "Unimplemented Type 2 charstring op: %d", file[i]);
1183 case 0x0012: // hstemhm
1186 cvtGlyphWidth(nOps & 1, charBuf, pDict);
1190 //~ error(-1, "Wrong number of args (%d) to Type 2 hstemhm", nOps);
1195 case 0x0013: // hintmask
1198 cvtGlyphWidth(nOps & 1, charBuf, pDict);
1203 //~ error(-1, "Wrong number of args (%d) to Type 2 hintmask/vstemhm",
1208 pos += (nHints + 7) >> 3;
1211 case 0x0014: // cntrmask
1214 cvtGlyphWidth(nOps & 1, charBuf, pDict);
1219 //~ error(-1, "Wrong number of args (%d) to Type 2 cntrmask/vstemhm",
1224 pos += (nHints + 7) >> 3;
1227 case 0x0015: // rmoveto
1229 cvtGlyphWidth(nOps == 3, charBuf, pDict);
1233 charBuf->append((char)9);
1237 //~ error(-1, "Wrong number of args (%d) to Type 2 rmoveto", nOps);
1239 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1240 cvtNum(ops[1].num, ops[1].isFP, charBuf);
1241 charBuf->append((char)21);
1244 case 0x0016: // hmoveto
1246 cvtGlyphWidth(nOps == 2, charBuf, pDict);
1250 charBuf->append((char)9);
1254 //~ error(-1, "Wrong number of args (%d) to Type 2 hmoveto", nOps);
1256 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1257 charBuf->append((char)22);
1260 case 0x0017: // vstemhm
1263 cvtGlyphWidth(nOps & 1, charBuf, pDict);
1267 //~ error(-1, "Wrong number of args (%d) to Type 2 vstemhm", nOps);
1272 case 0x0018: // rcurveline
1273 if (nOps < 8 || (nOps - 2) % 6 != 0) {
1274 //~ error(-1, "Wrong number of args (%d) to Type 2 rcurveline", nOps);
1276 for (k = 0; k < nOps - 2; k += 6) {
1277 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1278 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1279 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1280 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1281 cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
1282 cvtNum(ops[k+5].num, ops[k+5].isFP, charBuf);
1283 charBuf->append((char)8);
1285 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1286 cvtNum(ops[k+1].num, ops[k].isFP, charBuf);
1287 charBuf->append((char)5);
1291 case 0x0019: // rlinecurve
1292 if (nOps < 8 || (nOps - 6) % 2 != 0) {
1293 //~ error(-1, "Wrong number of args (%d) to Type 2 rlinecurve", nOps);
1295 for (k = 0; k < nOps - 6; k += 2) {
1296 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1297 cvtNum(ops[k+1].num, ops[k].isFP, charBuf);
1298 charBuf->append((char)5);
1300 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1301 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1302 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1303 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1304 cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
1305 cvtNum(ops[k+5].num, ops[k+5].isFP, charBuf);
1306 charBuf->append((char)8);
1310 case 0x001a: // vvcurveto
1311 if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) {
1312 //~ error(-1, "Wrong number of args (%d) to Type 2 vvcurveto", nOps);
1314 if (nOps % 2 == 1) {
1315 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1316 cvtNum(ops[1].num, ops[1].isFP, charBuf);
1317 cvtNum(ops[2].num, ops[2].isFP, charBuf);
1318 cvtNum(ops[3].num, ops[3].isFP, charBuf);
1319 cvtNum(0, gFalse, charBuf);
1320 cvtNum(ops[4].num, ops[4].isFP, charBuf);
1321 charBuf->append((char)8);
1326 for (; k < nOps; k += 4) {
1327 cvtNum(0, gFalse, charBuf);
1328 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1329 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1330 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1331 cvtNum(0, gFalse, charBuf);
1332 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1333 charBuf->append((char)8);
1338 case 0x001b: // hhcurveto
1339 if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) {
1340 //~ error(-1, "Wrong number of args (%d) to Type 2 hhcurveto", nOps);
1342 if (nOps % 2 == 1) {
1343 cvtNum(ops[1].num, ops[1].isFP, charBuf);
1344 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1345 cvtNum(ops[2].num, ops[2].isFP, charBuf);
1346 cvtNum(ops[3].num, ops[3].isFP, charBuf);
1347 cvtNum(ops[4].num, ops[4].isFP, charBuf);
1348 cvtNum(0, gFalse, charBuf);
1349 charBuf->append((char)8);
1354 for (; k < nOps; k += 4) {
1355 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1356 cvtNum(0, gFalse, charBuf);
1357 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1358 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1359 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1360 cvtNum(0, gFalse, charBuf);
1361 charBuf->append((char)8);
1366 case 0x001d: // callgsubr
1368 k = gsubrBias + (int)ops[nOps - 1].num;
1371 getIndexVal(&gsubrIdx, k, &val, &ok);
1373 cvtGlyph(val.pos, val.len, charBuf, subrIdx, pDict, gFalse);
1376 //~ error(-1, "Too few args to Type 2 callgsubr");
1378 // don't clear the stack
1380 case 0x001e: // vhcurveto
1381 if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) {
1382 //~ error(-1, "Wrong number of args (%d) to Type 2 vhcurveto", nOps);
1384 for (k = 0; k < nOps && k != nOps-5; k += 4) {
1386 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1387 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1388 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1389 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1390 charBuf->append((char)30);
1392 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1393 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1394 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1395 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1396 charBuf->append((char)31);
1401 cvtNum(0, gFalse, charBuf);
1402 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1403 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1404 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1405 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1406 cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
1408 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1409 cvtNum(0, gFalse, charBuf);
1410 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1411 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1412 cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
1413 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1415 charBuf->append((char)8);
1420 case 0x001f: // hvcurveto
1421 if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) {
1422 //~ error(-1, "Wrong number of args (%d) to Type 2 hvcurveto", nOps);
1424 for (k = 0; k < nOps && k != nOps-5; k += 4) {
1426 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1427 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1428 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1429 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1430 charBuf->append((char)31);
1432 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1433 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1434 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1435 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1436 charBuf->append((char)30);
1441 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1442 cvtNum(0, gFalse, charBuf);
1443 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1444 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1445 cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
1446 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1448 cvtNum(0, gFalse, charBuf);
1449 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1450 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1451 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1452 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1453 cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
1455 charBuf->append((char)8);
1460 case 0x0c00: // dotsection (should be Type 1 only?)
1467 case 0x0c08: // store
1472 case 0x0c0d: // load
1475 case 0x0c12: // drop
1478 case 0x0c16: // ifelse
1479 case 0x0c17: // random
1481 case 0x0c1a: // sqrt
1483 case 0x0c1c: // exch
1484 case 0x0c1d: // index
1485 case 0x0c1e: // roll
1486 //~ error(-1, "Unimplemented Type 2 charstring op: 12.%d", file[i+1]);
1489 case 0x0c22: // hflex
1491 //~ error(-1, "Wrong number of args (%d) to Type 2 hflex", nOps);
1493 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1494 cvtNum(0, gFalse, charBuf);
1495 cvtNum(ops[1].num, ops[1].isFP, charBuf);
1496 cvtNum(ops[2].num, ops[2].isFP, charBuf);
1497 cvtNum(ops[3].num, ops[3].isFP, charBuf);
1498 cvtNum(0, gFalse, charBuf);
1499 charBuf->append((char)8);
1500 cvtNum(ops[4].num, ops[4].isFP, charBuf);
1501 cvtNum(0, gFalse, charBuf);
1502 cvtNum(ops[5].num, ops[5].isFP, charBuf);
1503 cvtNum(-ops[2].num, ops[2].isFP, charBuf);
1504 cvtNum(ops[6].num, ops[6].isFP, charBuf);
1505 cvtNum(0, gFalse, charBuf);
1506 charBuf->append((char)8);
1510 case 0x0c23: // flex
1512 //~ error(-1, "Wrong number of args (%d) to Type 2 flex", nOps);
1514 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1515 cvtNum(ops[1].num, ops[1].isFP, charBuf);
1516 cvtNum(ops[2].num, ops[2].isFP, charBuf);
1517 cvtNum(ops[3].num, ops[3].isFP, charBuf);
1518 cvtNum(ops[4].num, ops[4].isFP, charBuf);
1519 cvtNum(ops[5].num, ops[5].isFP, charBuf);
1520 charBuf->append((char)8);
1521 cvtNum(ops[6].num, ops[6].isFP, charBuf);
1522 cvtNum(ops[7].num, ops[7].isFP, charBuf);
1523 cvtNum(ops[8].num, ops[8].isFP, charBuf);
1524 cvtNum(ops[9].num, ops[9].isFP, charBuf);
1525 cvtNum(ops[10].num, ops[10].isFP, charBuf);
1526 cvtNum(ops[11].num, ops[11].isFP, charBuf);
1527 charBuf->append((char)8);
1531 case 0x0c24: // hflex1
1533 //~ error(-1, "Wrong number of args (%d) to Type 2 hflex1", nOps);
1535 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1536 cvtNum(ops[1].num, ops[1].isFP, charBuf);
1537 cvtNum(ops[2].num, ops[2].isFP, charBuf);
1538 cvtNum(ops[3].num, ops[3].isFP, charBuf);
1539 cvtNum(ops[4].num, ops[4].isFP, charBuf);
1540 cvtNum(0, gFalse, charBuf);
1541 charBuf->append((char)8);
1542 cvtNum(ops[5].num, ops[5].isFP, charBuf);
1543 cvtNum(0, gFalse, charBuf);
1544 cvtNum(ops[6].num, ops[6].isFP, charBuf);
1545 cvtNum(ops[7].num, ops[7].isFP, charBuf);
1546 cvtNum(ops[8].num, ops[8].isFP, charBuf);
1547 cvtNum(-(ops[1].num + ops[3].num + ops[7].num),
1548 ops[1].isFP | ops[3].isFP | ops[7].isFP, charBuf);
1549 charBuf->append((char)8);
1553 case 0x0c25: // flex1
1555 //~ error(-1, "Wrong number of args (%d) to Type 2 flex1", nOps);
1557 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1558 cvtNum(ops[1].num, ops[1].isFP, charBuf);
1559 cvtNum(ops[2].num, ops[2].isFP, charBuf);
1560 cvtNum(ops[3].num, ops[3].isFP, charBuf);
1561 cvtNum(ops[4].num, ops[4].isFP, charBuf);
1562 cvtNum(ops[5].num, ops[5].isFP, charBuf);
1563 charBuf->append((char)8);
1564 cvtNum(ops[6].num, ops[6].isFP, charBuf);
1565 cvtNum(ops[7].num, ops[7].isFP, charBuf);
1566 cvtNum(ops[8].num, ops[8].isFP, charBuf);
1567 cvtNum(ops[9].num, ops[9].isFP, charBuf);
1568 dx = ops[0].num + ops[2].num + ops[4].num + ops[6].num + ops[8].num;
1569 dy = ops[1].num + ops[3].num + ops[5].num + ops[7].num + ops[9].num;
1570 if (fabs(dx) > fabs(dy)) {
1571 cvtNum(ops[10].num, ops[10].isFP, charBuf);
1572 cvtNum(-dy, ops[1].isFP | ops[3].isFP | ops[5].isFP |
1573 ops[7].isFP | ops[9].isFP, charBuf);
1575 cvtNum(-dx, ops[0].isFP | ops[2].isFP | ops[4].isFP |
1576 ops[6].isFP | ops[8].isFP, charBuf);
1577 cvtNum(ops[10].num, ops[10].isFP, charBuf);
1579 charBuf->append((char)8);
1584 //~ error(-1, "Illegal Type 2 charstring op: %04x",
1592 // charstring encryption
1595 for (i = start; i < charBuf->getLength(); ++i) {
1596 byte = charBuf->getChar(i) ^ (r2 >> 8);
1597 charBuf->setChar(i, byte);
1598 r2 = (byte + r2) * 52845 + 22719;
1603 void FoFiType1C::cvtGlyphWidth(GBool useOp, GString *charBuf,
1604 Type1CPrivateDict *pDict) {
1610 w = pDict->nominalWidthX + ops[0].num;
1611 wFP = pDict->nominalWidthXFP | ops[0].isFP;
1612 for (i = 1; i < nOps; ++i) {
1617 w = pDict->defaultWidthX;
1618 wFP = pDict->defaultWidthXFP;
1620 cvtNum(0, gFalse, charBuf);
1621 cvtNum(w, wFP, charBuf);
1622 charBuf->append((char)13);
1625 void FoFiType1C::cvtNum(double x, GBool isFP, GString *charBuf) {
1631 if (x >= -32768 && x < 32768) {
1632 y = (int)(x * 256.0);
1634 buf[1] = (Guchar)(y >> 24);
1635 buf[2] = (Guchar)(y >> 16);
1636 buf[3] = (Guchar)(y >> 8);
1647 //~ error(-1, "Type 2 fixed point constant out of range");
1651 if (y >= -107 && y <= 107) {
1652 buf[0] = (Guchar)(y + 139);
1654 } else if (y > 107 && y <= 1131) {
1656 buf[0] = (Guchar)((y >> 8) + 247);
1657 buf[1] = (Guchar)(y & 0xff);
1659 } else if (y < -107 && y >= -1131) {
1661 buf[0] = (Guchar)((y >> 8) + 251);
1662 buf[1] = (Guchar)(y & 0xff);
1666 buf[1] = (Guchar)(y >> 24);
1667 buf[2] = (Guchar)(y >> 16);
1668 buf[3] = (Guchar)(y >> 8);
1673 charBuf->append((char *)buf, n);
1676 void FoFiType1C::eexecWrite(Type1CEexecBuf *eb, char *s) {
1680 for (p = (Guchar *)s; *p; ++p) {
1681 x = *p ^ (eb->r1 >> 8);
1682 eb->r1 = (x + eb->r1) * 52845 + 22719;
1684 (*eb->outputFunc)(eb->outputStream, &hexChars[x >> 4], 1);
1685 (*eb->outputFunc)(eb->outputStream, &hexChars[x & 0x0f], 1);
1687 if (eb->line == 64) {
1688 (*eb->outputFunc)(eb->outputStream, "\n", 1);
1692 (*eb->outputFunc)(eb->outputStream, (char *)&x, 1);
1697 void FoFiType1C::eexecWriteCharstring(Type1CEexecBuf *eb,
1703 for (i = 0; i < n; ++i) {
1704 x = s[i] ^ (eb->r1 >> 8);
1705 eb->r1 = (x + eb->r1) * 52845 + 22719;
1707 (*eb->outputFunc)(eb->outputStream, &hexChars[x >> 4], 1);
1708 (*eb->outputFunc)(eb->outputStream, &hexChars[x & 0x0f], 1);
1710 if (eb->line == 64) {
1711 (*eb->outputFunc)(eb->outputStream, "\n", 1);
1715 (*eb->outputFunc)(eb->outputStream, (char *)&x, 1);
1720 GBool FoFiType1C::parse() {
1727 // some tools embed Type 1C fonts with an extra whitespace char at
1729 if (len > 0 && file[0] != '\x01') {
1735 getIndex(getU8(2, &parsedOk), &nameIdx, &parsedOk);
1736 getIndex(nameIdx.endPos, &topDictIdx, &parsedOk);
1737 getIndex(topDictIdx.endPos, &stringIdx, &parsedOk);
1738 getIndex(stringIdx.endPos, &gsubrIdx, &parsedOk);
1742 gsubrBias = (gsubrIdx.len < 1240) ? 107
1743 : (gsubrIdx.len < 33900) ? 1131 : 32768;
1745 // read the first font name
1746 getIndexVal(&nameIdx, 0, &val, &parsedOk);
1750 name = new GString((char *)&file[val.pos], val.len);
1752 // read the top dict for the first font
1755 // for CID fonts: read the FDArray dicts and private dicts
1756 if (topDict.firstOp == 0x0c1e) {
1757 if (topDict.fdArrayOffset == 0) {
1759 privateDicts = (Type1CPrivateDict *)gmalloc(sizeof(Type1CPrivateDict));
1760 readPrivateDict(0, 0, &privateDicts[0]);
1762 getIndex(topDict.fdArrayOffset, &fdIdx, &parsedOk);
1767 privateDicts = (Type1CPrivateDict *)
1768 gmallocn(nFDs, sizeof(Type1CPrivateDict));
1769 for (i = 0; i < nFDs; ++i) {
1770 getIndexVal(&fdIdx, i, &val, &parsedOk);
1774 readFD(val.pos, val.len, &privateDicts[i]);
1778 // for 8-bit fonts: read the private dict
1780 privateDicts = (Type1CPrivateDict *)gmalloc(sizeof(Type1CPrivateDict));
1781 readPrivateDict(topDict.privateOffset, topDict.privateSize,
1785 // check for parse errors in the private dict(s)
1790 // get the charstrings index
1791 if (topDict.charStringsOffset <= 0) {
1795 getIndex(topDict.charStringsOffset, &charStringsIdx, &parsedOk);
1799 nGlyphs = charStringsIdx.len;
1801 // for CID fonts: read the FDSelect table
1802 if (topDict.firstOp == 0x0c1e) {
1810 if (!readCharset()) {
1815 // for 8-bit fonts: build the encoding
1816 if (topDict.firstOp != 0x0c14 && topDict.firstOp != 0x0c1e) {
1826 void FoFiType1C::readTopDict() {
1827 Type1CIndexVal topDictPtr;
1830 topDict.firstOp = -1;
1831 topDict.versionSID = 0;
1832 topDict.noticeSID = 0;
1833 topDict.copyrightSID = 0;
1834 topDict.fullNameSID = 0;
1835 topDict.familyNameSID = 0;
1836 topDict.weightSID = 0;
1837 topDict.isFixedPitch = 0;
1838 topDict.italicAngle = 0;
1839 topDict.underlinePosition = -100;
1840 topDict.underlineThickness = 50;
1841 topDict.paintType = 0;
1842 topDict.charstringType = 2;
1843 topDict.fontMatrix[0] = 0.001;
1844 topDict.fontMatrix[1] = 0;
1845 topDict.fontMatrix[2] = 0;
1846 topDict.fontMatrix[3] = 0.001;
1847 topDict.fontMatrix[4] = 0;
1848 topDict.fontMatrix[5] = 0;
1849 topDict.hasFontMatrix = gFalse;
1850 topDict.uniqueID = 0;
1851 topDict.fontBBox[0] = 0;
1852 topDict.fontBBox[1] = 0;
1853 topDict.fontBBox[2] = 0;
1854 topDict.fontBBox[3] = 0;
1855 topDict.strokeWidth = 0;
1856 topDict.charsetOffset = 0;
1857 topDict.encodingOffset = 0;
1858 topDict.charStringsOffset = 0;
1859 topDict.privateSize = 0;
1860 topDict.privateOffset = 0;
1861 topDict.registrySID = 0;
1862 topDict.orderingSID = 0;
1863 topDict.supplement = 0;
1864 topDict.fdArrayOffset = 0;
1865 topDict.fdSelectOffset = 0;
1867 getIndexVal(&topDictIdx, 0, &topDictPtr, &parsedOk);
1868 pos = topDictPtr.pos;
1870 while (pos < topDictPtr.pos + topDictPtr.len) {
1871 pos = getOp(pos, gFalse, &parsedOk);
1875 if (!ops[nOps - 1].isNum) {
1876 --nOps; // drop the operator
1877 if (topDict.firstOp < 0) {
1878 topDict.firstOp = ops[nOps].op;
1880 switch (ops[nOps].op) {
1881 case 0x0000: topDict.versionSID = (int)ops[0].num; break;
1882 case 0x0001: topDict.noticeSID = (int)ops[0].num; break;
1883 case 0x0c00: topDict.copyrightSID = (int)ops[0].num; break;
1884 case 0x0002: topDict.fullNameSID = (int)ops[0].num; break;
1885 case 0x0003: topDict.familyNameSID = (int)ops[0].num; break;
1886 case 0x0004: topDict.weightSID = (int)ops[0].num; break;
1887 case 0x0c01: topDict.isFixedPitch = (int)ops[0].num; break;
1888 case 0x0c02: topDict.italicAngle = ops[0].num; break;
1889 case 0x0c03: topDict.underlinePosition = ops[0].num; break;
1890 case 0x0c04: topDict.underlineThickness = ops[0].num; break;
1891 case 0x0c05: topDict.paintType = (int)ops[0].num; break;
1892 case 0x0c06: topDict.charstringType = (int)ops[0].num; break;
1893 case 0x0c07: topDict.fontMatrix[0] = ops[0].num;
1894 topDict.fontMatrix[1] = ops[1].num;
1895 topDict.fontMatrix[2] = ops[2].num;
1896 topDict.fontMatrix[3] = ops[3].num;
1897 topDict.fontMatrix[4] = ops[4].num;
1898 topDict.fontMatrix[5] = ops[5].num;
1899 topDict.hasFontMatrix = gTrue; break;
1900 case 0x000d: topDict.uniqueID = (int)ops[0].num; break;
1901 case 0x0005: topDict.fontBBox[0] = ops[0].num;
1902 topDict.fontBBox[1] = ops[1].num;
1903 topDict.fontBBox[2] = ops[2].num;
1904 topDict.fontBBox[3] = ops[3].num; break;
1905 case 0x0c08: topDict.strokeWidth = ops[0].num; break;
1906 case 0x000f: topDict.charsetOffset = (int)ops[0].num; break;
1907 case 0x0010: topDict.encodingOffset = (int)ops[0].num; break;
1908 case 0x0011: topDict.charStringsOffset = (int)ops[0].num; break;
1909 case 0x0012: topDict.privateSize = (int)ops[0].num;
1910 topDict.privateOffset = (int)ops[1].num; break;
1911 case 0x0c1e: topDict.registrySID = (int)ops[0].num;
1912 topDict.orderingSID = (int)ops[1].num;
1913 topDict.supplement = (int)ops[2].num; break;
1914 case 0x0c24: topDict.fdArrayOffset = (int)ops[0].num; break;
1915 case 0x0c25: topDict.fdSelectOffset = (int)ops[0].num; break;
1922 // Read a CID font dict (FD) - this pulls out the private dict
1923 // pointer, and reads the private dict. It also pulls the FontMatrix
1924 // (if any) out of the FD.
1925 void FoFiType1C::readFD(int offset, int length, Type1CPrivateDict *pDict) {
1926 int pos, pSize, pOffset;
1927 double fontMatrix[6];
1928 GBool hasFontMatrix;
1930 hasFontMatrix = gFalse;
1931 pSize = pOffset = 0;
1934 while (pos < offset + length) {
1935 pos = getOp(pos, gFalse, &parsedOk);
1939 if (!ops[nOps - 1].isNum) {
1940 if (ops[nOps - 1].op == 0x0012) {
1945 pSize = (int)ops[0].num;
1946 pOffset = (int)ops[1].num;
1948 } else if (ops[nOps - 1].op == 0x0c07) {
1949 fontMatrix[0] = ops[0].num;
1950 fontMatrix[1] = ops[1].num;
1951 fontMatrix[2] = ops[2].num;
1952 fontMatrix[3] = ops[3].num;
1953 fontMatrix[4] = ops[4].num;
1954 fontMatrix[5] = ops[5].num;
1955 hasFontMatrix = gTrue;
1960 readPrivateDict(pOffset, pSize, pDict);
1961 if (hasFontMatrix) {
1962 pDict->fontMatrix[0] = fontMatrix[0];
1963 pDict->fontMatrix[1] = fontMatrix[1];
1964 pDict->fontMatrix[2] = fontMatrix[2];
1965 pDict->fontMatrix[3] = fontMatrix[3];
1966 pDict->fontMatrix[4] = fontMatrix[4];
1967 pDict->fontMatrix[5] = fontMatrix[5];
1968 pDict->hasFontMatrix = gTrue;
1972 void FoFiType1C::readPrivateDict(int offset, int length,
1973 Type1CPrivateDict *pDict) {
1976 pDict->hasFontMatrix = gFalse;
1977 pDict->nBlueValues = 0;
1978 pDict->nOtherBlues = 0;
1979 pDict->nFamilyBlues = 0;
1980 pDict->nFamilyOtherBlues = 0;
1981 pDict->blueScale = 0.039625;
1982 pDict->blueShift = 7;
1983 pDict->blueFuzz = 1;
1984 pDict->hasStdHW = gFalse;
1985 pDict->hasStdVW = gFalse;
1986 pDict->nStemSnapH = 0;
1987 pDict->nStemSnapV = 0;
1988 pDict->hasForceBold = gFalse;
1989 pDict->forceBoldThreshold = 0;
1990 pDict->languageGroup = 0;
1991 pDict->expansionFactor = 0.06;
1992 pDict->initialRandomSeed = 0;
1993 pDict->subrsOffset = 0;
1994 pDict->defaultWidthX = 0;
1995 pDict->defaultWidthXFP = gFalse;
1996 pDict->nominalWidthX = 0;
1997 pDict->nominalWidthXFP = gFalse;
2000 if (offset == 0 || length == 0) {
2006 while (pos < offset + length) {
2007 pos = getOp(pos, gFalse, &parsedOk);
2011 if (!ops[nOps - 1].isNum) {
2012 --nOps; // drop the operator
2013 switch (ops[nOps].op) {
2015 pDict->nBlueValues = getDeltaIntArray(pDict->blueValues,
2016 type1CMaxBlueValues);
2019 pDict->nOtherBlues = getDeltaIntArray(pDict->otherBlues,
2020 type1CMaxOtherBlues);
2023 pDict->nFamilyBlues = getDeltaIntArray(pDict->familyBlues,
2024 type1CMaxBlueValues);
2027 pDict->nFamilyOtherBlues = getDeltaIntArray(pDict->familyOtherBlues,
2028 type1CMaxOtherBlues);
2031 pDict->blueScale = ops[0].num;
2034 pDict->blueShift = (int)ops[0].num;
2037 pDict->blueFuzz = (int)ops[0].num;
2040 pDict->stdHW = ops[0].num;
2041 pDict->hasStdHW = gTrue;
2044 pDict->stdVW = ops[0].num;
2045 pDict->hasStdVW = gTrue;
2048 pDict->nStemSnapH = getDeltaFPArray(pDict->stemSnapH,
2052 pDict->nStemSnapV = getDeltaFPArray(pDict->stemSnapV,
2056 pDict->forceBold = ops[0].num != 0;
2057 pDict->hasForceBold = gTrue;
2060 pDict->forceBoldThreshold = ops[0].num;
2063 pDict->languageGroup = (int)ops[0].num;
2066 pDict->expansionFactor = ops[0].num;
2069 pDict->initialRandomSeed = (int)ops[0].num;
2072 pDict->subrsOffset = offset + (int)ops[0].num;
2075 pDict->defaultWidthX = ops[0].num;
2076 pDict->defaultWidthXFP = ops[0].isFP;
2079 pDict->nominalWidthX = ops[0].num;
2080 pDict->nominalWidthXFP = ops[0].isFP;
2088 void FoFiType1C::readFDSelect() {
2089 int fdSelectFmt, pos, nRanges, gid0, gid1, fd, i, j;
2091 fdSelect = (Guchar *)gmalloc(nGlyphs);
2092 if (topDict.fdSelectOffset == 0) {
2093 for (i = 0; i < nGlyphs; ++i) {
2097 pos = topDict.fdSelectOffset;
2098 fdSelectFmt = getU8(pos++, &parsedOk);
2102 if (fdSelectFmt == 0) {
2103 if (!checkRegion(pos, nGlyphs)) {
2107 memcpy(fdSelect, file + pos, nGlyphs);
2108 } else if (fdSelectFmt == 3) {
2109 nRanges = getU16BE(pos, &parsedOk);
2111 gid0 = getU16BE(pos, &parsedOk);
2113 for (i = 1; i <= nRanges; ++i) {
2114 fd = getU8(pos++, &parsedOk);
2115 gid1 = getU16BE(pos, &parsedOk);
2120 if (gid0 > gid1 || gid1 > nGlyphs) {
2121 //~ error(-1, "Bad FDSelect table in CID font");
2125 for (j = gid0; j < gid1; ++j) {
2131 //~ error(-1, "Unknown FDSelect table format in CID font");
2132 for (i = 0; i < nGlyphs; ++i) {
2139 void FoFiType1C::buildEncoding() {
2141 int nCodes, nRanges, encFormat;
2142 int pos, c, sid, nLeft, nSups, i, j;
2144 if (topDict.encodingOffset == 0) {
2145 encoding = fofiType1StandardEncoding;
2147 } else if (topDict.encodingOffset == 1) {
2148 encoding = fofiType1ExpertEncoding;
2151 encoding = (char **)gmallocn(256, sizeof(char *));
2152 for (i = 0; i < 256; ++i) {
2155 pos = topDict.encodingOffset;
2156 encFormat = getU8(pos++, &parsedOk);
2160 if ((encFormat & 0x7f) == 0) {
2161 nCodes = 1 + getU8(pos++, &parsedOk);
2165 if (nCodes > nGlyphs) {
2168 for (i = 1; i < nCodes; ++i) {
2169 c = getU8(pos++, &parsedOk);
2176 encoding[c] = copyString(getString(charset[i], buf, &parsedOk));
2178 } else if ((encFormat & 0x7f) == 1) {
2179 nRanges = getU8(pos++, &parsedOk);
2184 for (i = 0; i < nRanges; ++i) {
2185 c = getU8(pos++, &parsedOk);
2186 nLeft = getU8(pos++, &parsedOk);
2190 for (j = 0; j <= nLeft && nCodes < nGlyphs; ++j) {
2195 encoding[c] = copyString(getString(charset[nCodes], buf,
2203 if (encFormat & 0x80) {
2204 nSups = getU8(pos++, &parsedOk);
2208 for (i = 0; i < nSups; ++i) {
2209 c = getU8(pos++, &parsedOk);;
2213 sid = getU16BE(pos, &parsedOk);
2221 encoding[c] = copyString(getString(sid, buf, &parsedOk));
2227 GBool FoFiType1C::readCharset() {
2228 int charsetFormat, c, pos;
2231 if (topDict.charsetOffset == 0) {
2232 charset = fofiType1CISOAdobeCharset;
2233 } else if (topDict.charsetOffset == 1) {
2234 charset = fofiType1CExpertCharset;
2235 } else if (topDict.charsetOffset == 2) {
2236 charset = fofiType1CExpertSubsetCharset;
2238 charset = (Gushort *)gmallocn(nGlyphs, sizeof(Gushort));
2239 for (i = 0; i < nGlyphs; ++i) {
2242 pos = topDict.charsetOffset;
2243 charsetFormat = getU8(pos++, &parsedOk);
2244 if (charsetFormat == 0) {
2245 for (i = 1; i < nGlyphs; ++i) {
2246 charset[i] = (Gushort)getU16BE(pos, &parsedOk);
2252 } else if (charsetFormat == 1) {
2254 while (i < nGlyphs) {
2255 c = getU16BE(pos, &parsedOk);
2257 nLeft = getU8(pos++, &parsedOk);
2261 for (j = 0; j <= nLeft && i < nGlyphs; ++j) {
2262 charset[i++] = (Gushort)c++;
2265 } else if (charsetFormat == 2) {
2267 while (i < nGlyphs) {
2268 c = getU16BE(pos, &parsedOk);
2270 nLeft = getU16BE(pos, &parsedOk);
2275 for (j = 0; j <= nLeft && i < nGlyphs; ++j) {
2276 charset[i++] = (Gushort)c++;
2289 int FoFiType1C::getOp(int pos, GBool charstring, GBool *ok) {
2290 static char nybChars[16] = "0123456789.ee -";
2293 int b0, b1, nyb0, nyb1, x, i;
2295 b0 = getU8(pos++, ok);
2300 x = getU8(pos++, ok);
2301 x = (x << 8) | getU8(pos++, ok);
2307 } else if (!charstring && b0 == 29) {
2308 x = getU8(pos++, ok);
2309 x = (x << 8) | getU8(pos++, ok);
2310 x = (x << 8) | getU8(pos++, ok);
2311 x = (x << 8) | getU8(pos++, ok);
2312 if (x & 0x80000000) {
2317 } else if (!charstring && b0 == 30) {
2320 b1 = getU8(pos++, ok);
2326 buf[i++] = nybChars[nyb0];
2339 buf[i++] = nybChars[nyb1];
2351 } else if (b0 >= 32 && b0 <= 246) {
2354 } else if (b0 >= 247 && b0 <= 250) {
2355 op.num = ((b0 - 247) << 8) + getU8(pos++, ok) + 108;
2357 } else if (b0 >= 251 && b0 <= 254) {
2358 op.num = -((b0 - 251) << 8) - getU8(pos++, ok) - 108;
2360 } else if (charstring && b0 == 255) {
2361 x = getU8(pos++, ok);
2362 x = (x << 8) | getU8(pos++, ok);
2363 x = (x << 8) | getU8(pos++, ok);
2364 x = (x << 8) | getU8(pos++, ok);
2365 if (x & 0x80000000) {
2368 op.num = (double)x / 65536.0;
2371 } else if (b0 == 12) {
2373 op.op = 0x0c00 + getU8(pos++, ok);
2387 // Convert the delta-encoded ops array to an array of ints.
2388 int FoFiType1C::getDeltaIntArray(int *arr, int maxLen) {
2392 if ((n = nOps) > maxLen) {
2396 for (i = 0; i < n; ++i) {
2397 x += (int)ops[i].num;
2403 // Convert the delta-encoded ops array to an array of doubles.
2404 int FoFiType1C::getDeltaFPArray(double *arr, int maxLen) {
2408 if ((n = nOps) > maxLen) {
2412 for (i = 0; i < n; ++i) {
2419 void FoFiType1C::getIndex(int pos, Type1CIndex *idx, GBool *ok) {
2421 idx->len = getU16BE(pos, ok);
2422 if (idx->len == 0) {
2423 // empty indexes are legal and contain just the length field
2425 idx->startPos = idx->endPos = pos + 2;
2427 idx->offSize = getU8(pos + 2, ok);
2428 if (idx->offSize < 1 || idx->offSize > 4) {
2431 idx->startPos = pos + 3 + (idx->len + 1) * idx->offSize - 1;
2432 if (idx->startPos < 0 || idx->startPos >= len) {
2435 idx->endPos = idx->startPos + getUVarBE(pos + 3 + idx->len * idx->offSize,
2437 if (idx->endPos < idx->startPos || idx->endPos > len) {
2443 void FoFiType1C::getIndexVal(Type1CIndex *idx, int i,
2444 Type1CIndexVal *val, GBool *ok) {
2447 if (i < 0 || i >= idx->len) {
2451 pos0 = idx->startPos + getUVarBE(idx->pos + 3 + i * idx->offSize,
2453 pos1 = idx->startPos + getUVarBE(idx->pos + 3 + (i + 1) * idx->offSize,
2455 if (pos0 < idx->startPos || pos0 > idx->endPos ||
2456 pos1 <= idx->startPos || pos1 > idx->endPos ||
2461 val->len = pos1 - pos0;
2464 char *FoFiType1C::getString(int sid, char *buf, GBool *ok) {
2469 strcpy(buf, fofiType1CStdStrings[sid]);
2472 getIndexVal(&stringIdx, sid, &val, ok);
2474 if ((n = val.len) > 255) {
2477 strncpy(buf, (char *)&file[val.pos], n);