[poppler] Branch 'poppler-0.18' - 3 commits - poppler/PSOutputDev.cc poppler/PSOutputDev.h

Albert Astals Cid aacid at kemper.freedesktop.org
Thu Oct 13 13:58:24 PDT 2011


 poppler/PSOutputDev.cc |   71 ++++++++++++++++++++++++++++++++++++++++++++-----
 poppler/PSOutputDev.h  |    1 
 2 files changed, 66 insertions(+), 6 deletions(-)

New commits:
commit 0339b098f1b00f5ad1bb21bfda14c9c72cb1b058
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Oct 8 15:03:24 2011 +1030

    ps: fix uncolored tiling patterns
    
    Uncolored patterns and type 3 chars must not use color setting
    operators. When emitting an uncolored pattern:
     - disable the update color space functions
     - disable the update color functions
     - set pdfLastFill and pdfLastStroke to true to ensure the the sCol
       and fCol procedures that is used by some of the PS procedures that
       emulate PDF operators do not update the color.
    
    Bug 41462
    (cherry picked from commit acd8ecc9121db58851f73764f046a4f54bd80581)

diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 3c4c9e3..8fd3107 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -1149,6 +1149,7 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
   }
   processColors = 0;
   inType3Char = gFalse;
+  inUncoloredPattern = gFalse;
 
 #if OPI_SUPPORT
   // initialize OPI nesting levels
@@ -3688,6 +3689,9 @@ void PSOutputDev::updateLineWidth(GfxState *state) {
 }
 
 void PSOutputDev::updateFillColorSpace(GfxState *state) {
+  if (inUncoloredPattern) {
+    return;
+  }
   switch (level) {
   case psLevel1:
   case psLevel1Sep:
@@ -3706,6 +3710,9 @@ void PSOutputDev::updateFillColorSpace(GfxState *state) {
 }
 
 void PSOutputDev::updateStrokeColorSpace(GfxState *state) {
+  if (inUncoloredPattern) {
+    return;
+  }
   switch (level) {
   case psLevel1:
   case psLevel1Sep:
@@ -3732,6 +3739,9 @@ void PSOutputDev::updateFillColor(GfxState *state) {
   double c, m, y, k;
   int i;
 
+  if (inUncoloredPattern) {
+    return;
+  }
   switch (level) {
   case psLevel1:
     state->getFillGray(&gray);
@@ -3795,6 +3805,9 @@ void PSOutputDev::updateStrokeColor(GfxState *state) {
   double c, m, y, k;
   int i;
 
+  if (inUncoloredPattern) {
+    return;
+  }
   switch (level) {
   case psLevel1:
     state->getStrokeGray(&gray);
@@ -4052,9 +4065,21 @@ GBool PSOutputDev::tilingPatternFillL1(GfxState *state, Catalog *cat, Object *st
     }
   }
   inType3Char = gTrue;
+  if (paintType == 2) {
+    inUncoloredPattern = gTrue;
+    // ensure any PS procedures that contain sCol or fCol do not change the color
+    writePS("/pdfLastFill true def\n");
+    writePS("/pdfLastStroke true def\n");
+  }
   ++numTilingPatterns;
   gfx->display(str);
   --numTilingPatterns;
+  if (paintType == 2) {
+    inUncoloredPattern = gFalse;
+    // ensure the next PS procedures that uses sCol or fCol will update the color
+    writePS("/pdfLastFill false def\n");
+    writePS("/pdfLastStroke false def\n");
+  }
   inType3Char = gFalse;
   writePS("} def\n");
   delete gfx;
@@ -4081,6 +4106,10 @@ GBool PSOutputDev::tilingPatternFillL2(GfxState *state, Catalog *cat, Object *st
   PDFRectangle box;
   Gfx *gfx;
 
+  if (paintType == 2) {
+    // setpattern with PaintType 2 needs the paint color
+    writePS("currentcolor\n");
+  }
   writePS("<<\n  /PatternType 1\n");
   writePSFmt("  /PaintType {0:d}\n", paintType);
   writePSFmt("  /TilingType {0:d}\n", tilingType);
@@ -4094,7 +4123,19 @@ GBool PSOutputDev::tilingPatternFillL2(GfxState *state, Catalog *cat, Object *st
   box.y2 = bbox[3];
   gfx = new Gfx(xref, this, resDict, m_catalog, &box, NULL);
   inType3Char = gTrue;
+  if (paintType == 2) {
+    inUncoloredPattern = gTrue;
+    // ensure any PS procedures that contain sCol or fCol do not change the color
+    writePS("/pdfLastFill true def\n");
+    writePS("/pdfLastStroke true def\n");
+  }
   gfx->display(str);
+  if (paintType == 2) {
+    inUncoloredPattern = gFalse;
+    // ensure the next PS procedures that uses sCol or fCol will update the color
+    writePS("/pdfLastFill false def\n");
+    writePS("/pdfLastStroke false def\n");
+  }
   inType3Char = gFalse;
   delete gfx;
   writePS("  }\n");
diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h
index a1e0a29..8112bc4 100644
--- a/poppler/PSOutputDev.h
+++ b/poppler/PSOutputDev.h
@@ -450,6 +450,7 @@ private:
 				//   clipping render mode because of pattern colorspace
 
   GBool inType3Char;		// inside a Type 3 CharProc
+  GBool inUncoloredPattern;     // inside a uncolored pattern (PaintType = 2)
   GooString *t3String;		// Type 3 content string
   double t3WX, t3WY,		// Type 3 character parameters
          t3LLX, t3LLY, t3URX, t3URY;
commit e0e1b848aad2232adcd54943cb92b317f02da11d
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Fri Oct 7 20:29:36 2011 +1030

    ps: emit non repeating patterns in PSOutput with inType3Char = true
    
    instead of falling back to Gfx. This avoids emitting the image data
    twice.
    (cherry picked from commit 6e1326b11f98f2b277e53a6cdbcb373ce6c29958)

diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 14e7d16..3c4c9e3 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -4111,6 +4111,29 @@ GBool PSOutputDev::tilingPatternFill(GfxState *state, Catalog *cat, Object *str,
 				     double *mat, double *bbox,
 				     int x0, int y0, int x1, int y1,
 				     double xStep, double yStep) {
+  if (x1 - x0 == 1 && y1 - y0 == 1) {
+    // Don't need to use patterns if only one instance of the pattern is used
+    PDFRectangle box;
+    Gfx *gfx;
+    double x, y, tx, ty;
+
+    x = x0 * xStep;
+    y = y0 * yStep;
+    tx = x * mat[0] + y * mat[2] + mat[4];
+    ty = x * mat[1] + y * mat[3] + mat[5];
+    box.x1 = bbox[0];
+    box.y1 = bbox[1];
+    box.x2 = bbox[2];
+    box.y2 = bbox[3];
+    gfx = new Gfx(xref, this, resDict, m_catalog, &box, NULL);
+    writePSFmt("[{0:.6g} {1:.6g} {2:.6g} {3:.6g} {4:.6g} {5:.6g}] cm\n", mat[0], mat[1], mat[2], mat[3], tx, ty);
+    inType3Char = gTrue;
+    gfx->display(str);
+    inType3Char = gFalse;
+    delete gfx;
+    return gTrue;
+  }
+
   if (level == psLevel1 || level == psLevel1Sep) {
     return tilingPatternFillL1(state, cat, str, pmat, paintType, tilingType, resDict,
 			       mat, bbox, x0, y0, x1, y1, xStep, yStep);
commit 2ec41e76624eb7aab0368d76fac99bcbc8bc1879
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Oct 1 20:19:19 2011 +0930

    ps: fix tiling pattern fill matrix
    
    In PS the pattern matrix maps the pattern space to user space. In PDF
    the pattern matrix maps the pattern space to the default ctm of the
    content stream (baseMatrix in Gfx). The matrix mat already contains the
    correct pattern->baseMatrix so use it instead of pmat.
    
    Bug 41374
    (cherry picked from commit ed05fcb8c442b716c5e382c98f2625701926c86a)

diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 4e6392e..14e7d16 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -4080,7 +4080,6 @@ GBool PSOutputDev::tilingPatternFillL2(GfxState *state, Catalog *cat, Object *st
 				       double xStep, double yStep) {
   PDFRectangle box;
   Gfx *gfx;
-  double cxMin, cyMin, cxMax, cyMax;
 
   writePS("<<\n  /PatternType 1\n");
   writePSFmt("  /PaintType {0:d}\n", paintType);
@@ -4100,10 +4099,9 @@ GBool PSOutputDev::tilingPatternFillL2(GfxState *state, Catalog *cat, Object *st
   delete gfx;
   writePS("  }\n");
   writePS(">>\n");
-  writePSFmt("[{0:.6g} {1:.6g} {2:.6g} {3:.6g} {4:.6g} {5:.6g}]\n", pmat[0], pmat[1], pmat[2], pmat[3], pmat[4], pmat[5]);
+  writePSFmt("[{0:.6g} {1:.6g} {2:.6g} {3:.6g} {4:.6g} {5:.6g}]\n", mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
   writePS("makepattern setpattern\n");
-  state->getClipBBox(&cxMin, &cyMin, &cxMax, &cyMax);
-  writePSFmt("{0:.6g} {1:.6g} {2:.6g} {3:.6g} rectfill\n", cxMin, cyMin, cxMax - cxMin, cyMax - cyMin);
+  writePS("clippath fill\n"); // Gfx sets up a clip before calling out->tilingPatternFill()
 
   return gTrue;
 }
@@ -4113,9 +4111,6 @@ GBool PSOutputDev::tilingPatternFill(GfxState *state, Catalog *cat, Object *str,
 				     double *mat, double *bbox,
 				     int x0, int y0, int x1, int y1,
 				     double xStep, double yStep) {
-  if (x1 - x0 == 1 && y1 - y0 == 1)
-    return gFalse; // Don't need to use patterns if only one instance of the pattern is used
-
   if (level == psLevel1 || level == psLevel1Sep) {
     return tilingPatternFillL1(state, cat, str, pmat, paintType, tilingType, resDict,
 			       mat, bbox, x0, y0, x1, y1, xStep, yStep);


More information about the poppler mailing list