[poppler] 2 commits - poppler/PSOutputDev.cc poppler/PSOutputDev.h

Brad Hards bradh at kemper.freedesktop.org
Tue Dec 4 00:15:05 PST 2007


 poppler/PSOutputDev.cc |   81 ++++++++++++++++++++++++++++++++++++++++++++++++-
 poppler/PSOutputDev.h  |    2 +
 2 files changed, 82 insertions(+), 1 deletion(-)

New commits:
commit b925ea232b6ed5028712600f9aebe453f3b2ba06
Author: Brad Hards <bradh at kde.org>
Date:   Tue Dec 4 19:11:13 2007 +1100

    Remove redundant check.

diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 1b6c47e..ec65599 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -6381,7 +6381,7 @@ GooString* PSOutputDev::filterPSLabel(GooString *label, GBool *needParens) {
       label2->append("\\)");
     } else if (c == '(') {
       label2->append("\\(");
-    } else if (c < 0x20 || c > 0x7e || (j == 0 && c == '(')) {
+    } else if (c < 0x20 || c > 0x7e) {
       label2->append(GooString::format("\\{0:03o}", c));
       j += 4;
     } else {
commit 275afca4ef24020273df652ccfdf76c6994e9294
Author: Brad Hards <bradh at kde.org>
Date:   Sun Dec 2 19:45:16 2007 +1100

    Preserve PDF page labels when we output as postscript.
    
    Resolves bug 13338.

diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 7252d99..1b6c47e 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -1056,6 +1056,7 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
   outputFunc = outputFuncA;
   outputStream = outputStreamA;
   fileType = fileTypeA;
+  m_catalog = catalog;
   xref = xrefA;
   level = globalParams->getPSLevel();
   mode = modeA;
@@ -3068,7 +3069,20 @@ void PSOutputDev::startPage(int pageNum, GfxState *state) {
 
 
   if (mode == psModePS) {
-    writePSFmt("%%Page: {0:d} {1:d}\n", pageNum, seqPage);
+    GooString pageLabel;
+    const GBool gotLabel = m_catalog->indexToLabel(pageNum -1, &pageLabel);
+    if (gotLabel) {
+      // See bug13338 for why we try to avoid parentheses...
+      GBool needParens;
+      GooString *filteredString = filterPSLabel(&pageLabel, &needParens);
+      if (needParens) {
+	writePSFmt("%%Page: ({0:t}) {1:d}\n", filteredString, seqPage);
+      } else {
+	writePSFmt("%%Page: {0:t} {1:d}\n", filteredString, seqPage);
+      }
+    } else {
+      writePSFmt("%%Page: {0:d} {1:d}\n", pageNum, seqPage);
+    }
     writePS("%%BeginPageSetup\n");
   }
 
@@ -6316,6 +6330,71 @@ GooString *PSOutputDev::filterPSName(GooString *name) {
   return name2;
 }
 
+// Convert GooString to GooString, with appropriate escaping
+// of things that can't appear in a label
+// This is heavily based on the writePSTextLine() method
+GooString* PSOutputDev::filterPSLabel(GooString *label, GBool *needParens) {
+  int i, step;
+  GBool isNumeric;
+
+  // - DSC comments must be printable ASCII; control chars and
+  //   backslashes have to be escaped (we do cheap UCS2-to-ASCII
+  //   conversion by simply ignoring the high byte)
+  // - parentheses are escaped. this isn't strictly necessary for matched
+  //   parentheses, but shouldn't be a problem
+  // - lines are limited to 255 chars (we limit to 200 here to allow
+  //   for the keyword, which was emitted by the caller)
+
+  GooString *label2 = new GooString();
+  int labelLength = label->getLength();
+
+  if (labelLength == 0) {
+    isNumeric = false;
+  } else {
+    // this gets changed later if we find a non-numeric character
+    isNumeric = true;
+  }
+
+  if ( (labelLength >= 2) &&
+       ( (label->getChar(0) & 0xff) == 0xfe) &&
+       ( (label->getChar(1) & 0xff) == 0xff) ) {
+    // UCS2 mode
+    i = 3;
+    step = 2;
+    if ( (label->getChar(labelLength-1) == 0) ) {
+      // prune the trailing null (0x000 for UCS2)
+      labelLength -= 2;
+    }
+  } else {
+    i = 0;
+    step = 1;
+  }
+  for (int j = 0; i < labelLength && j < 200; i += step) {
+    char c = label->getChar(i);
+    if ( (c < '0') || (c > '9') ) {
+      isNumeric = false;
+    }
+    if (c == '\\') {
+      label2->append("\\\\");
+      j += 2;
+    } else if (c == ')') {
+      label2->append("\\)");
+    } else if (c == '(') {
+      label2->append("\\(");
+    } else if (c < 0x20 || c > 0x7e || (j == 0 && c == '(')) {
+      label2->append(GooString::format("\\{0:03o}", c));
+      j += 4;
+    } else {
+      label2->append(c);
+      ++j;
+    }
+  }
+  if (needParens) {
+    *needParens = !(isNumeric);
+  }
+  return label2;
+}
+
 // Write a DSC-compliant <textline>.
 void PSOutputDev::writePSTextLine(GooString *s) {
   int i, j, step;
diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h
index a245d85..06b633e 100644
--- a/poppler/PSOutputDev.h
+++ b/poppler/PSOutputDev.h
@@ -311,6 +311,7 @@ private:
   void writePSString(GooString *s);
   void writePSName(char *s);
   GooString *filterPSName(GooString *name);
+  GooString *filterPSLabel(GooString *label, GBool *needParens=0);
   void writePSTextLine(GooString *s);
 
   PSLevel level;		// PostScript level (1, 2, separation)
@@ -333,6 +334,7 @@ private:
   void *overlayCbkData;
 
   XRef *xref;			// the xref table for this PDF file
+  Catalog *m_catalog;           // the catalog for this PDF file
 
   Ref *fontIDs;			// list of object IDs of all used fonts
   int fontIDLen;		// number of entries in fontIDs array


More information about the poppler mailing list