From 28c37dbcf87665a4ccec58bef9ef8ff0697022dd Mon Sep 17 00:00:00 2001 From: Martin Kretzschmar Date: Mon, 31 Mar 2003 16:45:09 +0000 Subject: [PATCH] Import of Xpdf 2.00 for merge --- pdf/goo/GHash.cc | 5 +- pdf/goo/GHash.h | 4 +- pdf/goo/GList.cc | 5 +- pdf/goo/GList.h | 4 +- pdf/xpdf/Annot.cc | 5 +- pdf/xpdf/Annot.h | 4 +- pdf/xpdf/BuiltinFont.cc | 5 +- pdf/xpdf/BuiltinFont.h | 4 +- pdf/xpdf/BuiltinFontTables.cc | 3 +- pdf/xpdf/CMap.cc | 5 +- pdf/xpdf/CMap.h | 4 +- pdf/xpdf/CharCodeToUnicode.cc | 6 +- pdf/xpdf/CharCodeToUnicode.h | 4 +- pdf/xpdf/Decrypt.cc | 36 +- pdf/xpdf/Decrypt.h | 4 +- pdf/xpdf/FTFont.cc | 32 +- pdf/xpdf/FTFont.h | 4 +- pdf/xpdf/FontFile.cc | 709 ++++++++++++++++++++++------------ pdf/xpdf/FontFile.h | 43 ++- pdf/xpdf/Function.cc | 15 +- pdf/xpdf/Function.h | 4 +- pdf/xpdf/GlobalParams.cc | 86 ++++- pdf/xpdf/GlobalParams.h | 17 +- pdf/xpdf/NameToCharCode.cc | 5 +- pdf/xpdf/NameToCharCode.h | 4 +- pdf/xpdf/NameToUnicodeTable.h | 42 ++ pdf/xpdf/PSTokenizer.cc | 4 +- pdf/xpdf/PSTokenizer.h | 4 +- pdf/xpdf/SFont.cc | 5 +- pdf/xpdf/SFont.h | 4 +- pdf/xpdf/T1Font.cc | 49 ++- pdf/xpdf/T1Font.h | 6 +- pdf/xpdf/TTFont.cc | 8 +- pdf/xpdf/TTFont.h | 4 +- pdf/xpdf/UnicodeMap.cc | 15 +- pdf/xpdf/UnicodeMap.h | 12 +- pdf/xpdf/pdffonts.cc | 24 +- 37 files changed, 803 insertions(+), 391 deletions(-) diff --git a/pdf/goo/GHash.cc b/pdf/goo/GHash.cc index dc09f717..dfab9260 100644 --- a/pdf/goo/GHash.cc +++ b/pdf/goo/GHash.cc @@ -6,11 +6,12 @@ // //======================================================================== -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma implementation #endif -#include #include "gmem.h" #include "GString.h" #include "GHash.h" diff --git a/pdf/goo/GHash.h b/pdf/goo/GHash.h index 91d97006..8d73f3bb 100644 --- a/pdf/goo/GHash.h +++ b/pdf/goo/GHash.h @@ -9,7 +9,9 @@ #ifndef GHASH_H #define GHASH_H -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma interface #endif diff --git a/pdf/goo/GList.cc b/pdf/goo/GList.cc index f52bc262..accd73dc 100644 --- a/pdf/goo/GList.cc +++ b/pdf/goo/GList.cc @@ -6,11 +6,12 @@ // //======================================================================== -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma implementation #endif -#include #include #include "gmem.h" #include "GList.h" diff --git a/pdf/goo/GList.h b/pdf/goo/GList.h index 0ef4fd78..6a610ed1 100644 --- a/pdf/goo/GList.h +++ b/pdf/goo/GList.h @@ -9,7 +9,9 @@ #ifndef GLIST_H #define GLIST_H -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma interface #endif diff --git a/pdf/xpdf/Annot.cc b/pdf/xpdf/Annot.cc index b9c606f4..8ebf6a0c 100644 --- a/pdf/xpdf/Annot.cc +++ b/pdf/xpdf/Annot.cc @@ -6,11 +6,12 @@ // //======================================================================== -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma implementation #endif -#include #include "gmem.h" #include "Object.h" #include "Gfx.h" diff --git a/pdf/xpdf/Annot.h b/pdf/xpdf/Annot.h index 4113a0bd..731fa8a5 100644 --- a/pdf/xpdf/Annot.h +++ b/pdf/xpdf/Annot.h @@ -9,7 +9,9 @@ #ifndef ANNOT_H #define ANNOT_H -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma interface #endif diff --git a/pdf/xpdf/BuiltinFont.cc b/pdf/xpdf/BuiltinFont.cc index 1b070646..a504b4c3 100644 --- a/pdf/xpdf/BuiltinFont.cc +++ b/pdf/xpdf/BuiltinFont.cc @@ -6,11 +6,12 @@ // //======================================================================== -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma implementation #endif -#include #include #include #include "gmem.h" diff --git a/pdf/xpdf/BuiltinFont.h b/pdf/xpdf/BuiltinFont.h index a7953115..69d2e75d 100644 --- a/pdf/xpdf/BuiltinFont.h +++ b/pdf/xpdf/BuiltinFont.h @@ -9,7 +9,9 @@ #ifndef BUILTINFONT_H #define BUILTINFONT_H -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma interface #endif diff --git a/pdf/xpdf/BuiltinFontTables.cc b/pdf/xpdf/BuiltinFontTables.cc index 845abcd3..e2acfef8 100644 --- a/pdf/xpdf/BuiltinFontTables.cc +++ b/pdf/xpdf/BuiltinFontTables.cc @@ -1448,6 +1448,7 @@ static BuiltinFontWidth helveticaBoldWidthsTab[] = { { "ydieresis", 556, NULL }, { "Ccedilla", 722, NULL }, { "tilde", 333, NULL }, + { "dbldaggerumlaut", 556, NULL }, { "at", 975, NULL }, { "eacute", 556, NULL }, { "underscore", 556, NULL }, @@ -3346,7 +3347,7 @@ void initBuiltinFontTables() { builtinFonts[2].widths = new BuiltinFontWidths(courierBoldObliqueWidthsTab, 260); builtinFonts[3].widths = new BuiltinFontWidths(courierObliqueWidthsTab, 260); builtinFonts[4].widths = new BuiltinFontWidths(helveticaWidthsTab, 228); - builtinFonts[5].widths = new BuiltinFontWidths(helveticaBoldWidthsTab, 228); + builtinFonts[5].widths = new BuiltinFontWidths(helveticaBoldWidthsTab, 229); builtinFonts[6].widths = new BuiltinFontWidths(helveticaBoldObliqueWidthsTab, 228); builtinFonts[7].widths = new BuiltinFontWidths(helveticaObliqueWidthsTab, 228); builtinFonts[8].widths = new BuiltinFontWidths(symbolWidthsTab, 189); diff --git a/pdf/xpdf/CMap.cc b/pdf/xpdf/CMap.cc index b49cffdc..b0002183 100644 --- a/pdf/xpdf/CMap.cc +++ b/pdf/xpdf/CMap.cc @@ -6,11 +6,12 @@ // //======================================================================== -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma implementation #endif -#include #include #include #include diff --git a/pdf/xpdf/CMap.h b/pdf/xpdf/CMap.h index fe49acf7..ce926baf 100644 --- a/pdf/xpdf/CMap.h +++ b/pdf/xpdf/CMap.h @@ -9,7 +9,9 @@ #ifndef CMAP_H #define CMAP_H -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma interface #endif diff --git a/pdf/xpdf/CharCodeToUnicode.cc b/pdf/xpdf/CharCodeToUnicode.cc index 912981e9..f61d4007 100644 --- a/pdf/xpdf/CharCodeToUnicode.cc +++ b/pdf/xpdf/CharCodeToUnicode.cc @@ -6,11 +6,12 @@ // //======================================================================== -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma implementation #endif -#include #include #include #include "gmem.h" @@ -85,6 +86,7 @@ CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GString *collectionA) { } ++mapLenA; } + fclose(f); ctu = new CharCodeToUnicode(collectionA->copy(), mapA, mapLenA, gTrue, NULL, 0); diff --git a/pdf/xpdf/CharCodeToUnicode.h b/pdf/xpdf/CharCodeToUnicode.h index 06916c8f..9cbd2a96 100644 --- a/pdf/xpdf/CharCodeToUnicode.h +++ b/pdf/xpdf/CharCodeToUnicode.h @@ -11,7 +11,9 @@ #ifndef CHARCODETOUNICODE_H #define CHARCODETOUNICODE_H -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma interface #endif diff --git a/pdf/xpdf/Decrypt.cc b/pdf/xpdf/Decrypt.cc index 8de40911..bb3e3f1f 100644 --- a/pdf/xpdf/Decrypt.cc +++ b/pdf/xpdf/Decrypt.cc @@ -6,11 +6,12 @@ // //======================================================================== -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma implementation #endif -#include #include "gmem.h" #include "Decrypt.h" @@ -65,11 +66,12 @@ GBool Decrypt::makeFileKey(int encVersion, int encRevision, int keyLength, int permissions, GString *fileID, GString *ownerPassword, GString *userPassword, Guchar *fileKey, GBool *ownerPasswordOk) { - Guchar test[32]; + Guchar test[32], test2[32]; GString *userPassword2; Guchar fState[256]; + Guchar tmpKey[16]; Guchar fx, fy; - int len, i; + int len, i, j; // try using the supplied owner password to generate the user password if (ownerPassword) { @@ -89,12 +91,26 @@ GBool Decrypt::makeFileKey(int encVersion, int encRevision, int keyLength, md5(test, 16, test); } } - rc4InitKey(test, keyLength, fState); - fx = fy = 0; - for (i = 0; i < 32; ++i) { - test[i] = rc4DecryptByte(fState, &fx, &fy, ownerKey->getChar(i)); + if (encRevision == 2) { + rc4InitKey(test, keyLength, fState); + fx = fy = 0; + for (i = 0; i < 32; ++i) { + test2[i] = rc4DecryptByte(fState, &fx, &fy, ownerKey->getChar(i)); + } + } else { + memcpy(test2, ownerKey->getCString(), 32); + for (i = 19; i >= 0; --i) { + for (j = 0; j < keyLength; ++j) { + tmpKey[j] = test[j] ^ i; + } + rc4InitKey(tmpKey, keyLength, fState); + fx = fy = 0; + for (j = 0; j < 32; ++j) { + test2[j] = rc4DecryptByte(fState, &fx, &fy, test2[j]); + } + } } - userPassword2 = new GString((char *)test, 32); + userPassword2 = new GString((char *)test2, 32); if (makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey, permissions, fileID, userPassword2, fileKey)) { *ownerPasswordOk = gTrue; @@ -143,7 +159,7 @@ GBool Decrypt::makeFileKey2(int encVersion, int encRevision, int keyLength, md5(buf, 68 + fileID->getLength(), fileKey); if (encRevision == 3) { for (i = 0; i < 50; ++i) { - md5(fileKey, 16, fileKey); + md5(fileKey, keyLength, fileKey); } } diff --git a/pdf/xpdf/Decrypt.h b/pdf/xpdf/Decrypt.h index 52afb2f6..903ee12b 100644 --- a/pdf/xpdf/Decrypt.h +++ b/pdf/xpdf/Decrypt.h @@ -9,7 +9,9 @@ #ifndef DECRYPT_H #define DECRYPT_H -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma interface #endif diff --git a/pdf/xpdf/FTFont.cc b/pdf/xpdf/FTFont.cc index 0524c7ed..8de09e0e 100644 --- a/pdf/xpdf/FTFont.cc +++ b/pdf/xpdf/FTFont.cc @@ -6,14 +6,14 @@ // //======================================================================== -#ifdef __GNUC__ -#pragma implementation -#endif - #include #if FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H) +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + #include #include #include "gmem.h" @@ -261,15 +261,11 @@ FTFont::FTFont(FTFontFile *fontFileA, double *m) { yMax = (int)(1.2 * size); } // this should be (max - min + 1), but we add some padding to - // deal with rounding errors + // deal with rounding errors, bogus bboxes, etc. glyphW = xMax - xMin + 3; + glyphW += glyphW >> 1; glyphH = yMax - yMin + 3; - // another kludge: some CJK TT fonts have bogus bboxes, so add more - // padding - if (face->num_glyphs > 1000) { - glyphW += glyphW >> 1; - glyphH += glyphH >> 1; - } + glyphH += glyphH >> 1; if (engine->aa) { glyphSize = glyphW * glyphH; } else { @@ -444,9 +440,9 @@ Guchar *FTFont::getGlyphPixmap(CharCode c, Unicode u, int *x, int *y, int *w, int *h) { FT_GlyphSlot slot; FT_UInt idx; - int gSize; + int rowSize; int i, j, k; - Guchar *ret; + Guchar *ret, *p, *q; // check the cache i = (c & (cacheSets - 1)) * cacheAssoc; @@ -516,12 +512,16 @@ Guchar *FTFont::getGlyphPixmap(CharCode c, Unicode u, cacheTags[i+j].w = *w; cacheTags[i+j].h = *h; if (fontFile->engine->aa) { - gSize = *w * *h; + rowSize = *w; } else { - gSize = ((*w + 7) >> 3) * *h; + rowSize = (*w + 7) >> 3; } ret = cache + (i+j) * glyphSize; - memcpy(ret, slot->bitmap.buffer, gSize); + for (k = 0, p = ret, q = slot->bitmap.buffer; + k < slot->bitmap.rows; + ++k, p += rowSize, q += slot->bitmap.pitch) { + memcpy(p, q, rowSize); + } } else { ++cacheTags[i+j].mru; } diff --git a/pdf/xpdf/FTFont.h b/pdf/xpdf/FTFont.h index 4894a316..02c257ad 100644 --- a/pdf/xpdf/FTFont.h +++ b/pdf/xpdf/FTFont.h @@ -11,9 +11,11 @@ #ifndef FTFONT_H #define FTFONT_H +#include + #if FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H) -#ifdef __GNUC__ +#ifdef USE_GCC_PRAGMAS #pragma interface #endif diff --git a/pdf/xpdf/FontFile.cc b/pdf/xpdf/FontFile.cc index ae585470..74769096 100644 --- a/pdf/xpdf/FontFile.cc +++ b/pdf/xpdf/FontFile.cc @@ -6,14 +6,16 @@ // //======================================================================== -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma implementation #endif -#include #include #include #include +#include #include #include #include "gmem.h" @@ -344,10 +346,11 @@ void Type1CFontFile::readNameAndEncoding() { } } -void Type1CFontFile::convertToType1(FILE *outA) { +void Type1CFontFile::convertToType1(FontFileOutputFunc outputFuncA, + void *outputStreamA) { Type1CTopDict dict; Type1CPrivateDict privateDict; - char buf[256], eBuf[256]; + char buf[512], eBuf[256]; Guchar *idxPtr0, *idxPtr1, *subrsIdxPtr, *charStringsIdxPtr, *ptr; int nGlyphs, nCodes, nRanges, nLeft, nSups; Gushort *glyphNames; @@ -355,7 +358,8 @@ void Type1CFontFile::convertToType1(FILE *outA) { int c, sid; int i, j, n; - out = outA; + outputFunc = outputFuncA; + outputStream = outputStreamA; // read top dict (first font only) readTopDict(&dict); @@ -364,54 +368,81 @@ void Type1CFontFile::convertToType1(FILE *outA) { //~ ... global subrs are unimplemented // write header and font dictionary, up to encoding - fprintf(out, "%%!FontType1-1.0: %s", name->getCString()); + (*outputFunc)(outputStream, "%!FontType1-1.0: ", 17); + (*outputFunc)(outputStream, name->getCString(), name->getLength()); if (dict.version != 0) { - fprintf(out, "%s", getString(dict.version, buf)); + getString(dict.version, buf); + (*outputFunc)(outputStream, buf, strlen(buf)); } - fprintf(out, "\n"); - fprintf(out, "11 dict begin\n"); - fprintf(out, "/FontInfo 10 dict dup begin\n"); + (*outputFunc)(outputStream, "\n", 1); + (*outputFunc)(outputStream, "11 dict begin\n", 14); + (*outputFunc)(outputStream, "/FontInfo 10 dict dup begin\n", 28); if (dict.version != 0) { - fprintf(out, "/version (%s) readonly def\n", - getString(dict.version, buf)); + (*outputFunc)(outputStream, "/version (", 10); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, ") readonly def\n", 15); } if (dict.notice != 0) { - fprintf(out, "/Notice (%s) readonly def\n", - getString(dict.notice, buf)); + getString(dict.notice, buf); + (*outputFunc)(outputStream, "/Notice (", 9); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, ") readonly def\n", 15); } if (dict.copyright != 0) { - fprintf(out, "/Copyright (%s) readonly def\n", - getString(dict.copyright, buf)); + getString(dict.copyright, buf); + (*outputFunc)(outputStream, "/Copyright (", 12); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, ") readonly def\n", 15); } if (dict.fullName != 0) { - fprintf(out, "/FullName (%s) readonly def\n", - getString(dict.fullName, buf)); + getString(dict.fullName, buf); + (*outputFunc)(outputStream, "/FullName (", 11); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, ") readonly def\n", 15); } if (dict.familyName != 0) { - fprintf(out, "/FamilyName (%s) readonly def\n", - getString(dict.familyName, buf)); + getString(dict.familyName, buf); + (*outputFunc)(outputStream, "/FamilyName (", 13); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, ") readonly def\n", 15); } if (dict.weight != 0) { - fprintf(out, "/Weight (%s) readonly def\n", - getString(dict.weight, buf)); - } - fprintf(out, "/isFixedPitch %s def\n", dict.isFixedPitch ? "true" : "false"); - fprintf(out, "/ItalicAngle %g def\n", dict.italicAngle); - fprintf(out, "/UnderlinePosition %g def\n", dict.underlinePosition); - fprintf(out, "/UnderlineThickness %g def\n", dict.underlineThickness); - fprintf(out, "end readonly def\n"); - fprintf(out, "/FontName /%s def\n", name->getCString()); - fprintf(out, "/PaintType %d def\n", dict.paintType); - fprintf(out, "/FontType 1 def\n"); - fprintf(out, "/FontMatrix [%g %g %g %g %g %g] readonly def\n", + getString(dict.weight, buf); + (*outputFunc)(outputStream, "/Weight (", 9); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, ") readonly def\n", 15); + } + if (dict.isFixedPitch) { + (*outputFunc)(outputStream, "/isFixedPitch true def\n", 23); + } else { + (*outputFunc)(outputStream, "/isFixedPitch false def\n", 24); + } + sprintf(buf, "/ItalicAngle %g def\n", dict.italicAngle); + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, "/UnderlinePosition %g def\n", dict.underlinePosition); + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, "/UnderlineThickness %g def\n", dict.underlineThickness); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "end readonly def\n", 17); + (*outputFunc)(outputStream, "/FontName /", 11); + (*outputFunc)(outputStream, name->getCString(), name->getLength()); + (*outputFunc)(outputStream, " def\n", 5); + sprintf(buf, "/PaintType %d def\n", dict.paintType); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/FontType 1 def\n", 16); + sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] readonly def\n", dict.fontMatrix[0], dict.fontMatrix[1], dict.fontMatrix[2], dict.fontMatrix[3], dict.fontMatrix[4], dict.fontMatrix[5]); - fprintf(out, "/FontBBox [%g %g %g %g] readonly def\n", + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, "/FontBBox [%g %g %g %g] readonly def\n", dict.fontBBox[0], dict.fontBBox[1], dict.fontBBox[2], dict.fontBBox[3]); - fprintf(out, "/StrokeWidth %g def\n", dict.strokeWidth); + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, "/StrokeWidth %g def\n", dict.strokeWidth); + (*outputFunc)(outputStream, buf, strlen(buf)); if (dict.uniqueID != 0) { - fprintf(out, "/UniqueID %d def\n", dict.uniqueID); + sprintf(buf, "/UniqueID %d def\n", dict.uniqueID); + (*outputFunc)(outputStream, buf, strlen(buf)); } // get number of glyphs from charstrings index @@ -421,16 +452,18 @@ void Type1CFontFile::convertToType1(FILE *outA) { glyphNames = readCharset(dict.charset, nGlyphs); // read encoding (glyph -> code mapping), write Type 1 encoding - fprintf(out, "/Encoding "); + (*outputFunc)(outputStream, "/Encoding ", 10); if (dict.encoding == 0) { - fprintf(out, "StandardEncoding def\n"); + (*outputFunc)(outputStream, "StandardEncoding def\n", 21); } else { - fprintf(out, "256 array\n"); - fprintf(out, "0 1 255 {1 index exch /.notdef put} for\n"); + (*outputFunc)(outputStream, "256 array\n", 10); + (*outputFunc)(outputStream, + "0 1 255 {1 index exch /.notdef put} for\n", 40); if (dict.encoding == 1) { for (i = 0; i < 256; ++i) { if (expertEncoding[i]) { - fprintf(out, "dup %d /%s put\n", i, expertEncoding[i]); + sprintf(buf, "dup %d /%s put\n", i, expertEncoding[i]); + (*outputFunc)(outputStream, buf, strlen(buf)); } } } else { @@ -443,8 +476,11 @@ void Type1CFontFile::convertToType1(FILE *outA) { } for (i = 1; i < nCodes; ++i) { c = *ptr++; - fprintf(out, "dup %d /%s put\n", - c, getString(glyphNames[i], buf)); + sprintf(buf, "dup %d /", c); + (*outputFunc)(outputStream, buf, strlen(buf)); + getString(glyphNames[i], buf); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, " put\n", 5); } } else if ((encFormat & 0x7f) == 1) { nRanges = *ptr++; @@ -453,8 +489,11 @@ void Type1CFontFile::convertToType1(FILE *outA) { c = *ptr++; nLeft = *ptr++; for (j = 0; j <= nLeft && nCodes < nGlyphs; ++j) { - fprintf(out, "dup %d /%s put\n", - c, getString(glyphNames[nCodes], buf)); + sprintf(buf, "dup %d /", c); + (*outputFunc)(outputStream, buf, strlen(buf)); + getString(glyphNames[nCodes], buf); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, " put\n", 5); ++nCodes; ++c; } @@ -466,16 +505,20 @@ void Type1CFontFile::convertToType1(FILE *outA) { c = *ptr++; sid = getWord(ptr, 2); ptr += 2; - fprintf(out, "dup %d /%s put\n", c, getString(sid, buf)); + sprintf(buf, "dup %d /", c); + (*outputFunc)(outputStream, buf, strlen(buf)); + getString(sid, buf); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, " put\n", 5); } } } - fprintf(out, "readonly def\n"); + (*outputFunc)(outputStream, "readonly def\n", 13); } - fprintf(out, "currentdict end\n"); + (*outputFunc)(outputStream, "currentdict end\n", 16); // start the binary section - fprintf(out, "currentfile eexec\n"); + (*outputFunc)(outputStream, "currentfile eexec\n", 18); r1 = 55665; line = 0; @@ -538,12 +581,12 @@ void Type1CFontFile::convertToType1(FILE *outA) { // trailer if (line > 0) { - fputc('\n', out); + (*outputFunc)(outputStream, "\n", 1); } for (i = 0; i < 8; ++i) { - fprintf(out, "0000000000000000000000000000000000000000000000000000000000000000\n"); + (*outputFunc)(outputStream, "0000000000000000000000000000000000000000000000000000000000000000\n", 65); } - fprintf(out, "cleartomark\n"); + (*outputFunc)(outputStream, "cleartomark\n", 12); // clean up delete privateDict.dictData; @@ -552,7 +595,9 @@ void Type1CFontFile::convertToType1(FILE *outA) { } } -void Type1CFontFile::convertToCIDType0(char *psName, FILE *outA) { +void Type1CFontFile::convertToCIDType0(char *psName, + FontFileOutputFunc outputFuncA, + void *outputStreamA) { Type1CTopDict dict; Type1CPrivateDict *privateDicts; GString *charStrings; @@ -561,7 +606,7 @@ void Type1CFontFile::convertToCIDType0(char *psName, FILE *outA) { int *cidMap; Guchar *fdSelect; Guchar *charStringsIdxPtr, *fdArrayIdx, *idxPtr0, *idxPtr1, *ptr; - char buf[256]; + char buf[512], buf2[16]; int nGlyphs, nCIDs, gdBytes, nFDs; int fdSelectFmt, nRanges, gid0, gid1, fd, offset; int key; @@ -569,9 +614,10 @@ void Type1CFontFile::convertToCIDType0(char *psName, FILE *outA) { GBool isFP; int i, j, k, n; - out = outA; + outputFunc = outputFuncA; + outputStream = outputStreamA; - fprintf(out, "/CIDInit /ProcSet findresource begin\n"); + (*outputFunc)(outputStream, "/CIDInit /ProcSet findresource begin\n", 37); // read top dict (first font only) readTopDict(&dict); @@ -718,65 +764,84 @@ void Type1CFontFile::convertToCIDType0(char *psName, FILE *outA) { } // begin the font dictionary - fprintf(out, "20 dict begin\n"); - fprintf(out, "/CIDFontName /%s def\n", psName); - fprintf(out, "/CIDFontType 0 def\n"); - fprintf(out, "/CIDSystemInfo 3 dict dup begin\n"); + (*outputFunc)(outputStream, "20 dict begin\n", 14); + (*outputFunc)(outputStream, "/CIDFontName /", 14); + (*outputFunc)(outputStream, psName, strlen(psName)); + (*outputFunc)(outputStream, " def\n", 5); + (*outputFunc)(outputStream, "/CIDFontType 0 def\n", 19); + (*outputFunc)(outputStream, "/CIDSystemInfo 3 dict dup begin\n", 32); if (dict.registry > 0 && dict.ordering > 0) { - fprintf(out, " /Registry (%s) def\n", getString(dict.registry, buf)); - fprintf(out, " /Ordering (%s) def\n", getString(dict.ordering, buf)); + getString(dict.registry, buf); + (*outputFunc)(outputStream, " /Registry (", 13); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, ") def\n", 6); + getString(dict.ordering, buf); + (*outputFunc)(outputStream, " /Ordering (", 13); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, ") def\n", 6); } else { - fprintf(out, " /Registry (Adobe) def\n"); - fprintf(out, " /Ordering (Identity) def\n"); + (*outputFunc)(outputStream, " /Registry (Adobe) def\n", 24); + (*outputFunc)(outputStream, " /Ordering (Identity) def\n", 27); } - fprintf(out, " /Supplement %d def\n", dict.supplement); - fprintf(out, "end def\n"); - fprintf(out, "/FontMatrix [%g %g %g %g %g %g] def\n", + sprintf(buf, " /Supplement %d def\n", dict.supplement); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "end def\n", 8); + sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n", dict.fontMatrix[0], dict.fontMatrix[1], dict.fontMatrix[2], dict.fontMatrix[3], dict.fontMatrix[4], dict.fontMatrix[5]); - fprintf(out, "/FontBBox [%g %g %g %g] def\n", + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, "/FontBBox [%g %g %g %g] def\n", dict.fontBBox[0], dict.fontBBox[1], dict.fontBBox[2], dict.fontBBox[3]); - fprintf(out, "/FontInfo 1 dict dup begin\n"); - fprintf(out, " /FSType 8 def\n"); - fprintf(out, "end def\n"); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/FontInfo 1 dict dup begin\n", 27); + (*outputFunc)(outputStream, " /FSType 8 def\n", 16); + (*outputFunc)(outputStream, "end def\n", 8); // CIDFont-specific entries - fprintf(out, "/CIDCount %d def\n", nCIDs); - fprintf(out, "/FDBytes 1 def\n"); - fprintf(out, "/GDBytes %d def\n", gdBytes); - fprintf(out, "/CIDMapOffset 0 def\n"); + sprintf(buf, "/CIDCount %d def\n", nCIDs); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/FDBytes 1 def\n", 15); + sprintf(buf, "/GDBytes %d def\n", gdBytes); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/CIDMapOffset 0 def\n", 20); if (dict.paintType != 0) { - fprintf(out, "/PaintType %d def\n", dict.paintType); - fprintf(out, "/StrokeWidth %g def\n", dict.strokeWidth); + sprintf(buf, "/PaintType %d def\n", dict.paintType); + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, "/StrokeWidth %g def\n", dict.strokeWidth); + (*outputFunc)(outputStream, buf, strlen(buf)); } // FDArray entry - fprintf(out, "/FDArray %d array\n", nFDs); + sprintf(buf, "/FDArray %d array\n", nFDs); + (*outputFunc)(outputStream, buf, strlen(buf)); for (i = 0; i < nFDs; ++i) { - fprintf(out, "dup %d 10 dict begin\n", i); - fprintf(out, "/FontType 1 def\n"); - fprintf(out, "/FontMatrix [1 0 0 1 0 0] def\n"); - fprintf(out, "/PaintType %d def\n", dict.paintType); - fprintf(out, "/Private 32 dict begin\n"); - fwrite(privateDicts[i].dictData->getCString(), 1, - privateDicts[i].dictData->getLength(), out); - fprintf(out, "currentdict end def\n"); - fprintf(out, "currentdict end put\n"); - } - fprintf(out, "def\n"); + sprintf(buf, "dup %d 10 dict begin\n", i); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/FontType 1 def\n", 16); + (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); + sprintf(buf, "/PaintType %d def\n", dict.paintType); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/Private 32 dict begin\n", 23); + (*outputFunc)(outputStream, privateDicts[i].dictData->getCString(), + privateDicts[i].dictData->getLength()); + (*outputFunc)(outputStream, "currentdict end def\n", 20); + (*outputFunc)(outputStream, "currentdict end put\n", 20); + } + (*outputFunc)(outputStream, "def\n", 4); //~ need to deal with subrs // start the binary section offset = (nCIDs + 1) * (1 + gdBytes); - fprintf(out, "(Hex) %d StartData\n", + sprintf(buf, "(Hex) %d StartData\n", offset + charStrings->getLength()); + (*outputFunc)(outputStream, buf, strlen(buf)); // write the charstring offset (CIDMap) table for (i = 0; i <= nCIDs; i += 6) { for (j = 0; j < 6 && i+j <= nCIDs; ++j) { - if (cidMap[i+j] >= 0) { + if (i+j < nCIDs && cidMap[i+j] >= 0) { buf[0] = (char)fdSelect[cidMap[i+j]]; } else { buf[0] = (char)0; @@ -787,22 +852,24 @@ void Type1CFontFile::convertToCIDType0(char *psName, FILE *outA) { n >>= 8; } for (k = 0; k <= gdBytes; ++k) { - fprintf(out, "%02x", buf[k] & 0xff); + sprintf(buf2, "%02x", buf[k] & 0xff); + (*outputFunc)(outputStream, buf2, 2); } } - fputc('\n', out); + (*outputFunc)(outputStream, "\n", 1); } // write the charstring data n = charStrings->getLength(); for (i = 0; i < n; i += 32) { for (j = 0; j < 32 && i+j < n; ++j) { - fprintf(out, "%02x", charStrings->getChar(i+j) & 0xff); + sprintf(buf, "%02x", charStrings->getChar(i+j) & 0xff); + (*outputFunc)(outputStream, buf, strlen(buf)); } if (i + 32 >= n) { - fputc('>', out); + (*outputFunc)(outputStream, ">", 1); } - fputc('\n', out); + (*outputFunc)(outputStream, "\n", 1); } for (i = 0; i < nFDs; ++i) { @@ -816,14 +883,16 @@ void Type1CFontFile::convertToCIDType0(char *psName, FILE *outA) { gfree(fdSelect); } -void Type1CFontFile::convertToType0(char *psName, FILE *outA) { +void Type1CFontFile::convertToType0(char *psName, + FontFileOutputFunc outputFuncA, + void *outputStreamA) { Type1CTopDict dict; Type1CPrivateDict *privateDicts; Gushort *charset; int *cidMap; Guchar *fdSelect; Guchar *charStringsIdxPtr, *fdArrayIdx, *idxPtr0, *idxPtr1, *ptr; - char buf[256]; + char buf[512]; char eBuf[256]; int nGlyphs, nCIDs, nFDs; int fdSelectFmt, nRanges, gid0, gid1, fd; @@ -832,7 +901,8 @@ void Type1CFontFile::convertToType0(char *psName, FILE *outA) { GBool isFP; int i, j, n; - out = outA; + outputFunc = outputFuncA; + outputStream = outputStreamA; // read top dict (first font only) readTopDict(&dict); @@ -957,28 +1027,36 @@ void Type1CFontFile::convertToType0(char *psName, FILE *outA) { } // font dictionary (unencrypted section) - fprintf(out, "16 dict begin\n"); - fprintf(out, "/FontName /%s_%02x def\n", psName, i >> 8); - fprintf(out, "/FontType 1 def\n"); - fprintf(out, "/FontMatrix [%g %g %g %g %g %g] def\n", + (*outputFunc)(outputStream, "16 dict begin\n", 14); + (*outputFunc)(outputStream, "/FontName /", 11); + (*outputFunc)(outputStream, psName, strlen(psName)); + sprintf(buf, "_%02x def\n", i >> 8); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/FontType 1 def\n", 16); + sprintf(buf, "/FontMatrix [%g %g %g %g %g %g] def\n", dict.fontMatrix[0], dict.fontMatrix[1], dict.fontMatrix[2], dict.fontMatrix[3], dict.fontMatrix[4], dict.fontMatrix[5]); - fprintf(out, "/FontBBox [%g %g %g %g] def\n", + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, "/FontBBox [%g %g %g %g] def\n", dict.fontBBox[0], dict.fontBBox[1], dict.fontBBox[2], dict.fontBBox[3]); - fprintf(out, "/PaintType %d def\n", dict.paintType); + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, "/PaintType %d def\n", dict.paintType); + (*outputFunc)(outputStream, buf, strlen(buf)); if (dict.paintType != 0) { - fprintf(out, "/StrokeWidth %g def\n", dict.strokeWidth); + sprintf(buf, "/StrokeWidth %g def\n", dict.strokeWidth); + (*outputFunc)(outputStream, buf, strlen(buf)); } - fprintf(out, "/Encoding 256 array\n"); + (*outputFunc)(outputStream, "/Encoding 256 array\n", 20); for (j = 0; j < 256 && i+j < nCIDs; ++j) { - fprintf(out, "dup %d /c%02x put\n", j, j); + sprintf(buf, "dup %d /c%02x put\n", j, j); + (*outputFunc)(outputStream, buf, strlen(buf)); } - fprintf(out, "readonly def\n"); - fprintf(out, "currentdict end\n"); + (*outputFunc)(outputStream, "readonly def\n", 13); + (*outputFunc)(outputStream, "currentdict end\n", 16); // start the binary section - fprintf(out, "currentfile eexec\n"); + (*outputFunc)(outputStream, "currentfile eexec\n", 18); r1 = 55665; line = 0; @@ -1024,31 +1102,37 @@ void Type1CFontFile::convertToType0(char *psName, FILE *outA) { // trailer if (line > 0) { - fputc('\n', out); + (*outputFunc)(outputStream, "\n", 1); } for (j = 0; j < 8; ++j) { - fprintf(out, "0000000000000000000000000000000000000000000000000000000000000000\n"); + (*outputFunc)(outputStream, "0000000000000000000000000000000000000000000000000000000000000000\n", 65); } - fprintf(out, "cleartomark\n"); + (*outputFunc)(outputStream, "cleartomark\n", 12); } // write the Type 0 parent font - fprintf(out, "16 dict begin\n"); - fprintf(out, "/FontName /%s def\n", psName); - fprintf(out, "/FontType 0 def\n"); - fprintf(out, "/FontMatrix [1 0 0 1 0 0] def\n"); - fprintf(out, "/FMapType 2 def\n"); - fprintf(out, "/Encoding [\n"); + (*outputFunc)(outputStream, "16 dict begin\n", 14); + (*outputFunc)(outputStream, "/FontName /", 11); + (*outputFunc)(outputStream, psName, strlen(psName)); + (*outputFunc)(outputStream, " def\n", 5); + (*outputFunc)(outputStream, "/FontType 0 def\n", 16); + (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); + (*outputFunc)(outputStream, "/FMapType 2 def\n", 16); + (*outputFunc)(outputStream, "/Encoding [\n", 12); for (i = 0; i < nCIDs; i += 256) { - fprintf(out, "%d\n", i >> 8); + sprintf(buf, "%d\n", i >> 8); + (*outputFunc)(outputStream, buf, strlen(buf)); } - fprintf(out, "] def\n"); - fprintf(out, "/FDepVector [\n"); + (*outputFunc)(outputStream, "] def\n", 6); + (*outputFunc)(outputStream, "/FDepVector [\n", 14); for (i = 0; i < nCIDs; i += 256) { - fprintf(out, "/%s_%02x findfont\n", psName, i >> 8); + (*outputFunc)(outputStream, "/", 1); + (*outputFunc)(outputStream, psName, strlen(psName)); + sprintf(buf, "_%02x findfont\n", i >> 8); + (*outputFunc)(outputStream, buf, strlen(buf)); } - fprintf(out, "] def\n"); - fprintf(out, "FontName currentdict end definefont pop\n"); + (*outputFunc)(outputStream, "] def\n", 6); + (*outputFunc)(outputStream, "FontName currentdict end definefont pop\n", 40); // clean up for (i = 0; i < nFDs; ++i) { @@ -1328,11 +1412,11 @@ void Type1CFontFile::eexecWrite(char *s) { for (p = (Guchar *)s; *p; ++p) { x = *p ^ (r1 >> 8); r1 = (x + r1) * 52845 + 22719; - fputc(hexChars[x >> 4], out); - fputc(hexChars[x & 0x0f], out); + (*outputFunc)(outputStream, &hexChars[x >> 4], 1); + (*outputFunc)(outputStream, &hexChars[x & 0x0f], 1); line += 2; if (line == 64) { - fputc('\n', out); + (*outputFunc)(outputStream, "\n", 1); line = 0; } } @@ -2004,11 +2088,11 @@ void Type1CFontFile::eexecWriteCharstring(Guchar *s, int n) { for (i = 0; i < n; ++i) { x = s[i] ^ (r1 >> 8); r1 = (x + r1) * 52845 + 22719; - fputc(hexChars[x >> 4], out); - fputc(hexChars[x & 0x0f], out); + (*outputFunc)(outputStream, &hexChars[x >> 4], 1); + (*outputFunc)(outputStream, &hexChars[x & 0x0f], 1); line += 2; if (line == 64) { - fputc('\n', out); + (*outputFunc)(outputStream, "\n", 1); line = 0; } } @@ -2529,7 +2613,8 @@ enum T42FontIndexMode { }; TrueTypeFontFile::TrueTypeFontFile(char *fileA, int lenA) { - int pos, i; + int pos, i, idx, n, length; + Guint size, startPos, endPos; file = fileA; len = lenA; @@ -2563,6 +2648,31 @@ TrueTypeFontFile::TrueTypeFontFile(char *fileA, int lenA) { return; } + // some embedded TrueType fonts have an incorrect (too small) cmap + // table size + idx = seekTableIdx("cmap"); + if (idx >= 0) { + pos = tableHdrs[idx].offset; + n = getUShort(pos + 2); + size = (Guint)(4 + 8 * n); + for (i = 0; i < n; ++i) { + startPos = getULong(pos + 4 + 8*i + 4); + length = getUShort(pos + startPos + 2); + endPos = startPos + length; + if (endPos > size) { + size = endPos; + } + } + if ((mungedCmapSize = size > tableHdrs[idx].length)) { +#if 0 // don't bother printing this error message - it's too common + error(-1, "Bad cmap table size in TrueType font"); +#endif + tableHdrs[idx].length = size; + } + } else { + mungedCmapSize = gFalse; + } + // read the 'head' table pos = seekTable("head"); bbox[0] = getShort(pos + 36); @@ -2766,168 +2876,215 @@ char **TrueTypeFontFile::getEncoding() { void TrueTypeFontFile::convertToType42(char *name, char **encodingA, CharCodeToUnicode *toUnicode, - GBool pdfFontHasEncoding, FILE *out) { + GBool pdfFontHasEncoding, + FontFileOutputFunc outputFunc, + void *outputStream) { + char buf[512]; + // write the header - fprintf(out, "%%!PS-TrueTypeFont-%g\n", getFixed(0)); + sprintf(buf, "%%!PS-TrueTypeFont-%g\n", getFixed(0)); + (*outputFunc)(outputStream, buf, strlen(buf)); // begin the font dictionary - fprintf(out, "10 dict begin\n"); - fprintf(out, "/FontName /%s def\n", name); - fprintf(out, "/FontType 42 def\n"); - fprintf(out, "/FontMatrix [1 0 0 1 0 0] def\n"); - fprintf(out, "/FontBBox [%d %d %d %d] def\n", + (*outputFunc)(outputStream, "10 dict begin\n", 14); + (*outputFunc)(outputStream, "/FontName /", 11); + (*outputFunc)(outputStream, name, strlen(name)); + (*outputFunc)(outputStream, " def\n", 5); + (*outputFunc)(outputStream, "/FontType 42 def\n", 17); + (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); + sprintf(buf, "/FontBBox [%d %d %d %d] def\n", bbox[0], bbox[1], bbox[2], bbox[3]); - fprintf(out, "/PaintType 0 def\n"); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/PaintType 0 def\n", 17); // write the guts of the dictionary - cvtEncoding(encodingA, out); - cvtCharStrings(encodingA, toUnicode, pdfFontHasEncoding, out); - cvtSfnts(out, NULL); + cvtEncoding(encodingA, pdfFontHasEncoding, outputFunc, outputStream); + cvtCharStrings(encodingA, toUnicode, pdfFontHasEncoding, + outputFunc, outputStream); + cvtSfnts(outputFunc, outputStream, NULL); // end the dictionary and define the font - fprintf(out, "FontName currentdict end definefont pop\n"); + (*outputFunc)(outputStream, "FontName currentdict end definefont pop\n", 40); } void TrueTypeFontFile::convertToCIDType2(char *name, Gushort *cidMap, - int nCIDs, FILE *out) { + int nCIDs, + FontFileOutputFunc outputFunc, + void *outputStream) { + char buf[512]; Gushort cid; int i, j, k; // write the header - fprintf(out, "%%!PS-TrueTypeFont-%g\n", getFixed(0)); + sprintf(buf, "%%!PS-TrueTypeFont-%g\n", getFixed(0)); + (*outputFunc)(outputStream, buf, strlen(buf)); // begin the font dictionary - fprintf(out, "20 dict begin\n"); - fprintf(out, "/CIDFontName /%s def\n", name); - fprintf(out, "/CIDFontType 2 def\n"); - fprintf(out, "/FontType 42 def\n"); - fprintf(out, "/CIDSystemInfo 3 dict dup begin\n"); - fprintf(out, " /Registry (Adobe) def\n"); - fprintf(out, " /Ordering (Identity) def\n"); - fprintf(out, " /Supplement 0 def\n"); - fprintf(out, " end def\n"); - fprintf(out, "/GDBytes 2 def\n"); + (*outputFunc)(outputStream, "20 dict begin\n", 14); + (*outputFunc)(outputStream, "/CIDFontName /", 14); + (*outputFunc)(outputStream, name, strlen(name)); + (*outputFunc)(outputStream, " def\n", 5); + (*outputFunc)(outputStream, "/CIDFontType 2 def\n", 19); + (*outputFunc)(outputStream, "/FontType 42 def\n", 17); + (*outputFunc)(outputStream, "/CIDSystemInfo 3 dict dup begin\n", 32); + (*outputFunc)(outputStream, " /Registry (Adobe) def\n", 24); + (*outputFunc)(outputStream, " /Ordering (Identity) def\n", 27); + (*outputFunc)(outputStream, " /Supplement 0 def\n", 20); + (*outputFunc)(outputStream, " end def\n", 10); + (*outputFunc)(outputStream, "/GDBytes 2 def\n", 15); if (cidMap) { - fprintf(out, "/CIDCount %d def\n", nCIDs); + sprintf(buf, "/CIDCount %d def\n", nCIDs); + (*outputFunc)(outputStream, buf, strlen(buf)); if (nCIDs > 32767) { - fprintf(out, "/CIDMap ["); + (*outputFunc)(outputStream, "/CIDMap [", 9); for (i = 0; i < nCIDs; i += 32768 - 16) { - fprintf(out, "<\n"); + (*outputFunc)(outputStream, "<\n", 2); for (j = 0; j < 32768 - 16 && i+j < nCIDs; j += 16) { - fprintf(out, " "); + (*outputFunc)(outputStream, " ", 2); for (k = 0; k < 16 && i+j+k < nCIDs; ++k) { cid = cidMap[i+j+k]; - fprintf(out, "%02x%02x", (cid >> 8) & 0xff, cid & 0xff); + sprintf(buf, "%02x%02x", (cid >> 8) & 0xff, cid & 0xff); + (*outputFunc)(outputStream, buf, strlen(buf)); } - fprintf(out, "\n"); + (*outputFunc)(outputStream, "\n", 1); } - fprintf(out, " >"); + (*outputFunc)(outputStream, " >", 3); } - fprintf(out, "\n"); - fprintf(out, "] def\n"); + (*outputFunc)(outputStream, "\n", 1); + (*outputFunc)(outputStream, "] def\n", 6); } else { - fprintf(out, "/CIDMap <\n"); + (*outputFunc)(outputStream, "/CIDMap <\n", 10); for (i = 0; i < nCIDs; i += 16) { - fprintf(out, " "); + (*outputFunc)(outputStream, " ", 2); for (j = 0; j < 16 && i+j < nCIDs; ++j) { cid = cidMap[i+j]; - fprintf(out, "%02x%02x", (cid >> 8) & 0xff, cid & 0xff); + sprintf(buf, "%02x%02x", (cid >> 8) & 0xff, cid & 0xff); + (*outputFunc)(outputStream, buf, strlen(buf)); } - fprintf(out, "\n"); + (*outputFunc)(outputStream, "\n", 1); } - fprintf(out, "> def\n"); + (*outputFunc)(outputStream, "> def\n", 6); } } else { // direct mapping - just fill the string(s) with s[i]=i - fprintf(out, "/CIDCount %d def\n", nGlyphs); + sprintf(buf, "/CIDCount %d def\n", nGlyphs); + (*outputFunc)(outputStream, buf, strlen(buf)); if (nGlyphs > 32767) { - fprintf(out, "/CIDMap [\n"); + (*outputFunc)(outputStream, "/CIDMap [\n", 10); for (i = 0; i < nGlyphs; i += 32767) { j = nGlyphs - i < 32767 ? nGlyphs - i : 32767; - fprintf(out, " %d string 0 1 %d {\n", 2 * j, j - 1); - fprintf(out, " 2 copy dup 2 mul exch %d add -8 bitshift put\n", i); - fprintf(out, " 1 index exch dup 2 mul 1 add exch %d add" + sprintf(buf, " %d string 0 1 %d {\n", 2 * j, j - 1); + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, " 2 copy dup 2 mul exch %d add -8 bitshift put\n", i); + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, " 1 index exch dup 2 mul 1 add exch %d add" " 255 and put\n", i); - fprintf(out, " } for\n"); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, " } for\n", 8); } - fprintf(out, "] def\n"); + (*outputFunc)(outputStream, "] def\n", 6); } else { - fprintf(out, "/CIDMap %d string\n", 2 * nGlyphs); - fprintf(out, " 0 1 %d {\n", nGlyphs - 1); - fprintf(out, " 2 copy dup 2 mul exch -8 bitshift put\n"); - fprintf(out, " 1 index exch dup 2 mul 1 add exch 255 and put\n"); - fprintf(out, " } for\n"); - fprintf(out, "def\n"); - } - } - fprintf(out, "/FontMatrix [1 0 0 1 0 0] def\n"); - fprintf(out, "/FontBBox [%d %d %d %d] def\n", + sprintf(buf, "/CIDMap %d string\n", 2 * nGlyphs); + (*outputFunc)(outputStream, buf, strlen(buf)); + sprintf(buf, " 0 1 %d {\n", nGlyphs - 1); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, + " 2 copy dup 2 mul exch -8 bitshift put\n", 42); + (*outputFunc)(outputStream, + " 1 index exch dup 2 mul 1 add exch 255 and put\n", 50); + (*outputFunc)(outputStream, " } for\n", 8); + (*outputFunc)(outputStream, "def\n", 4); + } + } + (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); + sprintf(buf, "/FontBBox [%d %d %d %d] def\n", bbox[0], bbox[1], bbox[2], bbox[3]); - fprintf(out, "/PaintType 0 def\n"); - fprintf(out, "/Encoding [] readonly def\n"); - fprintf(out, "/CharStrings 1 dict dup begin\n"); - fprintf(out, " /.notdef 0 def\n"); - fprintf(out, " end readonly def\n"); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/PaintType 0 def\n", 17); + (*outputFunc)(outputStream, "/Encoding [] readonly def\n", 26); + (*outputFunc)(outputStream, "/CharStrings 1 dict dup begin\n", 30); + (*outputFunc)(outputStream, " /.notdef 0 def\n", 17); + (*outputFunc)(outputStream, " end readonly def\n", 19); // write the guts of the dictionary - cvtSfnts(out, NULL); + cvtSfnts(outputFunc, outputStream, NULL); // end the dictionary and define the font - fprintf(out, "CIDFontName currentdict end /CIDFont defineresource pop\n"); + (*outputFunc)(outputStream, + "CIDFontName currentdict end /CIDFont defineresource pop\n", + 56); } void TrueTypeFontFile::convertToType0(char *name, Gushort *cidMap, - int nCIDs, FILE *out) { + int nCIDs, + FontFileOutputFunc outputFunc, + void *outputStream) { + char buf[512]; GString *sfntsName; int n, i, j; // write the Type 42 sfnts array sfntsName = (new GString(name))->append("_sfnts"); - cvtSfnts(out, sfntsName); + cvtSfnts(outputFunc, outputStream, sfntsName); delete sfntsName; // write the descendant Type 42 fonts n = cidMap ? nCIDs : nGlyphs; for (i = 0; i < n; i += 256) { - fprintf(out, "10 dict begin\n"); - fprintf(out, "/FontName /%s_%02x def\n", name, i >> 8); - fprintf(out, "/FontType 42 def\n"); - fprintf(out, "/FontMatrix [1 0 0 1 0 0] def\n"); - fprintf(out, "/FontBBox [%d %d %d %d] def\n", + (*outputFunc)(outputStream, "10 dict begin\n", 14); + (*outputFunc)(outputStream, "/FontName /", 11); + (*outputFunc)(outputStream, name, strlen(name)); + sprintf(buf, "_%02x def\n", i >> 8); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/FontType 42 def\n", 17); + (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); + sprintf(buf, "/FontBBox [%d %d %d %d] def\n", bbox[0], bbox[1], bbox[2], bbox[3]); - fprintf(out, "/PaintType 0 def\n"); - fprintf(out, "/sfnts %s_sfnts def\n", name); - fprintf(out, "/Encoding 256 array\n"); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, "/PaintType 0 def\n", 17); + (*outputFunc)(outputStream, "/sfnts ", 7); + (*outputFunc)(outputStream, name, strlen(name)); + (*outputFunc)(outputStream, "_sfnts def\n", 11); + (*outputFunc)(outputStream, "/Encoding 256 array\n", 20); for (j = 0; j < 256 && i+j < n; ++j) { - fprintf(out, "dup %d /c%02x put\n", j, j); + sprintf(buf, "dup %d /c%02x put\n", j, j); + (*outputFunc)(outputStream, buf, strlen(buf)); } - fprintf(out, "readonly def\n"); - fprintf(out, "/CharStrings 257 dict dup begin\n"); - fprintf(out, "/.notdef 0 def\n"); + (*outputFunc)(outputStream, "readonly def\n", 13); + (*outputFunc)(outputStream, "/CharStrings 257 dict dup begin\n", 32); + (*outputFunc)(outputStream, "/.notdef 0 def\n", 15); for (j = 0; j < 256 && i+j < n; ++j) { - fprintf(out, "/c%02x %d def\n", j, cidMap ? cidMap[i+j] : i+j); + sprintf(buf, "/c%02x %d def\n", j, cidMap ? cidMap[i+j] : i+j); + (*outputFunc)(outputStream, buf, strlen(buf)); } - fprintf(out, "end readonly def\n"); - fprintf(out, "FontName currentdict end definefont pop\n"); + (*outputFunc)(outputStream, "end readonly def\n", 17); + (*outputFunc)(outputStream, + "FontName currentdict end definefont pop\n", 40); } // write the Type 0 parent font - fprintf(out, "16 dict begin\n"); - fprintf(out, "/FontName /%s def\n", name); - fprintf(out, "/FontType 0 def\n"); - fprintf(out, "/FontMatrix [1 0 0 1 0 0] def\n"); - fprintf(out, "/FMapType 2 def\n"); - fprintf(out, "/Encoding [\n"); + (*outputFunc)(outputStream, "16 dict begin\n", 14); + (*outputFunc)(outputStream, "/FontName /", 11); + (*outputFunc)(outputStream, name, strlen(name)); + (*outputFunc)(outputStream, " def\n", 5); + (*outputFunc)(outputStream, "/FontType 0 def\n", 16); + (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30); + (*outputFunc)(outputStream, "/FMapType 2 def\n", 16); + (*outputFunc)(outputStream, "/Encoding [\n", 12); for (i = 0; i < n; i += 256) { - fprintf(out, "%d\n", i >> 8); + sprintf(buf, "%d\n", i >> 8); + (*outputFunc)(outputStream, buf, strlen(buf)); } - fprintf(out, "] def\n"); - fprintf(out, "/FDepVector [\n"); + (*outputFunc)(outputStream, "] def\n", 6); + (*outputFunc)(outputStream, "/FDepVector [\n", 14); for (i = 0; i < n; i += 256) { - fprintf(out, "/%s_%02x findfont\n", name, i >> 8); + (*outputFunc)(outputStream, "/", 1); + (*outputFunc)(outputStream, name, strlen(name)); + sprintf(buf, "_%02x findfont\n", i >> 8); + (*outputFunc)(outputStream, buf, strlen(buf)); } - fprintf(out, "] def\n"); - fprintf(out, "FontName currentdict end definefont pop\n"); + (*outputFunc)(outputStream, "] def\n", 6); + (*outputFunc)(outputStream, "FontName currentdict end definefont pop\n", 40); } int TrueTypeFontFile::getByte(int pos) { @@ -3016,33 +3173,49 @@ int TrueTypeFontFile::seekTableIdx(char *tag) { return -1; } -void TrueTypeFontFile::cvtEncoding(char **encodingA, FILE *out) { +void TrueTypeFontFile::cvtEncoding(char **encodingA, GBool pdfFontHasEncoding, + FontFileOutputFunc outputFunc, + void *outputStream) { char *name; + char buf[64]; int i; - fprintf(out, "/Encoding 256 array\n"); - for (i = 0; i < 256; ++i) { - if (!(name = encodingA[i])) { - name = ".notdef"; + (*outputFunc)(outputStream, "/Encoding 256 array\n", 20); + if (pdfFontHasEncoding) { + for (i = 0; i < 256; ++i) { + if (!(name = encodingA[i])) { + name = ".notdef"; + } + sprintf(buf, "dup %d /", i); + (*outputFunc)(outputStream, buf, strlen(buf)); + (*outputFunc)(outputStream, name, strlen(name)); + (*outputFunc)(outputStream, " put\n", 5); + } + } else { + for (i = 0; i < 256; ++i) { + sprintf(buf, "dup %d /c%02x put\n", i, i); + (*outputFunc)(outputStream, buf, strlen(buf)); } - fprintf(out, "dup %d /%s put\n", i, name); } - fprintf(out, "readonly def\n"); + (*outputFunc)(outputStream, "readonly def\n", 13); } void TrueTypeFontFile::cvtCharStrings(char **encodingA, CharCodeToUnicode *toUnicode, - GBool pdfFontHasEncoding, FILE *out) { + GBool pdfFontHasEncoding, + FontFileOutputFunc outputFunc, + void *outputStream) { int unicodeCmap, macRomanCmap, msSymbolCmap; int nCmaps, cmapPlatform, cmapEncoding, cmapFmt, cmapOffset; T42FontIndexMode mode; char *name; + char buf[64], buf2[16]; Unicode u; int pos, i, j, k; // always define '.notdef' - fprintf(out, "/CharStrings 256 dict dup begin\n"); - fprintf(out, "/.notdef 0 def\n"); + (*outputFunc)(outputStream, "/CharStrings 256 dict dup begin\n", 32); + (*outputFunc)(outputStream, "/.notdef 0 def\n", 15); // if there's no 'cmap' table, punt if ((pos = seekTable("cmap")) < 0) { @@ -3113,7 +3286,12 @@ void TrueTypeFontFile::cvtCharStrings(char **encodingA, // 2. use cmap to map char code to glyph index j = 0; // make gcc happy for (i = 0; i < 256; ++i) { - name = encodingA[i]; + if (pdfFontHasEncoding) { + name = encodingA[i]; + } else { + sprintf(buf2, "c%02x", i); + name = buf2; + } if (name && strcmp(name, ".notdef")) { switch (mode) { case t42FontModeUnicode: @@ -3136,13 +3314,16 @@ void TrueTypeFontFile::cvtCharStrings(char **encodingA, // test if ((k = getCmapEntry(cmapFmt, pos, j)) > 0 && k < nGlyphs) { - fprintf(out, "/%s %d def\n", name, k); + (*outputFunc)(outputStream, "/", 1); + (*outputFunc)(outputStream, name, strlen(name)); + sprintf(buf, " %d def\n", k); + (*outputFunc)(outputStream, buf, strlen(buf)); } } } err: - fprintf(out, "end readonly def\n"); + (*outputFunc)(outputStream, "end readonly def\n", 17); } int TrueTypeFontFile::getCmapEntry(int cmapFmt, int pos, int code) { @@ -3207,7 +3388,8 @@ int TrueTypeFontFile::getCmapEntry(int cmapFmt, int pos, int code) { return 0; } -void TrueTypeFontFile::cvtSfnts(FILE *out, GString *name) { +void TrueTypeFontFile::cvtSfnts(FontFileOutputFunc outputFunc, + void *outputStream, GString *name) { TTFontTableHdr newTableHdrs[nT42Tables]; char tableDir[12 + nT42Tables*16]; char headTable[54]; @@ -3359,27 +3541,30 @@ void TrueTypeFontFile::cvtSfnts(FILE *out, GString *name) { // start the sfnts array if (name) { - fprintf(out, "/%s [\n", name->getCString()); + (*outputFunc)(outputStream, "/", 1); + (*outputFunc)(outputStream, name->getCString(), name->getLength()); + (*outputFunc)(outputStream, " [\n", 3); } else { - fprintf(out, "/sfnts [\n"); + (*outputFunc)(outputStream, "/sfnts [\n", 9); } // write the table directory - dumpString(tableDir, 12 + nNewTables*16, out); + dumpString(tableDir, 12 + nNewTables*16, outputFunc, outputStream); // write the tables for (i = 0; i < nNewTables; ++i) { if (i == t42HeadTable) { - dumpString(headTable, 54, out); + dumpString(headTable, 54, outputFunc, outputStream); } else if (i == t42LocaTable) { length = (nGlyphs + 1) * (locaFmt ? 4 : 2); - dumpString(locaTable, length, out); + dumpString(locaTable, length, outputFunc, outputStream); } else if (i == t42GlyfTable) { glyfPos = seekTable("glyf"); for (j = 0; j < nGlyphs; ++j) { length = origLocaTable[j+1] - origLocaTable[j]; if (length > 0) { - dumpString(file + glyfPos + origLocaTable[j], length, out); + dumpString(file + glyfPos + origLocaTable[j], length, + outputFunc, outputStream); } } } else { @@ -3387,40 +3572,45 @@ void TrueTypeFontFile::cvtSfnts(FILE *out, GString *name) { // already reported during the construction of the table // headers if ((length = newTableHdrs[i].length) > 0) { - dumpString(file + seekTable(t42Tables[i].tag), length, out); + dumpString(file + seekTable(t42Tables[i].tag), length, + outputFunc, outputStream); } } } // end the sfnts array - fprintf(out, "] def\n"); + (*outputFunc)(outputStream, "] def\n", 6); gfree(origLocaTable); gfree(locaTable); } -void TrueTypeFontFile::dumpString(char *s, int length, FILE *out) { +void TrueTypeFontFile::dumpString(char *s, int length, + FontFileOutputFunc outputFunc, + void *outputStream) { + char buf[64]; int pad, i, j; - fprintf(out, "<"); + (*outputFunc)(outputStream, "<", 1); for (i = 0; i < length; i += 32) { for (j = 0; j < 32 && i+j < length; ++j) { - fprintf(out, "%02X", s[i+j] & 0xff); + sprintf(buf, "%02X", s[i+j] & 0xff); + (*outputFunc)(outputStream, buf, strlen(buf)); } if (i % (65536 - 32) == 65536 - 64) { - fprintf(out, ">\n<"); + (*outputFunc)(outputStream, ">\n<", 3); } else if (i+32 < length) { - fprintf(out, "\n"); + (*outputFunc)(outputStream, "\n", 1); } } if (length & 3) { pad = 4 - (length & 3); for (i = 0; i < pad; ++i) { - fprintf(out, "00"); + (*outputFunc)(outputStream, "00", 2); } } // add an extra zero byte because the Adobe Type 42 spec says so - fprintf(out, "00>\n"); + (*outputFunc)(outputStream, "00>\n", 4); } Guint TrueTypeFontFile::computeTableChecksum(char *data, int length) { @@ -3494,7 +3684,7 @@ void TrueTypeFontFile::writeTTF(FILE *out) { haveName = seekTable("name") >= 0; havePost = seekTable("post") >= 0; nNewTables = (haveCmap ? 0 : 1) + (haveName ? 0 : 1) + (havePost ? 0 : 1); - if (!nNewTables) { + if (!nNewTables && !mungedCmapSize) { // none are missing - write the TTF file as is fwrite(file, 1, len, out); return; @@ -3585,12 +3775,23 @@ void TrueTypeFontFile::writeTTF(FILE *out) { ++j; dirPost = gTrue; } - memcpy(&tableDir[12 + 16*j], file + 12 + 16*i, 16); + tableDir[12 + 16*j ] = tableHdrs[i].tag[0]; + tableDir[12 + 16*j + 1] = tableHdrs[i].tag[1]; + tableDir[12 + 16*j + 2] = tableHdrs[i].tag[2]; + tableDir[12 + 16*j + 3] = tableHdrs[i].tag[3]; + tableDir[12 + 16*j + 4] = (char)((tableHdrs[i].checksum >> 24) & 0xff); + tableDir[12 + 16*j + 5] = (char)((tableHdrs[i].checksum >> 16) & 0xff); + tableDir[12 + 16*j + 6] = (char)((tableHdrs[i].checksum >> 8) & 0xff); + tableDir[12 + 16*j + 7] = (char)( tableHdrs[i].checksum & 0xff); t = tableHdrs[i].offset + nNewTables * 16; tableDir[12 + 16*j + 8] = (char)((t >> 24) & 0xff); tableDir[12 + 16*j + 9] = (char)((t >> 16) & 0xff); tableDir[12 + 16*j + 10] = (char)((t >> 8) & 0xff); tableDir[12 + 16*j + 11] = (char)( t & 0xff); + tableDir[12 + 16*j + 12] = (char)((tableHdrs[i].length >> 24) & 0xff); + tableDir[12 + 16*j + 13] = (char)((tableHdrs[i].length >> 16) & 0xff); + tableDir[12 + 16*j + 14] = (char)((tableHdrs[i].length >> 8) & 0xff); + tableDir[12 + 16*j + 15] = (char)( tableHdrs[i].length & 0xff); ++j; } if (!dirCmap) { diff --git a/pdf/xpdf/FontFile.h b/pdf/xpdf/FontFile.h index d5de25c5..72939922 100644 --- a/pdf/xpdf/FontFile.h +++ b/pdf/xpdf/FontFile.h @@ -9,7 +9,9 @@ #ifndef FONTFILE_H #define FONTFILE_H -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma interface #endif @@ -20,6 +22,10 @@ class CharCodeToUnicode; +//------------------------------------------------------------------------ + +typedef void (*FontFileOutputFunc)(void *stream, char *data, int len); + //------------------------------------------------------------------------ // FontFile //------------------------------------------------------------------------ @@ -75,17 +81,19 @@ public: // Convert to a Type 1 font, suitable for embedding in a PostScript // file. The name will be used as the PostScript font name. - void convertToType1(FILE *outA); + void convertToType1(FontFileOutputFunc outputFuncA, void *outputStreamA); // Convert to a Type 0 CIDFont, suitable for embedding in a // PostScript file. The name will be used as the PostScript font // name. - void convertToCIDType0(char *psName, FILE *outA); + void convertToCIDType0(char *psName, + FontFileOutputFunc outputFuncA, void *outputStreamA); // Convert to a Type 0 (but non-CID) composite font, suitable for // embedding in a PostScript file. The name will be used as the // PostScript font name. - void convertToType0(char *psName, FILE *outA); + void convertToType0(char *psName, + FontFileOutputFunc outputFuncA, void *outputStreamA); private: @@ -122,7 +130,8 @@ private: Guchar *stringIdxPtr; Guchar *gsubrIdxPtr; - FILE *out; + FontFileOutputFunc outputFunc; + void *outputStream; double op[48]; // operands GBool fp[48]; // true if operand is fixed point int nOps; // number of operands @@ -161,21 +170,22 @@ public: // encoding. void convertToType42(char *name, char **encodingA, CharCodeToUnicode *toUnicode, - GBool pdfFontHasEncoding, FILE *out); + GBool pdfFontHasEncoding, + FontFileOutputFunc outputFunc, void *outputStream); // Convert to a Type 2 CIDFont, suitable for embedding in a // PostScript file. The name will be used as the PostScript font // name (so we don't need to depend on the 'name' table in the // font). - void convertToCIDType2(char *name, Gushort *cidMap, - int nCIDs, FILE *out); + void convertToCIDType2(char *name, Gushort *cidMap, int nCIDs, + FontFileOutputFunc outputFunc, void *outputStream); // Convert to a Type 0 (but non-CID) composite font, suitable for // embedding in a PostScript file. The name will be used as the // PostScript font name (so we don't need to depend on the 'name' // table in the font). - void convertToType0(char *name, Gushort *cidMap, - int nCIDs, FILE *out); + void convertToType0(char *name, Gushort *cidMap, int nCIDs, + FontFileOutputFunc outputFunc, void *outputStream); // Write a TTF file, filling in any missing tables that are required // by the TrueType spec. If the font already has all the required @@ -194,6 +204,7 @@ private: int bbox[4]; int locaFmt; int nGlyphs; + GBool mungedCmapSize; int getByte(int pos); int getChar(int pos); @@ -203,12 +214,16 @@ private: double getFixed(int pos); int seekTable(char *tag); int seekTableIdx(char *tag); - void cvtEncoding(char **encodingA, FILE *out); + void cvtEncoding(char **encodingA, GBool pdfFontHasEncoding, + FontFileOutputFunc outputFunc, void *outputStream); void cvtCharStrings(char **encodingA, CharCodeToUnicode *toUnicode, - GBool pdfFontHasEncoding, FILE *out); + GBool pdfFontHasEncoding, + FontFileOutputFunc outputFunc, void *outputStream); int getCmapEntry(int cmapFmt, int pos, int code); - void cvtSfnts(FILE *out, GString *name); - void dumpString(char *s, int length, FILE *out); + void cvtSfnts(FontFileOutputFunc outputFunc, void *outputStream, + GString *name); + void dumpString(char *s, int length, + FontFileOutputFunc outputFunc, void *outputStream); Guint computeTableChecksum(char *data, int length); }; diff --git a/pdf/xpdf/Function.cc b/pdf/xpdf/Function.cc index 64ea60c1..82bbdce2 100644 --- a/pdf/xpdf/Function.cc +++ b/pdf/xpdf/Function.cc @@ -6,11 +6,12 @@ // //======================================================================== -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma implementation #endif -#include #include #include #include @@ -1095,14 +1096,14 @@ GBool PostScriptFunction::parseCode(Stream *str, int *codePtr) { if (!parseCode(str, codePtr)) { return gFalse; } + delete tok; + if (!(tok = getToken(str))) { + error(-1, "Unexpected end of PostScript function stream"); + return gFalse; + } } else { elsePtr = -1; } - delete tok; - if (!(tok = getToken(str))) { - error(-1, "Unexpected end of PostScript function stream"); - return gFalse; - } if (!tok->cmp("if")) { if (elsePtr >= 0) { error(-1, "Got 'if' operator with two blocks in PostScript function"); diff --git a/pdf/xpdf/Function.h b/pdf/xpdf/Function.h index 9b0879f3..eb88211d 100644 --- a/pdf/xpdf/Function.h +++ b/pdf/xpdf/Function.h @@ -9,7 +9,9 @@ #ifndef FUNCTION_H #define FUNCTION_H -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma interface #endif diff --git a/pdf/xpdf/GlobalParams.cc b/pdf/xpdf/GlobalParams.cc index 0bc908ea..b50c15bd 100644 --- a/pdf/xpdf/GlobalParams.cc +++ b/pdf/xpdf/GlobalParams.cc @@ -6,11 +6,12 @@ // //======================================================================== -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma implementation #endif -#include #include #include #if HAVE_PAPER_H @@ -144,11 +145,18 @@ GlobalParams::GlobalParams(char *cfgFileName) { displayCIDFonts = new GHash(); displayNamedCIDFonts = new GHash(); #if HAVE_PAPER_H + char *paperName; const struct paper *paperType; paperinit(); - paperType = paperinfo(systempapername()); - psPaperWidth = (int)paperpswidth(paperType); - psPaperHeight = (int)paperpsheight(paperType); + if ((paperName = systempapername())) { + paperType = paperinfo(paperName); + psPaperWidth = (int)paperpswidth(paperType); + psPaperHeight = (int)paperpsheight(paperType); + } else { + error(-1, "No paper information available - using defaults"); + psPaperWidth = defPaperWidth; + psPaperHeight = defPaperHeight; + } paperdone(); #else psPaperWidth = defPaperWidth; @@ -174,12 +182,15 @@ GlobalParams::GlobalParams(char *cfgFileName) { #else textEOL = eolUnix; #endif + textKeepTinyChars = gFalse; fontDirs = new GList(); initialZoom = new GString("1"); t1libControl = fontRastAALow; freetypeControl = fontRastAALow; urlCommand = NULL; + movieCommand = NULL; mapNumericCharNames = gTrue; + printCommands = gFalse; errQuiet = gFalse; cidToUnicodeCache = new CIDToUnicodeCache(); @@ -192,18 +203,21 @@ GlobalParams::GlobalParams(char *cfgFileName) { } // set up the residentUnicodeMaps table - map = new UnicodeMap("Latin1", latin1UnicodeMapRanges, latin1UnicodeMapLen); + map = new UnicodeMap("Latin1", gFalse, + latin1UnicodeMapRanges, latin1UnicodeMapLen); residentUnicodeMaps->add(map->getEncodingName(), map); - map = new UnicodeMap("ASCII7", ascii7UnicodeMapRanges, ascii7UnicodeMapLen); + map = new UnicodeMap("ASCII7", gFalse, + ascii7UnicodeMapRanges, ascii7UnicodeMapLen); residentUnicodeMaps->add(map->getEncodingName(), map); - map = new UnicodeMap("Symbol", symbolUnicodeMapRanges, symbolUnicodeMapLen); + map = new UnicodeMap("Symbol", gFalse, + symbolUnicodeMapRanges, symbolUnicodeMapLen); residentUnicodeMaps->add(map->getEncodingName(), map); - map = new UnicodeMap("ZapfDingbats", zapfDingbatsUnicodeMapRanges, + map = new UnicodeMap("ZapfDingbats", gFalse, zapfDingbatsUnicodeMapRanges, zapfDingbatsUnicodeMapLen); residentUnicodeMaps->add(map->getEncodingName(), map); - map = new UnicodeMap("UTF-8", &mapUTF8); + map = new UnicodeMap("UTF-8", gTrue, &mapUTF8); residentUnicodeMaps->add(map->getEncodingName(), map); - map = new UnicodeMap("UCS-2", &mapUCS2); + map = new UnicodeMap("UCS-2", gTrue, &mapUCS2); residentUnicodeMaps->add(map->getEncodingName(), map); // default displayFonts table @@ -235,7 +249,7 @@ GlobalParams::GlobalParams(char *cfgFileName) { i = GetModuleFileName(NULL, buf, sizeof(buf)); if (i <= 0 || i >= sizeof(buf)) { // error or path too long for buffer - just use the current dir - buf[i] = '\0'; + buf[0] = '\0'; } fileName = grabPath(buf); appendToPath(fileName, xpdfSysConfigFile); @@ -249,6 +263,7 @@ GlobalParams::GlobalParams(char *cfgFileName) { if (f) { parseFile(fileName, f); delete fileName; + fclose(f); } } @@ -354,6 +369,9 @@ void GlobalParams::parseFile(GString *fileName, FILE *f) { parseTextEncoding(tokens, fileName, line); } else if (!cmd->cmp("textEOL")) { parseTextEOL(tokens, fileName, line); + } else if (!cmd->cmp("textKeepTinyChars")) { + parseYesNo("textKeepTinyChars", &textKeepTinyChars, + tokens, fileName, line); } else if (!cmd->cmp("fontDir")) { parseFontDir(tokens, fileName, line); } else if (!cmd->cmp("initialZoom")) { @@ -365,10 +383,14 @@ void GlobalParams::parseFile(GString *fileName, FILE *f) { parseFontRastControl("freetypeControl", &freetypeControl, tokens, fileName, line); } else if (!cmd->cmp("urlCommand")) { - parseURLCommand(tokens, fileName, line); + parseCommand("urlCommand", &urlCommand, tokens, fileName, line); + } else if (!cmd->cmp("movieCommand")) { + parseCommand("movieCommand", &movieCommand, tokens, fileName, line); } else if (!cmd->cmp("mapNumericCharNames")) { parseYesNo("mapNumericCharNames", &mapNumericCharNames, tokens, fileName, line); + } else if (!cmd->cmp("printCommands")) { + parseYesNo("printCommands", &printCommands, tokens, fileName, line); } else if (!cmd->cmp("errQuiet")) { parseYesNo("errQuiet", &errQuiet, tokens, fileName, line); } else if (!cmd->cmp("fontpath") || !cmd->cmp("fontmap")) { @@ -697,17 +719,17 @@ void GlobalParams::parseFontRastControl(char *cmdName, FontRastControl *val, } } -void GlobalParams::parseURLCommand(GList *tokens, GString *fileName, - int line) { +void GlobalParams::parseCommand(char *cmdName, GString **val, + GList *tokens, GString *fileName, int line) { if (tokens->getLength() != 2) { - error(-1, "Bad 'urlCommand' config file command (%s:%d)", - fileName->getCString(), line); + error(-1, "Bad '%s' config file command (%s:%d)", + cmdName, fileName->getCString(), line); return; } - if (urlCommand) { - delete urlCommand; + if (*val) { + delete *val; } - urlCommand = ((GString *)tokens->get(1))->copy(); + *val = ((GString *)tokens->get(1))->copy(); } void GlobalParams::parseYesNo(char *cmdName, GBool *flag, @@ -759,6 +781,9 @@ GlobalParams::~GlobalParams() { if (urlCommand) { delete urlCommand; } + if (movieCommand) { + delete movieCommand; + } cMapDirs->startIter(&iter); while (cMapDirs->getNext(&iter, &key, (void **)&list)) { @@ -948,6 +973,15 @@ UnicodeMap *GlobalParams::getTextEncoding() { // functions to set parameters //------------------------------------------------------------------------ +void GlobalParams::addDisplayFont(DisplayFontParam *param) { + DisplayFontParam *old; + + if ((old = (DisplayFontParam *)displayFonts->remove(param->name))) { + delete old; + } + displayFonts->add(param->name, param); +} + void GlobalParams::setPSFile(char *file) { if (psFile) { delete psFile; @@ -1032,6 +1066,10 @@ GBool GlobalParams::setTextEOL(char *s) { return gTrue; } +void GlobalParams::setTextKeepTinyChars(GBool keep) { + textKeepTinyChars = keep; +} + void GlobalParams::setInitialZoom(char *s) { delete initialZoom; initialZoom = new GString(s); @@ -1060,6 +1098,14 @@ GBool GlobalParams::setFontRastControl(FontRastControl *val, char *s) { return gTrue; } +void GlobalParams::setMapNumericCharNames(GBool map) { + mapNumericCharNames = map; +} + +void GlobalParams::setPrintCommands(GBool printCommandsA) { + printCommands = printCommandsA; +} + void GlobalParams::setErrQuiet(GBool errQuietA) { errQuiet = errQuietA; } diff --git a/pdf/xpdf/GlobalParams.h b/pdf/xpdf/GlobalParams.h index b6511109..0f783e80 100644 --- a/pdf/xpdf/GlobalParams.h +++ b/pdf/xpdf/GlobalParams.h @@ -9,7 +9,9 @@ #ifndef GLOBALPARAMS_H #define GLOBALPARAMS_H -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma interface #endif @@ -150,12 +152,15 @@ public: GBool getPSASCIIHex() { return psASCIIHex; } GString *getTextEncodingName() { return textEncoding; } EndOfLineKind getTextEOL() { return textEOL; } + GBool getTextKeepTinyChars() { return textKeepTinyChars; } GString *findFontFile(GString *fontName, char *ext1, char *ext2); GString *getInitialZoom() { return initialZoom; } FontRastControl getT1libControl() { return t1libControl; } FontRastControl getFreeTypeControl() { return freetypeControl; } GString *getURLCommand() { return urlCommand; } + GString *getMovieCommand() { return movieCommand; } GBool getMapNumericCharNames() { return mapNumericCharNames; } + GBool getPrintCommands() { return printCommands; } GBool getErrQuiet() { return errQuiet; } CharCodeToUnicode *getCIDToUnicode(GString *collection); @@ -165,6 +170,7 @@ public: //----- functions to set parameters + void addDisplayFont(DisplayFontParam *param); void setPSFile(char *file); GBool setPSPaperSize(char *size); void setPSPaperWidth(int width); @@ -179,9 +185,12 @@ public: void setPSASCIIHex(GBool hex); void setTextEncoding(char *encodingName); GBool setTextEOL(char *s); + void setTextKeepTinyChars(GBool keep); void setInitialZoom(char *s); GBool setT1libControl(char *s); GBool setFreeTypeControl(char *s); + void setMapNumericCharNames(GBool map); + void setPrintCommands(GBool printCommandsA); void setErrQuiet(GBool errQuietA); private: @@ -207,7 +216,8 @@ private: void parseInitialZoom(GList *tokens, GString *fileName, int line); void parseFontRastControl(char *cmdName, FontRastControl *val, GList *tokens, GString *fileName, int line); - void parseURLCommand(GList *tokens, GString *fileName, int line); + void parseCommand(char *cmdName, GString **val, + GList *tokens, GString *fileName, int line); void parseYesNo(char *cmdName, GBool *flag, GList *tokens, GString *fileName, int line); GBool setFontRastControl(FontRastControl *val, char *s); @@ -256,13 +266,16 @@ private: // output EndOfLineKind textEOL; // type of EOL marker to use for text // output + GBool textKeepTinyChars; // keep all characters in text output GList *fontDirs; // list of font dirs [GString] GString *initialZoom; // initial zoom level FontRastControl t1libControl; // t1lib rasterization mode FontRastControl // FreeType rasterization mode freetypeControl; GString *urlCommand; // command executed for URL links + GString *movieCommand; // command executed for movie annotations GBool mapNumericCharNames; // map numeric char names (from font subsets)? + GBool printCommands; // print the drawing commands GBool errQuiet; // suppress error messages? CIDToUnicodeCache *cidToUnicodeCache; diff --git a/pdf/xpdf/NameToCharCode.cc b/pdf/xpdf/NameToCharCode.cc index b9cde77d..29a1dbbf 100644 --- a/pdf/xpdf/NameToCharCode.cc +++ b/pdf/xpdf/NameToCharCode.cc @@ -6,11 +6,12 @@ // //======================================================================== -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma implementation #endif -#include #include #include "gmem.h" #include "NameToCharCode.h" diff --git a/pdf/xpdf/NameToCharCode.h b/pdf/xpdf/NameToCharCode.h index 22e41b61..622e7d67 100644 --- a/pdf/xpdf/NameToCharCode.h +++ b/pdf/xpdf/NameToCharCode.h @@ -9,7 +9,9 @@ #ifndef NAMETOCHARCODE_H #define NAMETOCHARCODE_H -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma interface #endif diff --git a/pdf/xpdf/NameToUnicodeTable.h b/pdf/xpdf/NameToUnicodeTable.h index 432fafb3..320c5588 100644 --- a/pdf/xpdf/NameToUnicodeTable.h +++ b/pdf/xpdf/NameToUnicodeTable.h @@ -10,6 +10,37 @@ static struct { Unicode u; char *name; } nameToUnicodeTab[] = { + {0x0021, "!"}, + {0x0023, "#"}, + {0x0024, "$"}, + {0x0025, "%"}, + {0x0026, "&"}, + {0x0027, "'"}, + {0x0028, "("}, + {0x0029, ")"}, + {0x002a, "*"}, + {0x002b, "+"}, + {0x002c, ","}, + {0x002d, "-"}, + {0x002e, "."}, + {0x002f, "/"}, + {0x0030, "0"}, + {0x0031, "1"}, + {0x0032, "2"}, + {0x0033, "3"}, + {0x0034, "4"}, + {0x0035, "5"}, + {0x0036, "6"}, + {0x0037, "7"}, + {0x0038, "8"}, + {0x0039, "9"}, + {0x003a, ":"}, + {0x003b, ";"}, + {0x003c, "<"}, + {0x003d, "="}, + {0x003e, ">"}, + {0x003f, "?"}, + {0x0040, "@"}, {0x0041, "A"}, {0x00c6, "AE"}, {0x01fc, "AEacute"}, @@ -304,6 +335,12 @@ static struct { {0x017b, "Zdotaccent"}, {0x0396, "Zeta"}, {0x005a, "Zsmall"}, + {0x0022, "\""}, + {0x005c, "\\"}, + {0x005d, "]"}, + {0x005e, "^"}, + {0x005f, "_"}, + {0x0060, "`"}, {0x0061, "a"}, {0x00e1, "aacute"}, {0x0103, "abreve"}, @@ -715,6 +752,7 @@ static struct { {0x203c, "exclamdbl"}, {0x00a1, "exclamdown"}, {0x00a1, "exclamdownsmall"}, + {0x0021, "exclamleft"}, {0x0021, "exclamsmall"}, {0x2203, "existential"}, {0x0066, "f"}, @@ -1051,5 +1089,9 @@ static struct { {0x0030, "zerooldstyle"}, {0x2070, "zerosuperior"}, {0x03b6, "zeta"}, + {0x007b, "{"}, + {0x007c, "|"}, + {0x007d, "}"}, + {0x007e, "~"}, { 0, NULL } }; diff --git a/pdf/xpdf/PSTokenizer.cc b/pdf/xpdf/PSTokenizer.cc index 8d654bd2..570a7bac 100644 --- a/pdf/xpdf/PSTokenizer.cc +++ b/pdf/xpdf/PSTokenizer.cc @@ -6,7 +6,9 @@ // //======================================================================== -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma implementation #endif diff --git a/pdf/xpdf/PSTokenizer.h b/pdf/xpdf/PSTokenizer.h index 1053c675..c885ae1f 100644 --- a/pdf/xpdf/PSTokenizer.h +++ b/pdf/xpdf/PSTokenizer.h @@ -9,7 +9,9 @@ #ifndef PSTOKENIZER_H #define PSTOKENIZER_H -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma interface #endif diff --git a/pdf/xpdf/SFont.cc b/pdf/xpdf/SFont.cc index 69c1e484..53214b08 100644 --- a/pdf/xpdf/SFont.cc +++ b/pdf/xpdf/SFont.cc @@ -6,11 +6,12 @@ // //======================================================================== -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma implementation #endif -#include #include "SFont.h" //------------------------------------------------------------------------ diff --git a/pdf/xpdf/SFont.h b/pdf/xpdf/SFont.h index c4fb341e..8481ddaa 100644 --- a/pdf/xpdf/SFont.h +++ b/pdf/xpdf/SFont.h @@ -11,7 +11,9 @@ #ifndef SFONT_H #define SFONT_H -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma interface #endif diff --git a/pdf/xpdf/T1Font.cc b/pdf/xpdf/T1Font.cc index 7b79d874..9815e490 100644 --- a/pdf/xpdf/T1Font.cc +++ b/pdf/xpdf/T1Font.cc @@ -6,14 +6,14 @@ // //======================================================================== -#ifdef __GNUC__ -#pragma implementation -#endif - #include #if HAVE_T1LIB_H +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + #include #include #include @@ -23,6 +23,10 @@ //------------------------------------------------------------------------ +int T1FontEngine::t1libInitCount = 0; + +//------------------------------------------------------------------------ + T1FontEngine::T1FontEngine(Display *displayA, Visual *visualA, int depthA, Colormap colormapA, GBool aaA, GBool aaHighA): SFontEngine(displayA, visualA, depthA, colormapA) @@ -32,30 +36,37 @@ T1FontEngine::T1FontEngine(Display *displayA, Visual *visualA, int depthA, }; ok = gFalse; - T1_SetBitmapPad(8); - if (!T1_InitLib(NO_LOGFILE | IGNORE_CONFIGFILE | IGNORE_FONTDATABASE | - T1_NO_AFM)) { - return; - } aa = aaA; aaHigh = aaHighA; - if (aa) { - T1_AASetBitsPerPixel(8); - if (aaHigh) { - T1_AASetLevel(T1_AA_HIGH); - T1_AAHSetGrayValues(grayVals); + //~ for multithreading: need a mutex here + if (t1libInitCount == 0) { + T1_SetBitmapPad(8); + if (!T1_InitLib(NO_LOGFILE | IGNORE_CONFIGFILE | IGNORE_FONTDATABASE | + T1_NO_AFM)) { + return; + } + if (aa) { + T1_AASetBitsPerPixel(8); + if (aaHigh) { + T1_AASetLevel(T1_AA_HIGH); + T1_AAHSetGrayValues(grayVals); + } else { + T1_AASetLevel(T1_AA_LOW); + T1_AASetGrayValues(0, 1, 2, 3, 4); + } } else { - T1_AASetLevel(T1_AA_LOW); - T1_AASetGrayValues(0, 1, 2, 3, 4); + T1_AANSetGrayValues(0, 1); } - } else { - T1_AANSetGrayValues(0, 1); } + ++t1libInitCount; ok = gTrue; } T1FontEngine::~T1FontEngine() { - T1_CloseLib(); + //~ for multithreading: need a mutex here + if (--t1libInitCount == 0) { + T1_CloseLib(); + } } //------------------------------------------------------------------------ diff --git a/pdf/xpdf/T1Font.h b/pdf/xpdf/T1Font.h index 5215c3a6..cfd7f620 100644 --- a/pdf/xpdf/T1Font.h +++ b/pdf/xpdf/T1Font.h @@ -11,9 +11,11 @@ #ifndef T1FONT_H #define T1FONT_H +#include + #if HAVE_T1LIB_H -#ifdef __GNUC__ +#ifdef USE_GCC_PRAGMAS #pragma interface #endif @@ -39,6 +41,8 @@ private: GBool aaHigh; // use high-res anti-aliasing? GBool ok; + static int t1libInitCount; + friend class T1FontFile; friend class T1Font; }; diff --git a/pdf/xpdf/TTFont.cc b/pdf/xpdf/TTFont.cc index ea3fad22..6107fd43 100644 --- a/pdf/xpdf/TTFont.cc +++ b/pdf/xpdf/TTFont.cc @@ -6,14 +6,14 @@ // //======================================================================== -#ifdef __GNUC__ -#pragma implementation -#endif - #include #if !FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H) +#ifdef USE_GCC_PRAGMAS +#pragma implementation +#endif + #include #include "gmem.h" #include "GlobalParams.h" diff --git a/pdf/xpdf/TTFont.h b/pdf/xpdf/TTFont.h index b4ebd96e..997076c2 100644 --- a/pdf/xpdf/TTFont.h +++ b/pdf/xpdf/TTFont.h @@ -11,9 +11,11 @@ #ifndef TTFONT_H #define TTFONT_H +#include + #if !FREETYPE2 && (HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H) -#ifdef __GNUC__ +#ifdef USE_GCC_PRAGMAS #pragma interface #endif diff --git a/pdf/xpdf/UnicodeMap.cc b/pdf/xpdf/UnicodeMap.cc index 75f23d2b..bfa5eccb 100644 --- a/pdf/xpdf/UnicodeMap.cc +++ b/pdf/xpdf/UnicodeMap.cc @@ -6,11 +6,12 @@ // //======================================================================== -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma implementation #endif -#include #include #include #include "gmem.h" @@ -101,11 +102,14 @@ UnicodeMap *UnicodeMap::parse(GString *encodingNameA) { ++line; } + fclose(f); + return map; } UnicodeMap::UnicodeMap(GString *encodingNameA) { encodingName = encodingNameA; + unicodeOut = gFalse; kind = unicodeMapUser; ranges = NULL; len = 0; @@ -114,9 +118,10 @@ UnicodeMap::UnicodeMap(GString *encodingNameA) { refCnt = 1; } -UnicodeMap::UnicodeMap(char *encodingNameA, +UnicodeMap::UnicodeMap(char *encodingNameA, GBool unicodeOutA, UnicodeMapRange *rangesA, int lenA) { encodingName = new GString(encodingNameA); + unicodeOut = unicodeOutA; kind = unicodeMapResident; ranges = rangesA; len = lenA; @@ -125,8 +130,10 @@ UnicodeMap::UnicodeMap(char *encodingNameA, refCnt = 1; } -UnicodeMap::UnicodeMap(char *encodingNameA, UnicodeMapFunc funcA) { +UnicodeMap::UnicodeMap(char *encodingNameA, GBool unicodeOutA, + UnicodeMapFunc funcA) { encodingName = new GString(encodingNameA); + unicodeOut = unicodeOutA; kind = unicodeMapFunc; func = funcA; eMaps = NULL; diff --git a/pdf/xpdf/UnicodeMap.h b/pdf/xpdf/UnicodeMap.h index 274c4472..60c0c279 100644 --- a/pdf/xpdf/UnicodeMap.h +++ b/pdf/xpdf/UnicodeMap.h @@ -11,7 +11,9 @@ #ifndef UNICODEMAP_H #define UNICODEMAP_H -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma interface #endif @@ -47,12 +49,13 @@ public: static UnicodeMap *parse(GString *encodingNameA); // Create a resident UnicodeMap. - UnicodeMap(char *encodingNameA, + UnicodeMap(char *encodingNameA, GBool unicodeOutA, UnicodeMapRange *rangesA, int lenA); // Create a resident UnicodeMap that uses a function instead of a // list of ranges. - UnicodeMap(char *encodingNameA, UnicodeMapFunc funcA); + UnicodeMap(char *encodingNameA, GBool unicodeOutA, + UnicodeMapFunc funcA); ~UnicodeMap(); @@ -61,6 +64,8 @@ public: GString *getEncodingName() { return encodingName; } + GBool isUnicode() { return unicodeOut; } + // Return true if this UnicodeMap matches the specified // . GBool match(GString *encodingNameA); @@ -77,6 +82,7 @@ private: GString *encodingName; UnicodeMapKind kind; + GBool unicodeOut; union { UnicodeMapRange *ranges; // (user, resident) UnicodeMapFunc func; // (func) diff --git a/pdf/xpdf/pdffonts.cc b/pdf/xpdf/pdffonts.cc index 4a6ed401..fcb739a2 100644 --- a/pdf/xpdf/pdffonts.cc +++ b/pdf/xpdf/pdffonts.cc @@ -84,6 +84,9 @@ int main(int argc, char *argv[]) { Annots *annots; Object obj1, obj2; int pg, i; + int exitCode; + + exitCode = 99; // parse args ok = parseArgs(argDesc, &argc, argv); @@ -93,7 +96,7 @@ int main(int argc, char *argv[]) { if (!printVersion) { printUsage("pdfinfo", "", argDesc); } - exit(1); + goto err0; } fileName = new GString(argv[1]); @@ -119,7 +122,8 @@ int main(int argc, char *argv[]) { delete ownerPW; } if (!doc->isOk()) { - exit(1); + exitCode = 1; + goto err1; } // get page range @@ -155,16 +159,20 @@ int main(int argc, char *argv[]) { delete annots; } + exitCode = 0; + // clean up gfree(fonts); + err1: delete doc; delete globalParams; + err0: // check for memory leaks Object::memCheck(stderr); gMemReport(stderr); - return 0; + return exitCode; } static void scanFonts(Dict *resDict, PDFDoc *doc) { @@ -249,13 +257,17 @@ static void scanFont(GfxFont *font, PDFDoc *doc) { } // print the font info - printf("%-36s %-12s %-3s %-3s %-3s %6d %2d\n", + printf("%-36s %-12s %-3s %-3s %-3s", name ? name->getCString() : "[none]", fontTypeNames[font->getType()], font->getEmbeddedFontID(&embRef) ? "yes" : "no", subset ? "yes" : "no", - hasToUnicode ? "yes" : "no", - fontRef.num, fontRef.gen); + hasToUnicode ? "yes" : "no"); + if (fontRef.gen == 999999) { + printf(" [none]\n"); + } else { + printf(" %6d %2d\n", fontRef.num, fontRef.gen); + } if (name) { delete name; } -- 2.43.5