summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Astals Cid <aacid@kde.org>2012-02-01 22:56:55 +0100
committerAlbert Astals Cid <aacid@kde.org>2012-02-01 22:56:55 +0100
commitdc2471835c32e07f26014f273910156cb1d3ce62 (patch)
treedaeb0e82d4a63b864e32cb94cde2d0a97e7b169d
parentc885d0cb1e470ae19642f9c03b1c668bbeda1ae9 (diff)
Update after last merge from Thomas
-rw-r--r--ALL_DIFF3869
1 files changed, 0 insertions, 3869 deletions
diff --git a/ALL_DIFF b/ALL_DIFF
index e63adba..6c1ed7a 100644
--- a/ALL_DIFF
+++ b/ALL_DIFF
@@ -12,3260 +12,9 @@ diff -ru xpdf-3.02/doc/pdftotext.1 xpdf-3.03/doc/pdftotext.1
.B \-raw
Keep the text in content stream order. This is a hack which often
"undoes" column formatting, etc. Use of raw mode is no longer
-diff -ru xpdf-3.02/xpdf/Gfx.cc xpdf-3.03/xpdf/Gfx.cc
---- xpdf-3.02/xpdf/Gfx.cc 2007-02-27 23:05:52.000000000 +0100
-+++ xpdf-3.03/xpdf/Gfx.cc 2011-08-15 23:08:53.000000000 +0200
-@@ -18,9 +18,12 @@
- #include <string.h>
- #include <math.h>
- #include "gmem.h"
-+#include "GString.h"
-+#include "GList.h"
- #include "GlobalParams.h"
- #include "CharTypes.h"
- #include "Object.h"
- #include "PDFDoc.h"
- #include "Array.h"
- #include "Dict.h"
- #include "Stream.h"
-@@ -31,7 +34,9 @@
- #include "OutputDev.h"
- #include "Page.h"
- #include "Annot.h"
-+#include "OptionalContent.h"
- #include "Error.h"
-+#include "PDFDocEncoding.h"
- #include "Gfx.h"
-
- // the MSVC math.h doesn't define this
-@@ -562,7 +596,8 @@
- int lastAbortCheck;
-
- // scan a sequence of objects
-- updateLevel = lastAbortCheck = 0;
-+ updateLevel = 1; // make sure even empty pages trigger a call to dump()
-+ lastAbortCheck = 0;
- numArgs = 0;
- parser->getObj(&obj);
- while (!obj.isEOF()) {
-@@ -695,6 +734,7 @@
-
- a = -1;
- b = numOps;
-+ cmp = 0; // make gcc happy
- // invariant: opTab[a] < name < opTab[b]
- while (b - a > 1) {
- m = (a + b) / 2;
-@@ -801,6 +841,7 @@
-
- void Gfx::opSetExtGState(Object args[], int numArgs) {
- Object obj1, obj2, obj3, obj4, obj5;
-+ Object args2[2];
- GfxBlendMode mode;
- GBool haveFillOP;
- Function *funcs[4];
-@@ -808,9 +849,10 @@
- GBool haveBackdropColor;
- GfxColorSpace *blendingColorSpace;
- GBool alpha, isolated, knockout;
-+ double opac;
- int i;
-
- if (!res->lookupGState(args[0].getName(), &obj1)) {
- return;
- }
- if (!obj1.isDict()) {
-@@ -824,28 +867,77 @@
- printf("\n");
- }
-
-+ // parameters that are also set by individual PDF operators
-+ if (obj1.dictLookup("LW", &obj2)->isNum()) {
-+ opSetLineWidth(&obj2, 1);
-+ }
-+ obj2.free();
-+ if (obj1.dictLookup("LC", &obj2)->isInt()) {
-+ opSetLineCap(&obj2, 1);
-+ }
-+ obj2.free();
-+ if (obj1.dictLookup("LJ", &obj2)->isInt()) {
-+ opSetLineJoin(&obj2, 1);
-+ }
-+ obj2.free();
-+ if (obj1.dictLookup("ML", &obj2)->isNum()) {
-+ opSetMiterLimit(&obj2, 1);
-+ }
-+ obj2.free();
-+ if (obj1.dictLookup("D", &obj2)->isArray() &&
-+ obj2.arrayGetLength() == 2) {
-+ obj2.arrayGet(0, &args2[0]);
-+ obj2.arrayGet(1, &args2[1]);
-+ if (args2[0].isArray() && args2[1].isNum()) {
-+ opSetDash(args2, 2);
-+ }
-+ args2[0].free();
-+ args2[1].free();
-+ }
-+ obj2.free();
-+#if 0 //~ need to add a new version of GfxResources::lookupFont() that
-+ //~ takes an indirect ref instead of a name
-+ if (obj1.dictLookup("Font", &obj2)->isArray() &&
-+ obj2.arrayGetLength() == 2) {
-+ obj2.arrayGet(0, &args2[0]);
-+ obj2.arrayGet(1, &args2[1]);
-+ if (args2[0].isDict() && args2[1].isNum()) {
-+ opSetFont(args2, 2);
-+ }
-+ args2[0].free();
-+ args2[1].free();
-+ }
-+ obj2.free();
-+#endif
-+ if (obj1.dictLookup("FL", &obj2)->isNum()) {
-+ opSetFlat(&obj2, 1);
-+ }
-+ obj2.free();
-+
- // transparency support: blend mode, fill/stroke opacity
- if (!obj1.dictLookup("BM", &obj2)->isNull()) {
- if (state->parseBlendMode(&obj2, &mode)) {
- state->setBlendMode(mode);
- out->updateBlendMode(state);
- } else {
- error(errSyntaxError, getPos(), "Invalid blend mode in ExtGState");
- }
- }
- obj2.free();
- if (obj1.dictLookup("ca", &obj2)->isNum()) {
-- state->setFillOpacity(obj2.getNum());
-+ opac = obj2.getNum();
-+ state->setFillOpacity(opac < 0 ? 0 : opac > 1 ? 1 : opac);
- out->updateFillOpacity(state);
- }
- obj2.free();
- if (obj1.dictLookup("CA", &obj2)->isNum()) {
-- state->setStrokeOpacity(obj2.getNum());
-+ opac = obj2.getNum();
-+ state->setStrokeOpacity(opac < 0 ? 0 : opac > 1 ? 1 : opac);
- out->updateStrokeOpacity(state);
- }
- obj2.free();
-
-- // fill/stroke overprint
-+ // fill/stroke overprint, overprint mode
- if ((haveFillOP = (obj1.dictLookup("op", &obj2)->isBool()))) {
- state->setFillOverprint(obj2.getBool());
- out->updateFillOverprint(state);
-@@ -860,6 +952,11 @@
- }
- }
- obj2.free();
-+ if (obj1.dictLookup("OPM", &obj2)->isInt()) {
-+ state->setOverprintMode(obj2.getInt());
-+ out->updateOverprintMode(state);
-+ }
-+ obj2.free();
-
- // stroke adjust
- if (obj1.dictLookup("SA", &obj2)->isBool()) {
-@@ -915,13 +1012,18 @@
- obj3.free();
- funcs[0] = NULL;
- if (!obj2.dictLookup("TR", &obj3)->isNull()) {
-- funcs[0] = Function::parse(&obj3);
-- if (funcs[0]->getInputSize() != 1 ||
-- funcs[0]->getOutputSize() != 1) {
-- error(getPos(),
-- "Invalid transfer function in soft mask in ExtGState");
-- delete funcs[0];
-+ if (obj3.isName("Default") ||
-+ obj3.isName("Identity")) {
- funcs[0] = NULL;
-+ } else {
-+ funcs[0] = Function::parse(&obj3);
-+ if (funcs[0]->getInputSize() != 1 ||
-+ funcs[0]->getOutputSize() != 1) {
-+ error(errSyntaxError, getPos(),
-+ "Invalid transfer function in soft mask in ExtGState");
-+ delete funcs[0];
-+ funcs[0] = NULL;
-+ }
- }
- }
- obj3.free();
-@@ -1402,14 +1512,16 @@
-
- void Gfx::opStroke(Object args[], int numArgs) {
- if (!state->isCurPt()) {
-- //error(getPos(), "No path in stroke");
-+ //error(errSyntaxError, getPos(), "No path in stroke");
- return;
- }
- if (state->isPath()) {
-- if (state->getStrokeColorSpace()->getMode() == csPattern) {
-- doPatternStroke();
-- } else {
-- out->stroke(state);
-+ if (ocState) {
-+ if (state->getStrokeColorSpace()->getMode() == csPattern) {
-+ doPatternStroke();
-+ } else {
-+ out->stroke(state);
-+ }
- }
- }
- doEndPath();
-@@ -1417,15 +1529,17 @@
-
- void Gfx::opCloseStroke(Object args[], int numArgs) {
- if (!state->isCurPt()) {
-- //error(getPos(), "No path in closepath/stroke");
-+ //error(errSyntaxError, getPos(), "No path in closepath/stroke");
- return;
- }
- if (state->isPath()) {
- state->closePath();
-- if (state->getStrokeColorSpace()->getMode() == csPattern) {
-- doPatternStroke();
-- } else {
-- out->stroke(state);
-+ if (ocState) {
-+ if (state->getStrokeColorSpace()->getMode() == csPattern) {
-+ doPatternStroke();
-+ } else {
-+ out->stroke(state);
-+ }
- }
- }
- doEndPath();
-@@ -1433,14 +1547,16 @@
-
- void Gfx::opFill(Object args[], int numArgs) {
- if (!state->isCurPt()) {
-- //error(getPos(), "No path in fill");
-+ //error(errSyntaxError, getPos(), "No path in fill");
- return;
- }
- if (state->isPath()) {
-- if (state->getFillColorSpace()->getMode() == csPattern) {
-- doPatternFill(gFalse);
-- } else {
-- out->fill(state);
-+ if (ocState) {
-+ if (state->getFillColorSpace()->getMode() == csPattern) {
-+ doPatternFill(gFalse);
-+ } else {
-+ out->fill(state);
-+ }
- }
- }
- doEndPath();
-@@ -1448,14 +1564,16 @@
-
- void Gfx::opEOFill(Object args[], int numArgs) {
- if (!state->isCurPt()) {
-- //error(getPos(), "No path in eofill");
-+ //error(errSyntaxError, getPos(), "No path in eofill");
- return;
- }
- if (state->isPath()) {
-- if (state->getFillColorSpace()->getMode() == csPattern) {
-- doPatternFill(gTrue);
-- } else {
-- out->eoFill(state);
-+ if (ocState) {
-+ if (state->getFillColorSpace()->getMode() == csPattern) {
-+ doPatternFill(gTrue);
-+ } else {
-+ out->eoFill(state);
-+ }
- }
- }
- doEndPath();
-@@ -1463,19 +1581,21 @@
-
- void Gfx::opFillStroke(Object args[], int numArgs) {
- if (!state->isCurPt()) {
-- //error(getPos(), "No path in fill/stroke");
-+ //error(errSyntaxError, getPos(), "No path in fill/stroke");
- return;
- }
- if (state->isPath()) {
-- if (state->getFillColorSpace()->getMode() == csPattern) {
-- doPatternFill(gFalse);
-- } else {
-- out->fill(state);
-- }
-- if (state->getStrokeColorSpace()->getMode() == csPattern) {
-- doPatternStroke();
-- } else {
-- out->stroke(state);
-+ if (ocState) {
-+ if (state->getFillColorSpace()->getMode() == csPattern) {
-+ doPatternFill(gFalse);
-+ } else {
-+ out->fill(state);
-+ }
-+ if (state->getStrokeColorSpace()->getMode() == csPattern) {
-+ doPatternStroke();
-+ } else {
-+ out->stroke(state);
-+ }
- }
- }
- doEndPath();
-@@ -1483,20 +1603,22 @@
-
- void Gfx::opCloseFillStroke(Object args[], int numArgs) {
- if (!state->isCurPt()) {
-- //error(getPos(), "No path in closepath/fill/stroke");
-+ //error(errSyntaxError, getPos(), "No path in closepath/fill/stroke");
- return;
- }
- if (state->isPath()) {
- state->closePath();
-- if (state->getFillColorSpace()->getMode() == csPattern) {
-- doPatternFill(gFalse);
-- } else {
-- out->fill(state);
-- }
-- if (state->getStrokeColorSpace()->getMode() == csPattern) {
-- doPatternStroke();
-- } else {
-- out->stroke(state);
-+ if (ocState) {
-+ if (state->getFillColorSpace()->getMode() == csPattern) {
-+ doPatternFill(gFalse);
-+ } else {
-+ out->fill(state);
-+ }
-+ if (state->getStrokeColorSpace()->getMode() == csPattern) {
-+ doPatternStroke();
-+ } else {
-+ out->stroke(state);
-+ }
- }
- }
- doEndPath();
-@@ -1504,19 +1626,21 @@
-
- void Gfx::opEOFillStroke(Object args[], int numArgs) {
- if (!state->isCurPt()) {
-- //error(getPos(), "No path in eofill/stroke");
-+ //error(errSyntaxError, getPos(), "No path in eofill/stroke");
- return;
- }
- if (state->isPath()) {
-- if (state->getFillColorSpace()->getMode() == csPattern) {
-- doPatternFill(gTrue);
-- } else {
-- out->eoFill(state);
-- }
-- if (state->getStrokeColorSpace()->getMode() == csPattern) {
-- doPatternStroke();
-- } else {
-- out->stroke(state);
-+ if (ocState) {
-+ if (state->getFillColorSpace()->getMode() == csPattern) {
-+ doPatternFill(gTrue);
-+ } else {
-+ out->eoFill(state);
-+ }
-+ if (state->getStrokeColorSpace()->getMode() == csPattern) {
-+ doPatternStroke();
-+ } else {
-+ out->stroke(state);
-+ }
- }
- }
- doEndPath();
-@@ -1524,20 +1648,22 @@
-
- void Gfx::opCloseEOFillStroke(Object args[], int numArgs) {
- if (!state->isCurPt()) {
-- //error(getPos(), "No path in closepath/eofill/stroke");
-+ //error(errSyntaxError, getPos(), "No path in closepath/eofill/stroke");
- return;
- }
- if (state->isPath()) {
- state->closePath();
-- if (state->getFillColorSpace()->getMode() == csPattern) {
-- doPatternFill(gTrue);
-- } else {
-- out->eoFill(state);
-- }
-- if (state->getStrokeColorSpace()->getMode() == csPattern) {
-- doPatternStroke();
-- } else {
-- out->stroke(state);
-+ if (ocState) {
-+ if (state->getFillColorSpace()->getMode() == csPattern) {
-+ doPatternFill(gTrue);
-+ } else {
-+ out->eoFill(state);
-+ }
-+ if (state->getStrokeColorSpace()->getMode() == csPattern) {
-+ doPatternStroke();
-+ } else {
-+ out->stroke(state);
-+ }
- }
- }
- doEndPath();
-
-@@ -3373,7 +3650,7 @@
- GBool maskInvert;
- Stream *maskStr;
- Object obj1, obj2;
-- int i;
-+ int i, n;
-
- // get info from the stream
- bits = 0;
-@@ -3389,19 +3666,27 @@
- obj1.free();
- dict->lookup("W", &obj1);
- }
-- if (!obj1.isInt())
-+ if (!obj1.isInt()) {
- goto err2;
-+ }
- width = obj1.getInt();
- obj1.free();
-+ if (width <= 0) {
-+ goto err1;
-+ }
- dict->lookup("Height", &obj1);
- if (obj1.isNull()) {
- obj1.free();
- dict->lookup("H", &obj1);
- }
-- if (!obj1.isInt())
-+ if (!obj1.isInt()) {
- goto err2;
-+ }
- height = obj1.getInt();
- obj1.free();
-+ if (height <= 0) {
-+ goto err1;
-+ }
-
- // image or mask?
- dict->lookup("ImageMask", &obj1);
-@@ -3447,16 +3732,30 @@
- }
- if (obj1.isArray()) {
- obj1.arrayGet(0, &obj2);
-- if (obj2.isInt() && obj2.getInt() == 1)
-- invert = gTrue;
-+ invert = obj2.isNum() && obj2.getNum() == 1;
- obj2.free();
- } else if (!obj1.isNull()) {
- goto err2;
- }
- obj1.free();
-
-+ // if drawing is disabled, skip over inline image data
-+ if (!ocState) {
-+ str->reset();
-+ n = height * ((width + 7) / 8);
-+ for (i = 0; i < n; ++i) {
-+ str->getChar();
-+ }
-+ str->close();
-+
- // draw it
-- out->drawImageMask(state, ref, str, width, height, invert, inlineImg);
-+ } else {
-+ if (state->getFillColorSpace()->getMode() == csPattern) {
-+ doPatternImageMask(ref, str, width, height, invert, inlineImg);
-+ } else {
-+ out->drawImageMask(state, ref, str, width, height, invert, inlineImg);
-+ }
-+ }
-
- } else {
-
-@@ -3581,14 +3880,36 @@
- haveSoftMask = gTrue;
- } else if (maskObj.isArray()) {
- // color key mask
-+ haveColorKeyMask = gTrue;
- for (i = 0;
-- i < maskObj.arrayGetLength() && i < 2*gfxColorMaxComps;
-- ++i) {
-+ i+1 < maskObj.arrayGetLength() && i+1 < 2*gfxColorMaxComps;
-+ i += 2) {
- maskObj.arrayGet(i, &obj1);
-+ if (!obj1.isInt()) {
-+ obj1.free();
-+ haveColorKeyMask = gFalse;
-+ break;
-+ }
- maskColors[i] = obj1.getInt();
- obj1.free();
-+ if (maskColors[i] < 0 || maskColors[i] >= (1 << bits)) {
-+ haveColorKeyMask = gFalse;
-+ break;
-+ }
-+ maskObj.arrayGet(i+1, &obj1);
-+ if (!obj1.isInt()) {
-+ obj1.free();
-+ haveColorKeyMask = gFalse;
-+ break;
-+ }
-+ maskColors[i+1] = obj1.getInt();
-+ obj1.free();
-+ if (maskColors[i+1] < 0 || maskColors[i+1] >= (1 << bits) ||
-+ maskColors[i] > maskColors[i+1]) {
-+ haveColorKeyMask = gFalse;
-+ break;
-+ }
- }
-- haveColorKeyMask = gTrue;
- } else if (maskObj.isStream()) {
- // explicit mask
- if (inlineImg) {
-@@ -3633,9 +3954,7 @@
- }
- if (obj1.isArray()) {
- obj1.arrayGet(0, &obj2);
-- if (obj2.isInt() && obj2.getInt() == 1) {
-- maskInvert = gTrue;
-- }
-+ maskInvert = obj2.isNum() && obj2.getNum() == 1;
- obj2.free();
- } else if (!obj1.isNull()) {
- goto err2;
-@@ -3644,20 +3963,32 @@
- haveExplicitMask = gTrue;
- }
-
-+ // if drawing is disabled, skip over inline image data
-+ if (!ocState) {
-+ str->reset();
-+ n = height * ((width * colorMap->getNumPixelComps() *
-+ colorMap->getBits() + 7) / 8);
-+ for (i = 0; i < n; ++i) {
-+ str->getChar();
-+ }
-+ str->close();
-+
- // draw it
-- if (haveSoftMask) {
-- out->drawSoftMaskedImage(state, ref, str, width, height, colorMap,
-- maskStr, maskWidth, maskHeight, maskColorMap);
-- delete maskColorMap;
-- } else if (haveExplicitMask) {
-- out->drawMaskedImage(state, ref, str, width, height, colorMap,
-- maskStr, maskWidth, maskHeight, maskInvert);
- } else {
-- out->drawImage(state, ref, str, width, height, colorMap,
-- haveColorKeyMask ? maskColors : (int *)NULL, inlineImg);
-+ if (haveSoftMask) {
-+ out->drawSoftMaskedImage(state, ref, str, width, height, colorMap,
-+ maskStr, maskWidth, maskHeight, maskColorMap);
-+ delete maskColorMap;
-+ } else if (haveExplicitMask) {
-+ out->drawMaskedImage(state, ref, str, width, height, colorMap,
-+ maskStr, maskWidth, maskHeight, maskInvert);
-+ } else {
-+ out->drawImage(state, ref, str, width, height, colorMap,
-+ haveColorKeyMask ? maskColors : (int *)NULL, inlineImg);
-+ }
- }
-- delete colorMap;
-
-+ delete colorMap;
- maskObj.free();
- smaskObj.free();
- }
-@@ -3869,6 +4218,9 @@
- Stream *str;
- int c1, c2;
-
-+ // NB: this function is run even if ocState is false -- doImage() is
-+ // responsible for skipping over the inline image data
-+
- // build dict/stream
- str = buildImageStream();
-
-@@ -3921,18 +4274,23 @@
- obj.free();
-
- // make stream
-- str = new EmbedStream(parser->getStream(), &dict, gFalse, 0);
-+ if (!(str = parser->getStream())) {
-+ error(errSyntaxError, getPos(), "Invalid inline image data");
-+ dict.free();
-+ return NULL;
-+ }
-+ str = new EmbedStream(str, &dict, gFalse, 0);
- str = str->addFilters(&dict);
-
- return str;
- }
-
- void Gfx::opImageData(Object args[], int numArgs) {
- error(errInternal, getPos(), "Got 'ID' operator");
- }
-
- void Gfx::opEndImage(Object args[], int numArgs) {
- error(errInternal, getPos(), "Got 'EI' operator");
- }
-
- //------------------------------------------------------------------------
-@@ -3967,23 +4325,88 @@
- //------------------------------------------------------------------------
-
- void Gfx::opBeginMarkedContent(Object args[], int numArgs) {
-+ GfxMarkedContent *mc;
-+ Object obj;
-+ GBool ocStateNew;
-+ GString *s;
-+ Unicode *u;
-+ int uLen, i;
-+ GfxMarkedContentKind mcKind;
-+
- if (printCommands) {
- printf(" marked content: %s ", args[0].getName());
-- if (numArgs == 2)
-- args[2].print(stdout);
-+ if (numArgs == 2) {
-+ args[1].print(stdout);
-+ }
- printf("\n");
- fflush(stdout);
- }
-+ mcKind = gfxMCOther;
-+ if (args[0].isName("OC") && numArgs == 2 && args[1].isName() &&
-+ res->lookupPropertiesNF(args[1].getName(), &obj)) {
-+ if (doc->getOptionalContent()->evalOCObject(&obj, &ocStateNew)) {
-+ ocState = ocStateNew;
-+ }
-+ obj.free();
-+ mcKind = gfxMCOptionalContent;
- }
-
- void Gfx::opEndMarkedContent(Object args[], int numArgs) {
-+ GfxMarkedContent *mc;
-+ GfxMarkedContentKind mcKind;
-+
-+ if (markedContentStack->getLength() > 0) {
-+ mc = (GfxMarkedContent *)
-+ markedContentStack->del(markedContentStack->getLength() - 1);
-+ mcKind = mc->kind;
-+ delete mc;
-+ if (mcKind == gfxMCOptionalContent) {
-+ if (markedContentStack->getLength() > 0) {
-+ mc = (GfxMarkedContent *)
-+ markedContentStack->get(markedContentStack->getLength() - 1);
-+ ocState = mc->ocState;
-+ } else {
-+ ocState = gTrue;
-+ }
-
-
- void Gfx::opMarkPoint(Object args[], int numArgs) {
- if (printCommands) {
- printf(" mark point: %s ", args[0].getName());
- if (numArgs == 2)
-- args[2].print(stdout);
-+ args[1].print(stdout);
- printf("\n");
- fflush(stdout);
- }
-diff -ru xpdf-3.02/xpdf/GfxFont.cc xpdf-3.03/xpdf/GfxFont.cc
---- xpdf-3.02/xpdf/GfxFont.cc 2007-02-27 23:05:52.000000000 +0100
-+++ xpdf-3.03/xpdf/GfxFont.cc 2011-08-15 23:08:53.000000000 +0200
-@@ -16,6 +16,11 @@
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
-+#include <math.h>
-+#include <limits.h>
-+#if HAVE_STD_SORT
-+#include <algorithm>
-+#endif
- #include "gmem.h"
- #include "Error.h"
- #include "Object.h"
-@@ -25,6 +30,7 @@
- #include "CharCodeToUnicode.h"
- #include "FontEncodingTables.h"
- #include "BuiltinFontTables.h"
-+#include "FoFiIdentifier.h"
- #include "FoFiType1.h"
- #include "FoFiType1C.h"
- #include "FoFiTrueType.h"
-@@ -93,15 +107,66 @@
- GfxFont *GfxFont::makeFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict) {
- GString *nameA;
-+ Ref embFontIDA;
-+ GfxFontType typeA;
- GfxFont *font;
- Object obj1;
-
-@@ -113,53 +178,235 @@
- }
- obj1.free();
-
-- // get font type
-+ // get embedded font ID and font type
-+ typeA = getFontType(xref, fontDict, &embFontIDA);
-+
-+ // create the font object
- font = NULL;
-- fontDict->lookup("Subtype", &obj1);
-- if (obj1.isName("Type1") || obj1.isName("MMType1")) {
-- font = new Gfx8BitFont(xref, tagA, idA, nameA, fontType1, fontDict);
-- } else if (obj1.isName("Type1C")) {
-- font = new Gfx8BitFont(xref, tagA, idA, nameA, fontType1C, fontDict);
-- } else if (obj1.isName("Type3")) {
-- font = new Gfx8BitFont(xref, tagA, idA, nameA, fontType3, fontDict);
-- } else if (obj1.isName("TrueType")) {
-- font = new Gfx8BitFont(xref, tagA, idA, nameA, fontTrueType, fontDict);
-- } else if (obj1.isName("Type0")) {
-- font = new GfxCIDFont(xref, tagA, idA, nameA, fontDict);
-+ if (typeA < fontCIDType0) {
-+ font = new Gfx8BitFont(xref, tagA, idA, nameA, typeA, embFontIDA,
-+ fontDict);
- } else {
-- error(-1, "Unknown font type: '%s'",
-- obj1.isName() ? obj1.getName() : "???");
-- font = new Gfx8BitFont(xref, tagA, idA, nameA, fontUnknownType, fontDict);
-+ font = new GfxCIDFont(xref, tagA, idA, nameA, typeA, embFontIDA,
-+ fontDict);
- }
-- obj1.free();
-
- return font;
- }
-
--GfxFont::GfxFont(char *tagA, Ref idA, GString *nameA) {
-+GfxFont::GfxFont(char *tagA, Ref idA, GString *nameA,
-+ GfxFontType typeA, Ref embFontIDA) {
- ok = gFalse;
- tag = new GString(tagA);
- id = idA;
- name = nameA;
-+ type = typeA;
-+ embFontID = embFontIDA;
- embFontName = NULL;
-- extFontFile = NULL;
- }
-
- GfxFont::~GfxFont() {
- delete tag;
- if (name) {
- delete name;
- }
- if (embFontName) {
- delete embFontName;
- }
-- if (extFontFile) {
-- delete extFontFile;
-+}
-+
-+// This function extracts three pieces of information:
-+// 1. the "expected" font type, i.e., the font type implied by
-+// Font.Subtype, DescendantFont.Subtype, and
-+// FontDescriptor.FontFile3.Subtype
-+// 2. the embedded font object ID
-+// 3. the actual font type - determined by examining the embedded font
-+// if there is one, otherwise equal to the expected font type
-+// If the expected and actual font types don't match, a warning
-+// message is printed. The expected font type is not used for
-+// anything else.
-+GfxFontType GfxFont::getFontType(XRef *xref, Dict *fontDict, Ref *embID) {
-+ GfxFontType t, expectedType;
-+ FoFiIdentifierType fft;
-+ Dict *fontDict2;
-+ Object subtype, fontDesc, obj1, obj2, obj3, obj4;
-+ GBool isType0, err;
-+
-+ t = fontUnknownType;
-+ embID->num = embID->gen = -1;
-+ err = gFalse;
-+
-+ fontDict->lookup("Subtype", &subtype);
-+ expectedType = fontUnknownType;
-+ isType0 = gFalse;
-+ if (subtype.isName("Type1") || subtype.isName("MMType1")) {
-+ expectedType = fontType1;
-+ } else if (subtype.isName("Type1C")) {
-+ expectedType = fontType1C;
-+ } else if (subtype.isName("Type3")) {
-+ expectedType = fontType3;
-+ } else if (subtype.isName("TrueType")) {
-+ expectedType = fontTrueType;
-+ } else if (subtype.isName("Type0")) {
-+ isType0 = gTrue;
-+ } else {
-+ error(errSyntaxWarning, -1, "Unknown font type: '{0:s}'",
-+ subtype.isName() ? subtype.getName() : "???");
-+ }
-+ subtype.free();
-+
-+ fontDict2 = fontDict;
-+ if (fontDict->lookup("DescendantFonts", &obj1)->isArray()) {
-+ if (obj1.arrayGetLength() == 0) {
-+ error(errSyntaxWarning, -1, "Empty DescendantFonts array in font");
-+ obj2.initNull();
-+ } else if (obj1.arrayGet(0, &obj2)->isDict()) {
-+ if (!isType0) {
-+ error(errSyntaxWarning, -1, "Non-CID font with DescendantFonts array");
-+ }
-+ fontDict2 = obj2.getDict();
-+ fontDict2->lookup("Subtype", &subtype);
-+ if (subtype.isName("CIDFontType0")) {
-+ if (isType0) {
-+ expectedType = fontCIDType0;
-+ }
-+ } else if (subtype.isName("CIDFontType2")) {
-+ if (isType0) {
-+ expectedType = fontCIDType2;
-+ }
-+ }
-+ subtype.free();
-+ }
-+ } else {
-+ obj2.initNull();
-+ }
-+
-+ if (fontDict2->lookup("FontDescriptor", &fontDesc)->isDict()) {
-+ if (fontDesc.dictLookupNF("FontFile", &obj3)->isRef()) {
-+ *embID = obj3.getRef();
-+ if (expectedType != fontType1) {
-+ err = gTrue;
-+ }
-+ }
-+ obj3.free();
-+ if (embID->num == -1 &&
-+ fontDesc.dictLookupNF("FontFile2", &obj3)->isRef()) {
-+ *embID = obj3.getRef();
-+ if (isType0) {
-+ expectedType = fontCIDType2;
-+ } else if (expectedType != fontTrueType) {
-+ err = gTrue;
-+ }
-+ }
-+ obj3.free();
-+ if (embID->num == -1 &&
-+ fontDesc.dictLookupNF("FontFile3", &obj3)->isRef()) {
-+ *embID = obj3.getRef();
-+ if (obj3.fetch(xref, &obj4)->isStream()) {
-+ obj4.streamGetDict()->lookup("Subtype", &subtype);
-+ if (subtype.isName("Type1")) {
-+ if (expectedType != fontType1) {
-+ err = gTrue;
-+ expectedType = isType0 ? fontCIDType0 : fontType1;
-+ }
-+ } else if (subtype.isName("Type1C")) {
-+ if (expectedType == fontType1) {
-+ expectedType = fontType1C;
-+ } else if (expectedType != fontType1C) {
-+ err = gTrue;
-+ expectedType = isType0 ? fontCIDType0C : fontType1C;
-+ }
-+ } else if (subtype.isName("TrueType")) {
-+ if (expectedType != fontTrueType) {
-+ err = gTrue;
-+ expectedType = isType0 ? fontCIDType2 : fontTrueType;
-+ }
-+ } else if (subtype.isName("CIDFontType0C")) {
-+ if (expectedType == fontCIDType0) {
-+ expectedType = fontCIDType0C;
-+ } else {
-+ err = gTrue;
-+ expectedType = isType0 ? fontCIDType0C : fontType1C;
-+ }
-+ } else if (subtype.isName("OpenType")) {
-+ if (expectedType == fontTrueType) {
-+ expectedType = fontTrueTypeOT;
-+ } else if (expectedType == fontType1) {
-+ expectedType = fontType1COT;
-+ } else if (expectedType == fontCIDType0) {
-+ expectedType = fontCIDType0COT;
-+ } else if (expectedType == fontCIDType2) {
-+ expectedType = fontCIDType2OT;
-+ } else {
-+ err = gTrue;
-+ }
-+ } else {
-+ error(errSyntaxError, -1, "Unknown font type '{0:s}'",
-+ subtype.isName() ? subtype.getName() : "???");
-+ }
-+ subtype.free();
-+ }
-+ obj4.free();
-+ }
-+ obj3.free();
-+ }
-+ fontDesc.free();
-+
-+ t = fontUnknownType;
-+ if (embID->num >= 0) {
-+ obj3.initRef(embID->num, embID->gen);
-+ obj3.fetch(xref, &obj4);
-+ if (obj4.isStream()) {
-+ obj4.streamReset();
-+ fft = FoFiIdentifier::identifyStream(&readFromStream, obj4.getStream());
-+ obj4.streamClose();
-+ switch (fft) {
-+ case fofiIdType1PFA:
-+ case fofiIdType1PFB:
-+ t = fontType1;
-+ break;
-+ case fofiIdCFF8Bit:
-+ t = isType0 ? fontCIDType0C : fontType1C;
-+ break;
-+ case fofiIdCFFCID:
-+ t = fontCIDType0C;
-+ break;
-+ case fofiIdTrueType:
-+ case fofiIdTrueTypeCollection:
-+ t = isType0 ? fontCIDType2 : fontTrueType;
-+ break;
-+ case fofiIdOpenTypeCFF8Bit:
-+ t = isType0 ? fontCIDType0COT : fontType1COT;
-+ break;
-+ case fofiIdOpenTypeCFFCID:
-+ t = fontCIDType0COT;
-+ break;
-+ default:
-+ error(errSyntaxError, -1, "Embedded font file may be invalid");
-+ break;
-+ }
-+ }
-+ obj4.free();
-+ obj3.free();
-+ }
-+
-+ if (t == fontUnknownType) {
-+ t = expectedType;
- }
-+
-+ if (t != expectedType) {
-+ err = gTrue;
-+ }
-+
-+ if (err) {
-+ error(errSyntaxWarning, -1,
-+ "Mismatch between font type and embedded font file");
-+ }
-+
-+ obj2.free();
-+ obj1.free();
-+
-+ return t;
- }
-
- void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) {
-@@ -170,8 +417,6 @@
- // assume Times-Roman by default (for substitution purposes)
- flags = fontSerif;
-
-- embFontID.num = -1;
-- embFontID.gen = -1;
- missingWidth = 0;
-
- if (fontDict->lookup("FontDescriptor", &obj1)->isDict()) {
-@@ -189,75 +434,6 @@
- }
- obj2.free();
-
-- // look for embedded font file
-- if (obj1.dictLookupNF("FontFile", &obj2)->isRef()) {
-- embFontID = obj2.getRef();
-- if (type != fontType1) {
-- error(-1, "Mismatch between font type and embedded font file");
-- type = fontType1;
-- }
-- }
-- obj2.free();
-- if (embFontID.num == -1 &&
-- obj1.dictLookupNF("FontFile2", &obj2)->isRef()) {
-- embFontID = obj2.getRef();
-- if (type != fontTrueType && type != fontCIDType2) {
-- error(-1, "Mismatch between font type and embedded font file");
-- type = type == fontCIDType0 ? fontCIDType2 : fontTrueType;
-- }
-- }
-- obj2.free();
-- if (embFontID.num == -1 &&
-- obj1.dictLookupNF("FontFile3", &obj2)->isRef()) {
-- if (obj2.fetch(xref, &obj3)->isStream()) {
-- obj3.streamGetDict()->lookup("Subtype", &obj4);
-- if (obj4.isName("Type1")) {
-- embFontID = obj2.getRef();
-- if (type != fontType1) {
-- error(-1, "Mismatch between font type and embedded font file");
-- type = fontType1;
-- }
-- } else if (obj4.isName("Type1C")) {
-- embFontID = obj2.getRef();
-- if (type != fontType1 && type != fontType1C) {
-- error(-1, "Mismatch between font type and embedded font file");
-- }
-- type = fontType1C;
-- } else if (obj4.isName("TrueType")) {
-- embFontID = obj2.getRef();
-- if (type != fontTrueType) {
-- error(-1, "Mismatch between font type and embedded font file");
-- type = fontTrueType;
-- }
-- } else if (obj4.isName("CIDFontType0C")) {
-- embFontID = obj2.getRef();
-- if (type != fontCIDType0) {
-- error(-1, "Mismatch between font type and embedded font file");
-- }
-- type = fontCIDType0C;
-- } else if (obj4.isName("OpenType")) {
-- embFontID = obj2.getRef();
-- if (type == fontTrueType) {
-- type = fontTrueTypeOT;
-- } else if (type == fontType1) {
-- type = fontType1COT;
-- } else if (type == fontCIDType0) {
-- type = fontCIDType0COT;
-- } else if (type == fontCIDType2) {
-- type = fontCIDType2OT;
-- } else {
-- error(-1, "Mismatch between font type and embedded font file");
-- }
-- } else {
-- error(-1, "Unknown embedded font type '%s'",
-- obj4.isName() ? obj4.getName() : "???");
-- }
-- obj4.free();
-- }
-- obj3.free();
-- }
-- obj2.free();
--
- // look for MissingWidth
- obj1.dictLookup("MissingWidth", &obj2);
- if (obj2.isNum()) {
-@@ -269,8 +445,13 @@
- obj1.dictLookup("Ascent", &obj2);
- if (obj2.isNum()) {
- t = 0.001 * obj2.getNum();
-- // some broken font descriptors set ascent and descent to 0
-- if (t != 0) {
-+ // some broken font descriptors specify a negative ascent
-+ if (t < 0) {
-+ t = -t;
-+ }
-+ // some broken font descriptors set ascent and descent to 0;
-+ // others set it to ridiculous values (e.g., 32768)
-+ if (t != 0 && t < 3) {
- ascent = t;
- }
- }
-@@ -278,14 +459,14 @@
- obj1.dictLookup("Descent", &obj2);
- if (obj2.isNum()) {
- t = 0.001 * obj2.getNum();
-+ // some broken font descriptors specify a positive descent
-+ if (t > 0) {
-+ t = -t;
-+ }
- // some broken font descriptors set ascent and descent to 0
-- if (t != 0) {
-+ if (t != 0 && t > -3) {
- descent = t;
- }
-- // some broken font descriptors specify a positive descent
-- if (descent > 0) {
-- descent = -descent;
-- }
- }
- obj2.free();
-
-@@ -330,37 +511,280 @@
- return ctu;
- }
-
--void GfxFont::findExtFontFile() {
-- static char *type1Exts[] = { ".pfa", ".pfb", ".ps", "", NULL };
-- static char *ttExts[] = { ".ttf", NULL };
-+GfxFontLoc *GfxFont::locateFont(XRef *xref, GBool ps) {
-+ GfxFontLoc *fontLoc;
-+ SysFontType sysFontType;
-+ GString *path, *base14Name, *substName;
-+ PSFontParam16 *psFont16;
-+ Object refObj, embFontObj;
-+ int substIdx, fontNum;
-+ GBool embed;
-
-- if (name) {
-- if (type == fontType1) {
-- extFontFile = globalParams->findFontFile(name, type1Exts);
-- } else if (type == fontTrueType) {
-- extFontFile = globalParams->findFontFile(name, ttExts);
-+ if (type == fontType3) {
-+ return NULL;
-+ }
-+
-+ //----- embedded font
-+ if (embFontID.num >= 0) {
-+ embed = gTrue;
-+ refObj.initRef(embFontID.num, embFontID.gen);
-+ refObj.fetch(xref, &embFontObj);
-+ if (!embFontObj.isStream()) {
-+ error(errSyntaxError, -1, "Embedded font object is wrong type");
-+ embed = gFalse;
-+ }
-+ embFontObj.free();
-+ refObj.free();
-+ if (embed) {
-+ if (ps) {
-+ switch (type) {
-+ case fontType1:
-+ case fontType1C:
-+ case fontType1COT:
-+ embed = globalParams->getPSEmbedType1();
-+ break;
-+ case fontTrueType:
-+ case fontTrueTypeOT:
-+ embed = globalParams->getPSEmbedTrueType();
-+ break;
-+ case fontCIDType0C:
-+ case fontCIDType0COT:
-+ embed = globalParams->getPSEmbedCIDPostScript();
-+ break;
-+ case fontCIDType2:
-+ case fontCIDType2OT:
-+ embed = globalParams->getPSEmbedCIDTrueType();
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ if (embed) {
-+ fontLoc = new GfxFontLoc();
-+ fontLoc->locType = gfxFontLocEmbedded;
-+ fontLoc->fontType = type;
-+ fontLoc->embFontID = embFontID;
-+ return fontLoc;
-+ }
-+ }
-+ }
-+
-+ //----- PS passthrough
-+ if (ps && !isCIDFont() && globalParams->getPSFontPassthrough()) {
-+ fontLoc = new GfxFontLoc();
-+ fontLoc->locType = gfxFontLocResident;
-+ fontLoc->fontType = fontType1;
-+ fontLoc->path = name->copy();
-+ return fontLoc;
-+ }
-+
-+ //----- PS resident Base-14 font
-+ if (ps && !isCIDFont() && ((Gfx8BitFont *)this)->base14) {
-+ fontLoc = new GfxFontLoc();
-+ fontLoc->locType = gfxFontLocResident;
-+ fontLoc->fontType = fontType1;
-+ fontLoc->path = new GString(((Gfx8BitFont *)this)->base14->base14Name);
-+ return fontLoc;
-+ }
-+
-+ //----- external font file (fontFile, fontDir)
-+ if ((path = globalParams->findFontFile(name))) {
-+ if ((fontLoc = getExternalFont(path, isCIDFont()))) {
-+ return fontLoc;
-+ }
-+ }
-+
-+ //----- external font file for Base-14 font
-+ if (!ps && !isCIDFont() && ((Gfx8BitFont *)this)->base14) {
-+ base14Name = new GString(((Gfx8BitFont *)this)->base14->base14Name);
-+ if ((path = globalParams->findFontFile(base14Name))) {
-+ if ((fontLoc = getExternalFont(path, gFalse))) {
-+ delete base14Name;
-+ return fontLoc;
-+ }
-+ }
-+ delete base14Name;
-+ }
-+
-+ //----- system font
-+ if ((path = globalParams->findSystemFontFile(name, &sysFontType,
-+ &fontNum))) {
-+ if (isCIDFont()) {
-+ if (sysFontType == sysFontTTF || sysFontType == sysFontTTC) {
-+ fontLoc = new GfxFontLoc();
-+ fontLoc->locType = gfxFontLocExternal;
-+ fontLoc->fontType = fontCIDType2;
-+ fontLoc->path = path;
-+ fontLoc->fontNum = fontNum;
-+ return fontLoc;
-+ }
-+ } else {
-+ if (sysFontType == sysFontTTF || sysFontType == sysFontTTC) {
-+ fontLoc = new GfxFontLoc();
-+ fontLoc->locType = gfxFontLocExternal;
-+ fontLoc->fontType = fontTrueType;
-+ fontLoc->path = path;
-+ return fontLoc;
-+ } else if (sysFontType == sysFontPFA || sysFontType == sysFontPFB) {
-+ fontLoc = new GfxFontLoc();
-+ fontLoc->locType = gfxFontLocExternal;
-+ fontLoc->fontType = fontType1;
-+ fontLoc->path = path;
-+ fontLoc->fontNum = fontNum;
-+ return fontLoc;
-+ }
-+ }
-+ delete path;
-+ }
-+
-+ if (!isCIDFont()) {
-+
-+ //----- 8-bit PS resident font
-+ if (ps) {
-+ if ((path = globalParams->getPSResidentFont(name))) {
-+ fontLoc = new GfxFontLoc();
-+ fontLoc->locType = gfxFontLocResident;
-+ fontLoc->fontType = fontType1;
-+ fontLoc->path = path;
-+ return fontLoc;
-+ }
-+ }
-+
-+ //----- 8-bit font substitution
-+ if (flags & fontFixedWidth) {
-+ substIdx = 0;
-+ } else if (flags & fontSerif) {
-+ substIdx = 8;
-+ } else {
-+ substIdx = 4;
-+ }
-+ if (isBold()) {
-+ substIdx += 2;
-+ }
-+ if (isItalic()) {
-+ substIdx += 1;
-+ }
-+ substName = new GString(base14SubstFonts[substIdx]);
-+ if (ps) {
-+ error(errSyntaxWarning, -1, "Substituting font '{0:s}' for '{1:t}'",
-+ base14SubstFonts[substIdx], name);
-+ fontLoc = new GfxFontLoc();
-+ fontLoc->locType = gfxFontLocResident;
-+ fontLoc->fontType = fontType1;
-+ fontLoc->path = substName;
-+ fontLoc->substIdx = substIdx;
-+ return fontLoc;
-+ } else {
-+ path = globalParams->findFontFile(substName);
-+ delete substName;
-+ if (path) {
-+ if ((fontLoc = getExternalFont(path, gFalse))) {
-+ error(errSyntaxWarning, -1, "Substituting font '{0:s}' for '{1:t}'",
-+ base14SubstFonts[substIdx], name);
-+ fontLoc->substIdx = substIdx;
-+ return fontLoc;
-+ }
-+ }
-+ }
-+
-+ // failed to find a substitute font
-+ return NULL;
-+ }
-+
-+ //----- 16-bit PS resident font
-+ if (ps && ((psFont16 = globalParams->getPSResidentFont16(
-+ name,
-+ ((GfxCIDFont *)this)->getWMode())))) {
-+ fontLoc = new GfxFontLoc();
-+ fontLoc->locType = gfxFontLocResident;
-+ fontLoc->fontType = fontCIDType0; // this is not used
-+ fontLoc->path = psFont16->psFontName->copy();
-+ fontLoc->encoding = psFont16->encoding->copy();
-+ fontLoc->wMode = psFont16->wMode;
-+ return fontLoc;
-+ }
-+ if (ps && ((psFont16 = globalParams->getPSResidentFontCC(
-+ ((GfxCIDFont *)this)->getCollection(),
-+ ((GfxCIDFont *)this)->getWMode())))) {
-+ error(errSyntaxWarning, -1, "Substituting font '{0:t}' for '{1:t}'",
-+ psFont16->psFontName, name);
-+ fontLoc = new GfxFontLoc();
-+ fontLoc->locType = gfxFontLocResident;
-+ fontLoc->fontType = fontCIDType0; // this is not used
-+ fontLoc->path = psFont16->psFontName->copy();
-+ fontLoc->encoding = psFont16->encoding->copy();
-+ fontLoc->wMode = psFont16->wMode;
-+ return fontLoc;
-+ }
-+
-+ //----- CID font substitution
-+ if ((path = globalParams->findCCFontFile(
-+ ((GfxCIDFont *)this)->getCollection()))) {
-+ if ((fontLoc = getExternalFont(path, gTrue))) {
-+ error(errSyntaxWarning, -1, "Substituting font '{0:t}' for '{1:t}'",
-+ fontLoc->path, name);
-+ return fontLoc;
- }
- }
-+
-+ // failed to find a substitute font
-+ return NULL;
- }
-
--char *GfxFont::readExtFontFile(int *len) {
-- FILE *f;
-- char *buf;
-+GfxFontLoc *GfxFont::locateBase14Font(GString *base14Name) {
-+ GString *path;
-
-- if (!(f = fopen(extFontFile->getCString(), "rb"))) {
-- error(-1, "External font file '%s' vanished", extFontFile->getCString());
-+ path = globalParams->findFontFile(base14Name);
-+ if (!path) {
- return NULL;
- }
-- fseek(f, 0, SEEK_END);
-- *len = (int)ftell(f);
-- fseek(f, 0, SEEK_SET);
-- buf = (char *)gmalloc(*len);
-- if ((int)fread(buf, 1, *len, f) != *len) {
-- error(-1, "Error reading external font file '%s'",
-- extFontFile->getCString());
-+ return getExternalFont(path, gFalse);
-+}
-+
-+GfxFontLoc *GfxFont::getExternalFont(GString *path, GBool cid) {
-+ FoFiIdentifierType fft;
-+ GfxFontType fontType;
-+ GfxFontLoc *fontLoc;
-+
-+ fft = FoFiIdentifier::identifyFile(path->getCString());
-+ switch (fft) {
-+ case fofiIdType1PFA:
-+ case fofiIdType1PFB:
-+ fontType = fontType1;
-+ break;
-+ case fofiIdCFF8Bit:
-+ fontType = fontType1C;
-+ break;
-+ case fofiIdCFFCID:
-+ fontType = fontCIDType0C;
-+ break;
-+ case fofiIdTrueType:
-+ case fofiIdTrueTypeCollection:
-+ fontType = cid ? fontCIDType2 : fontTrueType;
-+ break;
-+ case fofiIdOpenTypeCFF8Bit:
-+ fontType = fontType1COT;
-+ break;
-+ case fofiIdOpenTypeCFFCID:
-+ fontType = fontCIDType0COT;
-+ break;
-+ case fofiIdUnknown:
-+ case fofiIdError:
-+ default:
-+ fontType = fontUnknownType;
-+ break;
-+ }
-+ if (fontType == fontUnknownType ||
-+ (cid ? (fontType < fontCIDType0)
-+ : (fontType >= fontCIDType0))) {
-+ delete path;
-+ return NULL;
- }
-- fclose(f);
-- return buf;
-+ fontLoc = new GfxFontLoc();
-+ fontLoc->locType = gfxFontLocExternal;
-+ fontLoc->fontType = fontType;
-+ fontLoc->path = path;
-+ return fontLoc;
- }
-
- char *GfxFont::readEmbFontFile(XRef *xref, int *len) {
-@@ -386,6 +810,10 @@
- str->reset();
- while ((c = str->getChar()) != EOF) {
- if (i == size) {
-+ if (size > INT_MAX - 4096) {
-+ error(errSyntaxError, -1, "Embedded font file is too large");
-+ break;
-+ }
- size += 4096;
- buf = (char *)grealloc(buf, size);
- }
-@@ -405,8 +833,8 @@
- //------------------------------------------------------------------------
-
- Gfx8BitFont::Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
-- GfxFontType typeA, Dict *fontDict):
-- GfxFont(tagA, idA, nameA)
-+ GfxFontType typeA, Ref embFontIDA, Dict *fontDict):
-+ GfxFont(tagA, idA, nameA, typeA, embFontIDA)
- {
- GString *name2;
- BuiltinFont *builtinFont;
-@@ -428,11 +856,11 @@
- Object obj1, obj2, obj3;
- int n, i, a, b, m;
-
-- type = typeA;
- ctu = NULL;
-
- // do font name substitution for various aliases of the Base 14 font
- // names
- base14 = NULL;
- if (name) {
- name2 = name->copy();
- i = 0;
-@@ -499,9 +927,6 @@
- fontBBox[3] = 0.001 * builtinFont->bbox[3];
- }
-
-- // look for an external font file
-- findExtFontFile();
--
- // get font matrix
- fontMat[0] = fontMat[3] = 1;
- fontMat[1] = fontMat[2] = fontMat[4] = fontMat[5] = 0;
-@@ -581,54 +1007,45 @@
- baseEnc = winAnsiEncoding;
- }
-
-- // check embedded or external font file for base encoding
-+ // check embedded font file for base encoding
- // (only for Type 1 fonts - trying to get an encoding out of a
- // TrueType font is a losing proposition)
- ffT1 = NULL;
- ffT1C = NULL;
- buf = NULL;
-- if (type == fontType1 && (extFontFile || embFontID.num >= 0)) {
-- if (extFontFile) {
-- ffT1 = FoFiType1::load(extFontFile->getCString());
-- } else {
-- buf = readEmbFontFile(xref, &len);
-- ffT1 = FoFiType1::make(buf, len);
-- }
-- if (ffT1) {
-- if (ffT1->getName()) {
-- if (embFontName) {
-- delete embFontName;
-+ if (type == fontType1 && embFontID.num >= 0) {
-+ if ((buf = readEmbFontFile(xref, &len))) {
-+ if ((ffT1 = FoFiType1::make(buf, len))) {
-+ if (ffT1->getName()) {
-+ if (embFontName) {
-+ delete embFontName;
-+ }
-+ embFontName = new GString(ffT1->getName());
-+ }
-+ if (!baseEnc) {
-+ baseEnc = (const char **)ffT1->getEncoding();
-+ baseEncFromFontFile = gTrue;
- }
-- embFontName = new GString(ffT1->getName());
-- }
-- if (!baseEnc) {
-- baseEnc = (const char **)ffT1->getEncoding();
-- baseEncFromFontFile = gTrue;
- }
-+ gfree(buf);
- }
-- } else if (type == fontType1C && (extFontFile || embFontID.num >= 0)) {
-- if (extFontFile) {
-- ffT1C = FoFiType1C::load(extFontFile->getCString());
-- } else {
-- buf = readEmbFontFile(xref, &len);
-- ffT1C = FoFiType1C::make(buf, len);
-- }
-- if (ffT1C) {
-- if (ffT1C->getName()) {
-- if (embFontName) {
-- delete embFontName;
-+ } else if (type == fontType1C && embFontID.num >= 0) {
-+ if ((buf = readEmbFontFile(xref, &len))) {
-+ if ((ffT1C = FoFiType1C::make(buf, len))) {
-+ if (ffT1C->getName()) {
-+ if (embFontName) {
-+ delete embFontName;
-+ }
-+ embFontName = new GString(ffT1C->getName());
-+ }
-+ if (!baseEnc) {
-+ baseEnc = (const char **)ffT1C->getEncoding();
-+ baseEncFromFontFile = gTrue;
- }
-- embFontName = new GString(ffT1C->getName());
-- }
-- if (!baseEnc) {
-- baseEnc = (const char **)ffT1C->getEncoding();
-- baseEncFromFontFile = gTrue;
- }
-+ gfree(buf);
- }
- }
-- if (buf) {
-- gfree(buf);
-- }
-
- // get default base encoding
- if (!baseEnc) {
-@@ -644,7 +1061,7 @@
-
- // copy the base encoding
- for (i = 0; i < 256; ++i) {
-- enc[i] = baseEnc[i];
-+ enc[i] = (char *)baseEnc[i];
- if ((encFree[i] = baseEncFromFontFile) && enc[i]) {
- enc[i] = copyString(baseEnc[i]);
- }
-@@ -654,11 +1071,10 @@
- // T1C->T1 conversion (since the 'seac' operator depends on having
- // the accents in the encoding), so we fill in any gaps from
- // StandardEncoding
-- if (type == fontType1C && (extFontFile || embFontID.num >= 0) &&
-- baseEncFromFontFile) {
-+ if (type == fontType1C && embFontID.num >= 0 && baseEncFromFontFile) {
- for (i = 0; i < 256; ++i) {
- if (!enc[i] && standardEncoding[i]) {
- enc[i] = (char *)standardEncoding[i];
- encFree[i] = gFalse;
- }
- }
-@@ -734,14 +1151,21 @@
- }
-
- // pass 2: try to fill in the missing chars, looking for names of
-- // the form 'Axx', 'xx', 'Ann', 'ABnn', or 'nn', where 'A' and 'B'
-- // are any letters, 'xx' is two hex digits, and 'nn' is 2-4
-- // decimal digits
-+ // any of the following forms:
-+ // - 'xx'
-+ // - 'Axx'
-+ // - 'nn'
-+ // - 'Ann'
-+ // - 'ABnn'
-+ // - 'unixxxx' (possibly followed by garbage - some Arabic files
-+ // use 'uni0628.medi', etc.)
-+ // where 'A' and 'B' are any letters, 'xx' is two hex digits, 'xxxx'
-+ // is four hex digits, and 'nn' is 2-4 decimal digits
- if (missing && globalParams->getMapNumericCharNames()) {
- for (code = 0; code < 256; ++code) {
- if ((charName = enc[code]) && !toUnicode[code] &&
- strcmp(charName, ".notdef")) {
- n = strlen(charName);
- code2 = -1;
- if (hex && n == 3 && isalpha(charName[0]) &&
- isxdigit(charName[1]) && isxdigit(charName[2])) {
-@@ -758,8 +1182,13 @@
- } else if (n >= 4 && n <= 6 &&
- isdigit(charName[2]) && isdigit(charName[3])) {
- code2 = atoi(charName+2);
-+ } else if (n >= 7 && charName[0] == 'u' && charName[1] == 'n' &&
-+ charName[2] == 'i' &&
-+ isxdigit(charName[3]) && isxdigit(charName[4]) &&
-+ isxdigit(charName[5]) && isxdigit(charName[6])) {
-+ sscanf(charName + 3, "%x", &code2);
- }
-- if (code2 >= 0 && code2 <= 0xff) {
-+ if (code2 >= 0 && code2 <= 0xffff) {
- toUnicode[code] = (Unicode)code2;
- }
- }
-@@ -835,7 +1264,7 @@
- obj1.arrayGet(code - firstChar, &obj2);
- if (obj2.isNum()) {
- widths[code] = obj2.getNum() * mul;
-- if (widths[code] != widths[firstChar]) {
-+ if (fabs(widths[code] - widths[firstChar]) > 0.00001) {
- flags &= ~fontFixedWidth;
- }
- }
-@@ -945,9 +1374,10 @@
- // TrueType font has a Macintosh Roman cmap, use it, and
- // reverse map the char names through MacRomanEncoding to
- // get char codes.
-- // 1b. If the TrueType font has a Microsoft Unicode cmap or a
-- // non-Microsoft Unicode cmap, use it, and use the Unicode
-- // indexes, not the char codes.
-+ // 1b. If the PDF font is not symbolic or the PDF font is not
-+ // embedded, and the TrueType font has a Microsoft Unicode
-+ // cmap or a non-Microsoft Unicode cmap, use it, and use the
-+ // Unicode indexes, not the char codes.
- // 1c. If the PDF font is symbolic and the TrueType font has a
- // Microsoft Symbol cmap, use it, and use char codes
- // directly (possibly with an offset of 0xf000).
-@@ -983,7 +1413,8 @@
- if (usesMacRomanEnc && macRomanCmap >= 0) {
- cmap = macRomanCmap;
- useMacRoman = gTrue;
-- } else if (unicodeCmap >= 0) {
-+ } else if ((!(flags & fontSymbolic) || embFontID.num < 0) &&
-+ unicodeCmap >= 0) {
- cmap = unicodeCmap;
- useUnicode = gTrue;
- } else if ((flags & fontSymbolic) && msSymbolCmap >= 0) {
-@@ -1010,6 +1441,8 @@
- if ((code = globalParams->getMacRomanCharCode(charName))) {
- map[i] = ff->mapCodeToGID(cmap, code);
- }
-+ } else {
-+ map[i] = -1;
- }
- }
-
-@@ -1020,6 +1453,8 @@
- (u = globalParams->mapNameToUnicode(charName))) ||
- (n = ctu->mapToUnicode((CharCode)i, &u, 1))) {
- map[i] = ff->mapCodeToGID(cmap, u);
-+ } else {
-+ map[i] = -1;
- }
- }
-
-@@ -1035,8 +1470,8 @@
-
- // try the TrueType 'post' table to handle any unmapped characters
- for (i = 0; i < 256; ++i) {
-- if (!map[i] && (charName = enc[i])) {
-+ if (map[i] <= 0 && (charName = enc[i])) {
- map[i] = ff->mapNameToGID(charName);
- }
- }
-
-@@ -1077,12 +1530,11 @@
- GfxCIDFont::GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
-- Dict *fontDict):
-- GfxFont(tagA, idA, nameA)
-+ GfxFontType typeA, Ref embFontIDA, Dict *fontDict):
-+ GfxFont(tagA, idA, nameA, typeA, embFontIDA)
- {
- Dict *desFontDict;
-- GString *collection, *cMapName;
- Object desFontDictObj;
- Object obj1, obj2, obj3, obj4, obj5, obj6;
- CharCodeToUnicode *utu;
-@@ -1091,8 +1545,10 @@
- ascent = 0.95;
- descent = -0.35;
- fontBBox[0] = fontBBox[1] = fontBBox[2] = fontBBox[3] = 0;
-+ collection = NULL;
- cMap = NULL;
- ctu = NULL;
-+ ctuUsesCharCode = gTrue;
- widths.defWidth = 1.0;
- widths.defHeight = -1.0;
- widths.defVY = 0.880;
-@@ -1104,52 +1560,38 @@
- cidToGIDLen = 0;
-
- // get the descendant font
-- if (!fontDict->lookup("DescendantFonts", &obj1)->isArray()) {
-- error(-1, "Missing DescendantFonts entry in Type 0 font");
-+ if (!fontDict->lookup("DescendantFonts", &obj1)->isArray() ||
-+ obj1.arrayGetLength() == 0) {
-+ error(errSyntaxError, -1,
-+ "Missing or empty DescendantFonts entry in Type 0 font");
- obj1.free();
-+
- goto err1;
- }
- if (!obj1.arrayGet(0, &desFontDictObj)->isDict()) {
-- error(-1, "Bad descendant font in Type 0 font");
-- goto err3;
-+ error(errSyntaxError, -1, "Bad descendant font in Type 0 font");
-+ goto err2;
- }
- obj1.free();
- desFontDict = desFontDictObj.getDict();
-
-- // font type
-- if (!desFontDict->lookup("Subtype", &obj1)) {
-- error(-1, "Missing Subtype entry in Type 0 descendant font");
-- goto err3;
-- }
-- if (obj1.isName("CIDFontType0")) {
-- type = fontCIDType0;
-- } else if (obj1.isName("CIDFontType2")) {
-- type = fontCIDType2;
-- } else {
-- error(-1, "Unknown Type 0 descendant font type '%s'",
-- obj1.isName() ? obj1.getName() : "???");
-- goto err3;
-- }
-- obj1.free();
--
- // get info from font descriptor
- readFontDescriptor(xref, desFontDict);
-
-- // look for an external font file
-- findExtFontFile();
--
- //----- encoding info -----
-
- // char collection
- if (!desFontDict->lookup("CIDSystemInfo", &obj1)->isDict()) {
-- error(-1, "Missing CIDSystemInfo dictionary in Type 0 descendant font");
-- goto err3;
-+ error(errSyntaxError, -1,
-+ "Missing CIDSystemInfo dictionary in Type 0 descendant font");
-+ goto err2;
- }
- obj1.dictLookup("Registry", &obj2);
- obj1.dictLookup("Ordering", &obj3);
- if (!obj2.isString() || !obj3.isString()) {
-- error(-1, "Invalid CIDSystemInfo dictionary in Type 0 descendant font");
-- goto err4;
-+ error(errSyntaxError, -1,
-+ "Invalid CIDSystemInfo dictionary in Type 0 descendant font");
-+ goto err3;
- }
- collection = obj2.getString()->copy()->append('-')->append(obj3.getString());
- obj3.free();
-@@ -1158,19 +1600,18 @@
-
- // look for a ToUnicode CMap
- if (!(ctu = readToUnicodeCMap(fontDict, 16, NULL))) {
-+ ctuUsesCharCode = gFalse;
-
-- // the "Adobe-Identity" and "Adobe-UCS" collections don't have
-- // cidToUnicode files
-- if (collection->cmp("Adobe-Identity") &&
-- collection->cmp("Adobe-UCS")) {
--
-- // look for a user-supplied .cidToUnicode file
-- if (!(ctu = globalParams->getCIDToUnicode(collection))) {
-- error(-1, "Unknown character collection '%s'",
-- collection->getCString());
-- // fall-through, assuming the Identity mapping -- this appears
-- // to match Adobe's behavior
-- }
-+ // use an identity mapping for the "Adobe-Identity" and
-+ // "Adobe-UCS" collections
-+ if (!collection->cmp("Adobe-Identity") ||
-+ !collection->cmp("Adobe-UCS")) {
-+ ctu = CharCodeToUnicode::makeIdentityMapping();
-+
-+ // look for a user-supplied .cidToUnicode file
-+ } else if (!(ctu = globalParams->getCIDToUnicode(collection))) {
-+ error(errSyntaxError, -1,
-+ "Unknown character collection '{0:t}'", collection);
- }
- }
-
-@@ -1193,43 +1634,35 @@
- }
-
- // encoding (i.e., CMap)
-- //~ need to handle a CMap stream here
-- //~ also need to deal with the UseCMap entry in the stream dict
-- if (!fontDict->lookup("Encoding", &obj1)->isName()) {
-- error(-1, "Missing or invalid Encoding entry in Type 0 font");
-- delete collection;
-- goto err3;
-+ if (fontDict->lookup("Encoding", &obj1)->isNull()) {
-+ error(errSyntaxError, -1, "Missing Encoding entry in Type 0 font");
-+ goto err2;
- }
-- cMapName = new GString(obj1.getName());
-- obj1.free();
-- if (!(cMap = globalParams->getCMap(collection, cMapName))) {
-- error(-1, "Unknown CMap '%s' for character collection '%s'",
-- cMapName->getCString(), collection->getCString());
-- delete collection;
-- delete cMapName;
-+ if (!(cMap = CMap::parse(NULL, collection, &obj1))) {
- goto err2;
- }
-- delete collection;
-- delete cMapName;
-+ obj1.free();
-
-- // CIDToGIDMap (for embedded TrueType fonts)
-- if (type == fontCIDType2) {
-+ // CIDToGIDMap
-+ // (the PDF spec only allows these for TrueType fonts, but Acrobat
-+ // apparently also allows them for OpenType CFF fonts)
-+ if (type == fontCIDType2 || type == fontCIDType0COT) {
- desFontDict->lookup("CIDToGIDMap", &obj1);
- if (obj1.isStream()) {
- cidToGIDLen = 0;
- i = 64;
-@@ -1387,17 +1830,19 @@
- ok = gTrue;
- return;
-
-- err4:
-+ err3:
- obj3.free();
- obj2.free();
-- err3:
-- obj1.free();
- err2:
-+ obj1.free();
- desFontDictObj.free();
- err1:;
- }
-
- GfxCIDFont::~GfxCIDFont() {
-+ if (collection) {
-+ delete collection;
-+ }
- if (cMap) {
- cMap->decRefCnt();
- }
-@@ -1425,12 +1871,16 @@
- return 1;
- }
-
- *code = (CharCode)(cid = cMap->getCID(s, len, &c, &n));
- if (ctu) {
-- *uLen = ctu->mapToUnicode(cid, u, uSize);
-+ *uLen = ctu->mapToUnicode(ctuUsesCharCode ? c : cid, u, uSize);
- } else {
- *uLen = 0;
- }
-+ if (!*uLen && uSize >= 1 && globalParams->getMapUnknownCharNames()) {
-+ u[0] = *code;
-+ *uLen = 1;
-+ }
-
- // horizontal
- if (cMap->getWMode() == 0) {
-diff -ru xpdf-3.02/xpdf/GfxFont.h xpdf-3.03/xpdf/GfxFont.h
---- xpdf-3.02/xpdf/GfxFont.h 2007-02-27 23:05:52.000000000 +0100
-+++ xpdf-3.03/xpdf/GfxFont.h 2011-08-15 23:08:53.000000000 +0200
-@@ -91,7 +127,8 @@
- // Build a GfxFont object.
- static GfxFont *makeFont(XRef *xref, char *tagA, Ref idA, Dict *fontDict);
-
-- GfxFont(char *tagA, Ref idA, GString *nameA);
-+ GfxFont(char *tagA, Ref idA, GString *nameA,
-+ GfxFontType typeA, Ref embFontIDA);
-
- virtual ~GfxFont();
-
-@@ -126,10 +160,6 @@
- // NULL if there is no embedded font.
- GString *getEmbeddedFontName() { return embFontName; }
-
-- // Get the name of the external font file. Returns NULL if there
-- // is no external font file.
-- GString *getExtFontFile() { return extFontFile; }
--
- // Get font descriptor flags.
- int getFlags() { return flags; }
- GBool isFixedWidth() { return flags & fontFixedWidth; }
-@@ -151,8 +181,14 @@
- // Return the writing mode (0=horizontal, 1=vertical).
- virtual int getWMode() { return 0; }
-
-- // Read an external or embedded font file into a buffer.
-- char *readExtFontFile(int *len);
-+ // Locate the font file for this font. If <ps> is true, includes PS
-+ // printer-resident fonts. Returns NULL on failure.
-+ GfxFontLoc *locateFont(XRef *xref, GBool ps);
-+
-+ // Locate a Base-14 font file for a specified font name.
-+ static GfxFontLoc *locateBase14Font(GString *base14Name);
-+
-+ // Read an embedded font file into a buffer.
- char *readEmbFontFile(XRef *xref, int *len);
-
- // Get the next char from a string <s> of <len> bytes, returning the
-@@ -167,22 +203,21 @@
-
- protected:
-
-+ static GfxFontType getFontType(XRef *xref, Dict *fontDict, Ref *embID);
- void readFontDescriptor(XRef *xref, Dict *fontDict);
- CharCodeToUnicode *readToUnicodeCMap(Dict *fontDict, int nBits,
- CharCodeToUnicode *ctu);
-- void findExtFontFile();
-+ static GfxFontLoc *getExternalFont(GString *path, GBool cid);
-
- GString *tag; // PDF font tag
- Ref id; // reference (used as unique ID)
- GString *name; // font name
- GfxFontType type; // type of font
- int flags; // font descriptor flags
- GString *embFontName; // name of embedded font
- Ref embFontID; // ref to embedded font file stream
-- GString *extFontFile; // external font file name
-- double fontMat[6]; // font matrix (Type 3 only)
-- double fontBBox[4]; // font bounding box (Type 3 only)
-+ double fontMat[6]; // font matrix
-+ double fontBBox[4]; // font bounding box
- double missingWidth; // "default" width
- double ascent; // max height above baseline
- double descent; // max depth below baseline
-@@ -197,7 +232,7 @@
- public:
-
- Gfx8BitFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
-- GfxFontType typeA, Dict *fontDict);
-+ GfxFontType typeA, Ref embFontIDA, Dict *fontDict);
-
- virtual ~Gfx8BitFont();
-
-@@ -247,6 +283,8 @@
- double widths[256]; // character widths
- Object charProcs; // Type 3 CharProcs dictionary
- Object resources; // Type 3 Resources dictionary
-+
-+ friend class GfxFont;
- };
-
- //------------------------------------------------------------------------
-@@ -257,7 +295,7 @@
- public:
-
- GfxCIDFont(XRef *xref, char *tagA, Ref idA, GString *nameA,
-- Dict *fontDict);
-+ GfxFontType typeA, Ref embFontIDA, Dict *fontDict);
-
- virtual ~GfxCIDFont();
-
-@@ -278,15 +316,18 @@
-
- private:
-
-+ GString *collection; // collection name
- CMap *cMap; // char code --> CID
-- CharCodeToUnicode *ctu; // CID --> Unicode
-+ CharCodeToUnicode *ctu; // CID/char code --> Unicode
-+ GBool ctuUsesCharCode; // true: ctu maps char code to Unicode;
-+ // false: ctu maps CID to Unicode
- GfxFontCIDWidths widths; // character widths
-diff -ru xpdf-3.02/xpdf/GfxState.cc xpdf-3.03/xpdf/GfxState.cc
---- xpdf-3.02/xpdf/GfxState.cc 2007-02-27 23:05:52.000000000 +0100
-+++ xpdf-3.03/xpdf/GfxState.cc 2011-08-15 23:08:53.000000000 +0200
-@@ -819,26 +854,27 @@
- obj1.free();
- arr->get(1, &obj1);
- if (!obj1.isStream()) {
- error(errSyntaxError, -1, "Bad ICCBased color space (stream)");
- obj1.free();
- return NULL;
- }
- dict = obj1.streamGetDict();
- if (!dict->lookup("N", &obj2)->isInt()) {
- error(errSyntaxError, -1, "Bad ICCBased color space (N)");
- obj2.free();
- obj1.free();
- return NULL;
- }
- nCompsA = obj2.getInt();
- obj2.free();
-- if (nCompsA > gfxColorMaxComps) {
-- error(-1, "ICCBased color space with too many (%d > %d) components",
-- nCompsA, gfxColorMaxComps);
-- nCompsA = gfxColorMaxComps;
-+ if (nCompsA > 4) {
-+ error(errSyntaxError, -1,
-+ "ICCBased color space with too many ({0:d} > 4) components",
-+ nCompsA);
-+ nCompsA = 4;
- }
- if (dict->lookup("Alternate", &obj2)->isNull() ||
-@@ -986,8 +1025,9 @@
- for (i = 0; i <= indexHighA; ++i) {
- for (j = 0; j < n; ++j) {
- if ((x = obj1.streamGetChar()) == EOF) {
-- error(-1, "Bad Indexed color space (lookup table stream too short)");
-- goto err3;
-+ error(errSyntaxError, -1,
-+ "Bad Indexed color space (lookup table stream too short)");
-+ cs->indexHigh = indexHighA = i - 1;
- }
- cs->lookup[i*n + j] = (Guchar)x;
- }
-@@ -995,8 +1035,9 @@
- obj1.streamClose();
- } else if (obj1.isString()) {
- if (obj1.getString()->getLength() < (indexHighA + 1) * n) {
-- error(-1, "Bad Indexed color space (lookup table string too short)");
-- goto err3;
-+ error(errSyntaxError, -1,
-+ "Bad Indexed color space (lookup table string too short)");
-+ cs->indexHigh = indexHighA = obj1.getString()->getLength() / n - 1;
- }
- s = obj1.getString()->getCString();
- for (i = 0; i <= indexHighA; ++i) {
-@@ -1254,14 +1354,7 @@
- goto err4;
- }
- obj1.free();
-- cs = new GfxDeviceNColorSpace(nCompsA, altA, funcA);
-- cs->nonMarking = gTrue;
-- for (i = 0; i < nCompsA; ++i) {
-- cs->names[i] = namesA[i];
-- if (namesA[i]->cmp("None")) {
-- cs->nonMarking = gFalse;
-- }
-- }
-+ cs = new GfxDeviceNColorSpace(nCompsA, namesA, altA, funcA);
- return cs;
-
- err4:
-@@ -3187,7 +3299,7 @@
- GfxIndexedColorSpace *indexedCS;
- GfxSeparationColorSpace *sepCS;
- int maxPixel, indexHigh;
-- Guchar *lookup2;
-+ Guchar *indexedLookup;
- Function *sepFunc;
- Object obj;
- double x[gfxColorMaxComps];
-@@ -3204,6 +3316,7 @@
- // initialize
- for (k = 0; k < gfxColorMaxComps; ++k) {
- lookup[k] = NULL;
-+ lookup2[k] = NULL;
- }
-
- // get decode map
-@@ -3236,10 +3353,18 @@
- // Construct a lookup table -- this stores pre-computed decoded
- // values for each component, i.e., the result of applying the
- // decode mapping to each possible image pixel component value.
-- //
-+ for (k = 0; k < nComps; ++k) {
-+ lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
-+ sizeof(GfxColorComp));
-+ for (i = 0; i <= maxPixel; ++i) {
-+ lookup[k][i] = dblToCol(decodeLow[k] +
-+ (i * decodeRange[k]) / maxPixel);
-+ }
-+ }
-+
- // Optimization: for Indexed and Separation color spaces (which have
-- // only one component), we store color values in the lookup table
-- // rather than component values.
-+ // only one component), we pre-compute a second lookup table with
-+ // color values
- colorSpace2 = NULL;
- nComps2 = 0;
- if (colorSpace->getMode() == csIndexed) {
-@@ -3250,20 +3375,22 @@
- colorSpace2 = indexedCS->getBase();
- indexHigh = indexedCS->getIndexHigh();
- nComps2 = colorSpace2->getNComps();
-- lookup2 = indexedCS->getLookup();
-+ indexedLookup = indexedCS->getLookup();
- colorSpace2->getDefaultRanges(x, y, indexHigh);
- for (k = 0; k < nComps2; ++k) {
-- lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
-- sizeof(GfxColorComp));
-- for (i = 0; i <= maxPixel; ++i) {
-- j = (int)(decodeLow[0] + (i * decodeRange[0]) / maxPixel + 0.5);
-- if (j < 0) {
-- j = 0;
-- } else if (j > indexHigh) {
-- j = indexHigh;
-- }
-- lookup[k][i] =
-- dblToCol(x[k] + (lookup2[j*nComps2 + k] / 255.0) * y[k]);
-+ lookup2[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
-+ sizeof(GfxColorComp));
-+ }
-+ for (i = 0; i <= maxPixel; ++i) {
-+ j = (int)(decodeLow[0] + (i * decodeRange[0]) / maxPixel + 0.5);
-+ if (j < 0) {
-+ j = 0;
-+ } else if (j > indexHigh) {
-+ j = indexHigh;
-+ }
-+ for (k = 0; k < nComps2; ++k) {
-+ lookup2[k][i] =
-+ dblToCol(x[k] + (indexedLookup[j*nComps2 + k] / 255.0) * y[k]);
- }
- }
- } else if (colorSpace->getMode() == csSeparation) {
-@@ -3272,21 +3399,14 @@
- nComps2 = colorSpace2->getNComps();
- sepFunc = sepCS->getFunc();
- for (k = 0; k < nComps2; ++k) {
-- lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
-- sizeof(GfxColorComp));
-- for (i = 0; i <= maxPixel; ++i) {
-- x[0] = decodeLow[0] + (i * decodeRange[0]) / maxPixel;
-- sepFunc->transform(x, y);
-- lookup[k][i] = dblToCol(y[k]);
-- }
-+ lookup2[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
-+ sizeof(GfxColorComp));
- }
-- } else {
-- for (k = 0; k < nComps; ++k) {
-- lookup[k] = (GfxColorComp *)gmallocn(maxPixel + 1,
-- sizeof(GfxColorComp));
-- for (i = 0; i <= maxPixel; ++i) {
-- lookup[k][i] = dblToCol(decodeLow[k] +
-- (i * decodeRange[k]) / maxPixel);
-+ for (i = 0; i <= maxPixel; ++i) {
-+ x[0] = decodeLow[0] + (i * decodeRange[0]) / maxPixel;
-+ sepFunc->transform(x, y);
-+ for (k = 0; k < nComps2; ++k) {
-+ lookup2[k][i] = dblToCol(y[k]);
- }
- }
- }
-@@ -3309,24 +3429,24 @@
- colorSpace2 = NULL;
- for (k = 0; k < gfxColorMaxComps; ++k) {
- lookup[k] = NULL;
-+ lookup2[k] = NULL;
- }
- n = 1 << bits;
-+ for (k = 0; k < nComps; ++k) {
-+ lookup[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp));
-+ memcpy(lookup[k], colorMap->lookup[k], n * sizeof(GfxColorComp));
-+ }
- if (colorSpace->getMode() == csIndexed) {
- colorSpace2 = ((GfxIndexedColorSpace *)colorSpace)->getBase();
- for (k = 0; k < nComps2; ++k) {
-- lookup[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp));
-- memcpy(lookup[k], colorMap->lookup[k], n * sizeof(GfxColorComp));
-+ lookup2[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp));
-+ memcpy(lookup2[k], colorMap->lookup2[k], n * sizeof(GfxColorComp));
- }
- } else if (colorSpace->getMode() == csSeparation) {
- colorSpace2 = ((GfxSeparationColorSpace *)colorSpace)->getAlt();
- for (k = 0; k < nComps2; ++k) {
-- lookup[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp));
-- memcpy(lookup[k], colorMap->lookup[k], n * sizeof(GfxColorComp));
-- }
-- } else {
-- for (k = 0; k < nComps; ++k) {
-- lookup[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp));
-- memcpy(lookup[k], colorMap->lookup[k], n * sizeof(GfxColorComp));
-+ lookup2[k] = (GfxColorComp *)gmallocn(n, sizeof(GfxColorComp));
-+ memcpy(lookup2[k], colorMap->lookup2[k], n * sizeof(GfxColorComp));
- }
- }
- for (i = 0; i < nComps; ++i) {
-@@ -3342,6 +3462,7 @@
- delete colorSpace;
- for (i = 0; i < gfxColorMaxComps; ++i) {
- gfree(lookup[i]);
-+ gfree(lookup2[i]);
- }
- }
-
-@@ -3351,7 +3472,7 @@
-
- if (colorSpace2) {
- for (i = 0; i < nComps2; ++i) {
-- color.c[i] = lookup[i][x[0]];
-+ color.c[i] = lookup2[i][x[0]];
- }
- colorSpace2->getGray(&color, gray);
- } else {
-@@ -3368,7 +3489,7 @@
-
- if (colorSpace2) {
- for (i = 0; i < nComps2; ++i) {
-- color.c[i] = lookup[i][x[0]];
-+ color.c[i] = lookup2[i][x[0]];
- }
- colorSpace2->getRGB(&color, rgb);
- } else {
-@@ -3385,7 +3506,7 @@
-
- if (colorSpace2) {
- for (i = 0; i < nComps2; ++i) {
-- color.c[i] = lookup[i][x[0]];
-+ color.c[i] = lookup2[i][x[0]];
- }
- colorSpace2->getCMYK(&color, cmyk);
- } else {
-@@ -3405,6 +3527,88 @@
- }
- }
-
-+void GfxImageColorMap::getGrayByteLine(Guchar *in, Guchar *out, int n) {
-+ GfxColor color;
-+ GfxGray gray;
-+ int i, j;
-+
-+ if (colorSpace2) {
-+ for (j = 0; j < n; ++j) {
-+ for (i = 0; i < nComps2; ++i) {
-+ color.c[i] = lookup2[i][in[j]];
-+ }
-+ colorSpace2->getGray(&color, &gray);
-+ out[j] = colToByte(gray);
-+ }
-+ } else {
-+ for (j = 0; j < n; ++j) {
-+ for (i = 0; i < nComps; ++i) {
-+ color.c[i] = lookup[i][in[j * nComps + i]];
-+ }
-+ colorSpace->getGray(&color, &gray);
-+ out[j] = colToByte(gray);
-+ }
-+ }
-+}
-+
-+void GfxImageColorMap::getRGBByteLine(Guchar *in, Guchar *out, int n) {
-+ GfxColor color;
-+ GfxRGB rgb;
-+ int i, j;
-+
-+ if (colorSpace2) {
-+ for (j = 0; j < n; ++j) {
-+ for (i = 0; i < nComps2; ++i) {
-+ color.c[i] = lookup2[i][in[j]];
-+ }
-+ colorSpace2->getRGB(&color, &rgb);
-+ out[j*3] = colToByte(rgb.r);
-+ out[j*3 + 1] = colToByte(rgb.g);
-+ out[j*3 + 2] = colToByte(rgb.b);
-+ }
-+ } else {
-+ for (j = 0; j < n; ++j) {
-+ for (i = 0; i < nComps; ++i) {
-+ color.c[i] = lookup[i][in[j * nComps + i]];
-+ }
-+ colorSpace->getRGB(&color, &rgb);
-+ out[j*3] = colToByte(rgb.r);
-+ out[j*3 + 1] = colToByte(rgb.g);
-+ out[j*3 + 2] = colToByte(rgb.b);
-+ }
-+ }
-+}
-+
-+void GfxImageColorMap::getCMYKByteLine(Guchar *in, Guchar *out, int n) {
-+ GfxColor color;
-+ GfxCMYK cmyk;
-+ int i, j;
-+
-+ if (colorSpace2) {
-+ for (j = 0; j < n; ++j) {
-+ for (i = 0; i < nComps2; ++i) {
-+ color.c[i] = lookup2[i][in[j]];
-+ }
-+ colorSpace2->getCMYK(&color, &cmyk);
-+ out[j*4] = colToByte(cmyk.c);
-+ out[j*4 + 1] = colToByte(cmyk.m);
-+ out[j*4 + 2] = colToByte(cmyk.y);
-+ out[j*4 + 3] = colToByte(cmyk.k);
-+ }
-+ } else {
-+ for (j = 0; j < n; ++j) {
-+ for (i = 0; i < nComps; ++i) {
-+ color.c[i] = lookup[i][in[j * nComps + i]];
-+ }
-+ colorSpace->getCMYK(&color, &cmyk);
-+ out[j*4] = colToByte(cmyk.c);
-+ out[j*4 + 1] = colToByte(cmyk.m);
-+ out[j*4 + 2] = colToByte(cmyk.y);
-+ out[j*4 + 3] = colToByte(cmyk.k);
-+ }
-+ }
-+}
-+
- //------------------------------------------------------------------------
- // GfxSubpath and GfxPath
- //------------------------------------------------------------------------
-@@ -3526,13 +3730,18 @@
- }
-
- void GfxPath::lineTo(double x, double y) {
-- if (justMoved) {
-+ if (justMoved || (n > 0 && subpaths[n-1]->isClosed())) {
- if (n >= size) {
- size *= 2;
- subpaths = (GfxSubpath **)
- greallocn(subpaths, size, sizeof(GfxSubpath *));
- }
-- subpaths[n] = new GfxSubpath(firstX, firstY);
-+ if (justMoved) {
-+ subpaths[n] = new GfxSubpath(firstX, firstY);
-+ } else {
-+ subpaths[n] = new GfxSubpath(subpaths[n-1]->getLastX(),
-+ subpaths[n-1]->getLastY());
-+ }
- ++n;
- justMoved = gFalse;
- }
-@@ -3541,13 +3750,18 @@
-
- void GfxPath::curveTo(double x1, double y1, double x2, double y2,
- double x3, double y3) {
-- if (justMoved) {
-+ if (justMoved || (n > 0 && subpaths[n-1]->isClosed())) {
- if (n >= size) {
- size *= 2;
- subpaths = (GfxSubpath **)
- greallocn(subpaths, size, sizeof(GfxSubpath *));
- }
-- subpaths[n] = new GfxSubpath(firstX, firstY);
-+ if (justMoved) {
-+ subpaths[n] = new GfxSubpath(firstX, firstY);
-+ } else {
-+ subpaths[n] = new GfxSubpath(subpaths[n-1]->getLastX(),
-+ subpaths[n-1]->getLastY());
-+ }
- ++n;
- justMoved = gFalse;
- }
-@@ -3719,13 +3934,10 @@
- // this gets set to NULL by restore()
- delete path;
- }
-- if (saved) {
-- delete saved;
-- }
- }
-
-diff -ru xpdf-3.02/xpdf/GfxState.h xpdf-3.03/xpdf/GfxState.h
---- xpdf-3.02/xpdf/GfxState.h 2007-02-27 23:05:52.000000000 +0100
-+++ xpdf-3.03/xpdf/GfxState.h 2011-08-15 23:08:53.000000000 +0200
-@@ -878,6 +894,11 @@
- void getCMYK(Guchar *x, GfxCMYK *cmyk);
- void getColor(Guchar *x, GfxColor *color);
-
-+ // Convert a line of <n> pixels to 8-bit colors.
-+ void getGrayByteLine(Guchar *in, Guchar *out, int n);
-+ void getRGBByteLine(Guchar *in, Guchar *out, int n);
-+ void getCMYKByteLine(Guchar *in, Guchar *out, int n);
-+
- private:
-
- GfxImageColorMap(GfxImageColorMap *colorMap);
-@@ -889,6 +910,8 @@
- int nComps2; // number of components in colorSpace2
- GfxColorComp * // lookup table
- lookup[gfxColorMaxComps];
-+ GfxColorComp * // optimized case lookup table
-+ lookup2[gfxColorMaxComps];
- double // minimum values for each component
- decodeLow[gfxColorMaxComps];
- double // max - min value for each component
diff -ru xpdf-3.02/xpdf/GlobalParams.cc xpdf-3.03/xpdf/GlobalParams.cc
--- xpdf-3.02/xpdf/GlobalParams.cc 2007-02-27 23:05:52.000000000 +0100
+++ xpdf-3.03/xpdf/GlobalParams.cc 2011-08-15 23:08:53.000000000 +0200
-@@ -124,215 +124,138 @@
- GlobalParams *globalParams = NULL;
-
- //------------------------------------------------------------------------
--// DisplayFontParam
-+// PSFontParam16
- //------------------------------------------------------------------------
-
--DisplayFontParam::DisplayFontParam(GString *nameA,
-- DisplayFontParamKind kindA) {
-+PSFontParam16::PSFontParam16(GString *nameA, int wModeA,
-+ GString *psFontNameA, GString *encodingA) {
- name = nameA;
-- kind = kindA;
-- switch (kind) {
-- case displayFontT1:
-- t1.fileName = NULL;
-- break;
-- case displayFontTT:
-- tt.fileName = NULL;
-- break;
-- }
-+ wMode = wModeA;
-+ psFontName = psFontNameA;
-+ encoding = encodingA;
- }
-
--DisplayFontParam::~DisplayFontParam() {
-+PSFontParam16::~PSFontParam16() {
- delete name;
-- switch (kind) {
-- case displayFontT1:
-- if (t1.fileName) {
-- delete t1.fileName;
-- }
-- break;
-- case displayFontTT:
-- if (tt.fileName) {
-- delete tt.fileName;
-- }
-- break;
-- }
-+ delete psFontName;
-+ delete encoding;
- }
-
--#ifdef WIN32
--
- //------------------------------------------------------------------------
--// WinFontInfo
-+// SysFontInfo
- //------------------------------------------------------------------------
-
--class WinFontInfo: public DisplayFontParam {
-+class SysFontInfo {
- public:
-
-- GBool bold, italic;
-+ GString *name;
-+ GBool bold;
-+ GBool italic;
-+ GString *path;
-+ SysFontType type;
-+ int fontNum; // for TrueType collections
-
-- static WinFontInfo *make(GString *nameA, GBool boldA, GBool italicA,
-- HKEY regKey, char *winFontDir);
-- WinFontInfo(GString *nameA, GBool boldA, GBool italicA,
-- GString *fileNameA);
-- virtual ~WinFontInfo();
-- GBool equals(WinFontInfo *fi);
-+ SysFontInfo(GString *nameA, GBool boldA, GBool italicA,
-+ GString *pathA, SysFontType typeA, int fontNumA);
-+ ~SysFontInfo();
-+ GBool match(SysFontInfo *fi);
-+ GBool match(GString *nameA, GBool boldA, GBool italicA);
- };
-
--WinFontInfo *WinFontInfo::make(GString *nameA, GBool boldA, GBool italicA,
-- HKEY regKey, char *winFontDir) {
-- GString *regName;
-- GString *fileNameA;
-- char buf[MAX_PATH];
-- DWORD n;
-- char c;
-- int i;
--
-- //----- find the font file
-- fileNameA = NULL;
-- regName = nameA->copy();
-- if (boldA) {
-- regName->append(" Bold");
-- }
-- if (italicA) {
-- regName->append(" Italic");
-- }
-- regName->append(" (TrueType)");
-- n = sizeof(buf);
-- if (RegQueryValueEx(regKey, regName->getCString(), NULL, NULL,
-- (LPBYTE)buf, &n) == ERROR_SUCCESS) {
-- fileNameA = new GString(winFontDir);
-- fileNameA->append('\\')->append(buf);
-- }
-- delete regName;
-- if (!fileNameA) {
-- delete nameA;
-- return NULL;
-- }
--
-- //----- normalize the font name
-- i = 0;
-- while (i < nameA->getLength()) {
-- c = nameA->getChar(i);
-- if (c == ' ' || c == ',' || c == '-') {
-- nameA->del(i);
-- } else {
-- ++i;
-- }
-- }
--
-- return new WinFontInfo(nameA, boldA, italicA, fileNameA);
--}
--
--WinFontInfo::WinFontInfo(GString *nameA, GBool boldA, GBool italicA,
-- GString *fileNameA):
-- DisplayFontParam(nameA, displayFontTT)
--{
-+SysFontInfo::SysFontInfo(GString *nameA, GBool boldA, GBool italicA,
-+ GString *pathA, SysFontType typeA, int fontNumA) {
-+ name = nameA;
- bold = boldA;
- italic = italicA;
-- tt.fileName = fileNameA;
-+ path = pathA;
-+ type = typeA;
-+ fontNum = fontNumA;
-+}
-+
-+SysFontInfo::~SysFontInfo() {
-+ delete name;
-+ delete path;
- }
-
--WinFontInfo::~WinFontInfo() {
-+GBool SysFontInfo::match(SysFontInfo *fi) {
-+ return !strcasecmp(name->getCString(), fi->name->getCString()) &&
-+ bold == fi->bold && italic == fi->italic;
- }
-
--GBool WinFontInfo::equals(WinFontInfo *fi) {
-- return !name->cmp(fi->name) && bold == fi->bold && italic == fi->italic;
-+GBool SysFontInfo::match(GString *nameA, GBool boldA, GBool italicA) {
-+ return !strcasecmp(name->getCString(), nameA->getCString()) &&
-+ bold == boldA && italic == italicA;
- }
-
- //------------------------------------------------------------------------
--// WinFontList
-+// SysFontList
- //------------------------------------------------------------------------
-
--class WinFontList {
-+class SysFontList {
- public:
-
-- WinFontList(char *winFontDirA);
-- ~WinFontList();
-- WinFontInfo *find(GString *font);
-+ SysFontList();
-+ ~SysFontList();
-+ SysFontInfo *find(GString *name);
-+
-+#ifdef WIN32
-+ void scanWindowsFonts(char *winFontDir);
-+#endif
-
- private:
-
-- void add(WinFontInfo *fi);
-- static int CALLBACK enumFunc1(CONST LOGFONT *font,
-- CONST TEXTMETRIC *metrics,
-- DWORD type, LPARAM data);
-- static int CALLBACK enumFunc2(CONST LOGFONT *font,
-- CONST TEXTMETRIC *metrics,
-- DWORD type, LPARAM data);
--
-- GList *fonts; // [WinFontInfo]
-- HDC dc; // (only used during enumeration)
-- HKEY regKey; // (only used during enumeration)
-- char *winFontDir; // (only used during enumeration)
--};
-+#ifdef WIN32
-+ SysFontInfo *makeWindowsFont(char *name, int fontNum,
-+ char *path);
-+#endif
-
--WinFontList::WinFontList(char *winFontDirA) {
-- OSVERSIONINFO version;
-- char *path;
-+ GList *fonts; // [SysFontInfo]
-+};
-
-+SysFontList::SysFontList() {
- fonts = new GList();
-- dc = GetDC(NULL);
-- winFontDir = winFontDirA;
-- version.dwOSVersionInfoSize = sizeof(version);
-- GetVersionEx(&version);
-- if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
-- path = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\\";
-- } else {
-- path = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts\\";
-- }
-- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0,
-- KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
-- &regKey) == ERROR_SUCCESS) {
-- EnumFonts(dc, NULL, &WinFontList::enumFunc1, (LPARAM)this);
-- RegCloseKey(regKey);
-- }
-- ReleaseDC(NULL, dc);
- }
-
--WinFontList::~WinFontList() {
-- deleteGList(fonts, WinFontInfo);
-+SysFontList::~SysFontList() {
-+ deleteGList(fonts, SysFontInfo);
- }
-
--void WinFontList::add(WinFontInfo *fi) {
-- int i;
--
-- for (i = 0; i < fonts->getLength(); ++i) {
-- if (((WinFontInfo *)fonts->get(i))->equals(fi)) {
-- delete fi;
-- return;
-- }
-- }
-- fonts->append(fi);
--}
--
--WinFontInfo *WinFontList::find(GString *font) {
-- GString *name;
-+SysFontInfo *SysFontList::find(GString *name) {
-+ GString *name2;
- GBool bold, italic;
-- WinFontInfo *fi;
-+ SysFontInfo *fi;
- char c;
- int n, i;
-
-- name = font->copy();
-+ name2 = name->copy();
-
- // remove space, comma, dash chars
- i = 0;
-- while (i < name->getLength()) {
-- c = name->getChar(i);
-+ while (i < name2->getLength()) {
-+ c = name2->getChar(i);
- if (c == ' ' || c == ',' || c == '-') {
-- name->del(i);
-+ name2->del(i);
- } else {
- ++i;
- }
- }
-- n = name->getLength();
-+ n = name2->getLength();
-
- // remove trailing "MT" (Foo-MT, Foo-BoldMT, etc.)
-- if (!strcmp(name->getCString() + n - 2, "MT")) {
-- name->del(n - 2, 2);
-+ if (n > 2 && !strcmp(name2->getCString() + n - 2, "MT")) {
-+ name2->del(n - 2, 2);
- n -= 2;
- }
-
-+ // look for "Regular"
-+ if (n > 7 && !strcmp(name2->getCString() + n - 7, "Regular")) {
-+ name2->del(n - 7, 7);
-+ n -= 7;
-+ }
-+
- // look for "Italic"
-- if (!strcmp(name->getCString() + n - 6, "Italic")) {
-- name->del(n - 6, 6);
-+ if (n > 6 && !strcmp(name2->getCString() + n - 6, "Italic")) {
-+ name2->del(n - 6, 6);
- italic = gTrue;
- n -= 6;
- } else {
-@@ -340,8 +263,8 @@
- }
-
- // look for "Bold"
-- if (!strcmp(name->getCString() + n - 4, "Bold")) {
-- name->del(n - 4, 4);
-+ if (n > 4 && !strcmp(name2->getCString() + n - 4, "Bold")) {
-+ name2->del(n - 4, 4);
- bold = gTrue;
- n -= 4;
- } else {
-@@ -349,84 +272,183 @@
- }
-
- // remove trailing "MT" (FooMT-Bold, etc.)
-- if (!strcmp(name->getCString() + n - 2, "MT")) {
-- name->del(n - 2, 2);
-+ if (n > 2 && !strcmp(name2->getCString() + n - 2, "MT")) {
-+ name2->del(n - 2, 2);
- n -= 2;
- }
-
- // remove trailing "PS"
-- if (!strcmp(name->getCString() + n - 2, "PS")) {
-- name->del(n - 2, 2);
-+ if (n > 2 && !strcmp(name2->getCString() + n - 2, "PS")) {
-+ name2->del(n - 2, 2);
- n -= 2;
- }
-
-+ // remove trailing "IdentityH"
-+ if (n > 9 && !strcmp(name2->getCString() + n - 9, "IdentityH")) {
-+ name2->del(n - 9, 9);
-+ n -= 9;
-+ }
-+
- // search for the font
- fi = NULL;
- for (i = 0; i < fonts->getLength(); ++i) {
-- fi = (WinFontInfo *)fonts->get(i);
-- if (!fi->name->cmp(name) && fi->bold == bold && fi->italic == italic) {
-+ fi = (SysFontInfo *)fonts->get(i);
-+ if (fi->match(name2, bold, italic)) {
- break;
- }
- fi = NULL;
- }
-+ if (!fi && bold) {
-+ // try ignoring the bold flag
-+ for (i = 0; i < fonts->getLength(); ++i) {
-+ fi = (SysFontInfo *)fonts->get(i);
-+ if (fi->match(name2, gFalse, italic)) {
-+ break;
-+ }
-+ fi = NULL;
-+ }
-+ }
-+ if (!fi && (bold || italic)) {
-+ // try ignoring the bold and italic flags
-+ for (i = 0; i < fonts->getLength(); ++i) {
-+ fi = (SysFontInfo *)fonts->get(i);
-+ if (fi->match(name2, gFalse, gFalse)) {
-+ break;
-+ }
-+ fi = NULL;
-+ }
-+ }
-
-- delete name;
-+ delete name2;
- return fi;
- }
-
--int CALLBACK WinFontList::enumFunc1(CONST LOGFONT *font,
-- CONST TEXTMETRIC *metrics,
-- DWORD type, LPARAM data) {
-- WinFontList *fl = (WinFontList *)data;
--
-- EnumFonts(fl->dc, font->lfFaceName, &WinFontList::enumFunc2, (LPARAM)fl);
-- return 1;
--}
--
--int CALLBACK WinFontList::enumFunc2(CONST LOGFONT *font,
-- CONST TEXTMETRIC *metrics,
-- DWORD type, LPARAM data) {
-- WinFontList *fl = (WinFontList *)data;
-- WinFontInfo *fi;
--
-- if (type & TRUETYPE_FONTTYPE) {
-- if ((fi = WinFontInfo::make(new GString(font->lfFaceName),
-- font->lfWeight >= 600,
-- font->lfItalic ? gTrue : gFalse,
-- fl->regKey, fl->winFontDir))) {
-- fl->add(fi);
-+#ifdef WIN32
-+void SysFontList::scanWindowsFonts(char *winFontDir) {
-+ OSVERSIONINFO version;
-+ char *path;
-+ DWORD idx, valNameLen, dataLen, type;
-+ HKEY regKey;
-+ char valName[1024], data[1024];
-+ int n, fontNum;
-+ char *p0, *p1;
-+ GString *fontPath;
-+
-+ version.dwOSVersionInfoSize = sizeof(version);
-+ GetVersionEx(&version);
-+ if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
-+ path = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\\";
-+ } else {
-+ path = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts\\";
-+ }
-+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0,
-+ KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
-+ &regKey) == ERROR_SUCCESS) {
-+ idx = 0;
-+ while (1) {
-+ valNameLen = sizeof(valName) - 1;
-+ dataLen = sizeof(data) - 1;
-+ if (RegEnumValue(regKey, idx, valName, &valNameLen, NULL,
-+ &type, (LPBYTE)data, &dataLen) != ERROR_SUCCESS) {
-+ break;
-+ }
-+ if (type == REG_SZ &&
-+ valNameLen > 0 && valNameLen < sizeof(valName) &&
-+ dataLen > 0 && dataLen < sizeof(data)) {
-+ valName[valNameLen] = '\0';
-+ data[dataLen] = '\0';
-+ n = strlen(data);
-+ if (!strcasecmp(data + n - 4, ".ttf") ||
-+ !strcasecmp(data + n - 4, ".ttc")) {
-+ fontPath = new GString(data);
-+ if (!(dataLen >= 3 && data[1] == ':' && data[2] == '\\')) {
-+ fontPath->insert(0, '\\');
-+ fontPath->insert(0, winFontDir);
-+ }
-+ p0 = valName;
-+ fontNum = 0;
-+ while (*p0) {
-+ p1 = strstr(p0, " & ");
-+ if (p1) {
-+ *p1 = '\0';
-+ p1 = p1 + 3;
-+ } else {
-+ p1 = p0 + strlen(p0);
-+ }
-+ fonts->append(makeWindowsFont(p0, fontNum,
-+ fontPath->getCString()));
-+ p0 = p1;
-+ ++fontNum;
-+ }
-+ delete fontPath;
-+ }
-+ }
-+ ++idx;
- }
-+ RegCloseKey(regKey);
- }
-- return 1;
- }
-
--#endif // WIN32
-+SysFontInfo *SysFontList::makeWindowsFont(char *name, int fontNum,
-+ char *path) {
-+ int n;
-+ GBool bold, italic;
-+ GString *s;
-+ char c;
-+ int i;
-+ SysFontType type;
-
--//------------------------------------------------------------------------
--// PSFontParam
--//------------------------------------------------------------------------
-+ n = strlen(name);
-+ bold = italic = gFalse;
-
--PSFontParam::PSFontParam(GString *pdfFontNameA, int wModeA,
-- GString *psFontNameA, GString *encodingA) {
-- pdfFontName = pdfFontNameA;
-- wMode = wModeA;
-- psFontName = psFontNameA;
-- encoding = encodingA;
--}
-+ // remove trailing ' (TrueType)'
-+ if (n > 11 && !strncmp(name + n - 11, " (TrueType)", 11)) {
-+ n -= 11;
-+ }
-
--PSFontParam::~PSFontParam() {
-- delete pdfFontName;
-- delete psFontName;
-- if (encoding) {
-- delete encoding;
-+ // remove trailing ' Italic'
-+ if (n > 7 && !strncmp(name + n - 7, " Italic", 7)) {
-+ n -= 7;
-+ italic = gTrue;
-+ }
-+
-+ // remove trailing ' Bold'
-+ if (n > 5 && !strncmp(name + n - 5, " Bold", 5)) {
-+ n -= 5;
-+ bold = gTrue;
- }
-+
-+ // remove trailing ' Regular'
-+ if (n > 5 && !strncmp(name + n - 8, " Regular", 8)) {
-+ n -= 8;
-+ }
-+
-+ //----- normalize the font name
-+ s = new GString(name, n);
-+ i = 0;
-+ while (i < s->getLength()) {
-+ c = s->getChar(i);
-+ if (c == ' ' || c == ',' || c == '-') {
-+ s->del(i);
-+ } else {
-+ ++i;
-+ }
-+ }
-+
-+ if (!strcasecmp(path + strlen(path) - 4, ".ttc")) {
-+ type = sysFontTTC;
-+ } else {
-+ type = sysFontTTF;
-+ }
-+ return new SysFontInfo(s, bold, italic, new GString(path), type, fontNum);
- }
-+#endif
-
- //------------------------------------------------------------------------
- // KeyBinding
- //------------------------------------------------------------------------
-
--KeyBinding::KeyBinding(int codeA, int modsA, int contextA, char *cmd0) {
-+KeyBinding::KeyBinding(int codeA, int modsA, int contextA, const char *cmd0) {
- code = codeA;
- mods = modsA;
- context = contextA;
-@@ -637,9 +657,10 @@
- unicodeMaps = new GHash(gTrue);
- cMapDirs = new GHash(gTrue);
- toUnicodeDirs = new GList();
-- displayFonts = new GHash();
-- displayCIDFonts = new GHash();
-- displayNamedCIDFonts = new GHash();
-+ fontFiles = new GHash(gTrue);
-+ fontDirs = new GList();
-+ ccFontFiles = new GHash(gTrue);
-+ sysFonts = new SysFontList();
- #if HAVE_PAPER_H
- char *paperName;
- const struct paper *paperType;
-@@ -668,16 +689,21 @@
- psDuplex = gFalse;
- psLevel = psLevel2;
- psFile = NULL;
-- psFonts = new GHash();
-- psNamedFonts16 = new GList();
-- psFonts16 = new GList();
-+ psResidentFonts = new GHash(gTrue);
-+ psResidentFonts16 = new GList();
-+ psResidentFontsCC = new GList();
- psEmbedType1 = gTrue;
- psEmbedTrueType = gTrue;
- psEmbedCIDPostScript = gTrue;
- psEmbedCIDTrueType = gTrue;
-+ psFontPassthrough = gFalse;
- psPreload = gFalse;
- psOPI = gFalse;
- psASCIIHex = gFalse;
-+ psUncompressPreloadedImages = gFalse;
-+ psRasterResolution = 300;
-+ psRasterMono = gFalse;
-+ psAlwaysRasterize = gFalse;
- textEncoding = new GString("Latin1");
- #if defined(WIN32)
- textEOL = eolDOS;
-@@ -688,13 +714,14 @@
- #endif
- textPageBreaks = gTrue;
- textKeepTinyChars = gFalse;
-- fontDirs = new GList();
- initialZoom = new GString("125");
- continuousView = gFalse;
- enableT1lib = gTrue;
- enableFreeType = gTrue;
-+ disableFreeTypeHinting = gFalse;
- antialias = gTrue;
- vectorAntialias = gTrue;
-+ antialiasPrinting = gFalse;
- strokeAdjust = gTrue;
- screenType = screenUnset;
- screenSize = -1;
-@@ -702,6 +729,10 @@
- screenGamma = 1.0;
- screenBlackThreshold = 0.0;
- screenWhiteThreshold = 1.0;
-+ minLineWidth = 0.0;
-+ overprintPreview = gFalse;
- urlCommand = NULL;
- movieCommand = NULL;
- mapNumericCharNames = gTrue;
-@@ -716,10 +747,6 @@
- unicodeMapCache = new UnicodeMapCache();
- cMapCache = new CMapCache();
-
--#ifdef WIN32
-- winFontList = NULL;
--#endif
--
- #ifdef ENABLE_PLUGINS
- plugins = new GList();
- securityHandlers = new GList();
-@@ -764,7 +791,7 @@
- }
- }
- if (!f) {
--#if defined(WIN32) && !defined(__CYGWIN32__)
-+#ifdef WIN32
- char buf[512];
- i = GetModuleFileName(NULL, buf, sizeof(buf));
- if (i <= 0 || i >= sizeof(buf)) {
-@@ -1762,23 +1833,21 @@
- deleteGHash(residentUnicodeMaps, UnicodeMap);
- deleteGHash(unicodeMaps, GString);
- deleteGList(toUnicodeDirs, GString);
-- deleteGHash(displayFonts, DisplayFontParam);
-- deleteGHash(displayCIDFonts, DisplayFontParam);
-- deleteGHash(displayNamedCIDFonts, DisplayFontParam);
--#ifdef WIN32
-- if (winFontList) {
-- delete winFontList;
-- }
--#endif
-+ deleteGHash(fontFiles, GString);
-+ deleteGList(fontDirs, GString);
-+ deleteGHash(ccFontFiles, GString);
-+ delete sysFonts;
- if (psFile) {
- delete psFile;
- }
-- deleteGHash(psFonts, PSFontParam);
-- deleteGList(psNamedFonts16, PSFontParam);
-- deleteGList(psFonts16, PSFontParam);
-+ deleteGHash(psResidentFonts, GString);
-+ deleteGList(psResidentFonts16, PSFontParam16);
-+ deleteGList(psResidentFontsCC, PSFontParam16);
- delete textEncoding;
-- deleteGList(fontDirs, GString);
- delete initialZoom;
-@@ -1829,8 +1898,6 @@
- char winFontDir[MAX_PATH];
- #endif
- FILE *f;
-- DisplayFontParamKind kind;
-- DisplayFontParam *dfp;
- int i, j;
-
- #ifdef WIN32
-@@ -1850,16 +1917,13 @@
- }
- #endif
- for (i = 0; displayFontTab[i].name; ++i) {
-- fontName = new GString(displayFontTab[i].name);
-- if (getDisplayFont(fontName)) {
-- delete fontName;
-+ if (fontFiles->lookup(displayFontTab[i].name)) {
- continue;
- }
-+ fontName = new GString(displayFontTab[i].name);
- fileName = NULL;
-- kind = displayFontT1; // make gcc happy
- if (dir) {
- fileName = appendToPath(new GString(dir), displayFontTab[i].t1FileName);
-- kind = displayFontT1;
- if ((f = fopen(fileName->getCString(), "rb"))) {
- fclose(f);
- } else {
-@@ -1871,7 +1935,6 @@
- if (!fileName && winFontDir[0] && displayFontTab[i].ttFileName) {
- fileName = appendToPath(new GString(winFontDir),
- displayFontTab[i].ttFileName);
-- kind = displayFontTT;
- if ((f = fopen(fileName->getCString(), "rb"))) {
- fclose(f);
- } else {
-@@ -1886,7 +1949,6 @@
- for (j = 0; !fileName && displayFontDirs[j]; ++j) {
- fileName = appendToPath(new GString(displayFontDirs[j]),
- displayFontTab[i].ttFileName);
-- kind = displayFontTT;
- if ((f = fopen(fileName->getCString(), "rb"))) {
- fclose(f);
- } else {
-@@ -1895,11 +1957,10 @@
- }
- }
- }
--#else
-+#else // WIN32
- for (j = 0; !fileName && displayFontDirs[j]; ++j) {
- fileName = appendToPath(new GString(displayFontDirs[j]),
- displayFontTab[i].t1FileName);
-- kind = displayFontT1;
- if ((f = fopen(fileName->getCString(), "rb"))) {
- fclose(f);
- } else {
-@@ -1907,20 +1968,19 @@
- fileName = NULL;
- }
- }
--#endif
-+#endif // WIN32
- if (!fileName) {
-- error(-1, "No display font for '%s'", displayFontTab[i].name);
-+ error(errConfig, -1, "No display font for '{0:s}'",
-+ displayFontTab[i].name);
- delete fontName;
- continue;
- }
-- dfp = new DisplayFontParam(fontName, kind);
-- dfp->t1.fileName = fileName;
-- globalParams->addDisplayFont(dfp);
-+ addFontFile(fontName, fileName);
- }
-
- #ifdef WIN32
- if (winFontDir[0]) {
-- winFontList = new WinFontList(winFontDir);
-+ sysFonts->scanWindowsFonts(winFontDir);
- }
- #endif
- }
-@@ -2020,31 +2080,72 @@
- return NULL;
- }
-
--DisplayFontParam *GlobalParams::getDisplayFont(GString *fontName) {
-- DisplayFontParam *dfp;
-+GString *GlobalParams::findFontFile(GString *fontName) {
-+ static const char *exts[] = { ".pfa", ".pfb", ".ttf", ".ttc" };
-+ GString *path, *dir;
-+#ifdef WIN32
-+ GString *fontNameU;
-+#endif
-+ const char *ext;
-+ FILE *f;
-+ int i, j;
-
- lockGlobalParams;
-- dfp = (DisplayFontParam *)displayFonts->lookup(fontName);
--#ifdef WIN32
-- if (!dfp && winFontList) {
-- dfp = winFontList->find(fontName);
-+ if ((path = (GString *)fontFiles->lookup(fontName))) {
-+ path = path->copy();
-+ unlockGlobalParams;
-+ return path;
- }
-+ for (i = 0; i < fontDirs->getLength(); ++i) {
-+ dir = (GString *)fontDirs->get(i);
-+ for (j = 0; j < (int)(sizeof(exts) / sizeof(exts[0])); ++j) {
-+ ext = exts[j];
-+#ifdef WIN32
-+ fontNameU = fileNameToUTF8(fontName->getCString());
-+ path = appendToPath(dir->copy(), fontNameU->getCString());
-+ delete fontNameU;
-+#else
-+ path = appendToPath(dir->copy(), fontName->getCString());
- #endif
-+ path->append(ext);
-+ if ((f = openFile(path->getCString(), "rb"))) {
-+ fclose(f);
-+ unlockGlobalParams;
-+ return path;
-+ }
-+ delete path;
-+ }
-+ }
-+ unlockGlobalParams;
-+ return NULL;
-+}
-+
-+GString *GlobalParams::findSystemFontFile(GString *fontName,
-+ SysFontType *type,
-+ int *fontNum) {
-+ SysFontInfo *fi;
-+ GString *path;
-+
-+ path = NULL;
-+ lockGlobalParams;
-+ if ((fi = sysFonts->find(fontName))) {
-+ path = fi->path->copy();
-+ *type = fi->type;
-+ *fontNum = fi->fontNum;
-+ }
- unlockGlobalParams;
-- return dfp;
-+ return path;
- }
-
--DisplayFontParam *GlobalParams::getDisplayCIDFont(GString *fontName,
-- GString *collection) {
-- DisplayFontParam *dfp;
-+GString *GlobalParams::findCCFontFile(GString *collection) {
-+ GString *path;
-
- lockGlobalParams;
-- if (!fontName ||
-- !(dfp = (DisplayFontParam *)displayNamedCIDFonts->lookup(fontName))) {
-- dfp = (DisplayFontParam *)displayCIDFonts->lookup(collection);
-+ if ((path = (GString *)ccFontFiles->lookup(collection))) {
-+ path = path->copy();
- }
- unlockGlobalParams;
-- return dfp;
-+ return path;
- }
-
- GString *GlobalParams::getPSFile() {
-@@ -2137,41 +2238,62 @@
- return level;
- }
-
--PSFontParam *GlobalParams::getPSFont(GString *fontName) {
-- PSFontParam *p;
-+GString *GlobalParams::getPSResidentFont(GString *fontName) {
-+ GString *psName;
-
- lockGlobalParams;
-- p = (PSFontParam *)psFonts->lookup(fontName);
-+ psName = (GString *)psResidentFonts->lookup(fontName);
- unlockGlobalParams;
-- return p;
-+ return psName;
- }
-
--PSFontParam *GlobalParams::getPSFont16(GString *fontName,
-- GString *collection, int wMode) {
-- PSFontParam *p;
-+GList *GlobalParams::getPSResidentFonts() {
-+ GList *names;
-+ GHashIter *iter;
-+ GString *name;
-+ GString *psName;
-+
-+ names = new GList();
-+ lockGlobalParams;
-+ psResidentFonts->startIter(&iter);
-+ while (psResidentFonts->getNext(&iter, &name, (void **)&psName)) {
-+ names->append(psName->copy());
-+ }
-+ unlockGlobalParams;
-+ return names;
-+}
-+
-+PSFontParam16 *GlobalParams::getPSResidentFont16(GString *fontName,
-+ int wMode) {
-+ PSFontParam16 *p;
- int i;
-
- lockGlobalParams;
- p = NULL;
-- if (fontName) {
-- for (i = 0; i < psNamedFonts16->getLength(); ++i) {
-- p = (PSFontParam *)psNamedFonts16->get(i);
-- if (!p->pdfFontName->cmp(fontName) &&
-- p->wMode == wMode) {
-- break;
-- }
-- p = NULL;
-+ for (i = 0; i < psResidentFonts16->getLength(); ++i) {
-+ p = (PSFontParam16 *)psResidentFonts16->get(i);
-+ if (!(p->name->cmp(fontName)) && p->wMode == wMode) {
-+ break;
- }
-+ p = NULL;
- }
-- if (!p && collection) {
-- for (i = 0; i < psFonts16->getLength(); ++i) {
-- p = (PSFontParam *)psFonts16->get(i);
-- if (!p->pdfFontName->cmp(collection) &&
-- p->wMode == wMode) {
-- break;
-- }
-- p = NULL;
-+ unlockGlobalParams;
-+ return p;
-+}
-+
-+PSFontParam16 *GlobalParams::getPSResidentFontCC(GString *collection,
-+ int wMode) {
-+ PSFontParam16 *p;
-+ int i;
-+
-+ lockGlobalParams;
-+ p = NULL;
-+ for (i = 0; i < psResidentFontsCC->getLength(); ++i) {
-+ p = (PSFontParam16 *)psResidentFontsCC->get(i);
-+ if (!(p->name->cmp(collection)) && p->wMode == wMode) {
-+ break;
- }
-+ p = NULL;
- }
- unlockGlobalParams;
- return p;
-@@ -2213,6 +2335,15 @@
- return e;
- }
-
-+GBool GlobalParams::getPSFontPassthrough() {
-+ GBool e;
-+
-+ lockGlobalParams;
-+ e = psFontPassthrough;
-+ unlockGlobalParams;
-+ return e;
-+}
-+
- GBool GlobalParams::getPSPreload() {
- GBool preload;
-
@@ -2240,6 +2371,42 @@
return ah;
}
@@ -3309,37 +58,6 @@ diff -ru xpdf-3.02/xpdf/GlobalParams.cc xpdf-3.03/xpdf/GlobalParams.cc
GString *GlobalParams::getTextEncodingName() {
GString *s;
-@@ -2276,30 +2443,6 @@
- return tiny;
- }
-
--GString *GlobalParams::findFontFile(GString *fontName, char **exts) {
-- GString *dir, *fileName;
-- char **ext;
-- FILE *f;
-- int i;
--
-- lockGlobalParams;
-- for (i = 0; i < fontDirs->getLength(); ++i) {
-- dir = (GString *)fontDirs->get(i);
-- for (ext = exts; *ext; ++ext) {
-- fileName = appendToPath(dir->copy(), fontName->getCString());
-- fileName->append(*ext);
-- if ((f = fopen(fileName->getCString(), "rb"))) {
-- fclose(f);
-- unlockGlobalParams;
-- return fileName;
-- }
-- delete fileName;
-- }
-- }
-- unlockGlobalParams;
-- return NULL;
--}
--
- GString *GlobalParams::getInitialZoom() {
- GString *s;
-
@@ -2355,6 +2507,15 @@
return f;
}
@@ -3356,129 +74,9 @@ diff -ru xpdf-3.02/xpdf/GlobalParams.cc xpdf-3.03/xpdf/GlobalParams.cc
GBool GlobalParams::getStrokeAdjust() {
GBool f;
-@@ -2552,14 +2731,9 @@
- // functions to set parameters
- //------------------------------------------------------------------------
-
--void GlobalParams::addDisplayFont(DisplayFontParam *param) {
-- DisplayFontParam *old;
--
-+void GlobalParams::addFontFile(GString *fontName, GString *path) {
- lockGlobalParams;
-- if ((old = (DisplayFontParam *)displayFonts->remove(param->name))) {
-- delete old;
-- }
-- displayFonts->add(param->name, param);
-+ fontFiles->add(fontName, path);
- unlockGlobalParams;
- }
-
-@@ -2684,6 +2858,12 @@
- unlockGlobalParams;
- }
-
-+void GlobalParams::setPSFontPassthrough(GBool passthrough) {
-+ lockGlobalParams;
-+ psFontPassthrough = passthrough;
-+ unlockGlobalParams;
-+}
-+
- void GlobalParams::setPSPreload(GBool preload) {
- lockGlobalParams;
- psPreload = preload;
diff -ru xpdf-3.02/xpdf/GlobalParams.h xpdf-3.03/xpdf/GlobalParams.h
--- xpdf-3.02/xpdf/GlobalParams.h 2007-02-27 23:05:52.000000000 +0100
+++ xpdf-3.03/xpdf/GlobalParams.h 2011-08-15 23:08:53.000000000 +0200
-@@ -35,9 +35,7 @@
- class CMapCache;
- struct XpdfSecurityHandler;
- class GlobalParams;
--#ifdef WIN32
--class WinFontList;
--#endif
-+class SysFontList;
-
- //------------------------------------------------------------------------
-
-@@ -46,51 +44,27 @@
-
- //------------------------------------------------------------------------
-
--enum DisplayFontParamKind {
-- displayFontT1,
-- displayFontTT
--};
--
--struct DisplayFontParamT1 {
-- GString *fileName;
--};
--
--struct DisplayFontParamTT {
-- GString *fileName;
--};
--
--class DisplayFontParam {
--public:
--
-- GString *name; // font name for 8-bit fonts and named
-- // CID fonts; collection name for
-- // generic CID fonts
-- DisplayFontParamKind kind;
-- union {
-- DisplayFontParamT1 t1;
-- DisplayFontParamTT tt;
-- };
--
-- DisplayFontParam(GString *nameA, DisplayFontParamKind kindA);
-- virtual ~DisplayFontParam();
-+enum SysFontType {
-+ sysFontPFA,
-+ sysFontPFB,
-+ sysFontTTF,
-+ sysFontTTC
- };
-
- //------------------------------------------------------------------------
-
--class PSFontParam {
-+class PSFontParam16 {
- public:
-
-- GString *pdfFontName; // PDF font name for 8-bit fonts and
-- // named 16-bit fonts; char collection
-- // name for generic 16-bit fonts
-- int wMode; // writing mode (0=horiz, 1=vert) for
-- // 16-bit fonts
-+ GString *name; // PDF font name for psResidentFont16;
-+ // char collection name for psResidentFontCC
-+ int wMode; // writing mode (0=horiz, 1=vert)
- GString *psFontName; // PostScript font name
-- GString *encoding; // encoding, for 16-bit fonts only
-+ GString *encoding; // encoding
-
-- PSFontParam(GString *pdfFontNameA, int wModeA,
-- GString *psFontNameA, GString *encodingA);
-- ~PSFontParam();
-+ PSFontParam16(GString *nameA, int wModeA,
-+ GString *psFontNameA, GString *encodingA);
-+ ~PSFontParam16();
- };
-
- //------------------------------------------------------------------------
-@@ -212,9 +191,11 @@
- UnicodeMap *getResidentUnicodeMap(GString *encodingName);
- FILE *getUnicodeMapFile(GString *encodingName);
- FILE *findCMapFile(GString *collection, GString *cMapName);
- FILE *findToUnicodeFile(GString *name);
-- DisplayFontParam *getDisplayFont(GString *fontName);
-- DisplayFontParam *getDisplayCIDFont(GString *fontName, GString *collection);
-+ GString *findFontFile(GString *fontName);
-+ GString *findSystemFontFile(GString *fontName, SysFontType *type,
-+ int *fontNum);
-+ GString *findCCFontFile(GString *collection);
- GString *getPSFile();
- int getPSPaperWidth();
- int getPSPaperHeight();
@@ -225,26 +206,34 @@
GBool getPSShrinkLarger();
GBool getPSCenter();
@@ -3526,45 +124,6 @@ diff -ru xpdf-3.02/xpdf/GlobalParams.h xpdf-3.03/xpdf/GlobalParams.h
GString *getURLCommand() { return urlCommand; }
GString *getMovieCommand() { return movieCommand; }
GBool getMapNumericCharNames();
-@@ -268,7 +261,7 @@
-
- //----- functions to set parameters
-
-- void addDisplayFont(DisplayFontParam *param);
-+ void addFontFile(GString *fontName, GString *path);
- void setPSFile(char *file);
- GBool setPSPaperSize(char *size);
- void setPSPaperWidth(int width);
-@@ -284,6 +277,7 @@
- void setPSEmbedTrueType(GBool embed);
- void setPSEmbedCIDPostScript(GBool embed);
- void setPSEmbedCIDTrueType(GBool embed);
-+ void setPSFontPassthrough(GBool passthrough);
- void setPSPreload(GBool preload);
- void setPSOPI(GBool opi);
- void setPSASCIIHex(GBool hex);
-@@ -380,15 +374,12 @@
- GHash *cMapDirs; // list of CMap dirs, indexed by collection
- // name [GList[GString]]
- GList *toUnicodeDirs; // list of ToUnicode CMap dirs [GString]
-- GHash *displayFonts; // display font info, indexed by font name
-- // [DisplayFontParam]
--#ifdef WIN32
-- WinFontList *winFontList; // system TrueType fonts
--#endif
-- GHash *displayCIDFonts; // display CID font info, indexed by
-- // collection [DisplayFontParam]
-- GHash *displayNamedCIDFonts; // display CID font info, indexed by
-- // font name [DisplayFontParam]
-+ GHash *fontFiles; // font files: font name mapped to path
-+ // [GString]
-+ GList *fontDirs; // list of font dirs [GString]
-+ GHash *ccFontFiles; // character collection font files:
-+ // collection name mapped to path [GString]
-+ SysFontList *sysFonts; // system fonts
- GString *psFile; // PostScript file or command (for xpdf)
- int psPaperWidth; // paper size, in PostScript points, for
- int psPaperHeight; // PostScript output
@@ -402,31 +393,44 @@
GBool psCenter; // center pages on the paper
GBool psDuplex; // enable duplexing in PostScript?
@@ -3616,31 +175,6 @@ diff -ru xpdf-3.02/xpdf/GlobalParams.h xpdf-3.03/xpdf/GlobalParams.h
int screenSize; // screen matrix size
Només a xpdf-3.03/xpdf: OptionalContent.cc
Només a xpdf-3.03/xpdf: OptionalContent.h
-diff -ru xpdf-3.02/xpdf/OutputDev.cc xpdf-3.03/xpdf/OutputDev.cc
---- xpdf-3.02/xpdf/OutputDev.cc 2007-02-27 23:05:52.000000000 +0100
-+++ xpdf-3.03/xpdf/OutputDev.cc 2011-08-15 23:08:53.000000000 +0200
-@@ -65,6 +65,7 @@
- updateStrokeOpacity(state);
- updateFillOverprint(state);
- updateStrokeOverprint(state);
-+ updateOverprintMode(state);
- updateTransfer(state);
- updateFont(state);
- }
-@@ -89,6 +90,13 @@
- }
- }
-
-+void OutputDev::setSoftMaskFromImageMask(GfxState *state,
-+ Object *ref, Stream *str,
-+ int width, int height, GBool invert,
-+ GBool inlineImg) {
-+ drawImageMask(state, ref, str, width, height, invert, inlineImg);
-+}
-+
- void OutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
- int width, int height, GfxImageColorMap *colorMap,
- int *maskColors, GBool inlineImg) {
diff -ru xpdf-3.02/xpdf/PDFDoc.cc xpdf-3.03/xpdf/PDFDoc.cc
--- xpdf-3.02/xpdf/PDFDoc.cc 2007-02-27 23:05:52.000000000 +0100
+++ xpdf-3.03/xpdf/PDFDoc.cc 2011-08-15 23:08:53.000000000 +0200
@@ -4350,75 +884,6 @@ diff -ru xpdf-3.02/xpdf/PSOutputDev.cc xpdf-3.03/xpdf/PSOutputDev.cc
"/pr { 2 index 2 index 3 2 roll putinterval 4 add } def",
"/pdfImClip {",
" gsave",
-@@ -607,7 +644,7 @@
- " func n array astore",
- "} def",
- "/axialSH {",
-- " dup 0 eq {",
-+ " dup 2 lt {",
- " true",
- " } {",
- " dup 8 eq {",
-@@ -753,25 +790,12 @@
- double mWidth; // width of 'm' character
- };
-
--static char *psFonts[] = {
-- "Courier",
-- "Courier-Bold",
-- "Courier-Oblique",
-- "Courier-BoldOblique",
-- "Helvetica",
-- "Helvetica-Bold",
-- "Helvetica-Oblique",
-- "Helvetica-BoldOblique",
-- "Symbol",
-- "Times-Roman",
-- "Times-Bold",
-- "Times-Italic",
-- "Times-BoldItalic",
-- "ZapfDingbats",
-- NULL
--};
--
--static PSSubstFont psSubstFonts[] = {
-+// NB: must be in same order as base14SubstFonts in GfxFont.cc
-+static PSSubstFont psBase14SubstFonts[14] = {
-+ {"Courier", 0.600},
-+ {"Courier-Oblique", 0.600},
-+ {"Courier-Bold", 0.600},
-+ {"Courier-BoldOblique", 0.600},
- {"Helvetica", 0.833},
- {"Helvetica-Oblique", 0.833},
- {"Helvetica-Bold", 0.889},
-@@ -780,22 +804,28 @@
- {"Times-Italic", 0.722},
- {"Times-Bold", 0.833},
- {"Times-BoldItalic", 0.778},
-- {"Courier", 0.600},
-- {"Courier-Oblique", 0.600},
-- {"Courier-Bold", 0.600},
-- {"Courier-BoldOblique", 0.600}
-+ // the last two are never used for substitution
-+ {"Symbol", 0},
-+ {"ZapfDingbats", 0}
-+};
-+
-+// Mapping from Type 1/1C font file to PS font name.
-+struct PST1FontName {
-+ Ref fontFileID;
-+ GString *psName; // PostScript font name used for this
-+ // embedded font file
- };
-
- // Encoding info for substitute 16-bit font
- struct PSFont16Enc {
- Ref fontID;
-- GString *enc;
-+ GString *enc; // NULL means font wasn't correctly substituted
- };
-
- //------------------------------------------------------------------------
@@ -845,6 +875,13 @@
};
@@ -4790,340 +1255,6 @@ diff -ru xpdf-3.02/xpdf/PSOutputDev.cc xpdf-3.03/xpdf/PSOutputDev.cc
}
void PSOutputDev::writePageTrailer() {
-@@ -1558,18 +1681,15 @@
- }
-
- void PSOutputDev::setupFont(GfxFont *font, Dict *parentResDict) {
-- Ref fontFileID;
-- GString *name;
-- PSFontParam *fontParam;
-+ GfxFontLoc *fontLoc;
- GString *psName;
-- char buf[16];
- GBool subst;
-+ char buf[16];
- UnicodeMap *uMap;
- char *charName;
- double xs, ys;
- int code;
- double w1, w2;
-- double *fm;
- int i, j;
-
- // check if font is already set up
-@@ -1587,119 +1707,120 @@
- }
- fontIDs[fontIDLen++] = *font->getID();
-
-+ psName = NULL;
- xs = ys = 1;
- subst = gFalse;
-
-- // check for resident 8-bit font
-- if (font->getName() &&
-- (fontParam = globalParams->getPSFont(font->getName()))) {
-- psName = new GString(fontParam->psFontName->getCString());
--
-- // check for embedded Type 1 font
-- } else if (globalParams->getPSEmbedType1() &&
-- font->getType() == fontType1 &&
-- font->getEmbeddedFontID(&fontFileID)) {
-- psName = filterPSName(font->getEmbeddedFontName());
-- setupEmbeddedType1Font(&fontFileID, psName);
--
-- // check for embedded Type 1C font
-- } else if (globalParams->getPSEmbedType1() &&
-- font->getType() == fontType1C &&
-- font->getEmbeddedFontID(&fontFileID)) {
-- // use the PDF font name because the embedded font name might
-- // not include the subset prefix
-- psName = filterPSName(font->getOrigName());
-- setupEmbeddedType1CFont(font, &fontFileID, psName);
--
-- // check for embedded OpenType - Type 1C font
-- } else if (globalParams->getPSEmbedType1() &&
-- font->getType() == fontType1COT &&
-- font->getEmbeddedFontID(&fontFileID)) {
-- // use the PDF font name because the embedded font name might
-- // not include the subset prefix
-- psName = filterPSName(font->getOrigName());
-- setupEmbeddedOpenTypeT1CFont(font, &fontFileID, psName);
--
-- // check for external Type 1 font file
-- } else if (globalParams->getPSEmbedType1() &&
-- font->getType() == fontType1 &&
-- font->getExtFontFile()) {
-- // this assumes that the PS font name matches the PDF font name
-- psName = font->getName()->copy();
-- setupExternalType1Font(font->getExtFontFile(), psName);
--
-- // check for embedded TrueType font
-- } else if (globalParams->getPSEmbedTrueType() &&
-- (font->getType() == fontTrueType ||
-- font->getType() == fontTrueTypeOT) &&
-- font->getEmbeddedFontID(&fontFileID)) {
-- psName = filterPSName(font->getEmbeddedFontName());
-- setupEmbeddedTrueTypeFont(font, &fontFileID, psName);
--
-- // check for external TrueType font file
-- } else if (globalParams->getPSEmbedTrueType() &&
-- font->getType() == fontTrueType &&
-- font->getExtFontFile()) {
-- psName = filterPSName(font->getName());
-- setupExternalTrueTypeFont(font, psName);
--
-- // check for embedded CID PostScript font
-- } else if (globalParams->getPSEmbedCIDPostScript() &&
-- font->getType() == fontCIDType0C &&
-- font->getEmbeddedFontID(&fontFileID)) {
-- psName = filterPSName(font->getEmbeddedFontName());
-- setupEmbeddedCIDType0Font(font, &fontFileID, psName);
--
-- // check for embedded CID TrueType font
-- } else if (globalParams->getPSEmbedCIDTrueType() &&
-- (font->getType() == fontCIDType2 ||
-- font->getType() == fontCIDType2OT) &&
-- font->getEmbeddedFontID(&fontFileID)) {
-- psName = filterPSName(font->getEmbeddedFontName());
-- //~ should check to see if font actually uses vertical mode
-- setupEmbeddedCIDTrueTypeFont(font, &fontFileID, psName, gTrue);
--
-- // check for embedded OpenType - CID CFF font
-- } else if (globalParams->getPSEmbedCIDPostScript() &&
-- font->getType() == fontCIDType0COT &&
-- font->getEmbeddedFontID(&fontFileID)) {
-- psName = filterPSName(font->getEmbeddedFontName());
-- setupEmbeddedOpenTypeCFFFont(font, &fontFileID, psName);
--
-- // check for Type 3 font
-- } else if (font->getType() == fontType3) {
-+ if (font->getType() == fontType3) {
- psName = GString::format("T3_{0:d}_{1:d}",
- font->getID()->num, font->getID()->gen);
- setupType3Font(font, psName, parentResDict);
--
-- // do 8-bit font substitution
-- } else if (!font->isCIDFont()) {
-- subst = gTrue;
-- name = font->getName();
-- psName = NULL;
-- if (name) {
-- for (i = 0; psFonts[i]; ++i) {
-- if (name->cmp(psFonts[i]) == 0) {
-- psName = new GString(psFonts[i]);
-- break;
-+ } else {
-+ fontLoc = font->locateFont(xref, gTrue);
-+ switch (fontLoc->locType) {
-+ case gfxFontLocEmbedded:
-+ switch (fontLoc->fontType) {
-+ case fontType1:
-+ // this assumes that the PS font name matches the PDF font name
-+ psName = font->getEmbeddedFontName()->copy();
-+ setupEmbeddedType1Font(&fontLoc->embFontID, psName);
-+ break;
-+ case fontType1C:
-+ psName = makePSFontName(font, &fontLoc->embFontID);
-+ setupEmbeddedType1CFont(font, &fontLoc->embFontID, psName);
-+ break;
-+ case fontType1COT:
-+ psName = makePSFontName(font, &fontLoc->embFontID);
-+ setupEmbeddedOpenTypeT1CFont(font, &fontLoc->embFontID, psName);
-+ break;
-+ case fontTrueType:
-+ case fontTrueTypeOT:
-+ psName = makePSFontName(font, font->getID());
-+ setupEmbeddedTrueTypeFont(font, &fontLoc->embFontID, psName);
-+ break;
-+ case fontCIDType0C:
-+ psName = makePSFontName(font, &fontLoc->embFontID);
-+ setupEmbeddedCIDType0Font(font, &fontLoc->embFontID, psName);
-+ break;
-+ case fontCIDType2:
-+ case fontCIDType2OT:
-+ psName = makePSFontName(font, font->getID());
-+ //~ should check to see if font actually uses vertical mode
-+ setupEmbeddedCIDTrueTypeFont(font, &fontLoc->embFontID, psName, gTrue);
-+ break;
-+ case fontCIDType0COT:
-+ psName = makePSFontName(font, &fontLoc->embFontID);
-+ setupEmbeddedOpenTypeCFFFont(font, &fontLoc->embFontID, psName);
-+ break;
-+ default:
-+ break;
-+ }
-+ break;
-+ case gfxFontLocExternal:
-+ //~ add cases for external 16-bit fonts
-+ switch (fontLoc->fontType) {
-+ case fontType1:
-+ if (font->getName()) {
-+ // this assumes that the PS font name matches the PDF font name
-+ psName = font->getName()->copy();
-+ } else {
-+ //~ this won't work -- the PS font name won't match
-+ psName = makePSFontName(font, font->getID());
- }
-+ setupExternalType1Font(fontLoc->path, psName);
-+ break;
-+ case fontTrueType:
-+ case fontTrueTypeOT:
-+ psName = makePSFontName(font, font->getID());
-+ setupExternalTrueTypeFont(font, fontLoc->path, psName);
-+ break;
-+ case fontCIDType2:
-+ case fontCIDType2OT:
-+ psName = makePSFontName(font, font->getID());
-+ //~ should check to see if font actually uses vertical mode
-+ setupExternalCIDTrueTypeFont(font, fontLoc->path, psName, gTrue);
-+ break;
-+ default:
-+ break;
- }
-+ break;
-+ case gfxFontLocResident:
-+ psName = fontLoc->path->copy();
-+ break;
- }
-+
- if (!psName) {
-- if (font->isFixedWidth()) {
-- i = 8;
-- } else if (font->isSerif()) {
-- i = 4;
-+ if (font->isCIDFont()) {
-+ error(errSyntaxError, -1,
-+ "Couldn't find a font to substitute for '{0:s}' ('{1:s}' character collection)",
-+ font->getName() ? font->getName()->getCString()
-+ : "(unnamed)",
-+ ((GfxCIDFont *)font)->getCollection()
-+ ? ((GfxCIDFont *)font)->getCollection()->getCString()
-+ : "(unknown)");
-+ if (font16EncLen >= font16EncSize) {
-+ font16EncSize += 16;
-+ font16Enc = (PSFont16Enc *)greallocn(font16Enc,
-+ font16EncSize,
-+ sizeof(PSFont16Enc));
-+ }
-+ font16Enc[font16EncLen].fontID = *font->getID();
-+ font16Enc[font16EncLen].enc = NULL;
-+ ++font16EncLen;
- } else {
-- i = 0;
-- }
-- if (font->isBold()) {
-- i += 2;
-- }
-- if (font->isItalic()) {
-- i += 1;
-+ error(errSyntaxError, -1,
-+ "Couldn't find a font to substitute for '{0:s}'",
-+ font->getName() ? font->getName()->getCString()
-+ : "(unnamed)");
- }
-- psName = new GString(psSubstFonts[i].psName);
-+ delete fontLoc;
-+ return;
-+ }
-+
-+ // scale substituted 8-bit fonts
-+ if (fontLoc->locType == gfxFontLocResident &&
-+ fontLoc->substIdx >= 0) {
-+ subst = gTrue;
- for (code = 0; code < 256; ++code) {
- if ((charName = ((Gfx8BitFont *)font)->getCharName(code)) &&
- charName[0] == 'm' && charName[1] == '\0') {
-@@ -1711,56 +1832,37 @@
- } else {
- w1 = 0;
- }
-- w2 = psSubstFonts[i].mWidth;
-+ w2 = psBase14SubstFonts[fontLoc->substIdx].mWidth;
- xs = w1 / w2;
- if (xs < 0.1) {
- xs = 1;
- }
-- if (font->getType() == fontType3) {
-- // This is a hack which makes it possible to substitute for some
-- // Type 3 fonts. The problem is that it's impossible to know what
-- // the base coordinate system used in the font is without actually
-- // rendering the font.
-- ys = xs;
-- fm = font->getFontMatrix();
-- if (fm[0] != 0) {
-- ys *= fm[3] / fm[0];
-- }
-- } else {
-- ys = 1;
-- }
- }
-
-- // do 16-bit font substitution
-- } else if ((fontParam = globalParams->
-- getPSFont16(font->getName(),
-- ((GfxCIDFont *)font)->getCollection(),
-- font->getWMode()))) {
-- subst = gTrue;
-- psName = fontParam->psFontName->copy();
-- if (font16EncLen >= font16EncSize) {
-- font16EncSize += 16;
-- font16Enc = (PSFont16Enc *)greallocn(font16Enc,
-- font16EncSize, sizeof(PSFont16Enc));
-- }
-- font16Enc[font16EncLen].fontID = *font->getID();
-- font16Enc[font16EncLen].enc = fontParam->encoding->copy();
-- if ((uMap = globalParams->getUnicodeMap(font16Enc[font16EncLen].enc))) {
-- uMap->decRefCnt();
-+ // handle encodings for substituted CID fonts
-+ if (fontLoc->locType == gfxFontLocResident &&
-+ fontLoc->fontType >= fontCIDType0) {
-+ subst = gTrue;
-+ if (font16EncLen >= font16EncSize) {
-+ font16EncSize += 16;
-+ font16Enc = (PSFont16Enc *)greallocn(font16Enc,
-+ font16EncSize,
-+ sizeof(PSFont16Enc));
-+ }
-+ font16Enc[font16EncLen].fontID = *font->getID();
-+ if ((uMap = globalParams->getUnicodeMap(fontLoc->encoding))) {
-+ font16Enc[font16EncLen].enc = fontLoc->encoding->copy();
-+ uMap->decRefCnt();
-+ } else {
-+ error(errSyntaxError, -1,
-+ "Couldn't find Unicode map for 16-bit font encoding '{0:t}'",
-+ fontLoc->encoding);
-+ font16Enc[font16EncLen].enc = NULL;
-+ }
- ++font16EncLen;
-- } else {
-- error(-1, "Couldn't find Unicode map for 16-bit font encoding '%s'",
-- font16Enc[font16EncLen].enc->getCString());
- }
-
-- // give up - can't do anything with this font
-- } else {
-- error(-1, "Couldn't find a font to substitute for '%s' ('%s' character collection)",
-- font->getName() ? font->getName()->getCString() : "(unnamed)",
-- ((GfxCIDFont *)font)->getCollection()
-- ? ((GfxCIDFont *)font)->getCollection()->getCString()
-- : "(unknown)");
-- return;
-+ delete fontLoc;
- }
-
- // generate PostScript code to set up the font
-@@ -1787,11 +1889,6 @@
- charName = buf;
- } else {
- charName = ((Gfx8BitFont *)font)->getCharName(i+j);
-- // this is a kludge for broken PDF files that encode char 32
-- // as .notdef
-- if (i+j == 32 && charName && !strcmp(charName, ".notdef")) {
-- charName = "space";
-- }
- }
- writePS("/");
- writePSName(charName ? charName : (char *)".notdef");
@@ -1821,36 +1918,30 @@
int i;