Hello,

I went through the xpdf changes that were done in cups and tried to port them 
to poppler.

poppler-0.5.4_psheader_fix.patch seems to be necessary to get a valid 
postscript header.

poppler-0.5.4_renderHiddenAnnotations.patch adds a new function to OutputDev.h
that can be overwritten to disable rendering of hidden annotations.
I did not find a pdf to test, therefore this hunk is untested.

poppler-0.5.4_renderPage.patch adds the function renderPage to OutputDev. It 
will be called by Gfx.cc for every page to check if the selected page should 
be printed. With this patch it is possible to render only a subset of the 
available pages.

Please review.

Regards

Sascha Sommer
diff -Naur poppler-0.5.4.org/poppler/Gfx.cc poppler-0.5.4/poppler/Gfx.cc
--- poppler-0.5.4.org/poppler/Gfx.cc	2006-10-09 09:40:58.000000000 +0200
+++ poppler-0.5.4/poppler/Gfx.cc	2006-10-09 09:41:17.000000000 +0200
@@ -3318,18 +3318,36 @@
 void Gfx::doAnnot(Object *str, double xMin, double yMin,
 		  double xMax, double yMax) {
   Dict *dict, *resDict;
-  Object matrixObj, bboxObj, resObj;
+  Object matrixObj, bboxObj, resObj, flagsObj;;
   Object obj1;
   double m[6], bbox[6], ictm[6];
   double *ctm;
   double formX0, formY0, formX1, formY1;
   double annotX0, annotY0, annotX1, annotY1;
   double det, x, y, sx, sy;
-  int i;
+  int i, flags;
 
   // get stream dict
   dict = str->streamGetDict();
 
+  // get annotation flags and only print annotations that are hidden or
+  // don't have the print bit set.
+  dict->lookup("F", &flagsObj);
+  if (flagsObj.isInt()) {
+    flags = flagsObj.getInt();
+  } else {
+    // Print anything that doesn't have any flags set...
+    flags = 4;
+  }
+  flagsObj.free();
+
+//  fprintf(stderr, "DEBUG: doAnnot found annotation with flags = %x\n",flags);
+
+  if (!out->renderHiddenAnnotations() && ((flags & 2) == 2 || (flags & 4) == 0)) {
+    // Don't print hidden or no-print annotations...
+    return;
+  }
+
   // get the form bounding box
   dict->lookup("BBox", &bboxObj);
   if (!bboxObj.isArray()) {
diff -Naur poppler-0.5.4.org/poppler/OutputDev.h poppler-0.5.4/poppler/OutputDev.h
--- poppler-0.5.4.org/poppler/OutputDev.h	2006-10-09 09:40:58.000000000 +0200
+++ poppler-0.5.4/poppler/OutputDev.h	2006-10-09 09:41:17.000000000 +0200
@@ -76,6 +76,7 @@
 
   // Should the page be rendered
   virtual GBool renderPage(int /*pageNum*/) { return gTrue; }
+  virtual GBool renderHiddenAnnotations() { return gTrue; }
 
   // Start a page.
   virtual void startPage(int /*pageNum*/, GfxState * /*state*/) {}
diff -Naur poppler-0.5.4.org/poppler/PSOutputDev.cc poppler-0.5.4/poppler/PSOutputDev.cc
--- poppler-0.5.4.org/poppler/PSOutputDev.cc	2006-10-09 09:42:58.000000000 +0200
+++ poppler-0.5.4/poppler/PSOutputDev.cc	2006-10-09 09:43:11.000000000 +0200
@@ -34,6 +34,7 @@
 #include "Page.h"
 #include "Stream.h"
 #include "Annot.h"
+#include "XRef.h"
 #include "PSOutputDev.h"
 #include "UGooString.h"
 
@@ -1153,20 +1154,119 @@
 void PSOutputDev::writeHeader(int firstPage, int lastPage,
 			      PDFRectangle *mediaBox, PDFRectangle *cropBox,
 			      int pageRotate) {
+  Object info, obj1;
   double x1, y1, x2, y2;
+  GooString *s;
+  int i;
 
   switch (mode) {
   case psModePS:
     writePS("%!PS-Adobe-3.0\n");
-    writePSFmt("%%%%Creator: xpdf/pdftops %s\n", xpdfVersion);
-    writePSFmt("%%%%LanguageLevel: %d\n",
-	       (level == psLevel1 || level == psLevel1Sep) ? 1 :
-	       (level == psLevel2 || level == psLevel2Sep) ? 2 : 3);
-    if (level == psLevel1Sep || level == psLevel2Sep || level == psLevel3Sep) {
-      writePS("%%DocumentProcessColors: (atend)\n");
-      writePS("%%DocumentCustomColors: (atend)\n");
+    break;
+  case psModeEPS:
+    writePS("%!PS-Adobe-3.0 EPSF-3.0\n");
+    break;
+  case psModeForm:
+    writePS("%!PS-Adobe-3.0 Resource-Form\n");
+    break;
+  }    
+  writePSFmt("%%Producer: xpdf/pdftops %s\n", xpdfVersion);
+  xref->getDocInfo(&info);
+  if (info.dictLookup("Creator", &obj1)->isString()) {
+    writePS("%%Creator: ");
+    s = obj1.getString();
+    if ((s->getChar(0) & 0xff) == 0xfe &&
+	(s->getChar(1) & 0xff) == 0xff) {
+      // Convert UTF-16 to UTF-8...
+      for (i = 2; i < s->getLength() && i < 400; i += 2) {
+	int ch = ((s->getChar(i) & 255) << 8) | (s->getChar(i + 1) & 255);
+
+        if (ch >= 0xd800 && ch <= 0xdbff) {
+	  // Multi-word UTF-16 char...
+	  i += 2;
+	  int lch = ((s->getChar(i) & 255) << 8) | (s->getChar(i + 1) & 255);
+
+          if (lch < 0xdc00 || lch >= 0xdfff) continue;
+
+          ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000;
+	}
+
+	if (ch < 0x80)
+	{
+	 /*
+	  * Single byte ASCII...
+	  */
+
+	  writePSChar(ch);
+	}
+	else if (ch < 0x800)
+	{
+	 /*
+	  * Two-byte UTF-8...
+	  */
+
+	  writePSChar(0xc0 | (ch >> 6));
+	  writePSChar(0x80 | (ch & 0x3f));
+	}
+	else if (ch < 0x10000)
+	{
+	 /*
+	  * Three-byte UTF-8...
+	  */
+
+	  writePSChar(0xe0 | (ch >> 12));
+	  writePSChar(0x80 | ((ch >> 6) & 0x3f));
+	  writePSChar(0x80 | (ch & 0x3f));
+	}
+	else
+	{
+	 /*
+	  * Four-byte UTF-8...
+	  */
+
+	  writePSChar(0xf0 | (ch >> 18));
+	  writePSChar(0x80 | ((ch >> 12) & 0x3f));
+	  writePSChar(0x80 | ((ch >> 6) & 0x3f));
+	  writePSChar(0x80 | (ch & 0x3f));
+	}
+      }
+    } else {
+      for (i = 0; i < s->getLength() && i < 200; ++i) {
+	writePSChar(s->getChar(i));
+      }
+    }
+    writePS("\n");
+  }
+  obj1.free();
+  if (info.dictLookup("Title", &obj1)->isString()) {
+    writePS("%%Title: ");
+    s = obj1.getString();
+    if ((s->getChar(0) & 0xff) == 0xfe &&
+	(s->getChar(1) & 0xff) == 0xff) {
+      // cheap Unicode-to-ASCII conversion
+      for (i = 3; i < s->getLength() && i < 400; i += 2) {
+	writePSChar(s->getChar(i));
+      }
+    } else {
+      for (i = 0; i < s->getLength() && i < 200; ++i) {
+	writePSChar(s->getChar(i));
+      }
     }
-    writePS("%%DocumentSuppliedResources: (atend)\n");
+    writePS("\n");
+  }
+  obj1.free();
+  info.free();
+  writePSFmt("%%%%LanguageLevel: %d\n",
+	     (level == psLevel1 || level == psLevel1Sep) ? 1 :
+	     (level == psLevel2 || level == psLevel2Sep) ? 2 : 3);
+  if (level == psLevel1Sep || level == psLevel2Sep || level == psLevel3Sep) {
+    writePS("%%DocumentProcessColors: (atend)\n");
+    writePS("%%DocumentCustomColors: (atend)\n");
+  }
+  writePS("%%DocumentSuppliedResources: (atend)\n");
+
+  switch (mode) {
+  case psModePS:
     writePSFmt("%%%%DocumentMedia: plain %d %d 0 () ()\n",
 	       paperWidth, paperHeight);
     writePSFmt("%%%%BoundingBox: 0 0 %d %d\n", paperWidth, paperHeight);
@@ -1177,15 +1277,6 @@
     writePS("%%EndDefaults\n");
     break;
   case psModeEPS:
-    writePS("%!PS-Adobe-3.0 EPSF-3.0\n");
-    writePSFmt("%%%%Creator: xpdf/pdftops %s\n", xpdfVersion);
-    writePSFmt("%%%%LanguageLevel: %d\n",
-	       (level == psLevel1 || level == psLevel1Sep) ? 1 :
-	       (level == psLevel2 || level == psLevel2Sep) ? 2 : 3);
-    if (level == psLevel1Sep || level == psLevel2Sep || level == psLevel3Sep) {
-      writePS("%%DocumentProcessColors: (atend)\n");
-      writePS("%%DocumentCustomColors: (atend)\n");
-    }
     epsX1 = cropBox->x1;
     epsY1 = cropBox->y1;
     epsX2 = cropBox->x2;
@@ -1207,20 +1298,9 @@
 	floor(x2) != ceil(x2) || floor(y2) != ceil(y2)) {
       writePSFmt("%%%%HiResBoundingBox: %g %g %g %g\n", x1, y1, x2, y2);
     }
-    writePS("%%DocumentSuppliedResources: (atend)\n");
     writePS("%%EndComments\n");
     break;
   case psModeForm:
-    writePS("%!PS-Adobe-3.0 Resource-Form\n");
-    writePSFmt("%%%%Creator: xpdf/pdftops %s\n", xpdfVersion);
-    writePSFmt("%%%%LanguageLevel: %d\n",
-	       (level == psLevel1 || level == psLevel1Sep) ? 1 :
-	       (level == psLevel2 || level == psLevel2Sep) ? 2 : 3);
-    if (level == psLevel1Sep || level == psLevel2Sep || level == psLevel3Sep) {
-      writePS("%%DocumentProcessColors: (atend)\n");
-      writePS("%%DocumentCustomColors: (atend)\n");
-    }
-    writePS("%%DocumentSuppliedResources: (atend)\n");
     writePS("%%EndComments\n");
     writePS("32 dict dup begin\n");
     writePSFmt("/BBox [%d %d %d %d] def\n",
diff -Naur poppler-0.5.4.org/poppler/Gfx.cc poppler-0.5.4/poppler/Gfx.cc
--- poppler-0.5.4.org/poppler/Gfx.cc	2006-10-09 11:12:40.000000000 +0200
+++ poppler-0.5.4/poppler/Gfx.cc	2006-10-09 11:14:07.000000000 +0200
@@ -444,7 +444,12 @@
   fontChanged = gFalse;
   clip = clipNone;
   ignoreUndef = 0;
+
   out->startPage(pageNum, state);
+  renderThisPage = out->renderPage(pageNum);
+  if (!renderThisPage)
+    return;
+
   out->setDefaultCTM(state->getCTM());
   out->updateAll(state);
   for (i = 0; i < 6; ++i) {
@@ -476,6 +481,7 @@
   xref = xrefA;
   subPage = gTrue;
   printCommands = globalParams->getPrintCommands();
+  renderThisPage = gTrue;
 
   // start the resource stack
   res = new GfxResources(xref, resDict, NULL);
@@ -525,6 +531,9 @@
   Object obj2;
   int i;
 
+  if (!renderThisPage)
+    return;
+
   if (obj->isArray()) {
     for (i = 0; i < obj->arrayGetLength(); ++i) {
       obj->arrayGet(i, &obj2);
diff -Naur poppler-0.5.4.org/poppler/Gfx.h poppler-0.5.4/poppler/Gfx.h
--- poppler-0.5.4.org/poppler/Gfx.h	2006-10-09 11:12:40.000000000 +0200
+++ poppler-0.5.4/poppler/Gfx.h	2006-10-09 11:12:52.000000000 +0200
@@ -156,6 +156,7 @@
   GBool				// callback to check for an abort
     (*abortCheckCbk)(void *data);
   void *abortCheckCbkData;
+  GBool renderThisPage;		// Render this page?
 
   static Operator opTab[];	// table of operators
 
diff -Naur poppler-0.5.4.org/poppler/OutputDev.h poppler-0.5.4/poppler/OutputDev.h
--- poppler-0.5.4.org/poppler/OutputDev.h	2006-10-09 11:12:40.000000000 +0200
+++ poppler-0.5.4/poppler/OutputDev.h	2006-10-09 11:12:52.000000000 +0200
@@ -74,6 +74,9 @@
   // Set default transform matrix.
   virtual void setDefaultCTM(double *ctm);
 
+  // Should the page be rendered
+  virtual GBool renderPage(int /*pageNum*/) { return gTrue; }
+
   // Start a page.
   virtual void startPage(int /*pageNum*/, GfxState * /*state*/) {}
 
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler

Reply via email to