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;
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 *)gmalloc(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 *)gmalloc((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 sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n",
483 topDict.fontMatrix[0], topDict.fontMatrix[1], topDict.fontMatrix[2],
484 topDict.fontMatrix[3], topDict.fontMatrix[4], topDict.fontMatrix[5]);
485 (*outputFunc)(outputStream, buf, strlen(buf));
486 sprintf(buf, "/FontBBox [%g %g %g %g] def\n",
487 topDict.fontBBox[0], topDict.fontBBox[1],
488 topDict.fontBBox[2], topDict.fontBBox[3]);
489 (*outputFunc)(outputStream, buf, strlen(buf));
490 (*outputFunc)(outputStream, "/FontInfo 1 dict dup begin\n", 27);
491 (*outputFunc)(outputStream, " /FSType 8 def\n", 16);
492 (*outputFunc)(outputStream, "end def\n", 8);
494 // CIDFont-specific entries
495 sprintf(buf, "/CIDCount %d def\n", nCIDs);
496 (*outputFunc)(outputStream, buf, strlen(buf));
497 (*outputFunc)(outputStream, "/FDBytes 1 def\n", 15);
498 sprintf(buf, "/GDBytes %d def\n", gdBytes);
499 (*outputFunc)(outputStream, buf, strlen(buf));
500 (*outputFunc)(outputStream, "/CIDMapOffset 0 def\n", 20);
501 if (topDict.paintType != 0) {
502 sprintf(buf, "/PaintType %d def\n", topDict.paintType);
503 (*outputFunc)(outputStream, buf, strlen(buf));
504 sprintf(buf, "/StrokeWidth %g def\n", topDict.strokeWidth);
505 (*outputFunc)(outputStream, buf, strlen(buf));
509 sprintf(buf, "/FDArray %d array\n", nFDs);
510 (*outputFunc)(outputStream, buf, strlen(buf));
511 for (i = 0; i < nFDs; ++i) {
512 sprintf(buf, "dup %d 10 dict begin\n", i);
513 (*outputFunc)(outputStream, buf, strlen(buf));
514 (*outputFunc)(outputStream, "/FontType 1 def\n", 16);
515 (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
516 sprintf(buf, "/PaintType %d def\n", topDict.paintType);
517 (*outputFunc)(outputStream, buf, strlen(buf));
518 (*outputFunc)(outputStream, "/Private 32 dict begin\n", 23);
519 if (privateDicts[i].nBlueValues) {
520 (*outputFunc)(outputStream, "/BlueValues [", 13);
521 for (j = 0; j < privateDicts[i].nBlueValues; ++j) {
522 sprintf(buf, "%s%d", j > 0 ? " " : "", privateDicts[i].blueValues[j]);
523 (*outputFunc)(outputStream, buf, strlen(buf));
525 (*outputFunc)(outputStream, "] def\n", 6);
527 if (privateDicts[i].nOtherBlues) {
528 (*outputFunc)(outputStream, "/OtherBlues [", 13);
529 for (j = 0; j < privateDicts[i].nOtherBlues; ++j) {
530 sprintf(buf, "%s%d", j > 0 ? " " : "", privateDicts[i].otherBlues[j]);
531 (*outputFunc)(outputStream, buf, strlen(buf));
533 (*outputFunc)(outputStream, "] def\n", 6);
535 if (privateDicts[i].nFamilyBlues) {
536 (*outputFunc)(outputStream, "/FamilyBlues [", 14);
537 for (j = 0; j < privateDicts[i].nFamilyBlues; ++j) {
538 sprintf(buf, "%s%d", j > 0 ? " " : "", privateDicts[i].familyBlues[j]);
539 (*outputFunc)(outputStream, buf, strlen(buf));
541 (*outputFunc)(outputStream, "] def\n", 6);
543 if (privateDicts[i].nFamilyOtherBlues) {
544 (*outputFunc)(outputStream, "/FamilyOtherBlues [", 19);
545 for (j = 0; j < privateDicts[i].nFamilyOtherBlues; ++j) {
546 sprintf(buf, "%s%d", j > 0 ? " " : "",
547 privateDicts[i].familyOtherBlues[j]);
548 (*outputFunc)(outputStream, buf, strlen(buf));
550 (*outputFunc)(outputStream, "] def\n", 6);
552 if (privateDicts[i].blueScale != 0.039625) {
553 sprintf(buf, "/BlueScale %g def\n", privateDicts[i].blueScale);
554 (*outputFunc)(outputStream, buf, strlen(buf));
556 if (privateDicts[i].blueShift != 7) {
557 sprintf(buf, "/BlueShift %d def\n", privateDicts[i].blueShift);
558 (*outputFunc)(outputStream, buf, strlen(buf));
560 if (privateDicts[i].blueFuzz != 1) {
561 sprintf(buf, "/BlueFuzz %d def\n", privateDicts[i].blueFuzz);
562 (*outputFunc)(outputStream, buf, strlen(buf));
564 if (privateDicts[i].hasStdHW) {
565 sprintf(buf, "/StdHW [%g] def\n", privateDicts[i].stdHW);
566 (*outputFunc)(outputStream, buf, strlen(buf));
568 if (privateDicts[i].hasStdVW) {
569 sprintf(buf, "/StdVW [%g] def\n", privateDicts[i].stdVW);
570 (*outputFunc)(outputStream, buf, strlen(buf));
572 if (privateDicts[i].nStemSnapH) {
573 (*outputFunc)(outputStream, "/StemSnapH [", 12);
574 for (j = 0; j < privateDicts[i].nStemSnapH; ++j) {
575 sprintf(buf, "%s%g", j > 0 ? " " : "", privateDicts[i].stemSnapH[j]);
576 (*outputFunc)(outputStream, buf, strlen(buf));
578 (*outputFunc)(outputStream, "] def\n", 6);
580 if (privateDicts[i].nStemSnapV) {
581 (*outputFunc)(outputStream, "/StemSnapV [", 12);
582 for (j = 0; j < privateDicts[i].nStemSnapV; ++j) {
583 sprintf(buf, "%s%g", j > 0 ? " " : "", privateDicts[i].stemSnapV[j]);
584 (*outputFunc)(outputStream, buf, strlen(buf));
586 (*outputFunc)(outputStream, "] def\n", 6);
588 if (privateDicts[i].hasForceBold) {
589 sprintf(buf, "/ForceBold %s def\n",
590 privateDicts[i].forceBold ? "true" : "false");
591 (*outputFunc)(outputStream, buf, strlen(buf));
593 if (privateDicts[i].forceBoldThreshold != 0) {
594 sprintf(buf, "/ForceBoldThreshold %g def\n",
595 privateDicts[i].forceBoldThreshold);
596 (*outputFunc)(outputStream, buf, strlen(buf));
598 if (privateDicts[i].languageGroup != 0) {
599 sprintf(buf, "/LanguageGroup %d def\n", privateDicts[i].languageGroup);
600 (*outputFunc)(outputStream, buf, strlen(buf));
602 if (privateDicts[i].expansionFactor != 0.06) {
603 sprintf(buf, "/ExpansionFactor %g def\n",
604 privateDicts[i].expansionFactor);
605 (*outputFunc)(outputStream, buf, strlen(buf));
607 (*outputFunc)(outputStream, "currentdict end def\n", 20);
608 (*outputFunc)(outputStream, "currentdict end put\n", 20);
610 (*outputFunc)(outputStream, "def\n", 4);
612 // start the binary section
613 offset = (nCIDs + 1) * (1 + gdBytes);
614 sprintf(buf, "(Hex) %d StartData\n",
615 offset + charStrings->getLength());
616 (*outputFunc)(outputStream, buf, strlen(buf));
618 // write the charstring offset (CIDMap) table
619 for (i = 0; i <= nCIDs; i += 6) {
620 for (j = 0; j < 6 && i+j <= nCIDs; ++j) {
621 if (i+j < nCIDs && cidMap[i+j] >= 0) {
622 buf[0] = (char)fdSelect[cidMap[i+j]];
626 n = offset + charStringOffsets[i+j];
627 for (k = gdBytes; k >= 1; --k) {
628 buf[k] = (char)(n & 0xff);
631 for (k = 0; k <= gdBytes; ++k) {
632 sprintf(buf2, "%02x", buf[k] & 0xff);
633 (*outputFunc)(outputStream, buf2, 2);
636 (*outputFunc)(outputStream, "\n", 1);
639 // write the charstring data
640 n = charStrings->getLength();
641 for (i = 0; i < n; i += 32) {
642 for (j = 0; j < 32 && i+j < n; ++j) {
643 sprintf(buf, "%02x", charStrings->getChar(i+j) & 0xff);
644 (*outputFunc)(outputStream, buf, strlen(buf));
647 (*outputFunc)(outputStream, ">", 1);
649 (*outputFunc)(outputStream, "\n", 1);
652 gfree(charStringOffsets);
657 void FoFiType1C::convertToType0(char *psName,
658 FoFiOutputFunc outputFunc,
659 void *outputStream) {
669 // compute the CID count and build the CID-to-GID mapping
671 for (i = 0; i < nGlyphs; ++i) {
672 if (charset[i] >= nCIDs) {
673 nCIDs = charset[i] + 1;
676 cidMap = (int *)gmalloc(nCIDs * sizeof(int));
677 for (i = 0; i < nCIDs; ++i) {
680 for (i = 0; i < nGlyphs; ++i) {
681 cidMap[charset[i]] = i;
684 // write the descendant Type 1 fonts
685 for (i = 0; i < nCIDs; i += 256) {
687 //~ this assumes that all CIDs in this block have the same FD --
688 //~ to handle multiple FDs correctly, need to somehow divide the
691 for (j = 0; j < 256 && i+j < nCIDs; ++j) {
692 if (cidMap[i+j] >= 0) {
693 fd = fdSelect[cidMap[i+j]];
698 // font dictionary (unencrypted section)
699 (*outputFunc)(outputStream, "16 dict begin\n", 14);
700 (*outputFunc)(outputStream, "/FontName /", 11);
701 (*outputFunc)(outputStream, psName, strlen(psName));
702 sprintf(buf, "_%02x def\n", i >> 8);
703 (*outputFunc)(outputStream, buf, strlen(buf));
704 (*outputFunc)(outputStream, "/FontType 1 def\n", 16);
705 sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n",
706 topDict.fontMatrix[0], topDict.fontMatrix[1],
707 topDict.fontMatrix[2], topDict.fontMatrix[3],
708 topDict.fontMatrix[4], topDict.fontMatrix[5]);
709 (*outputFunc)(outputStream, buf, strlen(buf));
710 sprintf(buf, "/FontBBox [%g %g %g %g] def\n",
711 topDict.fontBBox[0], topDict.fontBBox[1],
712 topDict.fontBBox[2], topDict.fontBBox[3]);
713 (*outputFunc)(outputStream, buf, strlen(buf));
714 sprintf(buf, "/PaintType %d def\n", topDict.paintType);
715 (*outputFunc)(outputStream, buf, strlen(buf));
716 if (topDict.paintType != 0) {
717 sprintf(buf, "/StrokeWidth %g def\n", topDict.strokeWidth);
718 (*outputFunc)(outputStream, buf, strlen(buf));
720 (*outputFunc)(outputStream, "/Encoding 256 array\n", 20);
721 for (j = 0; j < 256 && i+j < nCIDs; ++j) {
722 sprintf(buf, "dup %d /c%02x put\n", j, j);
723 (*outputFunc)(outputStream, buf, strlen(buf));
726 sprintf(buf, "%d 1 255 { 1 index exch /.notdef put } for\n", j);
727 (*outputFunc)(outputStream, buf, strlen(buf));
729 (*outputFunc)(outputStream, "readonly def\n", 13);
730 (*outputFunc)(outputStream, "currentdict end\n", 16);
732 // start the binary section
733 (*outputFunc)(outputStream, "currentfile eexec\n", 18);
734 eb.outputFunc = outputFunc;
735 eb.outputStream = outputStream;
740 // start the private dictionary
741 eexecWrite(&eb, "\x83\xca\x73\xd5");
742 eexecWrite(&eb, "dup /Private 32 dict dup begin\n");
743 eexecWrite(&eb, "/RD {string currentfile exch readstring pop}"
744 " executeonly def\n");
745 eexecWrite(&eb, "/ND {noaccess def} executeonly def\n");
746 eexecWrite(&eb, "/NP {noaccess put} executeonly def\n");
747 eexecWrite(&eb, "/MinFeature {16 16} def\n");
748 eexecWrite(&eb, "/password 5839 def\n");
749 if (privateDicts[fd].nBlueValues) {
750 eexecWrite(&eb, "/BlueValues [");
751 for (k = 0; k < privateDicts[fd].nBlueValues; ++k) {
752 sprintf(buf, "%s%d", k > 0 ? " " : "", privateDicts[fd].blueValues[k]);
753 eexecWrite(&eb, buf);
755 eexecWrite(&eb, "] def\n");
757 if (privateDicts[fd].nOtherBlues) {
758 eexecWrite(&eb, "/OtherBlues [");
759 for (k = 0; k < privateDicts[fd].nOtherBlues; ++k) {
760 sprintf(buf, "%s%d", k > 0 ? " " : "", privateDicts[fd].otherBlues[k]);
761 eexecWrite(&eb, buf);
763 eexecWrite(&eb, "] def\n");
765 if (privateDicts[fd].nFamilyBlues) {
766 eexecWrite(&eb, "/FamilyBlues [");
767 for (k = 0; k < privateDicts[fd].nFamilyBlues; ++k) {
768 sprintf(buf, "%s%d", k > 0 ? " " : "",
769 privateDicts[fd].familyBlues[k]);
770 eexecWrite(&eb, buf);
772 eexecWrite(&eb, "] def\n");
774 if (privateDicts[fd].nFamilyOtherBlues) {
775 eexecWrite(&eb, "/FamilyOtherBlues [");
776 for (k = 0; k < privateDicts[fd].nFamilyOtherBlues; ++k) {
777 sprintf(buf, "%s%d", k > 0 ? " " : "",
778 privateDicts[fd].familyOtherBlues[k]);
779 eexecWrite(&eb, buf);
781 eexecWrite(&eb, "] def\n");
783 if (privateDicts[fd].blueScale != 0.039625) {
784 sprintf(buf, "/BlueScale %g def\n", privateDicts[fd].blueScale);
785 eexecWrite(&eb, buf);
787 if (privateDicts[fd].blueShift != 7) {
788 sprintf(buf, "/BlueShift %d def\n", privateDicts[fd].blueShift);
789 eexecWrite(&eb, buf);
791 if (privateDicts[fd].blueFuzz != 1) {
792 sprintf(buf, "/BlueFuzz %d def\n", privateDicts[fd].blueFuzz);
793 eexecWrite(&eb, buf);
795 if (privateDicts[fd].hasStdHW) {
796 sprintf(buf, "/StdHW [%g] def\n", privateDicts[fd].stdHW);
797 eexecWrite(&eb, buf);
799 if (privateDicts[fd].hasStdVW) {
800 sprintf(buf, "/StdVW [%g] def\n", privateDicts[fd].stdVW);
801 eexecWrite(&eb, buf);
803 if (privateDicts[fd].nStemSnapH) {
804 eexecWrite(&eb, "/StemSnapH [");
805 for (k = 0; k < privateDicts[fd].nStemSnapH; ++k) {
806 sprintf(buf, "%s%g", k > 0 ? " " : "", privateDicts[fd].stemSnapH[k]);
807 eexecWrite(&eb, buf);
809 eexecWrite(&eb, "] def\n");
811 if (privateDicts[fd].nStemSnapV) {
812 eexecWrite(&eb, "/StemSnapV [");
813 for (k = 0; k < privateDicts[fd].nStemSnapV; ++k) {
814 sprintf(buf, "%s%g", k > 0 ? " " : "", privateDicts[fd].stemSnapV[k]);
815 eexecWrite(&eb, buf);
817 eexecWrite(&eb, "] def\n");
819 if (privateDicts[fd].hasForceBold) {
820 sprintf(buf, "/ForceBold %s def\n",
821 privateDicts[fd].forceBold ? "true" : "false");
822 eexecWrite(&eb, buf);
824 if (privateDicts[fd].forceBoldThreshold != 0) {
825 sprintf(buf, "/ForceBoldThreshold %g def\n",
826 privateDicts[fd].forceBoldThreshold);
827 eexecWrite(&eb, buf);
829 if (privateDicts[fd].languageGroup != 0) {
830 sprintf(buf, "/LanguageGroup %d def\n", privateDicts[fd].languageGroup);
831 eexecWrite(&eb, buf);
833 if (privateDicts[fd].expansionFactor != 0.06) {
834 sprintf(buf, "/ExpansionFactor %g def\n",
835 privateDicts[fd].expansionFactor);
836 eexecWrite(&eb, buf);
839 // set up the subroutines
841 getIndex(privateDicts[fd].subrsOffset, &subrIdx, &ok);
846 // start the CharStrings
847 sprintf(buf, "2 index /CharStrings 256 dict dup begin\n");
848 eexecWrite(&eb, buf);
850 // write the .notdef CharString
852 getIndexVal(&charStringsIdx, 0, &val, &ok);
854 eexecCvtGlyph(&eb, ".notdef", val.pos, val.len,
855 &subrIdx, &privateDicts[fd]);
858 // write the CharStrings
859 for (j = 0; j < 256 && i+j < nCIDs; ++j) {
860 if (cidMap[i+j] >= 0) {
862 getIndexVal(&charStringsIdx, cidMap[i+j], &val, &ok);
864 sprintf(buf, "c%02x", j);
865 eexecCvtGlyph(&eb, buf, val.pos, val.len,
866 &subrIdx, &privateDicts[fd]);
870 eexecWrite(&eb, "end\n");
871 eexecWrite(&eb, "end\n");
872 eexecWrite(&eb, "readonly put\n");
873 eexecWrite(&eb, "noaccess put\n");
874 eexecWrite(&eb, "dup /FontName get exch definefont pop\n");
875 eexecWrite(&eb, "mark currentfile closefile\n");
879 (*outputFunc)(outputStream, "\n", 1);
881 for (j = 0; j < 8; ++j) {
882 (*outputFunc)(outputStream, "0000000000000000000000000000000000000000000000000000000000000000\n", 65);
884 (*outputFunc)(outputStream, "cleartomark\n", 12);
887 // write the Type 0 parent font
888 (*outputFunc)(outputStream, "16 dict begin\n", 14);
889 (*outputFunc)(outputStream, "/FontName /", 11);
890 (*outputFunc)(outputStream, psName, strlen(psName));
891 (*outputFunc)(outputStream, " def\n", 5);
892 (*outputFunc)(outputStream, "/FontType 0 def\n", 16);
893 (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
894 (*outputFunc)(outputStream, "/FMapType 2 def\n", 16);
895 (*outputFunc)(outputStream, "/Encoding [\n", 12);
896 for (i = 0; i < nCIDs; i += 256) {
897 sprintf(buf, "%d\n", i >> 8);
898 (*outputFunc)(outputStream, buf, strlen(buf));
900 (*outputFunc)(outputStream, "] def\n", 6);
901 (*outputFunc)(outputStream, "/FDepVector [\n", 14);
902 for (i = 0; i < nCIDs; i += 256) {
903 (*outputFunc)(outputStream, "/", 1);
904 (*outputFunc)(outputStream, psName, strlen(psName));
905 sprintf(buf, "_%02x findfont\n", i >> 8);
906 (*outputFunc)(outputStream, buf, strlen(buf));
908 (*outputFunc)(outputStream, "] def\n", 6);
909 (*outputFunc)(outputStream, "FontName currentdict end definefont pop\n", 40);
914 void FoFiType1C::eexecCvtGlyph(Type1CEexecBuf *eb, char *glyphName,
915 int offset, int nBytes,
916 Type1CIndex *subrIdx,
917 Type1CPrivateDict *pDict) {
921 // generate the charstring
922 charBuf = new GString();
923 cvtGlyph(offset, nBytes, charBuf, subrIdx, pDict, gTrue);
925 sprintf(buf, "/%s %d RD ", glyphName, charBuf->getLength());
927 eexecWriteCharstring(eb, (Guchar *)charBuf->getCString(),
928 charBuf->getLength());
929 eexecWrite(eb, " ND\n");
934 void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf,
935 Type1CIndex *subrIdx, Type1CPrivateDict *pDict,
942 int pos, subrBias, start, i, k;
944 start = charBuf->getLength();
946 charBuf->append((char)73);
947 charBuf->append((char)58);
948 charBuf->append((char)147);
949 charBuf->append((char)134);
956 while (pos < offset + nBytes) {
958 pos = getOp(pos, gTrue, &ok);
962 if (!ops[nOps - 1].isNum) {
963 --nOps; // drop the operator
964 switch (ops[nOps].op) {
965 case 0x0001: // hstem
967 cvtGlyphWidth(nOps & 1, charBuf, pDict);
971 //~ error(-1, "Wrong number of args (%d) to Type 2 hstem", nOps);
975 for (k = 0; k < nOps; k += 2) {
976 if (ops[k+1].num < 0) {
977 d += ops[k].num + ops[k+1].num;
978 dFP |= ops[k].isFP | ops[k+1].isFP;
979 cvtNum(d, dFP, charBuf);
980 cvtNum(-ops[k+1].num, ops[k+1].isFP, charBuf);
984 cvtNum(d, dFP, charBuf);
985 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
987 dFP |= ops[k+1].isFP;
989 charBuf->append((char)1);
994 case 0x0003: // vstem
996 cvtGlyphWidth(nOps & 1, charBuf, pDict);
1000 //~ error(-1, "Wrong number of args (%d) to Type 2 vstem", nOps);
1004 for (k = 0; k < nOps; k += 2) {
1005 if (ops[k+1].num < 0) {
1006 d += ops[k].num + ops[k+1].num;
1007 dFP |= ops[k].isFP | ops[k+1].isFP;
1008 cvtNum(d, dFP, charBuf);
1009 cvtNum(-ops[k+1].num, ops[k+1].isFP, charBuf);
1013 cvtNum(d, dFP, charBuf);
1014 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1016 dFP |= ops[k+1].isFP;
1018 charBuf->append((char)3);
1023 case 0x0004: // vmoveto
1025 cvtGlyphWidth(nOps == 2, charBuf, pDict);
1029 //~ error(-1, "Wrong number of args (%d) to Type 2 vmoveto", nOps);
1031 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1032 charBuf->append((char)4);
1035 case 0x0005: // rlineto
1036 if (nOps < 2 || nOps % 2 != 0) {
1037 //~ error(-1, "Wrong number of args (%d) to Type 2 rlineto", nOps);
1039 for (k = 0; k < nOps; k += 2) {
1040 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1041 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1042 charBuf->append((char)5);
1046 case 0x0006: // hlineto
1048 //~ error(-1, "Wrong number of args (%d) to Type 2 hlineto", nOps);
1050 for (k = 0; k < nOps; ++k) {
1051 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1052 charBuf->append((char)((k & 1) ? 7 : 6));
1056 case 0x0007: // vlineto
1058 //~ error(-1, "Wrong number of args (%d) to Type 2 vlineto", nOps);
1060 for (k = 0; k < nOps; ++k) {
1061 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1062 charBuf->append((char)((k & 1) ? 6 : 7));
1066 case 0x0008: // rrcurveto
1067 if (nOps < 6 || nOps % 6 != 0) {
1068 //~ error(-1, "Wrong number of args (%d) to Type 2 rrcurveto", nOps);
1070 for (k = 0; k < nOps; k += 6) {
1071 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1072 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1073 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1074 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1075 cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
1076 cvtNum(ops[k+5].num, ops[k+5].isFP, charBuf);
1077 charBuf->append((char)8);
1081 case 0x000a: // callsubr
1083 subrBias = (subrIdx->len < 1240)
1084 ? 107 : (subrIdx->len < 33900) ? 1131 : 32768;
1085 k = subrBias + (int)ops[nOps - 1].num;
1088 getIndexVal(subrIdx, k, &val, &ok);
1090 cvtGlyph(val.pos, val.len, charBuf, subrIdx, pDict, gFalse);
1093 //~ error(-1, "Too few args to Type 2 callsubr");
1095 // don't clear the stack
1097 case 0x000b: // return
1098 // don't clear the stack
1100 case 0x000e: // endchar / seac
1102 cvtGlyphWidth(nOps == 1 || nOps == 5, charBuf, pDict);
1106 cvtNum(0, gFalse, charBuf);
1107 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1108 cvtNum(ops[1].num, ops[1].isFP, charBuf);
1109 cvtNum(ops[2].num, ops[2].isFP, charBuf);
1110 cvtNum(ops[3].num, ops[3].isFP, charBuf);
1111 charBuf->append((char)12)->append((char)6);
1112 } else if (nOps == 0) {
1113 charBuf->append((char)14);
1115 //~ error(-1, "Wrong number of args (%d) to Type 2 endchar", nOps);
1119 case 0x000f: // (obsolete)
1120 // this op is ignored, but we need the glyph width
1122 cvtGlyphWidth(nOps > 0, charBuf, pDict);
1127 case 0x0010: // blend
1128 //~ error(-1, "Unimplemented Type 2 charstring op: %d", file[i]);
1131 case 0x0012: // hstemhm
1134 cvtGlyphWidth(nOps & 1, charBuf, pDict);
1138 //~ error(-1, "Wrong number of args (%d) to Type 2 hstemhm", nOps);
1143 case 0x0013: // hintmask
1146 cvtGlyphWidth(nOps & 1, charBuf, pDict);
1151 //~ error(-1, "Wrong number of args (%d) to Type 2 hintmask/vstemhm",
1156 pos += (nHints + 7) >> 3;
1159 case 0x0014: // cntrmask
1162 cvtGlyphWidth(nOps & 1, charBuf, pDict);
1167 //~ error(-1, "Wrong number of args (%d) to Type 2 cntrmask/vstemhm",
1172 pos += (nHints + 7) >> 3;
1175 case 0x0015: // rmoveto
1177 cvtGlyphWidth(nOps == 3, charBuf, pDict);
1181 //~ error(-1, "Wrong number of args (%d) to Type 2 rmoveto", nOps);
1183 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1184 cvtNum(ops[1].num, ops[1].isFP, charBuf);
1185 charBuf->append((char)21);
1188 case 0x0016: // hmoveto
1190 cvtGlyphWidth(nOps == 2, charBuf, pDict);
1194 //~ error(-1, "Wrong number of args (%d) to Type 2 hmoveto", nOps);
1196 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1197 charBuf->append((char)22);
1200 case 0x0017: // vstemhm
1203 cvtGlyphWidth(nOps & 1, charBuf, pDict);
1207 //~ error(-1, "Wrong number of args (%d) to Type 2 vstemhm", nOps);
1212 case 0x0018: // rcurveline
1213 if (nOps < 8 || (nOps - 2) % 6 != 0) {
1214 //~ error(-1, "Wrong number of args (%d) to Type 2 rcurveline", nOps);
1216 for (k = 0; k < nOps - 2; k += 6) {
1217 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1218 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1219 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1220 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1221 cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
1222 cvtNum(ops[k+5].num, ops[k+5].isFP, charBuf);
1223 charBuf->append((char)8);
1225 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1226 cvtNum(ops[k+1].num, ops[k].isFP, charBuf);
1227 charBuf->append((char)5);
1230 case 0x0019: // rlinecurve
1231 if (nOps < 8 || (nOps - 6) % 2 != 0) {
1232 //~ error(-1, "Wrong number of args (%d) to Type 2 rlinecurve", nOps);
1234 for (k = 0; k < nOps - 6; k += 2) {
1235 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1236 cvtNum(ops[k+1].num, ops[k].isFP, charBuf);
1237 charBuf->append((char)5);
1239 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1240 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1241 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1242 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1243 cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
1244 cvtNum(ops[k+5].num, ops[k+5].isFP, charBuf);
1245 charBuf->append((char)8);
1248 case 0x001a: // vvcurveto
1249 if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) {
1250 //~ error(-1, "Wrong number of args (%d) to Type 2 vvcurveto", nOps);
1252 if (nOps % 2 == 1) {
1253 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1254 cvtNum(ops[1].num, ops[1].isFP, charBuf);
1255 cvtNum(ops[2].num, ops[2].isFP, charBuf);
1256 cvtNum(ops[3].num, ops[3].isFP, charBuf);
1257 cvtNum(0, gFalse, charBuf);
1258 cvtNum(ops[4].num, ops[4].isFP, charBuf);
1259 charBuf->append((char)8);
1264 for (; k < nOps; k += 4) {
1265 cvtNum(0, gFalse, charBuf);
1266 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1267 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1268 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1269 cvtNum(0, gFalse, charBuf);
1270 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1271 charBuf->append((char)8);
1275 case 0x001b: // hhcurveto
1276 if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) {
1277 //~ error(-1, "Wrong number of args (%d) to Type 2 hhcurveto", nOps);
1279 if (nOps % 2 == 1) {
1280 cvtNum(ops[1].num, ops[1].isFP, charBuf);
1281 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1282 cvtNum(ops[2].num, ops[2].isFP, charBuf);
1283 cvtNum(ops[3].num, ops[3].isFP, charBuf);
1284 cvtNum(ops[4].num, ops[4].isFP, charBuf);
1285 cvtNum(0, gFalse, charBuf);
1286 charBuf->append((char)8);
1291 for (; k < nOps; k += 4) {
1292 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1293 cvtNum(0, gFalse, charBuf);
1294 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1295 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1296 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1297 cvtNum(0, gFalse, charBuf);
1298 charBuf->append((char)8);
1302 case 0x001d: // callgsubr
1304 k = gsubrBias + (int)ops[nOps - 1].num;
1307 getIndexVal(&gsubrIdx, k, &val, &ok);
1309 cvtGlyph(val.pos, val.len, charBuf, subrIdx, pDict, gFalse);
1312 //~ error(-1, "Too few args to Type 2 callgsubr");
1314 // don't clear the stack
1316 case 0x001e: // vhcurveto
1317 if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) {
1318 //~ error(-1, "Wrong number of args (%d) to Type 2 vhcurveto", nOps);
1320 for (k = 0; k < nOps && k != nOps-5; k += 4) {
1322 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1323 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1324 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1325 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1326 charBuf->append((char)30);
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(ops[k+3].num, ops[k+3].isFP, charBuf);
1332 charBuf->append((char)31);
1337 cvtNum(0, gFalse, charBuf);
1338 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1339 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1340 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1341 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1342 cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
1344 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1345 cvtNum(0, gFalse, charBuf);
1346 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1347 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1348 cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
1349 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1351 charBuf->append((char)8);
1355 case 0x001f: // hvcurveto
1356 if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) {
1357 //~ error(-1, "Wrong number of args (%d) to Type 2 hvcurveto", nOps);
1359 for (k = 0; k < nOps && k != nOps-5; k += 4) {
1361 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1362 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1363 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1364 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1365 charBuf->append((char)31);
1367 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1368 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1369 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1370 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1371 charBuf->append((char)30);
1376 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1377 cvtNum(0, gFalse, charBuf);
1378 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1379 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1380 cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
1381 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1383 cvtNum(0, gFalse, charBuf);
1384 cvtNum(ops[k].num, ops[k].isFP, charBuf);
1385 cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf);
1386 cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf);
1387 cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf);
1388 cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf);
1390 charBuf->append((char)8);
1394 case 0x0c00: // dotsection (should be Type 1 only?)
1401 case 0x0c08: // store
1406 case 0x0c0d: // load
1409 case 0x0c12: // drop
1412 case 0x0c16: // ifelse
1413 case 0x0c17: // random
1415 case 0x0c1a: // sqrt
1417 case 0x0c1c: // exch
1418 case 0x0c1d: // index
1419 case 0x0c1e: // roll
1420 //~ error(-1, "Unimplemented Type 2 charstring op: 12.%d", file[i+1]);
1423 case 0x0c22: // hflex
1425 //~ error(-1, "Wrong number of args (%d) to Type 2 hflex", nOps);
1427 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1428 cvtNum(0, gFalse, charBuf);
1429 cvtNum(ops[1].num, ops[1].isFP, charBuf);
1430 cvtNum(ops[2].num, ops[2].isFP, charBuf);
1431 cvtNum(ops[3].num, ops[3].isFP, charBuf);
1432 cvtNum(0, gFalse, charBuf);
1433 charBuf->append((char)8);
1434 cvtNum(ops[4].num, ops[4].isFP, charBuf);
1435 cvtNum(0, gFalse, charBuf);
1436 cvtNum(ops[5].num, ops[5].isFP, charBuf);
1437 cvtNum(-ops[2].num, ops[2].isFP, charBuf);
1438 cvtNum(ops[6].num, ops[6].isFP, charBuf);
1439 cvtNum(0, gFalse, charBuf);
1440 charBuf->append((char)8);
1443 case 0x0c23: // flex
1445 //~ error(-1, "Wrong number of args (%d) to Type 2 flex", nOps);
1447 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1448 cvtNum(ops[1].num, ops[1].isFP, charBuf);
1449 cvtNum(ops[2].num, ops[2].isFP, charBuf);
1450 cvtNum(ops[3].num, ops[3].isFP, charBuf);
1451 cvtNum(ops[4].num, ops[4].isFP, charBuf);
1452 cvtNum(ops[5].num, ops[5].isFP, charBuf);
1453 charBuf->append((char)8);
1454 cvtNum(ops[6].num, ops[6].isFP, charBuf);
1455 cvtNum(ops[7].num, ops[7].isFP, charBuf);
1456 cvtNum(ops[8].num, ops[8].isFP, charBuf);
1457 cvtNum(ops[9].num, ops[9].isFP, charBuf);
1458 cvtNum(ops[10].num, ops[10].isFP, charBuf);
1459 cvtNum(ops[11].num, ops[11].isFP, charBuf);
1460 charBuf->append((char)8);
1463 case 0x0c24: // hflex1
1465 //~ error(-1, "Wrong number of args (%d) to Type 2 hflex1", nOps);
1467 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1468 cvtNum(ops[1].num, ops[1].isFP, charBuf);
1469 cvtNum(ops[2].num, ops[2].isFP, charBuf);
1470 cvtNum(ops[3].num, ops[3].isFP, charBuf);
1471 cvtNum(ops[4].num, ops[4].isFP, charBuf);
1472 cvtNum(0, gFalse, charBuf);
1473 charBuf->append((char)8);
1474 cvtNum(ops[5].num, ops[5].isFP, charBuf);
1475 cvtNum(0, gFalse, charBuf);
1476 cvtNum(ops[6].num, ops[6].isFP, charBuf);
1477 cvtNum(ops[7].num, ops[7].isFP, charBuf);
1478 cvtNum(ops[8].num, ops[8].isFP, charBuf);
1479 cvtNum(-(ops[1].num + ops[3].num + ops[7].num),
1480 ops[1].isFP | ops[3].isFP | ops[7].isFP, charBuf);
1481 charBuf->append((char)8);
1484 case 0x0c25: // flex1
1486 //~ error(-1, "Wrong number of args (%d) to Type 2 flex1", nOps);
1488 cvtNum(ops[0].num, ops[0].isFP, charBuf);
1489 cvtNum(ops[1].num, ops[1].isFP, charBuf);
1490 cvtNum(ops[2].num, ops[2].isFP, charBuf);
1491 cvtNum(ops[3].num, ops[3].isFP, charBuf);
1492 cvtNum(ops[4].num, ops[4].isFP, charBuf);
1493 cvtNum(ops[5].num, ops[5].isFP, charBuf);
1494 charBuf->append((char)8);
1495 cvtNum(ops[6].num, ops[6].isFP, charBuf);
1496 cvtNum(ops[7].num, ops[7].isFP, charBuf);
1497 cvtNum(ops[8].num, ops[8].isFP, charBuf);
1498 cvtNum(ops[9].num, ops[9].isFP, charBuf);
1499 dx = ops[0].num + ops[2].num + ops[4].num + ops[6].num + ops[8].num;
1500 dy = ops[1].num + ops[3].num + ops[5].num + ops[7].num + ops[9].num;
1501 if (fabs(dx) > fabs(dy)) {
1502 cvtNum(ops[10].num, ops[10].isFP, charBuf);
1503 cvtNum(-dy, ops[1].isFP | ops[3].isFP | ops[5].isFP |
1504 ops[7].isFP | ops[9].isFP, charBuf);
1506 cvtNum(-dx, ops[0].isFP | ops[2].isFP | ops[4].isFP |
1507 ops[6].isFP | ops[8].isFP, charBuf);
1508 cvtNum(ops[10].num, ops[10].isFP, charBuf);
1510 charBuf->append((char)8);
1514 //~ error(-1, "Illegal Type 2 charstring op: %04x",
1522 // charstring encryption
1525 for (i = start; i < charBuf->getLength(); ++i) {
1526 byte = charBuf->getChar(i) ^ (r2 >> 8);
1527 charBuf->setChar(i, byte);
1528 r2 = (byte + r2) * 52845 + 22719;
1533 void FoFiType1C::cvtGlyphWidth(GBool useOp, GString *charBuf,
1534 Type1CPrivateDict *pDict) {
1540 w = pDict->nominalWidthX + ops[0].num;
1541 wFP = pDict->nominalWidthXFP | ops[0].isFP;
1542 for (i = 1; i < nOps; ++i) {
1547 w = pDict->defaultWidthX;
1548 wFP = pDict->defaultWidthXFP;
1550 cvtNum(0, gFalse, charBuf);
1551 cvtNum(w, wFP, charBuf);
1552 charBuf->append((char)13);
1555 void FoFiType1C::cvtNum(double x, GBool isFP, GString *charBuf) {
1561 if (x >= -32768 && x < 32768) {
1562 y = (int)(x * 256.0);
1564 buf[1] = (Guchar)(y >> 24);
1565 buf[2] = (Guchar)(y >> 16);
1566 buf[3] = (Guchar)(y >> 8);
1577 //~ error(-1, "Type 2 fixed point constant out of range");
1581 if (y >= -107 && y <= 107) {
1582 buf[0] = (Guchar)(y + 139);
1584 } else if (y > 107 && y <= 1131) {
1586 buf[0] = (Guchar)((y >> 8) + 247);
1587 buf[1] = (Guchar)(y & 0xff);
1589 } else if (y < -107 && y >= -1131) {
1591 buf[0] = (Guchar)((y >> 8) + 251);
1592 buf[1] = (Guchar)(y & 0xff);
1596 buf[1] = (Guchar)(y >> 24);
1597 buf[2] = (Guchar)(y >> 16);
1598 buf[3] = (Guchar)(y >> 8);
1603 charBuf->append((char *)buf, n);
1606 void FoFiType1C::eexecWrite(Type1CEexecBuf *eb, char *s) {
1610 for (p = (Guchar *)s; *p; ++p) {
1611 x = *p ^ (eb->r1 >> 8);
1612 eb->r1 = (x + eb->r1) * 52845 + 22719;
1614 (*eb->outputFunc)(eb->outputStream, &hexChars[x >> 4], 1);
1615 (*eb->outputFunc)(eb->outputStream, &hexChars[x & 0x0f], 1);
1617 if (eb->line == 64) {
1618 (*eb->outputFunc)(eb->outputStream, "\n", 1);
1622 (*eb->outputFunc)(eb->outputStream, (char *)&x, 1);
1627 void FoFiType1C::eexecWriteCharstring(Type1CEexecBuf *eb,
1633 for (i = 0; i < n; ++i) {
1634 x = s[i] ^ (eb->r1 >> 8);
1635 eb->r1 = (x + eb->r1) * 52845 + 22719;
1637 (*eb->outputFunc)(eb->outputStream, &hexChars[x >> 4], 1);
1638 (*eb->outputFunc)(eb->outputStream, &hexChars[x & 0x0f], 1);
1640 if (eb->line == 64) {
1641 (*eb->outputFunc)(eb->outputStream, "\n", 1);
1645 (*eb->outputFunc)(eb->outputStream, (char *)&x, 1);
1650 GBool FoFiType1C::parse() {
1657 // some tools embed Type 1C fonts with an extra whitespace char at
1659 if (len > 0 && file[0] != '\x01') {
1665 getIndex(getU8(2, &parsedOk), &nameIdx, &parsedOk);
1666 getIndex(nameIdx.endPos, &topDictIdx, &parsedOk);
1667 getIndex(topDictIdx.endPos, &stringIdx, &parsedOk);
1668 getIndex(stringIdx.endPos, &gsubrIdx, &parsedOk);
1672 gsubrBias = (gsubrIdx.len < 1240) ? 107
1673 : (gsubrIdx.len < 33900) ? 1131 : 32768;
1675 // read the first font name
1676 getIndexVal(&nameIdx, 0, &val, &parsedOk);
1680 name = new GString((char *)&file[val.pos], val.len);
1682 // read the top dict for the first font
1685 // for CID fonts: read the FDArray dicts and private dicts
1686 if (topDict.firstOp == 0x0c1e) {
1687 if (topDict.fdArrayOffset == 0) {
1689 privateDicts = (Type1CPrivateDict *)gmalloc(sizeof(Type1CPrivateDict));
1690 readPrivateDict(0, 0, &privateDicts[0]);
1692 getIndex(topDict.fdArrayOffset, &fdIdx, &parsedOk);
1697 privateDicts = (Type1CPrivateDict *)
1698 gmalloc(nFDs * sizeof(Type1CPrivateDict));
1699 for (i = 0; i < nFDs; ++i) {
1700 getIndexVal(&fdIdx, i, &val, &parsedOk);
1704 readFD(val.pos, val.len, &privateDicts[i]);
1708 // for 8-bit fonts: read the private dict
1710 privateDicts = (Type1CPrivateDict *)gmalloc(sizeof(Type1CPrivateDict));
1711 readPrivateDict(topDict.privateOffset, topDict.privateSize,
1715 // check for parse errors in the private dict(s)
1720 // get the charstrings index
1721 if (topDict.charStringsOffset <= 0) {
1725 getIndex(topDict.charStringsOffset, &charStringsIdx, &parsedOk);
1729 nGlyphs = charStringsIdx.len;
1731 // for CID fonts: read the FDSelect table
1732 if (topDict.firstOp == 0x0c1e) {
1740 if (!readCharset()) {
1745 // for 8-bit fonts: build the encoding
1746 if (topDict.firstOp != 0x0c14 && topDict.firstOp != 0x0c1e) {
1756 void FoFiType1C::readTopDict() {
1757 Type1CIndexVal topDictPtr;
1760 topDict.firstOp = -1;
1761 topDict.versionSID = 0;
1762 topDict.noticeSID = 0;
1763 topDict.copyrightSID = 0;
1764 topDict.fullNameSID = 0;
1765 topDict.familyNameSID = 0;
1766 topDict.weightSID = 0;
1767 topDict.isFixedPitch = 0;
1768 topDict.italicAngle = 0;
1769 topDict.underlinePosition = -100;
1770 topDict.underlineThickness = 50;
1771 topDict.paintType = 0;
1772 topDict.charstringType = 2;
1773 topDict.fontMatrix[0] = 0.001;
1774 topDict.fontMatrix[1] = 0;
1775 topDict.fontMatrix[2] = 0;
1776 topDict.fontMatrix[3] = 0.001;
1777 topDict.fontMatrix[4] = 0;
1778 topDict.fontMatrix[5] = 0;
1779 topDict.uniqueID = 0;
1780 topDict.fontBBox[0] = 0;
1781 topDict.fontBBox[1] = 0;
1782 topDict.fontBBox[2] = 0;
1783 topDict.fontBBox[3] = 0;
1784 topDict.strokeWidth = 0;
1785 topDict.charsetOffset = 0;
1786 topDict.encodingOffset = 0;
1787 topDict.charStringsOffset = 0;
1788 topDict.privateSize = 0;
1789 topDict.privateOffset = 0;
1790 topDict.registrySID = 0;
1791 topDict.orderingSID = 0;
1792 topDict.supplement = 0;
1793 topDict.fdArrayOffset = 0;
1794 topDict.fdSelectOffset = 0;
1796 getIndexVal(&topDictIdx, 0, &topDictPtr, &parsedOk);
1797 pos = topDictPtr.pos;
1799 while (pos < topDictPtr.pos + topDictPtr.len) {
1800 pos = getOp(pos, gFalse, &parsedOk);
1804 if (!ops[nOps - 1].isNum) {
1805 --nOps; // drop the operator
1806 if (topDict.firstOp < 0) {
1807 topDict.firstOp = ops[nOps].op;
1809 switch (ops[nOps].op) {
1810 case 0x0000: topDict.versionSID = (int)ops[0].num; break;
1811 case 0x0001: topDict.noticeSID = (int)ops[0].num; break;
1812 case 0x0c00: topDict.copyrightSID = (int)ops[0].num; break;
1813 case 0x0002: topDict.fullNameSID = (int)ops[0].num; break;
1814 case 0x0003: topDict.familyNameSID = (int)ops[0].num; break;
1815 case 0x0004: topDict.weightSID = (int)ops[0].num; break;
1816 case 0x0c01: topDict.isFixedPitch = (int)ops[0].num; break;
1817 case 0x0c02: topDict.italicAngle = ops[0].num; break;
1818 case 0x0c03: topDict.underlinePosition = ops[0].num; break;
1819 case 0x0c04: topDict.underlineThickness = ops[0].num; break;
1820 case 0x0c05: topDict.paintType = (int)ops[0].num; break;
1821 case 0x0c06: topDict.charstringType = (int)ops[0].num; break;
1822 case 0x0c07: topDict.fontMatrix[0] = ops[0].num;
1823 topDict.fontMatrix[1] = ops[1].num;
1824 topDict.fontMatrix[2] = ops[2].num;
1825 topDict.fontMatrix[3] = ops[3].num;
1826 topDict.fontMatrix[4] = ops[4].num;
1827 topDict.fontMatrix[5] = ops[5].num; break;
1828 case 0x000d: topDict.uniqueID = (int)ops[0].num; break;
1829 case 0x0005: topDict.fontBBox[0] = ops[0].num;
1830 topDict.fontBBox[1] = ops[1].num;
1831 topDict.fontBBox[2] = ops[2].num;
1832 topDict.fontBBox[3] = ops[3].num; break;
1833 case 0x0c08: topDict.strokeWidth = ops[0].num; break;
1834 case 0x000f: topDict.charsetOffset = (int)ops[0].num; break;
1835 case 0x0010: topDict.encodingOffset = (int)ops[0].num; break;
1836 case 0x0011: topDict.charStringsOffset = (int)ops[0].num; break;
1837 case 0x0012: topDict.privateSize = (int)ops[0].num;
1838 topDict.privateOffset = (int)ops[1].num; break;
1839 case 0x0c1e: topDict.registrySID = (int)ops[0].num;
1840 topDict.orderingSID = (int)ops[1].num;
1841 topDict.supplement = (int)ops[2].num; break;
1842 case 0x0c24: topDict.fdArrayOffset = (int)ops[0].num; break;
1843 case 0x0c25: topDict.fdSelectOffset = (int)ops[0].num; break;
1850 // Read a CID font dict (FD) - this pulls out the private dict
1851 // pointer, and reads the private dict.
1852 void FoFiType1C::readFD(int offset, int length, Type1CPrivateDict *pDict) {
1853 int pos, pSize, pOffset;
1855 pSize = pOffset = 0;
1858 while (pos < offset + length) {
1859 pos = getOp(pos, gFalse, &parsedOk);
1863 if (!ops[nOps - 1].isNum) {
1864 if (ops[nOps - 1].op == 0x0012) {
1869 pSize = (int)ops[0].num;
1870 pOffset = (int)ops[1].num;
1876 readPrivateDict(pOffset, pSize, pDict);
1879 void FoFiType1C::readPrivateDict(int offset, int length,
1880 Type1CPrivateDict *pDict) {
1883 pDict->nBlueValues = 0;
1884 pDict->nOtherBlues = 0;
1885 pDict->nFamilyBlues = 0;
1886 pDict->nFamilyOtherBlues = 0;
1887 pDict->blueScale = 0.039625;
1888 pDict->blueShift = 7;
1889 pDict->blueFuzz = 1;
1890 pDict->hasStdHW = gFalse;
1891 pDict->hasStdVW = gFalse;
1892 pDict->nStemSnapH = 0;
1893 pDict->nStemSnapV = 0;
1894 pDict->hasForceBold = gFalse;
1895 pDict->forceBoldThreshold = 0;
1896 pDict->languageGroup = 0;
1897 pDict->expansionFactor = 0.06;
1898 pDict->initialRandomSeed = 0;
1899 pDict->subrsOffset = 0;
1900 pDict->defaultWidthX = 0;
1901 pDict->defaultWidthXFP = 0;
1902 pDict->nominalWidthX = 0;
1903 pDict->nominalWidthXFP = 0;
1906 if (offset == 0 || length == 0) {
1912 while (pos < offset + length) {
1913 pos = getOp(pos, gFalse, &parsedOk);
1917 if (!ops[nOps - 1].isNum) {
1918 --nOps; // drop the operator
1919 switch (ops[nOps].op) {
1921 pDict->nBlueValues = getDeltaIntArray(pDict->blueValues,
1922 type1CMaxBlueValues);
1925 pDict->nOtherBlues = getDeltaIntArray(pDict->otherBlues,
1926 type1CMaxOtherBlues);
1929 pDict->nFamilyBlues = getDeltaIntArray(pDict->familyBlues,
1930 type1CMaxBlueValues);
1933 pDict->nFamilyOtherBlues = getDeltaIntArray(pDict->familyOtherBlues,
1934 type1CMaxOtherBlues);
1937 pDict->blueScale = ops[0].num;
1940 pDict->blueShift = (int)ops[0].num;
1943 pDict->blueFuzz = (int)ops[0].num;
1946 pDict->stdHW = ops[0].num;
1947 pDict->hasStdHW = gTrue;
1950 pDict->stdVW = ops[0].num;
1951 pDict->hasStdVW = gTrue;
1954 pDict->nStemSnapH = getDeltaFPArray(pDict->stemSnapH,
1958 pDict->nStemSnapV = getDeltaFPArray(pDict->stemSnapV,
1962 pDict->forceBold = ops[0].num != 0;
1963 pDict->hasForceBold = gTrue;
1966 pDict->forceBoldThreshold = ops[0].num;
1969 pDict->languageGroup = (int)ops[0].num;
1972 pDict->expansionFactor = ops[0].num;
1975 pDict->initialRandomSeed = (int)ops[0].num;
1978 pDict->subrsOffset = offset + (int)ops[0].num;
1981 pDict->defaultWidthX = ops[0].num;
1984 pDict->nominalWidthX = ops[0].num;
1992 void FoFiType1C::readFDSelect() {
1993 int fdSelectFmt, pos, nRanges, gid0, gid1, fd, i, j;
1995 fdSelect = (Guchar *)gmalloc(nGlyphs);
1996 if (topDict.fdSelectOffset == 0) {
1997 for (i = 0; i < nGlyphs; ++i) {
2001 pos = topDict.fdSelectOffset;
2002 fdSelectFmt = getU8(pos++, &parsedOk);
2006 if (fdSelectFmt == 0) {
2007 if (!checkRegion(pos, nGlyphs)) {
2011 memcpy(fdSelect, file + pos, nGlyphs);
2012 } else if (fdSelectFmt == 3) {
2013 nRanges = getU16BE(pos, &parsedOk);
2015 gid0 = getU16BE(pos, &parsedOk);
2017 for (i = 1; i <= nRanges; ++i) {
2018 fd = getU8(pos++, &parsedOk);
2019 gid1 = getU16BE(pos, &parsedOk);
2024 if (gid0 > gid1 || gid1 > nGlyphs) {
2025 //~ error(-1, "Bad FDSelect table in CID font");
2029 for (j = gid0; j < gid1; ++j) {
2035 //~ error(-1, "Unknown FDSelect table format in CID font");
2036 for (i = 0; i < nGlyphs; ++i) {
2043 void FoFiType1C::buildEncoding() {
2045 int nCodes, nRanges, encFormat;
2046 int pos, c, sid, nLeft, nSups, i, j;
2048 if (topDict.encodingOffset == 0) {
2049 encoding = fofiType1StandardEncoding;
2051 } else if (topDict.encodingOffset == 1) {
2052 encoding = fofiType1ExpertEncoding;
2055 encoding = (char **)gmalloc(256 * sizeof(char *));
2056 for (i = 0; i < 256; ++i) {
2059 pos = topDict.encodingOffset;
2060 encFormat = getU8(pos++, &parsedOk);
2064 if ((encFormat & 0x7f) == 0) {
2065 nCodes = 1 + getU8(pos++, &parsedOk);
2069 if (nCodes > nGlyphs) {
2072 for (i = 1; i < nCodes; ++i) {
2073 c = getU8(pos++, &parsedOk);
2080 encoding[c] = copyString(getString(charset[i], buf, &parsedOk));
2082 } else if ((encFormat & 0x7f) == 1) {
2083 nRanges = getU8(pos++, &parsedOk);
2088 for (i = 0; i < nRanges; ++i) {
2089 c = getU8(pos++, &parsedOk);
2090 nLeft = getU8(pos++, &parsedOk);
2094 for (j = 0; j <= nLeft && nCodes < nGlyphs; ++j) {
2099 encoding[c] = copyString(getString(charset[nCodes], buf,
2107 if (encFormat & 0x80) {
2108 nSups = getU8(pos++, &parsedOk);
2112 for (i = 0; i < nSups; ++i) {
2113 c = getU8(pos++, &parsedOk);;
2117 sid = getU16BE(pos, &parsedOk);
2125 encoding[c] = copyString(getString(sid, buf, &parsedOk));
2131 GBool FoFiType1C::readCharset() {
2132 int charsetFormat, c, pos;
2135 if (topDict.charsetOffset == 0) {
2136 charset = fofiType1CISOAdobeCharset;
2137 } else if (topDict.charsetOffset == 1) {
2138 charset = fofiType1CExpertCharset;
2139 } else if (topDict.charsetOffset == 2) {
2140 charset = fofiType1CExpertSubsetCharset;
2142 charset = (Gushort *)gmalloc(nGlyphs * sizeof(Gushort));
2143 for (i = 0; i < nGlyphs; ++i) {
2146 pos = topDict.charsetOffset;
2147 charsetFormat = getU8(pos++, &parsedOk);
2148 if (charsetFormat == 0) {
2149 for (i = 1; i < nGlyphs; ++i) {
2150 charset[i] = (Gushort)getU16BE(pos, &parsedOk);
2156 } else if (charsetFormat == 1) {
2158 while (i < nGlyphs) {
2159 c = getU16BE(pos, &parsedOk);
2161 nLeft = getU8(pos++, &parsedOk);
2165 for (j = 0; j <= nLeft && i < nGlyphs; ++j) {
2166 charset[i++] = (Gushort)c++;
2169 } else if (charsetFormat == 2) {
2171 while (i < nGlyphs) {
2172 c = getU16BE(pos, &parsedOk);
2174 nLeft = getU16BE(pos, &parsedOk);
2179 for (j = 0; j <= nLeft && i < nGlyphs; ++j) {
2180 charset[i++] = (Gushort)c++;
2193 int FoFiType1C::getOp(int pos, GBool charstring, GBool *ok) {
2194 static char nybChars[16] = "0123456789.ee -";
2197 int b0, b1, nyb0, nyb1, x, i;
2199 b0 = getU8(pos++, ok);
2204 x = getU8(pos++, ok);
2205 x = (x << 8) | getU8(pos++, ok);
2211 } else if (!charstring && b0 == 29) {
2212 x = getU8(pos++, ok);
2213 x = (x << 8) | getU8(pos++, ok);
2214 x = (x << 8) | getU8(pos++, ok);
2215 x = (x << 8) | getU8(pos++, ok);
2216 if (x & 0x80000000) {
2221 } else if (!charstring && b0 == 30) {
2224 b1 = getU8(pos++, ok);
2230 buf[i++] = nybChars[nyb0];
2243 buf[i++] = nybChars[nyb1];
2255 } else if (b0 >= 32 && b0 <= 246) {
2258 } else if (b0 >= 247 && b0 <= 250) {
2259 op.num = ((b0 - 247) << 8) + getU8(pos++, ok) + 108;
2261 } else if (b0 >= 251 && b0 <= 254) {
2262 op.num = -((b0 - 251) << 8) - getU8(pos++, ok) - 108;
2264 } else if (charstring && b0 == 255) {
2265 x = getU8(pos++, ok);
2266 x = (x << 8) | getU8(pos++, ok);
2267 x = (x << 8) | getU8(pos++, ok);
2268 x = (x << 8) | getU8(pos++, ok);
2269 if (x & 0x80000000) {
2272 op.num = (double)x / 65536.0;
2275 } else if (b0 == 12) {
2277 op.op = 0x0c00 + getU8(pos++, ok);
2291 // Convert the delta-encoded ops array to an array of ints.
2292 int FoFiType1C::getDeltaIntArray(int *arr, int maxLen) {
2296 if ((n = nOps) > maxLen) {
2300 for (i = 0; i < n; ++i) {
2301 x += (int)ops[i].num;
2307 // Convert the delta-encoded ops array to an array of doubles.
2308 int FoFiType1C::getDeltaFPArray(double *arr, int maxLen) {
2312 if ((n = nOps) > maxLen) {
2316 for (i = 0; i < n; ++i) {
2323 void FoFiType1C::getIndex(int pos, Type1CIndex *idx, GBool *ok) {
2325 idx->len = getU16BE(pos, ok);
2326 if (idx->len == 0) {
2327 // empty indexes are legal
2329 idx->startPos = idx->endPos = 0;
2331 idx->offSize = getU8(pos + 2, ok);
2332 if (idx->offSize < 1 || idx->offSize > 4) {
2335 idx->startPos = pos + 3 + (idx->len + 1) * idx->offSize - 1;
2336 if (idx->startPos < 0 || idx->startPos >= len) {
2339 idx->endPos = idx->startPos + getUVarBE(pos + 3 + idx->len * idx->offSize,
2341 if (idx->endPos < idx->startPos || idx->endPos > len) {
2347 void FoFiType1C::getIndexVal(Type1CIndex *idx, int i,
2348 Type1CIndexVal *val, GBool *ok) {
2351 if (i < 0 || i >= idx->len) {
2355 pos0 = idx->startPos + getUVarBE(idx->pos + 3 + i * idx->offSize,
2357 pos1 = idx->startPos + getUVarBE(idx->pos + 3 + (i + 1) * idx->offSize,
2359 if (pos0 < idx->startPos || pos0 >= idx->endPos ||
2360 pos1 <= idx->startPos || pos1 > idx->endPos ||
2365 val->len = pos1 - pos0;
2368 char *FoFiType1C::getString(int sid, char *buf, GBool *ok) {
2373 strcpy(buf, fofiType1CStdStrings[sid]);
2376 getIndexVal(&stringIdx, sid, &val, ok);
2378 if ((n = val.len) > 255) {
2381 strncpy(buf, (char *)&file[val.pos], n);