[poppler] poppler/GfxState.cc poppler/GfxState.h poppler/PSOutputDev.cc

Adrian Johnson ajohnson at kemper.freedesktop.org
Wed Dec 2 14:23:22 PST 2015


 poppler/GfxState.cc    |   16 ++++++++++
 poppler/GfxState.h     |    5 +++
 poppler/PSOutputDev.cc |   72 ++++++++++++++++++++++++++++++++++++-------------
 3 files changed, 74 insertions(+), 19 deletions(-)

New commits:
commit 7980727d76b29db12b468e5da19d174d42bc3b00
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Tue Oct 27 22:27:22 2015 +1030

    pdftops: fix %%PageBoundingBox
    
    The %%PageBoundingBox calculation did not take into account the page transformation
    (eg rotate, fit-to-page).
    
    Bug 87161

diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 7fb84f4..52edbfa 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -80,6 +80,22 @@ GBool Matrix::invertTo(Matrix *other) const
   return gTrue;
 }
 
+void Matrix::translate(double tx, double ty)
+{
+  double x0 = tx*m[0] + ty*m[2] + m[4];
+  double y0 = tx*m[1] + ty*m[3] + m[5];
+  m[4] = x0;
+  m[5] = y0;
+}
+
+void Matrix::scale(double sx, double sy)
+{
+  m[0] *= sx;
+  m[1] *= sx;
+  m[2] *= sy;
+  m[3] *= sy;
+}
+
 void Matrix::transform(double x, double y, double *tx, double *ty) const
 {
   double temp_x, temp_y;
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index f018e93..f64b8e0 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -59,7 +59,12 @@ class Matrix {
 public:
   double m[6];
 
+  void init(double xx, double yx, double xy, double yy, double x0, double y0) {
+    m[0] = xx; m[1] = yx; m[2] = xy; m[3] = yy; m[4] = x0; m[5] = y0;
+  }
   GBool invertTo(Matrix *other) const;
+  void translate(double tx, double ty);
+  void scale(double sx, double sy);
   void transform(double x, double y, double *tx, double *ty) const;
   double determinant() const { return m[0] * m[3] - m[1] * m[2]; }
   double norm() const;
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 7b93e3b..d5b7400 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -3762,38 +3762,19 @@ void PSOutputDev::startPage(int pageNum, GfxState *state, XRef *xrefA) {
 	}
       }
     }
-    if (paperMatch) {
-      paperSize = (PSOutPaperSize *)paperSizes->get(pagePaperSize[pageNum]);
-      writePSFmt("%%PageMedia: {0:t}\n", paperSize->name);
-    }
-    if (rotate == 0 || rotate == 180) {
-      writePSFmt("%%PageBoundingBox: 0 0 {0:d} {1:d}\n", width, height);
-    } else {
-      writePSFmt("%%PageBoundingBox: 0 0 {0:d} {1:d}\n", height, width);
-    }
-    writePSFmt("%%PageOrientation: {0:s}\n",
-	       landscape ? "Landscape" : "Portrait");
-    writePS("%%BeginPageSetup\n");
-    if (paperMatch) {
-      writePSFmt("{0:d} {1:d} pdfSetupPaper\n", imgURX, imgURY);
-    }
-    writePS("pdfStartPage\n");
     if (rotate == 0) {
       imgWidth2 = imgWidth;
       imgHeight2 = imgHeight;
     } else if (rotate == 90) {
-      writePS("90 rotate\n");
       ty = -imgWidth;
       imgWidth2 = imgHeight;
       imgHeight2 = imgWidth;
     } else if (rotate == 180) {
-      writePS("180 rotate\n");
       imgWidth2 = imgWidth;
       imgHeight2 = imgHeight;
       tx = -imgWidth;
       ty = -imgHeight;
     } else { // rotate == 270
-      writePS("270 rotate\n");
       tx = -imgHeight;
       imgWidth2 = imgHeight;
       imgHeight2 = imgWidth;
@@ -3837,6 +3818,59 @@ void PSOutputDev::startPage(int pageNum, GfxState *state, XRef *xrefA) {
     }
     tx += (rotate == 0 || rotate == 180) ? imgLLX : imgLLY;
     ty += (rotate == 0 || rotate == 180) ? imgLLY : -imgLLX;
+
+    if (paperMatch) {
+      paperSize = (PSOutPaperSize *)paperSizes->get(pagePaperSize[pageNum]);
+      writePSFmt("%%PageMedia: {0:t}\n", paperSize->name);
+    }
+
+    // Create a matrix with the same transform that will be output to PS
+    Matrix m;
+    switch (rotate) {
+    default:
+    case 0:
+      m.init(1, 0,
+	     0, 1,
+	     0, 0);
+      break;
+    case 90:
+      m.init(0,  1,
+	     -1, 0,
+	     0,  0);
+      break;
+    case 180:
+      m.init(-1, 0,
+	     0, -1,
+	     0,  0);
+      break;
+    case 270:
+      m.init(0, -1,
+	     1,  0,
+	     0,  0);
+      break;
+    }
+    m.translate(tx, ty);
+    m.scale(xScale, yScale);
+
+    double bboxX1, bboxY1, bboxX2, bboxY2;
+    m.transform(0, 0, &bboxX1, &bboxY1);
+    m.transform(width, height, &bboxX2, &bboxY2);
+
+    writePSFmt("%%PageBoundingBox: {0:g} {1:g} {2:g} {3:g}\n",
+	       floor(std::min(bboxX1, bboxX2)),
+	       floor(std::min(bboxY1, bboxY2)),
+	       ceil (std::max(bboxX1, bboxX2)),
+	       ceil (std::max(bboxY1, bboxY2)));
+
+    writePSFmt("%%PageOrientation: {0:s}\n",
+	       landscape ? "Landscape" : "Portrait");
+    writePS("%%BeginPageSetup\n");
+    if (paperMatch) {
+      writePSFmt("{0:d} {1:d} pdfSetupPaper\n", imgURX, imgURY);
+    }
+    writePS("pdfStartPage\n");
+    if (rotate)
+      writePSFmt("{0:d} rotate\n", rotate);
     if (tx != 0 || ty != 0) {
       writePSFmt("{0:.6g} {1:.6g} translate\n", tx, ty);
     }


More information about the poppler mailing list