Diffstat (limited to 'noncore/unsupported/qpdf/xpdf/GfxFont.cc') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/unsupported/qpdf/xpdf/GfxFont.cc | 62 |
1 files changed, 51 insertions, 11 deletions
diff --git a/noncore/unsupported/qpdf/xpdf/GfxFont.cc b/noncore/unsupported/qpdf/xpdf/GfxFont.cc index 518f97b..8d722d6 100644 --- a/noncore/unsupported/qpdf/xpdf/GfxFont.cc +++ b/noncore/unsupported/qpdf/xpdf/GfxFont.cc | |||
@@ -1,11 +1,11 @@ | |||
1 | //======================================================================== | 1 | //======================================================================== |
2 | // | 2 | // |
3 | // GfxFont.cc | 3 | // GfxFont.cc |
4 | // | 4 | // |
5 | // Copyright 1996-2001 Derek B. Noonburg | 5 | // Copyright 1996-2002 Glyph & Cog, LLC |
6 | // | 6 | // |
7 | //======================================================================== | 7 | //======================================================================== |
8 | 8 | ||
9 | #ifdef __GNUC__ | 9 | #ifdef __GNUC__ |
10 | #pragma implementation | 10 | #pragma implementation |
11 | #endif | 11 | #endif |
@@ -451,19 +451,30 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA, | |||
451 | } | 451 | } |
452 | obj2.free(); | 452 | obj2.free(); |
453 | } | 453 | } |
454 | } | 454 | } |
455 | obj1.free(); | 455 | obj1.free(); |
456 | 456 | ||
457 | // get Type3 font definition | 457 | // get Type 3 bounding box, font definition, and resources |
458 | if (type == fontType3) { | 458 | if (type == fontType3) { |
459 | fontDict->lookup("CharProcs", &charProcs); | 459 | if (fontDict->lookup("FontBBox", &obj1)->isArray()) { |
460 | if (!charProcs.isDict()) { | 460 | for (i = 0; i < 4 && i < obj1.arrayGetLength(); ++i) { |
461 | if (obj1.arrayGet(i, &obj2)->isNum()) { | ||
462 | fontBBox[i] = obj2.getNum(); | ||
463 | } | ||
464 | obj2.free(); | ||
465 | } | ||
466 | } | ||
467 | obj1.free(); | ||
468 | if (!fontDict->lookup("CharProcs", &charProcs)->isDict()) { | ||
461 | error(-1, "Missing or invalid CharProcs dictionary in Type 3 font"); | 469 | error(-1, "Missing or invalid CharProcs dictionary in Type 3 font"); |
462 | charProcs.free(); | 470 | charProcs.free(); |
463 | } | 471 | } |
472 | if (!fontDict->lookup("Resources", &resources)->isDict()) { | ||
473 | resources.free(); | ||
474 | } | ||
464 | } | 475 | } |
465 | 476 | ||
466 | //----- build the font encoding ----- | 477 | //----- build the font encoding ----- |
467 | 478 | ||
468 | // Encodings start with a base encoding, which can come from | 479 | // Encodings start with a base encoding, which can come from |
469 | // (in order of priority): | 480 | // (in order of priority): |
@@ -510,29 +521,34 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA, | |||
510 | } else if (obj1.isName("StandardEncoding")) { | 521 | } else if (obj1.isName("StandardEncoding")) { |
511 | hasEncoding = gTrue; | 522 | hasEncoding = gTrue; |
512 | baseEnc = standardEncoding; | 523 | baseEnc = standardEncoding; |
513 | } | 524 | } |
514 | 525 | ||
515 | // check embedded or external font file for base encoding | 526 | // check embedded or external font file for base encoding |
527 | // (only for Type 1 fonts - trying to get an encoding out of a | ||
528 | // TrueType font is a losing proposition) | ||
516 | fontFile = NULL; | 529 | fontFile = NULL; |
517 | buf = NULL; | 530 | buf = NULL; |
518 | if ((type == fontType1 || type == fontType1C || type == fontTrueType) && | 531 | if ((type == fontType1 || type == fontType1C) && |
519 | (extFontFile || embFontID.num >= 0)) { | 532 | (extFontFile || embFontID.num >= 0)) { |
520 | if (extFontFile) { | 533 | if (extFontFile) { |
521 | buf = readExtFontFile(&len); | 534 | buf = readExtFontFile(&len); |
522 | } else { | 535 | } else { |
523 | buf = readEmbFontFile(xref, &len); | 536 | buf = readEmbFontFile(xref, &len); |
524 | } | 537 | } |
525 | if (buf) { | 538 | if (buf) { |
526 | #if 0 | 539 | #if 0 |
540 | if (type == fontType1C && !strncmp(buf, "%!", 2)) { | ||
541 | // various tools (including Adobe's) occasionally embed Type 1 | ||
542 | // fonts but label them Type 1C | ||
543 | type = fontType1; | ||
544 | } | ||
527 | if (type == fontType1) { | 545 | if (type == fontType1) { |
528 | fontFile = new Type1FontFile(buf, len); | 546 | fontFile = new Type1FontFile(buf, len); |
529 | } else if (type == fontType1C) { | ||
530 | fontFile = new Type1CFontFile(buf, len); | ||
531 | } else { | 547 | } else { |
532 | fontFile = new TrueTypeFontFile(buf, len); | 548 | fontFile = new Type1CFontFile(buf, len); |
533 | } | 549 | } |
534 | if (fontFile->getName()) { | 550 | if (fontFile->getName()) { |
535 | if (embFontName) { | 551 | if (embFontName) { |
536 | delete embFontName; | 552 | delete embFontName; |
537 | } | 553 | } |
538 | embFontName = new GString(fontFile->getName()); | 554 | embFontName = new GString(fontFile->getName()); |
@@ -566,12 +582,13 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA, | |||
566 | } | 582 | } |
567 | 583 | ||
568 | // merge differences into encoding | 584 | // merge differences into encoding |
569 | if (obj1.isDict()) { | 585 | if (obj1.isDict()) { |
570 | obj1.dictLookup("Differences", &obj2); | 586 | obj1.dictLookup("Differences", &obj2); |
571 | if (obj2.isArray()) { | 587 | if (obj2.isArray()) { |
588 | hasEncoding = gTrue; | ||
572 | code = 0; | 589 | code = 0; |
573 | for (i = 0; i < obj2.arrayGetLength(); ++i) { | 590 | for (i = 0; i < obj2.arrayGetLength(); ++i) { |
574 | obj2.arrayGet(i, &obj3); | 591 | obj2.arrayGet(i, &obj3); |
575 | if (obj3.isInt()) { | 592 | if (obj3.isInt()) { |
576 | code = obj3.getInt(); | 593 | code = obj3.getInt(); |
577 | } else if (obj3.isName()) { | 594 | } else if (obj3.isName()) { |
@@ -633,14 +650,15 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA, | |||
633 | } else { | 650 | } else { |
634 | toUnicode[code] = 0; | 651 | toUnicode[code] = 0; |
635 | } | 652 | } |
636 | } | 653 | } |
637 | 654 | ||
638 | // pass 2: try to fill in the missing chars, looking for names of | 655 | // pass 2: try to fill in the missing chars, looking for names of |
639 | // the form 'Axx', 'xx', 'Ann', or 'nn', where 'A' is any letter, | 656 | // the form 'Axx', 'xx', 'Ann', 'ABnn', or 'nn', where 'A' and 'B' |
640 | // 'xx' is two hex digits, and 'nn' is 2-4 decimal digits | 657 | // are any letters, 'xx' is two hex digits, and 'nn' is 2-4 |
658 | // decimal digits | ||
641 | if (missing && globalParams->getMapNumericCharNames()) { | 659 | if (missing && globalParams->getMapNumericCharNames()) { |
642 | for (code = 0; code < 256; ++code) { | 660 | for (code = 0; code < 256; ++code) { |
643 | if ((charName = enc[code]) && !toUnicode[code] && | 661 | if ((charName = enc[code]) && !toUnicode[code] && |
644 | strcmp(charName, ".notdef")) { | 662 | strcmp(charName, ".notdef")) { |
645 | n = strlen(charName); | 663 | n = strlen(charName); |
646 | code2 = -1; | 664 | code2 = -1; |
@@ -653,12 +671,15 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA, | |||
653 | } else if (!hex && n >= 2 && n <= 4 && | 671 | } else if (!hex && n >= 2 && n <= 4 && |
654 | isdigit(charName[0]) && isdigit(charName[1])) { | 672 | isdigit(charName[0]) && isdigit(charName[1])) { |
655 | code2 = atoi(charName); | 673 | code2 = atoi(charName); |
656 | } else if (n >= 3 && n <= 5 && | 674 | } else if (n >= 3 && n <= 5 && |
657 | isdigit(charName[1]) && isdigit(charName[2])) { | 675 | isdigit(charName[1]) && isdigit(charName[2])) { |
658 | code2 = atoi(charName+1); | 676 | code2 = atoi(charName+1); |
677 | } else if (n >= 4 && n <= 6 && | ||
678 | isdigit(charName[2]) && isdigit(charName[3])) { | ||
679 | code2 = atoi(charName+2); | ||
659 | } | 680 | } |
660 | if (code2 >= 0 && code2 <= 0xff) { | 681 | if (code2 >= 0 && code2 <= 0xff) { |
661 | toUnicode[code] = (Unicode)code2; | 682 | toUnicode[code] = (Unicode)code2; |
662 | } | 683 | } |
663 | } | 684 | } |
664 | } | 685 | } |
@@ -681,16 +702,20 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA, | |||
681 | fontDict->lookup("LastChar", &obj1); | 702 | fontDict->lookup("LastChar", &obj1); |
682 | lastChar = obj1.isInt() ? obj1.getInt() : 255; | 703 | lastChar = obj1.isInt() ? obj1.getInt() : 255; |
683 | obj1.free(); | 704 | obj1.free(); |
684 | mul = (type == fontType3) ? fontMat[0] : fouble(0.001); | 705 | mul = (type == fontType3) ? fontMat[0] : fouble(0.001); |
685 | fontDict->lookup("Widths", &obj1); | 706 | fontDict->lookup("Widths", &obj1); |
686 | if (obj1.isArray()) { | 707 | if (obj1.isArray()) { |
708 | flags |= fontFixedWidth; | ||
687 | for (code = firstChar; code <= lastChar; ++code) { | 709 | for (code = firstChar; code <= lastChar; ++code) { |
688 | obj1.arrayGet(code - firstChar, &obj2); | 710 | obj1.arrayGet(code - firstChar, &obj2); |
689 | if (obj2.isNum()) { | 711 | if (obj2.isNum()) { |
690 | widths[code] = obj2.getNum() * mul; | 712 | widths[code] = obj2.getNum() * mul; |
713 | if (widths[code] != widths[firstChar]) { | ||
714 | flags &= ~fontFixedWidth; | ||
715 | } | ||
691 | } | 716 | } |
692 | obj2.free(); | 717 | obj2.free(); |
693 | } | 718 | } |
694 | 719 | ||
695 | // use widths from built-in font | 720 | // use widths from built-in font |
696 | } else if (builtinFont) { | 721 | } else if (builtinFont) { |
@@ -749,12 +774,15 @@ Gfx8BitFont::~Gfx8BitFont() { | |||
749 | } | 774 | } |
750 | } | 775 | } |
751 | ctu->decRefCnt(); | 776 | ctu->decRefCnt(); |
752 | if (charProcs.isDict()) { | 777 | if (charProcs.isDict()) { |
753 | charProcs.free(); | 778 | charProcs.free(); |
754 | } | 779 | } |
780 | if (resources.isDict()) { | ||
781 | resources.free(); | ||
782 | } | ||
755 | } | 783 | } |
756 | 784 | ||
757 | int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code, | 785 | int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code, |
758 | Unicode *u, int uSize, int *uLen, | 786 | Unicode *u, int uSize, int *uLen, |
759 | fouble *dx, fouble *dy, fouble *ox, fouble *oy) { | 787 | fouble *dx, fouble *dy, fouble *ox, fouble *oy) { |
760 | CharCode c; | 788 | CharCode c; |
@@ -768,21 +796,29 @@ int Gfx8BitFont::getNextChar(char *s, int len, CharCode *code, | |||
768 | 796 | ||
769 | CharCodeToUnicode *Gfx8BitFont::getToUnicode() { | 797 | CharCodeToUnicode *Gfx8BitFont::getToUnicode() { |
770 | ctu->incRefCnt(); | 798 | ctu->incRefCnt(); |
771 | return ctu; | 799 | return ctu; |
772 | } | 800 | } |
773 | 801 | ||
802 | Dict *Gfx8BitFont::getCharProcs() { | ||
803 | return charProcs.isDict() ? charProcs.getDict() : (Dict *)NULL; | ||
804 | } | ||
805 | |||
774 | Object *Gfx8BitFont::getCharProc(int code, Object *proc) { | 806 | Object *Gfx8BitFont::getCharProc(int code, Object *proc) { |
775 | if (charProcs.isDict()) { | 807 | if (charProcs.isDict()) { |
776 | charProcs.dictLookup(enc[code], proc); | 808 | charProcs.dictLookup(enc[code], proc); |
777 | } else { | 809 | } else { |
778 | proc->initNull(); | 810 | proc->initNull(); |
779 | } | 811 | } |
780 | return proc; | 812 | return proc; |
781 | } | 813 | } |
782 | 814 | ||
815 | Dict *Gfx8BitFont::getResources() { | ||
816 | return resources.isDict() ? resources.getDict() : (Dict *)NULL; | ||
817 | } | ||
818 | |||
783 | //------------------------------------------------------------------------ | 819 | //------------------------------------------------------------------------ |
784 | // GfxCIDFont | 820 | // GfxCIDFont |
785 | //------------------------------------------------------------------------ | 821 | //------------------------------------------------------------------------ |
786 | 822 | ||
787 | static int cmpWidthExcep(const void *w1, const void *w2) { | 823 | static int cmpWidthExcep(const void *w1, const void *w2) { |
788 | return ((GfxFontCIDWidthExcep *)w1)->first - | 824 | return ((GfxFontCIDWidthExcep *)w1)->first - |
@@ -1183,12 +1219,16 @@ int GfxCIDFont::getNextChar(char *s, int len, CharCode *code, | |||
1183 | *ox = vx; | 1219 | *ox = vx; |
1184 | *oy = vy; | 1220 | *oy = vy; |
1185 | 1221 | ||
1186 | return n; | 1222 | return n; |
1187 | } | 1223 | } |
1188 | 1224 | ||
1225 | int GfxCIDFont::getWMode() { | ||
1226 | return cMap ? cMap->getWMode() : 0; | ||
1227 | } | ||
1228 | |||
1189 | CharCodeToUnicode *GfxCIDFont::getToUnicode() { | 1229 | CharCodeToUnicode *GfxCIDFont::getToUnicode() { |
1190 | ctu->incRefCnt(); | 1230 | ctu->incRefCnt(); |
1191 | return ctu; | 1231 | return ctu; |
1192 | } | 1232 | } |
1193 | 1233 | ||
1194 | GString *GfxCIDFont::getCollection() { | 1234 | GString *GfxCIDFont::getCollection() { |
@@ -1213,13 +1253,13 @@ GfxFontDict::GfxFontDict(XRef *xref, Dict *fontDict) { | |||
1213 | obj1.getRef(), obj2.getDict()); | 1253 | obj1.getRef(), obj2.getDict()); |
1214 | if (fonts[i] && !fonts[i]->isOk()) { | 1254 | if (fonts[i] && !fonts[i]->isOk()) { |
1215 | delete fonts[i]; | 1255 | delete fonts[i]; |
1216 | fonts[i] = NULL; | 1256 | fonts[i] = NULL; |
1217 | } | 1257 | } |
1218 | } else { | 1258 | } else { |
1219 | error(-1, "font resource is not a dictionary"); | 1259 | error(-1, "font resource is not a dictionary reference"); |
1220 | fonts[i] = NULL; | 1260 | fonts[i] = NULL; |
1221 | } | 1261 | } |
1222 | obj1.free(); | 1262 | obj1.free(); |
1223 | obj2.free(); | 1263 | obj2.free(); |
1224 | } | 1264 | } |
1225 | } | 1265 | } |