diff -aur poppler-0.6.2/poppler/Gfx.cc poppler-0.6.2-new/poppler/Gfx.cc --- poppler-0.6.2/poppler/Gfx.cc 2007-11-04 18:11:04.000000000 -0500 +++ poppler-0.6.2-new/poppler/Gfx.cc 2007-11-21 13:42:27.000000000 -0500 @@ -441,7 +441,8 @@ double hDPI, double vDPI, PDFRectangle *box, PDFRectangle *cropBox, int rotate, GBool (*abortCheckCbkA)(void *data), - void *abortCheckCbkDataA) { + void *abortCheckCbkDataA, + GooString *pageLabel) { int i; xref = xrefA; @@ -458,7 +459,7 @@ fontChanged = gFalse; clip = clipNone; ignoreUndef = 0; - out->startPage(pageNum, state); + out->startPage(pageNum, state, pageLabel); out->setDefaultCTM(state->getCTM()); out->updateAll(state); for (i = 0; i < 6; ++i) { diff -aur poppler-0.6.2/poppler/Gfx.h poppler-0.6.2-new/poppler/Gfx.h --- poppler-0.6.2/poppler/Gfx.h 2007-11-04 18:11:04.000000000 -0500 +++ poppler-0.6.2-new/poppler/Gfx.h 2007-11-21 15:47:34.000000000 -0500 @@ -113,7 +113,8 @@ double hDPI, double vDPI, PDFRectangle *box, PDFRectangle *cropBox, int rotate, GBool (*abortCheckCbkA)(void *data) = NULL, - void *abortCheckCbkDataA = NULL); + void *abortCheckCbkDataA = NULL, + GooString *pageLabel = NULL); // Constructor for a sub-page object. Gfx(XRef *xrefA, OutputDev *outA, Dict *resDict, diff -aur poppler-0.6.2/poppler/OutputDev.h poppler-0.6.2-new/poppler/OutputDev.h --- poppler-0.6.2/poppler/OutputDev.h 2007-11-04 18:11:04.000000000 -0500 +++ poppler-0.6.2-new/poppler/OutputDev.h 2007-11-21 13:43:39.000000000 -0500 @@ -96,6 +96,9 @@ // Start a page. virtual void startPage(int pageNum, GfxState *state) {} + virtual void startPage(int pageNum, GfxState *state, GooString *pageLabel) { + startPage(pageNum, state); + } // End a page. virtual void endPage() {} diff -aur poppler-0.6.2/poppler/PSOutputDev.cc poppler-0.6.2-new/poppler/PSOutputDev.cc --- poppler-0.6.2/poppler/PSOutputDev.cc 2007-11-04 18:11:04.000000000 -0500 +++ poppler-0.6.2-new/poppler/PSOutputDev.cc 2007-11-21 17:27:20.000000000 -0500 @@ -3062,13 +3062,23 @@ } void PSOutputDev::startPage(int pageNum, GfxState *state) { + startPage(pageNum, state, NULL); +} + +void PSOutputDev::startPage(int pageNum, GfxState *state, GooString *pageLabel) { int x1, y1, x2, y2, width, height; int imgWidth, imgHeight, imgWidth2, imgHeight2; GBool landscape; if (mode == psModePS) { - writePSFmt("%%Page: {0:d} {1:d}\n", pageNum, seqPage); + writePS("%%Page: "); + if (pageLabel) { + writePSText(pageLabel); + } else { + writePSFmt("{0:d}", pageNum); + } + writePSFmt(" {0:d}\n", seqPage); writePS("%%BeginPageSetup\n"); } @@ -6318,6 +6328,12 @@ // Write a DSC-compliant . void PSOutputDev::writePSTextLine(GooString *s) { + writePSText(s, false /*parens*/); + writePS("\n"); +} + +// Write a DSC-compliant . +void PSOutputDev::writePSText(GooString *s, bool parens) { int i, j, step; int c; @@ -6325,9 +6341,9 @@ // backslashes have to be escaped (we do cheap Unicode-to-ASCII // conversion by simply ignoring the high byte) // - lines are limited to 255 chars (we limit to 200 here to allow - // for the keyword, which was emitted by the caller) - // - lines that start with a left paren are treated as - // instead of , so we escape a leading paren + // for other material on the same line, emitted by the caller) + // - we also escape all parentheses, in order to be correct for + // both writePSTextLine and writePSText if (s->getLength() >= 2 && (s->getChar(0) & 0xff) == 0xfe && (s->getChar(1) & 0xff) == 0xff) { @@ -6337,18 +6353,43 @@ i = 0; step = 1; } + if (parens) { + // Omit parentheses if the string is comprised of one or more + // alphanumeric characters. + if (i < s->getLength()) { + for (int k = i; k < s->getLength(); k += step) { + c = s->getChar(i) & 0xff; + if (!(c >= '0' && c <= '9' || + c >= 'A' && c <= 'Z' || + c >= 'a' && c <= 'z')) + goto parens; + } + parens = false; + goto no_parens; + } +parens: + writePSChar('('); + } +no_parens: for (j = 0; i < s->getLength() && j < 200; i += step) { - c = s->getChar(i) & 0xff; - if (c == '\\') { + switch (c = s->getChar(i) & 0xff) { + case '\\': writePS("\\\\"); j += 2; - } else if (c < 0x20 || c > 0x7e || (j == 0 && c == '(')) { - writePSFmt("\\{0:03o}", c); - j += 4; - } else { - writePSChar(c); - ++j; + break; + default: + if (c < 0x20 || c > 0x7e) { + case '(': + case ')': + writePSFmt("\\{0:03o}", c); + j += 4; + break; + } else { + writePSChar(c); + ++j; + } } } - writePS("\n"); + if (parens) + writePSChar(')'); } diff -aur poppler-0.6.2/poppler/PSOutputDev.h poppler-0.6.2-new/poppler/PSOutputDev.h --- poppler-0.6.2/poppler/PSOutputDev.h 2007-11-04 18:11:04.000000000 -0500 +++ poppler-0.6.2-new/poppler/PSOutputDev.h 2007-11-21 17:14:04.000000000 -0500 @@ -142,6 +142,7 @@ // Start a page. virtual void startPage(int pageNum, GfxState *state); + virtual void startPage(int pageNum, GfxState *state, GooString *pageLabel); // End a page. virtual void endPage(); @@ -312,6 +313,7 @@ void writePSName(char *s); GooString *filterPSName(GooString *name); void writePSTextLine(GooString *s); + void writePSText(GooString *s, bool parens = true); PSLevel level; // PostScript level (1, 2, separation) PSOutMode mode; // PostScript mode (PS, EPS, form) diff -aur poppler-0.6.2/poppler/Page.cc poppler-0.6.2-new/poppler/Page.cc --- poppler-0.6.2/poppler/Page.cc 2007-11-04 18:11:04.000000000 -0500 +++ poppler-0.6.2-new/poppler/Page.cc 2007-11-21 17:10:19.000000000 -0500 @@ -366,9 +366,22 @@ printf("***** Rotate = %d\n", attrs->getRotate()); } + // Get our page label, if any, from the catalog. + GooString pageLabel; + const GBool gotLabel = catalog->indexToLabel(num - 1, &pageLabel); + // If the label is in UCS-2, remove any extra null at the end. + if (gotLabel && + pageLabel.getLength() >= 4 && + pageLabel.getLength() % 2 == 0 && + pageLabel.hasUnicodeMarker() && + !pageLabel.getChar(pageLabel.getLength() - 2) && + !pageLabel.getChar(pageLabel.getLength() - 1)) + pageLabel.del(pageLabel.getLength() - 2, 2); + gfx = new Gfx(xref, out, num, attrs->getResourceDict(), hDPI, vDPI, &box, crop ? cropBox : (PDFRectangle *)NULL, - rotate, abortCheckCbk, abortCheckCbkData); + rotate, abortCheckCbk, abortCheckCbkData, + gotLabel ? &pageLabel : NULL); return gfx; }