diff options
author | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2017-08-13 07:14:48 +0000 |
---|---|---|
committer | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2017-08-13 07:14:48 +0000 |
commit | 4b4995cda35627e06c43e25ecbe07c1bc1859bb5 (patch) | |
tree | 143ed02a389bab62f44043a54cbc70f69e312e2f /Build/source/libs/xpdf/xpdf-src/fofi | |
parent | 00d00899c484b81967558f43c4fe4a896ffdf610 (diff) |
xpdf 4.00
git-svn-id: svn://tug.org/texlive/trunk@45031 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/fofi')
11 files changed, 695 insertions, 423 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/CMakeLists.txt b/Build/source/libs/xpdf/xpdf-src/fofi/CMakeLists.txt new file mode 100644 index 00000000000..076cfafb247 --- /dev/null +++ b/Build/source/libs/xpdf/xpdf-src/fofi/CMakeLists.txt @@ -0,0 +1,26 @@ +#======================================================================== +# +# fofi/CMakeLists.txt +# +# CMake script for the fofi library. +# +# Copyright 2015 Glyph & Cog, LLC +# +#======================================================================== + +include_directories("${PROJECT_SOURCE_DIR}") +include_directories("${PROJECT_BINARY_DIR}") +include_directories("${PROJECT_SOURCE_DIR}/goo") + +add_library(fofi_objs OBJECT + FoFiBase.cc + FoFiEncodings.cc + FoFiIdentifier.cc + FoFiTrueType.cc + FoFiType1.cc + FoFiType1C.cc +) + +add_library(fofi + $<TARGET_OBJECTS:fofi_objs> +) diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc index c9ca440b814..07cc3fcd52f 100644 --- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc +++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiBase.cc @@ -15,6 +15,7 @@ #include <stdio.h> #include <limits.h> #include "gmem.h" +#include "gmempp.h" #include "FoFiBase.h" //------------------------------------------------------------------------ diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiEncodings.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiEncodings.cc index e654fab19bf..6b3debb9dab 100644 --- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiEncodings.cc +++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiEncodings.cc @@ -13,6 +13,7 @@ #endif #include <stdlib.h> +#include "gmempp.h" #include "FoFiEncodings.h" //------------------------------------------------------------------------ diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiIdentifier.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiIdentifier.cc index 978cc700ee3..333fe0763b3 100644 --- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiIdentifier.cc +++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiIdentifier.cc @@ -17,6 +17,7 @@ #include <limits.h> #include "gtypes.h" #include "gmem.h" +#include "gmempp.h" #include "GString.h" #include "GList.h" #include "FoFiIdentifier.h" diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc index 8a1bfec7080..c1dbfe1c260 100644 --- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc +++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.cc @@ -19,6 +19,7 @@ #endif #include "gtypes.h" #include "gmem.h" +#include "gmempp.h" #include "GString.h" #include "GHash.h" #include "FoFiType1C.h" @@ -119,7 +120,7 @@ struct TrueTypeLoca { #define os2Tag 0x4f532f32 #define postTag 0x706f7374 -#ifdef HAVE_STD_SORT +#if HAVE_STD_SORT struct cmpTrueTypeLocaOffsetFunctor { bool operator()(const TrueTypeLoca &loca1, const TrueTypeLoca &loca2) { @@ -525,6 +526,119 @@ void FoFiTrueType::getFontMatrix(double *mat) { delete ff; } +struct FoFiTrueTypeTrickyFont { + int cvtLen; + Guint cvtChecksum; + int fpgmLen; + Guint fpgmChecksum; + int prepLen; + Guint prepChecksum; +}; + +// This data was taken from the FreeType project. +static FoFiTrueTypeTrickyFont trickyFonts[] = { + { 0x000002e4, 0x05bcf058, // MingLiU 1995 + 0x000087c4, 0x28233bf1, + 0x000001e1, 0xa344a1ea }, + { 0x000002e4, 0x05bcf058, // MingLiU 1996- + 0x000087c4, 0x28233bf1, + 0x000001e1, 0xa344a1eb }, + { 0x00000350, 0x11e5ead4, // DFKaiShu + 0x00009063, 0x5a30ca3b, + 0x0000007e, 0x13a42602 }, + { 0x00000350, 0x11e5ead4, // DFKaiShu2 + 0x00008998, 0xa6e78c01, + 0x0000007e, 0x13a42602 }, + { 0x00000008, 0xfffbfffc, // HuaTianKaiTi + 0x0000bea2, 0x9c9e48b8, + 0x00000008, 0x70020112 }, + { 0x00000008, 0xfffbfffc, // HuaTianSongTi + 0x00017c39, 0x0a5a0483, + 0x00000008, 0x70020112 }, + { 0x00000000, 0x00000000, // NEC fadpop7.ttf + 0x000000e5, 0x40c92555, + 0x0000117c, 0xa39b58e3 }, + { 0x00000000, 0x00000000, // NEC fadrei5.ttf + 0x000000e5, 0x33c41652, + 0x00000f6a, 0x26d6c52a }, + { 0x00000000, 0x00000000, // NEC fangot7.ttf + 0x0000019d, 0x6db1651d, + 0x00002492, 0x6c6e4b03 }, + { 0x00000000, 0x00000000, // NEC fangyo5.ttf + 0x000000e5, 0x40c92555, + 0x0000117c, 0xde51fad0 }, + { 0x00000000, 0x00000000, // NEC fankyo5.ttf + 0x000000e5, 0x85e47664, + 0x00001caa, 0xa6c62831 }, + { 0x00000000, 0x00000000, // NEC fanrgo5.ttf + 0x0000019d, 0x2d891cfd, + 0x00001de8, 0xa0604633 }, + { 0x00000000, 0x00000000, // NEC fangot5.ttc + 0x000001cb, 0x40aa774c, + 0x00001f9a, 0x9b5caa96 }, + { 0x00000000, 0x00000000, // NEC fanmin3.ttc + 0x00000141, 0x0d3de9cb, + 0x00002280, 0xd4127766 }, + { 0x00000000, 0x00000000, // NEC FA-Gothic, 1996 + 0x000001f0, 0x4a692698, + 0x00001fca, 0x340d4346 }, + { 0x00000000, 0x00000000, // NEC FA-Minchou, 1996 + 0x00000166, 0xcd34c604, + 0x000022b0, 0x6cf31046 }, + { 0x00000000, 0x00000000, // NEC FA-RoundGothicB, 1996 + 0x0000019d, 0x5da75315, + 0x000022e0, 0x40745a5f }, + { 0x00000000, 0x00000000, // NEC FA-RoundGothicM, 1996 + 0x000001c2, 0xf055fc48, + 0x00001e18, 0x3900ded3 } +}; + +#define nTrickyFonts ((int)(sizeof(trickyFonts) / sizeof(FoFiTrueTypeTrickyFont))) + +// This looks at the length and checksum values for the cvt, fpgm, and +// prep tables. The theory is that those tables will be the same, +// even if the font is renamed and/or subsetted. +GBool FoFiTrueType::checkForTrickyCJK() { + int cvtIdx, fpgmIdx, prepIdx; + int cvtLen, fpgmLen, prepLen; + Guint cvtChecksum, fpgmChecksum, prepChecksum; + int i; + + if ((cvtIdx = seekTable("cvt ")) >= 0) { + cvtLen = tables[cvtIdx].len; + cvtChecksum = tables[cvtIdx].checksum; + } else { + cvtLen = 0; + cvtChecksum = 0; + } + if ((fpgmIdx = seekTable("fpgm")) >= 0) { + fpgmLen = tables[fpgmIdx].len; + fpgmChecksum = tables[fpgmIdx].checksum; + } else { + fpgmLen = 0; + fpgmChecksum = 0; + } + if ((prepIdx = seekTable("prep")) >= 0) { + prepLen = tables[prepIdx].len; + prepChecksum = tables[prepIdx].checksum; + } else { + prepLen = 0; + prepChecksum = 0; + } + + for (i = 0; i < nTrickyFonts; ++i) { + if (cvtLen == trickyFonts[i].cvtLen && + cvtChecksum == trickyFonts[i].cvtChecksum && + fpgmLen == trickyFonts[i].fpgmLen && + fpgmChecksum == trickyFonts[i].fpgmChecksum && + prepLen == trickyFonts[i].prepLen && + prepChecksum == trickyFonts[i].prepChecksum) { + return gTrue; + } + } + return gFalse; +} + void FoFiTrueType::convertToType42(char *psName, char **encoding, int *codeToGID, FoFiOutputFunc outputFunc, @@ -966,6 +1080,7 @@ void FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc, unsortedLoca = gFalse; i = seekTable("loca"); pos = tables[i].offset; + glyfLen = tables[seekTable("glyf")].len; ok = gTrue; for (i = 0; i <= nGlyphs; ++i) { if (locaFmt) { @@ -973,6 +1088,11 @@ void FoFiTrueType::writeTTF(FoFiOutputFunc outputFunc, } else { locaTable[i].origOffset = 2 * getU16BE(pos + i*2, &ok); } + if (locaTable[i].origOffset < 0 || + locaTable[i].origOffset > glyfLen) { + locaTable[i].origOffset = glyfLen; + unsortedLoca = gTrue; + } if (i > 0 && locaTable[i].origOffset < locaTable[i-1].origOffset) { unsortedLoca = gTrue; } @@ -1562,11 +1682,6 @@ void FoFiTrueType::cvtCharStrings(char **encoding, (*outputFunc)(outputStream, "/CharStrings 256 dict dup begin\n", 32); (*outputFunc)(outputStream, "/.notdef 0 def\n", 15); - // if there's no 'cmap' table, punt - if (nCmaps == 0) { - goto err; - } - // map char name to glyph index: // 1. use encoding to map name to char code // 2. use codeToGID to map char code to glyph index @@ -1597,7 +1712,6 @@ void FoFiTrueType::cvtCharStrings(char **encoding, } } - err: (*outputFunc)(outputStream, "end readonly def\n", 17); } @@ -2115,8 +2229,8 @@ void FoFiTrueType::parse(int fontNum, GBool allowHeadlessCFF) { return; } - // make sure the loca table is sane (correct length and entries are - // in bounds) + // make sure the loca table is sane (correct length) + // NB: out-of-bounds entries are handled in writeTTF() if (!openTypeCFF) { i = seekTable("loca"); if (tables[i].len < 0) { @@ -2126,16 +2240,6 @@ void FoFiTrueType::parse(int fontNum, GBool allowHeadlessCFF) { if (tables[i].len < (nGlyphs + 1) * (locaFmt ? 4 : 2)) { nGlyphs = tables[i].len / (locaFmt ? 4 : 2) - 1; } - for (j = 0; j <= nGlyphs; ++j) { - if (locaFmt) { - pos = (int)getU32BE(tables[i].offset + j*4, &parsedOk); - } else { - pos = getU16BE(tables[i].offset + j*2, &parsedOk); - } - if (pos < 0 || pos > len) { - parsedOk = gFalse; - } - } if (!parsedOk) { return; } @@ -2245,6 +2349,7 @@ void FoFiTrueType::readPostTable() { stringIdx = 0; stringPos = tablePos + 34 + 2*n; for (i = 0; i < n; ++i) { + ok = gTrue; j = getU16BE(tablePos + 34 + 2*i, &ok); if (j < 258) { nameToGID->removeInt(macGlyphNames[j]); @@ -2256,12 +2361,12 @@ void FoFiTrueType::readPostTable() { stringIdx < j; ++stringIdx, stringPos += 1 + getU8(stringPos, &ok)) ; if (!ok) { - goto err; + continue; } } m = getU8(stringPos, &ok); if (!ok || !checkRegion(stringPos + 1, m)) { - goto err; + continue; } name = new GString((char *)&file[stringPos + 1], m); nameToGID->removeInt(name); @@ -2275,7 +2380,7 @@ void FoFiTrueType::readPostTable() { for (i = 0; i < nGlyphs; ++i) { j = getU8(tablePos + 32 + i, &ok); if (!ok) { - goto err; + continue; } if (j < 258) { nameToGID->removeInt(macGlyphNames[j]); diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h index 2cf9417d609..afa56697ba8 100644 --- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h +++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiTrueType.h @@ -95,6 +95,10 @@ public: // for OpenType CFF fonts.) void getFontMatrix(double *mat); + // Returns true if this looks like a CJK font that uses bytecode + // instructions to assemble glyphs. + GBool checkForTrickyCJK(); + // Convert to a Type 42 font, suitable for embedding in a PostScript // file. <psName> will be used as the PostScript font name (so we // don't need to depend on the 'name' table in the font). The diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc index 9eeb363d459..4ff1369aaf8 100644 --- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc +++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1.cc @@ -15,6 +15,7 @@ #include <stdlib.h> #include <string.h> #include "gmem.h" +#include "gmempp.h" #include "FoFiEncodings.h" #include "FoFiType1.h" @@ -198,7 +199,7 @@ void FoFiType1::parse() { gotMatrix = gFalse; for (i = 1, line = (char *)file; - i <= 100 && line && (!name || !encoding); + i <= 100 && line && (!name || !encoding || !gotMatrix); ++i) { // get font name @@ -255,6 +256,7 @@ void FoFiType1::parse() { if (code >= 0 && code < 256) { c = *p2; *p2 = '\0'; + gfree(encoding[code]); encoding[code] = copyString(p); *p2 = c; } diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc index 7986cee88f1..f4de9571d1f 100644 --- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc +++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.cc @@ -16,6 +16,7 @@ #include <string.h> #include <math.h> #include "gmem.h" +#include "gmempp.h" #include "GString.h" #include "FoFiEncodings.h" #include "FoFiType1C.h" @@ -25,6 +26,44 @@ static char hexChars[17] = "0123456789ABCDEF"; //------------------------------------------------------------------------ + +GBool Type1COp::isZero() { + switch (kind) { + case type1COpInteger: return intgr == 0; + case type1COpFloat: return flt == 0; + case type1COpRational: return rat.num == 0; + default: return gFalse; // shouldn't happen + } +} + +GBool Type1COp::isNegative() { + switch (kind) { + case type1COpInteger: return intgr < 0; + case type1COpFloat: return flt < 0; + case type1COpRational: return (rat.num < 0) != (rat.den < 0); + default: return gFalse; // shouldn't happen + } +} + +int Type1COp::toInt() { + switch (kind) { + case type1COpInteger: return intgr; + case type1COpFloat: return (int)flt; + case type1COpRational: return rat.num / rat.den; + default: return 0; // shouldn't happen + } +} + +double Type1COp::toFloat() { + switch (kind) { + case type1COpInteger: return (double)intgr; + case type1COpFloat: return flt; + case type1COpRational: return (double)rat.num / (double)rat.den; + default: return 0.0; // shouldn't happen + } +} + +//------------------------------------------------------------------------ // FoFiType1C //------------------------------------------------------------------------ @@ -744,7 +783,7 @@ void FoFiType1C::convertToCIDType0(char *psName, int *codeMap, int nCodes, break; } } - if (j == privateDicts[0].nStemSnapH) { + if (j == privateDicts[i].nStemSnapH) { (*outputFunc)(outputStream, "/StemSnapH [", 12); for (j = 0; j < privateDicts[i].nStemSnapH; ++j) { buf = GString::format("{0:s}{1:.4g}", @@ -763,7 +802,7 @@ void FoFiType1C::convertToCIDType0(char *psName, int *codeMap, int nCodes, break; } } - if (j == privateDicts[0].nStemSnapV) { + if (j == privateDicts[i].nStemSnapV) { (*outputFunc)(outputStream, "/StemSnapV [", 12); for (j = 0; j < privateDicts[i].nStemSnapV; ++j) { buf = GString::format("{0:s}{1:.4g}", @@ -1060,7 +1099,7 @@ void FoFiType1C::convertToType0(char *psName, int *codeMap, int nCodes, break; } } - if (k == privateDicts[0].nStemSnapH) { + if (k == privateDicts[fd].nStemSnapH) { eexecWrite(&eb, "/StemSnapH ["); for (k = 0; k < privateDicts[fd].nStemSnapH; ++k) { buf = GString::format("{0:s}{1:.4g}", @@ -1080,7 +1119,7 @@ void FoFiType1C::convertToType0(char *psName, int *codeMap, int nCodes, break; } } - if (k == privateDicts[0].nStemSnapV) { + if (k == privateDicts[fd].nStemSnapV) { eexecWrite(&eb, "/StemSnapV ["); for (k = 0; k < privateDicts[fd].nStemSnapV; ++k) { buf = GString::format("{0:s}{1:.4g}", @@ -1228,11 +1267,12 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, Type1CIndex *subrIdx, Type1CPrivateDict *pDict, GBool top) { Type1CIndexVal val; - GBool ok, dFP; + Type1COp zero, tmp; + GBool ok, dInt; double d, dx, dy; Gushort r2; Guchar byte; - int pos, subrBias, start, i, k; + int pos, subrBias, start, num, den, i, k; start = charBuf->getLength(); if (top) { @@ -1246,6 +1286,9 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, openPath = gFalse; } + zero.kind = type1COpInteger; + zero.intgr = 0; + pos = offset; while (pos < offset + nBytes) { ok = gTrue; @@ -1253,7 +1296,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, if (!ok) { break; } - if (!ops[nOps - 1].isNum) { + if (ops[nOps - 1].kind == type1COpOperator) { --nOps; // drop the operator switch (ops[nOps].op) { case 0x0001: // hstem @@ -1265,21 +1308,47 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, //~ error(-1, "Wrong number of args (%d) to Type 2 hstem", nOps); } d = 0; - dFP = gFalse; - for (k = 0; k < nOps; k += 2) { + dInt = gTrue; + for (k = 0; k+1 < nOps; k += 2) { // convert Type 2 edge hints (-20 or -21) to Type 1 ghost hints - if (ops[k+1].num < 0) { - d += ops[k].num + ops[k+1].num; - dFP |= ops[k].isFP | ops[k+1].isFP; - cvtNum(d, dFP, charBuf); - cvtNum(-ops[k+1].num, ops[k+1].isFP, charBuf); + if (ops[k+1].isNegative()) { + d += ops[k].toFloat() + ops[k+1].toFloat(); + dInt &= ops[k].kind == type1COpInteger; + dInt &= ops[k+1].kind == type1COpInteger; + if (dInt) { + tmp.kind = type1COpInteger; + tmp.intgr = (int)(d + 0.5); + } else { + tmp.kind = type1COpFloat; + tmp.flt = d; + } + cvtNum(tmp, charBuf); + if (ops[k+1].kind == type1COpInteger) { + tmp.kind = type1COpInteger; + tmp.intgr = -ops[k+1].intgr; + } else if (ops[k+1].kind == type1COpRational) { + tmp.kind = type1COpRational; + tmp.rat.num = -ops[k+1].rat.num; + tmp.rat.den = ops[k+1].rat.den; + } else { + tmp.kind = type1COpFloat; + tmp.flt = -ops[k+1].toFloat(); + } + cvtNum(tmp, charBuf); } else { - d += ops[k].num; - dFP |= ops[k].isFP; - cvtNum(d, dFP, charBuf); - cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); - d += ops[k+1].num; - dFP |= ops[k+1].isFP; + d += ops[k].toFloat(); + dInt &= ops[k].kind == type1COpInteger; + if (dInt) { + tmp.kind = type1COpInteger; + tmp.intgr = (int)(d + 0.5); + } else { + tmp.kind = type1COpFloat; + tmp.flt = d; + } + cvtNum(tmp, charBuf); + cvtNum(ops[k+1], charBuf); + d += ops[k+1].toFloat(); + dInt &= ops[k+1].kind == type1COpInteger; } charBuf->append((char)1); } @@ -1295,21 +1364,47 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, //~ error(-1, "Wrong number of args (%d) to Type 2 vstem", nOps); } d = 0; - dFP = gFalse; - for (k = 0; k < nOps; k += 2) { + dInt = gTrue; + for (k = 0; k+1 < nOps; k += 2) { // convert Type 2 edge hints (-20 or -21) to Type 1 ghost hints - if (ops[k+1].num < 0) { - d += ops[k].num + ops[k+1].num; - dFP |= ops[k].isFP | ops[k+1].isFP; - cvtNum(d, dFP, charBuf); - cvtNum(-ops[k+1].num, ops[k+1].isFP, charBuf); + if (ops[k+1].isNegative()) { + d += ops[k].toFloat() + ops[k+1].toFloat(); + dInt &= ops[k].kind == type1COpInteger; + dInt &= ops[k+1].kind == type1COpInteger; + if (dInt) { + tmp.kind = type1COpInteger; + tmp.intgr = (int)(d + 0.5); + } else { + tmp.kind = type1COpFloat; + tmp.flt = d; + } + cvtNum(tmp, charBuf); + if (ops[k+1].kind == type1COpInteger) { + tmp.kind = type1COpInteger; + tmp.intgr = -ops[k+1].intgr; + } else if (ops[k+1].kind == type1COpRational) { + tmp.kind = type1COpRational; + tmp.rat.num = -ops[k+1].rat.num; + tmp.rat.den = ops[k+1].rat.den; + } else { + tmp.kind = type1COpFloat; + tmp.flt = -ops[k+1].toFloat(); + } + cvtNum(tmp, charBuf); } else { - d += ops[k].num; - dFP |= ops[k].isFP; - cvtNum(d, dFP, charBuf); - cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); - d += ops[k+1].num; - dFP |= ops[k+1].isFP; + d += ops[k].toFloat(); + dInt &= ops[k].kind == type1COpInteger; + if (dInt) { + tmp.kind = type1COpInteger; + tmp.intgr = (int)(d + 0.5); + } else { + tmp.kind = type1COpFloat; + tmp.flt = d; + } + cvtNum(tmp, charBuf); + cvtNum(ops[k+1], charBuf); + d += ops[k+1].toFloat(); + dInt &= ops[k+1].kind == type1COpInteger; } charBuf->append((char)3); } @@ -1328,7 +1423,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, if (nOps != 1) { //~ error(-1, "Wrong number of args (%d) to Type 2 vmoveto", nOps); } - cvtNum(ops[0].num, ops[0].isFP, charBuf); + cvtNum(ops[0], charBuf); charBuf->append((char)4); nOps = 0; break; @@ -1336,9 +1431,9 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, if (nOps < 2 || nOps % 2 != 0) { //~ error(-1, "Wrong number of args (%d) to Type 2 rlineto", nOps); } - for (k = 0; k < nOps; k += 2) { - cvtNum(ops[k].num, ops[k].isFP, charBuf); - cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); + for (k = 0; k+1 < nOps; k += 2) { + cvtNum(ops[k], charBuf); + cvtNum(ops[k+1], charBuf); charBuf->append((char)5); } nOps = 0; @@ -1349,7 +1444,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, //~ error(-1, "Wrong number of args (%d) to Type 2 hlineto", nOps); } for (k = 0; k < nOps; ++k) { - cvtNum(ops[k].num, ops[k].isFP, charBuf); + cvtNum(ops[k], charBuf); charBuf->append((char)((k & 1) ? 7 : 6)); } nOps = 0; @@ -1360,7 +1455,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, //~ error(-1, "Wrong number of args (%d) to Type 2 vlineto", nOps); } for (k = 0; k < nOps; ++k) { - cvtNum(ops[k].num, ops[k].isFP, charBuf); + cvtNum(ops[k], charBuf); charBuf->append((char)((k & 1) ? 6 : 7)); } nOps = 0; @@ -1371,12 +1466,12 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, //~ error(-1, "Wrong number of args (%d) to Type 2 rrcurveto", nOps); } for (k = 0; k < nOps; k += 6) { - cvtNum(ops[k].num, ops[k].isFP, charBuf); - cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); - cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); - cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); - cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf); - cvtNum(ops[k+5].num, ops[k+5].isFP, charBuf); + cvtNum(ops[k], charBuf); + cvtNum(ops[k+1], charBuf); + cvtNum(ops[k+2], charBuf); + cvtNum(ops[k+3], charBuf); + cvtNum(ops[k+4], charBuf); + cvtNum(ops[k+5], charBuf); charBuf->append((char)8); } nOps = 0; @@ -1386,7 +1481,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, if (nOps >= 1) { subrBias = (subrIdx->len < 1240) ? 107 : (subrIdx->len < 33900) ? 1131 : 32768; - k = subrBias + (int)ops[nOps - 1].num; + k = subrBias + ops[nOps - 1].toInt(); --nOps; ok = gTrue; getIndexVal(subrIdx, k, &val, &ok); @@ -1411,11 +1506,11 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, openPath = gFalse; } if (nOps == 4) { - cvtNum(0, gFalse, charBuf); - cvtNum(ops[0].num, ops[0].isFP, charBuf); - cvtNum(ops[1].num, ops[1].isFP, charBuf); - cvtNum(ops[2].num, ops[2].isFP, charBuf); - cvtNum(ops[3].num, ops[3].isFP, charBuf); + cvtNum(zero, charBuf); + cvtNum(ops[0], charBuf); + cvtNum(ops[1], charBuf); + cvtNum(ops[2], charBuf); + cvtNum(ops[3], charBuf); charBuf->append((char)12)->append((char)6); } else if (nOps == 0) { charBuf->append((char)14); @@ -1492,8 +1587,8 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, if (nOps != 2) { //~ error(-1, "Wrong number of args (%d) to Type 2 rmoveto", nOps); } - cvtNum(ops[0].num, ops[0].isFP, charBuf); - cvtNum(ops[1].num, ops[1].isFP, charBuf); + cvtNum(ops[0], charBuf); + cvtNum(ops[1], charBuf); charBuf->append((char)21); nOps = 0; break; @@ -1509,7 +1604,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, if (nOps != 1) { //~ error(-1, "Wrong number of args (%d) to Type 2 hmoveto", nOps); } - cvtNum(ops[0].num, ops[0].isFP, charBuf); + cvtNum(ops[0], charBuf); charBuf->append((char)22); nOps = 0; break; @@ -1529,17 +1624,17 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, if (nOps < 8 || (nOps - 2) % 6 != 0) { //~ error(-1, "Wrong number of args (%d) to Type 2 rcurveline", nOps); } - for (k = 0; k < nOps - 2; k += 6) { - cvtNum(ops[k].num, ops[k].isFP, charBuf); - cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); - cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); - cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); - cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf); - cvtNum(ops[k+5].num, ops[k+5].isFP, charBuf); + for (k = 0; k <= nOps - 8; k += 6) { + cvtNum(ops[k], charBuf); + cvtNum(ops[k+1], charBuf); + cvtNum(ops[k+2], charBuf); + cvtNum(ops[k+3], charBuf); + cvtNum(ops[k+4], charBuf); + cvtNum(ops[k+5], charBuf); charBuf->append((char)8); } - cvtNum(ops[k].num, ops[k].isFP, charBuf); - cvtNum(ops[k+1].num, ops[k].isFP, charBuf); + cvtNum(ops[k], charBuf); + cvtNum(ops[k+1], charBuf); charBuf->append((char)5); nOps = 0; openPath = gTrue; @@ -1548,17 +1643,17 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, if (nOps < 8 || (nOps - 6) % 2 != 0) { //~ error(-1, "Wrong number of args (%d) to Type 2 rlinecurve", nOps); } - for (k = 0; k < nOps - 6; k += 2) { - cvtNum(ops[k].num, ops[k].isFP, charBuf); - cvtNum(ops[k+1].num, ops[k].isFP, charBuf); + for (k = 0; k <= nOps - 8; k += 2) { + cvtNum(ops[k], charBuf); + cvtNum(ops[k+1], charBuf); charBuf->append((char)5); } - cvtNum(ops[k].num, ops[k].isFP, charBuf); - cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); - cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); - cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); - cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf); - cvtNum(ops[k+5].num, ops[k+5].isFP, charBuf); + cvtNum(ops[k], charBuf); + cvtNum(ops[k+1], charBuf); + cvtNum(ops[k+2], charBuf); + cvtNum(ops[k+3], charBuf); + cvtNum(ops[k+4], charBuf); + cvtNum(ops[k+5], charBuf); charBuf->append((char)8); nOps = 0; openPath = gTrue; @@ -1567,25 +1662,25 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) { //~ error(-1, "Wrong number of args (%d) to Type 2 vvcurveto", nOps); } - if (nOps % 2 == 1) { - cvtNum(ops[0].num, ops[0].isFP, charBuf); - cvtNum(ops[1].num, ops[1].isFP, charBuf); - cvtNum(ops[2].num, ops[2].isFP, charBuf); - cvtNum(ops[3].num, ops[3].isFP, charBuf); - cvtNum(0, gFalse, charBuf); - cvtNum(ops[4].num, ops[4].isFP, charBuf); + if (nOps % 2 == 1 && nOps >= 5) { + cvtNum(ops[0], charBuf); + cvtNum(ops[1], charBuf); + cvtNum(ops[2], charBuf); + cvtNum(ops[3], charBuf); + cvtNum(zero, charBuf); + cvtNum(ops[4], charBuf); charBuf->append((char)8); k = 5; } else { k = 0; } - for (; k < nOps; k += 4) { - cvtNum(0, gFalse, charBuf); - cvtNum(ops[k].num, ops[k].isFP, charBuf); - cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); - cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); - cvtNum(0, gFalse, charBuf); - cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + for (; k+3 < nOps; k += 4) { + cvtNum(zero, charBuf); + cvtNum(ops[k], charBuf); + cvtNum(ops[k+1], charBuf); + cvtNum(ops[k+2], charBuf); + cvtNum(zero, charBuf); + cvtNum(ops[k+3], charBuf); charBuf->append((char)8); } nOps = 0; @@ -1595,25 +1690,25 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) { //~ error(-1, "Wrong number of args (%d) to Type 2 hhcurveto", nOps); } - if (nOps % 2 == 1) { - cvtNum(ops[1].num, ops[1].isFP, charBuf); - cvtNum(ops[0].num, ops[0].isFP, charBuf); - cvtNum(ops[2].num, ops[2].isFP, charBuf); - cvtNum(ops[3].num, ops[3].isFP, charBuf); - cvtNum(ops[4].num, ops[4].isFP, charBuf); - cvtNum(0, gFalse, charBuf); + if (nOps % 2 == 1 && nOps >= 5) { + cvtNum(ops[1], charBuf); + cvtNum(ops[0], charBuf); + cvtNum(ops[2], charBuf); + cvtNum(ops[3], charBuf); + cvtNum(ops[4], charBuf); + cvtNum(zero, charBuf); charBuf->append((char)8); k = 5; } else { k = 0; } - for (; k < nOps; k += 4) { - cvtNum(ops[k].num, ops[k].isFP, charBuf); - cvtNum(0, gFalse, charBuf); - cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); - cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); - cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); - cvtNum(0, gFalse, charBuf); + for (; k+3 < nOps; k += 4) { + cvtNum(ops[k], charBuf); + cvtNum(zero, charBuf); + cvtNum(ops[k+1], charBuf); + cvtNum(ops[k+2], charBuf); + cvtNum(ops[k+3], charBuf); + cvtNum(zero, charBuf); charBuf->append((char)8); } nOps = 0; @@ -1621,7 +1716,7 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, break; case 0x001d: // callgsubr if (nOps >= 1) { - k = gsubrBias + (int)ops[nOps - 1].num; + k = gsubrBias + ops[nOps - 1].toInt(); --nOps; ok = gTrue; getIndexVal(&gsubrIdx, k, &val, &ok); @@ -1637,36 +1732,36 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) { //~ error(-1, "Wrong number of args (%d) to Type 2 vhcurveto", nOps); } - for (k = 0; k < nOps && k != nOps-5; k += 4) { + for (k = 0; k+3 < nOps && k != nOps-5; k += 4) { if (k % 8 == 0) { - cvtNum(ops[k].num, ops[k].isFP, charBuf); - cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); - cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); - cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + cvtNum(ops[k], charBuf); + cvtNum(ops[k+1], charBuf); + cvtNum(ops[k+2], charBuf); + cvtNum(ops[k+3], charBuf); charBuf->append((char)30); } else { - cvtNum(ops[k].num, ops[k].isFP, charBuf); - cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); - cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); - cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + cvtNum(ops[k], charBuf); + cvtNum(ops[k+1], charBuf); + cvtNum(ops[k+2], charBuf); + cvtNum(ops[k+3], charBuf); charBuf->append((char)31); } } if (k == nOps-5) { if (k % 8 == 0) { - cvtNum(0, gFalse, charBuf); - cvtNum(ops[k].num, ops[k].isFP, charBuf); - cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); - cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); - cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); - cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf); + cvtNum(zero, charBuf); + cvtNum(ops[k], charBuf); + cvtNum(ops[k+1], charBuf); + cvtNum(ops[k+2], charBuf); + cvtNum(ops[k+3], charBuf); + cvtNum(ops[k+4], charBuf); } else { - cvtNum(ops[k].num, ops[k].isFP, charBuf); - cvtNum(0, gFalse, charBuf); - cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); - cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); - cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf); - cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + cvtNum(ops[k], charBuf); + cvtNum(zero, charBuf); + cvtNum(ops[k+1], charBuf); + cvtNum(ops[k+2], charBuf); + cvtNum(ops[k+4], charBuf); + cvtNum(ops[k+3], charBuf); } charBuf->append((char)8); } @@ -1677,36 +1772,36 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) { //~ error(-1, "Wrong number of args (%d) to Type 2 hvcurveto", nOps); } - for (k = 0; k < nOps && k != nOps-5; k += 4) { + for (k = 0; k+3 < nOps && k != nOps-5; k += 4) { if (k % 8 == 0) { - cvtNum(ops[k].num, ops[k].isFP, charBuf); - cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); - cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); - cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + cvtNum(ops[k], charBuf); + cvtNum(ops[k+1], charBuf); + cvtNum(ops[k+2], charBuf); + cvtNum(ops[k+3], charBuf); charBuf->append((char)31); } else { - cvtNum(ops[k].num, ops[k].isFP, charBuf); - cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); - cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); - cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + cvtNum(ops[k], charBuf); + cvtNum(ops[k+1], charBuf); + cvtNum(ops[k+2], charBuf); + cvtNum(ops[k+3], charBuf); charBuf->append((char)30); } } if (k == nOps-5) { if (k % 8 == 0) { - cvtNum(ops[k].num, ops[k].isFP, charBuf); - cvtNum(0, gFalse, charBuf); - cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); - cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); - cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf); - cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); + cvtNum(ops[k], charBuf); + cvtNum(zero, charBuf); + cvtNum(ops[k+1], charBuf); + cvtNum(ops[k+2], charBuf); + cvtNum(ops[k+4], charBuf); + cvtNum(ops[k+3], charBuf); } else { - cvtNum(0, gFalse, charBuf); - cvtNum(ops[k].num, ops[k].isFP, charBuf); - cvtNum(ops[k+1].num, ops[k+1].isFP, charBuf); - cvtNum(ops[k+2].num, ops[k+2].isFP, charBuf); - cvtNum(ops[k+3].num, ops[k+3].isFP, charBuf); - cvtNum(ops[k+4].num, ops[k+4].isFP, charBuf); + cvtNum(zero, charBuf); + cvtNum(ops[k], charBuf); + cvtNum(ops[k+1], charBuf); + cvtNum(ops[k+2], charBuf); + cvtNum(ops[k+3], charBuf); + cvtNum(ops[k+4], charBuf); } charBuf->append((char)8); } @@ -1717,6 +1812,18 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, // ignored nOps = 0; break; + case 0x0c0c: // div + if (nOps >= 2) { + num = ops[nOps-2].toInt(); + den = ops[nOps-1].toInt(); + --nOps; + ops[nOps-1].kind = type1COpRational; + ops[nOps-1].rat.num = num; + ops[nOps-1].rat.den = den; + } else { + //~ error(-1, "Wrong number of args (%d) to Type 2 div", nOps); + } + break; case 0x0c03: // and case 0x0c04: // or case 0x0c05: // not @@ -1724,7 +1831,6 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, case 0x0c09: // abs case 0x0c0a: // add case 0x0c0b: // sub - case 0x0c0c: // div case 0x0c0d: // load case 0x0c0e: // neg case 0x0c0f: // eq @@ -1743,96 +1849,141 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, nOps = 0; break; case 0x0c22: // hflex - if (nOps != 7) { + if (nOps == 7) { + cvtNum(ops[0], charBuf); + cvtNum(zero, charBuf); + cvtNum(ops[1], charBuf); + cvtNum(ops[2], charBuf); + cvtNum(ops[3], charBuf); + cvtNum(zero, charBuf); + charBuf->append((char)8); + cvtNum(ops[4], charBuf); + cvtNum(zero, charBuf); + cvtNum(ops[5], charBuf); + if (ops[2].kind == type1COpInteger) { + tmp.kind = type1COpInteger; + tmp.intgr = -ops[2].intgr; + } else if (ops[2].kind == type1COpRational) { + tmp.kind = type1COpRational; + tmp.rat.num = -ops[2].rat.num; + tmp.rat.den = ops[2].rat.den; + } else { + tmp.kind = type1COpFloat; + tmp.flt = -ops[2].toFloat(); + } + cvtNum(tmp, charBuf); + cvtNum(ops[6], charBuf); + cvtNum(zero, charBuf); + charBuf->append((char)8); + } else { //~ error(-1, "Wrong number of args (%d) to Type 2 hflex", nOps); } - cvtNum(ops[0].num, ops[0].isFP, charBuf); - cvtNum(0, gFalse, charBuf); - cvtNum(ops[1].num, ops[1].isFP, charBuf); - cvtNum(ops[2].num, ops[2].isFP, charBuf); - cvtNum(ops[3].num, ops[3].isFP, charBuf); - cvtNum(0, gFalse, charBuf); - charBuf->append((char)8); - cvtNum(ops[4].num, ops[4].isFP, charBuf); - cvtNum(0, gFalse, charBuf); - cvtNum(ops[5].num, ops[5].isFP, charBuf); - cvtNum(-ops[2].num, ops[2].isFP, charBuf); - cvtNum(ops[6].num, ops[6].isFP, charBuf); - cvtNum(0, gFalse, charBuf); - charBuf->append((char)8); nOps = 0; openPath = gTrue; break; case 0x0c23: // flex - if (nOps != 13) { + if (nOps == 13) { + cvtNum(ops[0], charBuf); + cvtNum(ops[1], charBuf); + cvtNum(ops[2], charBuf); + cvtNum(ops[3], charBuf); + cvtNum(ops[4], charBuf); + cvtNum(ops[5], charBuf); + charBuf->append((char)8); + cvtNum(ops[6], charBuf); + cvtNum(ops[7], charBuf); + cvtNum(ops[8], charBuf); + cvtNum(ops[9], charBuf); + cvtNum(ops[10], charBuf); + cvtNum(ops[11], charBuf); + charBuf->append((char)8); + } else { //~ error(-1, "Wrong number of args (%d) to Type 2 flex", nOps); } - cvtNum(ops[0].num, ops[0].isFP, charBuf); - cvtNum(ops[1].num, ops[1].isFP, charBuf); - cvtNum(ops[2].num, ops[2].isFP, charBuf); - cvtNum(ops[3].num, ops[3].isFP, charBuf); - cvtNum(ops[4].num, ops[4].isFP, charBuf); - cvtNum(ops[5].num, ops[5].isFP, charBuf); - charBuf->append((char)8); - cvtNum(ops[6].num, ops[6].isFP, charBuf); - cvtNum(ops[7].num, ops[7].isFP, charBuf); - cvtNum(ops[8].num, ops[8].isFP, charBuf); - cvtNum(ops[9].num, ops[9].isFP, charBuf); - cvtNum(ops[10].num, ops[10].isFP, charBuf); - cvtNum(ops[11].num, ops[11].isFP, charBuf); - charBuf->append((char)8); nOps = 0; openPath = gTrue; break; case 0x0c24: // hflex1 - if (nOps != 9) { + if (nOps == 9) { + cvtNum(ops[0], charBuf); + cvtNum(ops[1], charBuf); + cvtNum(ops[2], charBuf); + cvtNum(ops[3], charBuf); + cvtNum(ops[4], charBuf); + cvtNum(zero, charBuf); + charBuf->append((char)8); + cvtNum(ops[5], charBuf); + cvtNum(zero, charBuf); + cvtNum(ops[6], charBuf); + cvtNum(ops[7], charBuf); + cvtNum(ops[8], charBuf); + if (ops[1].kind == type1COpInteger && + ops[3].kind == type1COpInteger && + ops[7].kind == type1COpInteger) { + tmp.kind = type1COpInteger; + tmp.intgr = -(ops[1].intgr + ops[3].intgr + ops[7].intgr); + } else { + tmp.kind = type1COpFloat; + tmp.flt = -(ops[1].toFloat() + ops[3].toFloat() + ops[7].toFloat()); + } + cvtNum(tmp, charBuf); + charBuf->append((char)8); + } else { //~ error(-1, "Wrong number of args (%d) to Type 2 hflex1", nOps); } - cvtNum(ops[0].num, ops[0].isFP, charBuf); - cvtNum(ops[1].num, ops[1].isFP, charBuf); - cvtNum(ops[2].num, ops[2].isFP, charBuf); - cvtNum(ops[3].num, ops[3].isFP, charBuf); - cvtNum(ops[4].num, ops[4].isFP, charBuf); - cvtNum(0, gFalse, charBuf); - charBuf->append((char)8); - cvtNum(ops[5].num, ops[5].isFP, charBuf); - cvtNum(0, gFalse, charBuf); - cvtNum(ops[6].num, ops[6].isFP, charBuf); - cvtNum(ops[7].num, ops[7].isFP, charBuf); - cvtNum(ops[8].num, ops[8].isFP, charBuf); - cvtNum(-(ops[1].num + ops[3].num + ops[7].num), - ops[1].isFP | ops[3].isFP | ops[7].isFP, charBuf); - charBuf->append((char)8); nOps = 0; openPath = gTrue; break; case 0x0c25: // flex1 - if (nOps != 11) { - //~ error(-1, "Wrong number of args (%d) to Type 2 flex1", nOps); - } - cvtNum(ops[0].num, ops[0].isFP, charBuf); - cvtNum(ops[1].num, ops[1].isFP, charBuf); - cvtNum(ops[2].num, ops[2].isFP, charBuf); - cvtNum(ops[3].num, ops[3].isFP, charBuf); - cvtNum(ops[4].num, ops[4].isFP, charBuf); - cvtNum(ops[5].num, ops[5].isFP, charBuf); - charBuf->append((char)8); - cvtNum(ops[6].num, ops[6].isFP, charBuf); - cvtNum(ops[7].num, ops[7].isFP, charBuf); - cvtNum(ops[8].num, ops[8].isFP, charBuf); - cvtNum(ops[9].num, ops[9].isFP, charBuf); - dx = ops[0].num + ops[2].num + ops[4].num + ops[6].num + ops[8].num; - dy = ops[1].num + ops[3].num + ops[5].num + ops[7].num + ops[9].num; - if (fabs(dx) > fabs(dy)) { - cvtNum(ops[10].num, ops[10].isFP, charBuf); - cvtNum(-dy, ops[1].isFP | ops[3].isFP | ops[5].isFP | - ops[7].isFP | ops[9].isFP, charBuf); + if (nOps == 11) { + cvtNum(ops[0], charBuf); + cvtNum(ops[1], charBuf); + cvtNum(ops[2], charBuf); + cvtNum(ops[3], charBuf); + cvtNum(ops[4], charBuf); + cvtNum(ops[5], charBuf); + charBuf->append((char)8); + cvtNum(ops[6], charBuf); + cvtNum(ops[7], charBuf); + cvtNum(ops[8], charBuf); + cvtNum(ops[9], charBuf); + dx = ops[0].toFloat() + ops[2].toFloat() + ops[4].toFloat() + + ops[6].toFloat() + ops[8].toFloat(); + dy = ops[1].toFloat() + ops[3].toFloat() + ops[5].toFloat() + + ops[7].toFloat() + ops[9].toFloat(); + if (fabs(dx) > fabs(dy)) { + cvtNum(ops[10], charBuf); + if (ops[1].kind == type1COpInteger && + ops[3].kind == type1COpInteger && + ops[5].kind == type1COpInteger && + ops[7].kind == type1COpInteger && + ops[9].kind == type1COpInteger) { + tmp.kind = type1COpInteger; + tmp.intgr = -(int)dy; + } else { + tmp.kind = type1COpFloat; + tmp.flt = -dy; + } + cvtNum(tmp, charBuf); + } else { + if (ops[0].kind == type1COpInteger && + ops[2].kind == type1COpInteger && + ops[4].kind == type1COpInteger && + ops[6].kind == type1COpInteger && + ops[8].kind == type1COpInteger) { + tmp.kind = type1COpInteger; + tmp.intgr = -(int)dx; + } else { + tmp.kind = type1COpFloat; + tmp.flt = -dx; + } + cvtNum(tmp, charBuf); + cvtNum(ops[10], charBuf); + } + charBuf->append((char)8); } else { - cvtNum(-dx, ops[0].isFP | ops[2].isFP | ops[4].isFP | - ops[6].isFP | ops[8].isFP, charBuf); - cvtNum(ops[10].num, ops[10].isFP, charBuf); + //~ error(-1, "Wrong number of args (%d) to Type 2 flex1", nOps); } - charBuf->append((char)8); nOps = 0; openPath = gTrue; break; @@ -1858,52 +2009,46 @@ void FoFiType1C::cvtGlyph(int offset, int nBytes, GString *charBuf, void FoFiType1C::cvtGlyphWidth(GBool useOp, GString *charBuf, Type1CPrivateDict *pDict) { - double w; - GBool wFP; + Type1COp zero, w; int i; if (useOp) { - w = pDict->nominalWidthX + ops[0].num; - wFP = pDict->nominalWidthXFP | ops[0].isFP; + if (pDict->nominalWidthXInt & (ops[0].kind == type1COpInteger)) { + w.kind = type1COpInteger; + w.intgr = (int)(pDict->nominalWidthX + ops[0].intgr); + } else { + w.kind = type1COpFloat; + w.flt = pDict->nominalWidthX + ops[0].toFloat(); + } for (i = 1; i < nOps; ++i) { ops[i-1] = ops[i]; } --nOps; } else { - w = pDict->defaultWidthX; - wFP = pDict->defaultWidthXFP; + if (pDict->defaultWidthXInt) { + w.kind = type1COpInteger; + w.intgr = (int)pDict->defaultWidthX; + } else { + w.kind = type1COpFloat; + w.flt = pDict->defaultWidthX; + } } - cvtNum(0, gFalse, charBuf); - cvtNum(w, wFP, charBuf); + zero.kind = type1COpInteger; + zero.intgr = 0; + cvtNum(zero, charBuf); + cvtNum(w, charBuf); charBuf->append((char)13); } -void FoFiType1C::cvtNum(double x, GBool isFP, GString *charBuf) { +void FoFiType1C::cvtNum(Type1COp op, GString *charBuf) { + Type1COp tmp; Guchar buf[12]; int y, n; n = 0; - if (isFP) { - if (x >= -32768 && x < 32768) { - y = (int)(x * 256.0); - buf[0] = 255; - buf[1] = (Guchar)(y >> 24); - buf[2] = (Guchar)(y >> 16); - buf[3] = (Guchar)(y >> 8); - buf[4] = (Guchar)y; - buf[5] = 255; - buf[6] = 0; - buf[7] = 0; - buf[8] = 1; - buf[9] = 0; - buf[10] = 12; - buf[11] = 12; - n = 12; - } else { - //~ error(-1, "Type 2 fixed point constant out of range"); - } - } else { - y = (int)x; + switch (op.kind) { + case type1COpInteger: + y = op.intgr; if (y >= -107 && y <= 107) { buf[0] = (Guchar)(y + 139); n = 1; @@ -1925,6 +2070,39 @@ void FoFiType1C::cvtNum(double x, GBool isFP, GString *charBuf) { buf[4] = (Guchar)y; n = 5; } + break; + case type1COpFloat: + if (op.flt >= -32768 && op.flt < 32768) { + y = (int)(op.flt * 256.0); + buf[0] = 255; + buf[1] = (Guchar)(y >> 24); + buf[2] = (Guchar)(y >> 16); + buf[3] = (Guchar)(y >> 8); + buf[4] = (Guchar)y; + buf[5] = 255; + buf[6] = 0; + buf[7] = 0; + buf[8] = 1; + buf[9] = 0; + buf[10] = 12; + buf[11] = 12; + n = 12; + } else { + //~ error(-1, "Type 2 fixed point constant out of range"); + } + break; + case type1COpRational: + tmp.kind = type1COpInteger; + tmp.intgr = op.rat.num; + cvtNum(tmp, charBuf); + tmp.intgr = op.rat.den; + cvtNum(tmp, charBuf); + buf[0] = 0x0c; + buf[1] = 0x0c; + n = 2; + break; + default: // shouldn't happen + break; } charBuf->append((char *)buf, n); } @@ -2161,47 +2339,51 @@ void FoFiType1C::readTopDict() { if (!parsedOk) { break; } - if (!ops[nOps - 1].isNum) { + if (ops[nOps - 1].kind == type1COpOperator) { --nOps; // drop the operator if (topDict.firstOp < 0) { topDict.firstOp = ops[nOps].op; } switch (ops[nOps].op) { - case 0x0000: topDict.versionSID = (int)ops[0].num; break; - case 0x0001: topDict.noticeSID = (int)ops[0].num; break; - case 0x0c00: topDict.copyrightSID = (int)ops[0].num; break; - case 0x0002: topDict.fullNameSID = (int)ops[0].num; break; - case 0x0003: topDict.familyNameSID = (int)ops[0].num; break; - case 0x0004: topDict.weightSID = (int)ops[0].num; break; - case 0x0c01: topDict.isFixedPitch = (int)ops[0].num; break; - case 0x0c02: topDict.italicAngle = ops[0].num; break; - case 0x0c03: topDict.underlinePosition = ops[0].num; break; - case 0x0c04: topDict.underlineThickness = ops[0].num; break; - case 0x0c05: topDict.paintType = (int)ops[0].num; break; - case 0x0c06: topDict.charstringType = (int)ops[0].num; break; - case 0x0c07: topDict.fontMatrix[0] = ops[0].num; - topDict.fontMatrix[1] = ops[1].num; - topDict.fontMatrix[2] = ops[2].num; - topDict.fontMatrix[3] = ops[3].num; - topDict.fontMatrix[4] = ops[4].num; - topDict.fontMatrix[5] = ops[5].num; - topDict.hasFontMatrix = gTrue; break; - case 0x000d: topDict.uniqueID = (int)ops[0].num; break; - case 0x0005: topDict.fontBBox[0] = ops[0].num; - topDict.fontBBox[1] = ops[1].num; - topDict.fontBBox[2] = ops[2].num; - topDict.fontBBox[3] = ops[3].num; break; - case 0x0c08: topDict.strokeWidth = ops[0].num; break; - case 0x000f: topDict.charsetOffset = (int)ops[0].num; break; - case 0x0010: topDict.encodingOffset = (int)ops[0].num; break; - case 0x0011: topDict.charStringsOffset = (int)ops[0].num; break; - case 0x0012: topDict.privateSize = (int)ops[0].num; - topDict.privateOffset = (int)ops[1].num; break; - case 0x0c1e: topDict.registrySID = (int)ops[0].num; - topDict.orderingSID = (int)ops[1].num; - topDict.supplement = (int)ops[2].num; break; - case 0x0c24: topDict.fdArrayOffset = (int)ops[0].num; break; - case 0x0c25: topDict.fdSelectOffset = (int)ops[0].num; break; + case 0x0000: topDict.versionSID = ops[0].toInt(); break; + case 0x0001: topDict.noticeSID = ops[0].toInt(); break; + case 0x0c00: topDict.copyrightSID = ops[0].toInt(); break; + case 0x0002: topDict.fullNameSID = ops[0].toInt(); break; + case 0x0003: topDict.familyNameSID = ops[0].toInt(); break; + case 0x0004: topDict.weightSID = ops[0].toInt(); break; + case 0x0c01: topDict.isFixedPitch = ops[0].toInt(); break; + case 0x0c02: topDict.italicAngle = ops[0].toFloat(); break; + case 0x0c03: topDict.underlinePosition = ops[0].toFloat(); break; + case 0x0c04: topDict.underlineThickness = ops[0].toFloat(); break; + case 0x0c05: topDict.paintType = ops[0].toInt(); break; + case 0x0c06: topDict.charstringType = ops[0].toInt(); break; + case 0x0c07: topDict.fontMatrix[0] = ops[0].toFloat(); + topDict.fontMatrix[1] = ops[1].toFloat(); + topDict.fontMatrix[2] = ops[2].toFloat(); + topDict.fontMatrix[3] = ops[3].toFloat(); + topDict.fontMatrix[4] = ops[4].toFloat(); + topDict.fontMatrix[5] = ops[5].toFloat(); + topDict.hasFontMatrix = gTrue; + break; + case 0x000d: topDict.uniqueID = ops[0].toInt(); break; + case 0x0005: topDict.fontBBox[0] = ops[0].toFloat(); + topDict.fontBBox[1] = ops[1].toFloat(); + topDict.fontBBox[2] = ops[2].toFloat(); + topDict.fontBBox[3] = ops[3].toFloat(); + break; + case 0x0c08: topDict.strokeWidth = ops[0].toFloat(); break; + case 0x000f: topDict.charsetOffset = ops[0].toInt(); break; + case 0x0010: topDict.encodingOffset = ops[0].toInt(); break; + case 0x0011: topDict.charStringsOffset = ops[0].toInt(); break; + case 0x0012: topDict.privateSize = ops[0].toInt(); + topDict.privateOffset = ops[1].toInt(); + break; + case 0x0c1e: topDict.registrySID = ops[0].toInt(); + topDict.orderingSID = ops[1].toInt(); + topDict.supplement = ops[2].toInt(); + break; + case 0x0c24: topDict.fdArrayOffset = ops[0].toInt(); break; + case 0x0c25: topDict.fdSelectOffset = ops[0].toInt(); break; } nOps = 0; } @@ -2227,22 +2409,22 @@ void FoFiType1C::readFD(int offset, int length, Type1CPrivateDict *pDict) { if (!parsedOk) { return; } - if (!ops[nOps - 1].isNum) { + if (ops[nOps - 1].kind == type1COpOperator) { if (ops[nOps - 1].op == 0x0012) { if (nOps < 3) { parsedOk = gFalse; return; } - pSize = (int)ops[0].num; - pOffset = (int)ops[1].num; + pSize = ops[0].toInt(); + pOffset = ops[1].toInt(); break; } else if (ops[nOps - 1].op == 0x0c07) { - fontMatrix[0] = ops[0].num; - fontMatrix[1] = ops[1].num; - fontMatrix[2] = ops[2].num; - fontMatrix[3] = ops[3].num; - fontMatrix[4] = ops[4].num; - fontMatrix[5] = ops[5].num; + fontMatrix[0] = ops[0].toFloat(); + fontMatrix[1] = ops[1].toFloat(); + fontMatrix[2] = ops[2].toFloat(); + fontMatrix[3] = ops[3].toFloat(); + fontMatrix[4] = ops[4].toFloat(); + fontMatrix[5] = ops[5].toFloat(); hasFontMatrix = gTrue; } nOps = 0; @@ -2283,9 +2465,9 @@ void FoFiType1C::readPrivateDict(int offset, int length, pDict->initialRandomSeed = 0; pDict->subrsOffset = 0; pDict->defaultWidthX = 0; - pDict->defaultWidthXFP = gFalse; + pDict->defaultWidthXInt = gTrue; pDict->nominalWidthX = 0; - pDict->nominalWidthXFP = gFalse; + pDict->nominalWidthXInt = gTrue; // no dictionary if (offset == 0 || length == 0) { @@ -2299,7 +2481,7 @@ void FoFiType1C::readPrivateDict(int offset, int length, if (!parsedOk) { break; } - if (!ops[nOps - 1].isNum) { + if (ops[nOps - 1].kind == type1COpOperator) { --nOps; // drop the operator switch (ops[nOps].op) { case 0x0006: @@ -2319,20 +2501,20 @@ void FoFiType1C::readPrivateDict(int offset, int length, type1CMaxOtherBlues); break; case 0x0c09: - pDict->blueScale = ops[0].num; + pDict->blueScale = ops[0].toFloat(); break; case 0x0c0a: - pDict->blueShift = (int)ops[0].num; + pDict->blueShift = ops[0].toInt(); break; case 0x0c0b: - pDict->blueFuzz = (int)ops[0].num; + pDict->blueFuzz = ops[0].toInt(); break; case 0x000a: - pDict->stdHW = ops[0].num; + pDict->stdHW = ops[0].toFloat(); pDict->hasStdHW = gTrue; break; case 0x000b: - pDict->stdVW = ops[0].num; + pDict->stdVW = ops[0].toFloat(); pDict->hasStdVW = gTrue; break; case 0x0c0c: @@ -2344,31 +2526,31 @@ void FoFiType1C::readPrivateDict(int offset, int length, type1CMaxStemSnap); break; case 0x0c0e: - pDict->forceBold = ops[0].num != 0; + pDict->forceBold = !ops[0].isZero(); pDict->hasForceBold = gTrue; break; case 0x0c0f: - pDict->forceBoldThreshold = ops[0].num; + pDict->forceBoldThreshold = ops[0].toFloat(); break; case 0x0c11: - pDict->languageGroup = (int)ops[0].num; + pDict->languageGroup = ops[0].toInt(); break; case 0x0c12: - pDict->expansionFactor = ops[0].num; + pDict->expansionFactor = ops[0].toFloat(); break; case 0x0c13: - pDict->initialRandomSeed = (int)ops[0].num; + pDict->initialRandomSeed = ops[0].toInt(); break; case 0x0013: - pDict->subrsOffset = offset + (int)ops[0].num; + pDict->subrsOffset = offset + ops[0].toInt(); break; case 0x0014: - pDict->defaultWidthX = ops[0].num; - pDict->defaultWidthXFP = ops[0].isFP; + pDict->defaultWidthX = ops[0].toFloat(); + pDict->defaultWidthXInt = ops[0].kind == type1COpInteger; break; case 0x0015: - pDict->nominalWidthX = ops[0].num; - pDict->nominalWidthXFP = ops[0].isFP; + pDict->nominalWidthX = ops[0].toFloat(); + pDict->nominalWidthXInt = ops[0].kind == type1COpInteger; break; } nOps = 0; @@ -2584,8 +2766,6 @@ int FoFiType1C::getOp(int pos, GBool charstring, GBool *ok) { int b0, b1, nyb0, nyb1, x, i; b0 = getU8(pos++, ok); - op.isNum = gTrue; - op.isFP = gFalse; if (b0 == 28) { x = getU8(pos++, ok); @@ -2593,7 +2773,8 @@ int FoFiType1C::getOp(int pos, GBool charstring, GBool *ok) { if (x & 0x8000) { x |= ~0xffff; } - op.num = x; + op.kind = type1COpInteger; + op.intgr = x; } else if (!charstring && b0 == 29) { x = getU8(pos++, ok); @@ -2603,7 +2784,8 @@ int FoFiType1C::getOp(int pos, GBool charstring, GBool *ok) { if (x & 0x80000000) { x |= ~0xffffffff; } - op.num = x; + op.kind = type1COpInteger; + op.intgr = x; } else if (!charstring && b0 == 30) { i = 0; @@ -2636,17 +2818,20 @@ int FoFiType1C::getOp(int pos, GBool charstring, GBool *ok) { } } while (i < 64); buf[i] = '\0'; - op.num = atof(buf); - op.isFP = gTrue; + op.kind = type1COpFloat; + op.flt = atof(buf); } else if (b0 >= 32 && b0 <= 246) { - op.num = b0 - 139; + op.kind = type1COpInteger; + op.intgr = b0 - 139; } else if (b0 >= 247 && b0 <= 250) { - op.num = ((b0 - 247) << 8) + getU8(pos++, ok) + 108; + op.kind = type1COpInteger; + op.intgr = ((b0 - 247) << 8) + getU8(pos++, ok) + 108; } else if (b0 >= 251 && b0 <= 254) { - op.num = -((b0 - 251) << 8) - getU8(pos++, ok) - 108; + op.kind = type1COpInteger; + op.intgr = -((b0 - 251) << 8) - getU8(pos++, ok) - 108; } else if (charstring && b0 == 255) { x = getU8(pos++, ok); @@ -2656,15 +2841,15 @@ int FoFiType1C::getOp(int pos, GBool charstring, GBool *ok) { if (x & 0x80000000) { x |= ~0xffffffff; } - op.num = (double)x / 65536.0; - op.isFP = gTrue; + op.kind = type1COpFloat; + op.flt = (double)x / 65536.0; } else if (b0 == 12) { - op.isNum = gFalse; + op.kind = type1COpOperator; op.op = 0x0c00 + getU8(pos++, ok); } else { - op.isNum = gFalse; + op.kind = type1COpOperator; op.op = b0; } @@ -2685,7 +2870,7 @@ int FoFiType1C::getDeltaIntArray(int *arr, int maxLen) { } x = 0; for (i = 0; i < n; ++i) { - x += (int)ops[i].num; + x += ops[i].toInt(); arr[i] = x; } return n; @@ -2701,7 +2886,7 @@ int FoFiType1C::getDeltaFPArray(double *arr, int maxLen) { } x = 0; for (i = 0; i < n; ++i) { - x += ops[i].num; + x += ops[i].toFloat(); arr[i] = x; } return n; @@ -2736,6 +2921,8 @@ void FoFiType1C::getIndexVal(Type1CIndex *idx, int i, int pos0, pos1; if (i < 0 || i >= idx->len) { + val->pos = 0; + val->len = 0; *ok = gFalse; return; } diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h index 0c5b4fb6ead..ae869687898 100644 --- a/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h +++ b/Build/source/libs/xpdf/xpdf-src/fofi/FoFiType1C.h @@ -105,18 +105,34 @@ struct Type1CPrivateDict { int initialRandomSeed; int subrsOffset; double defaultWidthX; - GBool defaultWidthXFP; + GBool defaultWidthXInt; double nominalWidthX; - GBool nominalWidthXFP; + GBool nominalWidthXInt; }; +// operand kind +enum Type1COpKind { + type1COpOperator, + type1COpInteger, + type1COpFloat, + type1COpRational +}; + +// operand struct Type1COp { - GBool isNum; // true -> number, false -> operator - GBool isFP; // true -> floating point number, false -> int + Type1COpKind kind; union { - double num; // if num is true - int op; // if num is false + int op; // type1COpOperator + int intgr; // type1COpInteger + double flt; // type1COpFloat + struct { + int num, den; // type1COpRational + } rat; }; + GBool isZero(); + GBool isNegative(); + int toInt(); + double toFloat(); }; struct Type1CEexecBuf { @@ -204,7 +220,7 @@ private: GBool top); void cvtGlyphWidth(GBool useOp, GString *charBuf, Type1CPrivateDict *pDict); - void cvtNum(double x, GBool isFP, GString *charBuf); + void cvtNum(Type1COp op, GString *charBuf); void eexecWrite(Type1CEexecBuf *eb, const char *s); void eexecWriteCharstring(Type1CEexecBuf *eb, Guchar *s, int n); void writePSString(char *s, FoFiOutputFunc outputFunc, void *outputStream); diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/Makefile.dep b/Build/source/libs/xpdf/xpdf-src/fofi/Makefile.dep deleted file mode 100644 index e69de29bb2d..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/fofi/Makefile.dep +++ /dev/null diff --git a/Build/source/libs/xpdf/xpdf-src/fofi/Makefile.in b/Build/source/libs/xpdf/xpdf-src/fofi/Makefile.in deleted file mode 100644 index d00f83f1c25..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/fofi/Makefile.in +++ /dev/null @@ -1,71 +0,0 @@ -#======================================================================== -# -# FoFi library Makefile -# -# Copyright 2003 Glyph & Cog, LLC -# -#======================================================================== - -SHELL = /bin/sh - -srcdir = @srcdir@ -VPATH = @srcdir@ - -GOOSRCDIR = $(srcdir)/../goo -GOOLIBDIR = ../goo - -CXXFLAGS = @CXXFLAGS@ @DEFS@ -I.. -I$(srcdir)/.. -I$(GOOSRCDIR) -I$(srcdir) - -CXX = @CXX@ -AR = @AR@ -RANLIB = @RANLIB@ - -LIBPREFIX = @LIBPREFIX@ - -#------------------------------------------------------------------------ - -.SUFFIXES: .cc - -.cc.o: - $(CXX) $(CXXFLAGS) -c $< - -#------------------------------------------------------------------------ - -CXX_SRC = \ - $(srcdir)/FoFiBase.cc \ - $(srcdir)/FoFiEncodings.cc \ - $(srcdir)/FoFiIdentifier.cc \ - $(srcdir)/FoFiTrueType.cc \ - $(srcdir)/FoFiType1.cc \ - $(srcdir)/FoFiType1C.cc - -#------------------------------------------------------------------------ - -all: $(LIBPREFIX)fofi.a - -#------------------------------------------------------------------------ - -FOFI_OBJS = \ - FoFiBase.o \ - FoFiEncodings.o \ - FoFiIdentifier.o \ - FoFiTrueType.o \ - FoFiType1.o \ - FoFiType1C.o - -$(LIBPREFIX)fofi.a: $(FOFI_OBJS) - rm -f $(LIBPREFIX)fofi.a - $(AR) $(LIBPREFIX)fofi.a $(FOFI_OBJS) - $(RANLIB) $(LIBPREFIX)fofi.a - -#------------------------------------------------------------------------ - -clean: - rm -f $(FOFI_OBJS) $(LIBPREFIX)fofi.a - -#------------------------------------------------------------------------ - -depend: - $(CXX) $(CXXFLAGS) -MM $(CXX_SRC) >Makefile.dep - --include Makefile.dep |