summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--poppler/PSOutputDev.cc167
-rw-r--r--poppler/PSOutputDev.h6
-rw-r--r--qt4/src/poppler-ps-converter.cc1
-rw-r--r--qt5/src/poppler-ps-converter.cc1
-rw-r--r--utils/pdftops.cc1
5 files changed, 119 insertions, 57 deletions
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 32be0a3d..4120f70c 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -944,7 +944,9 @@ struct PSOutImgClipRect {
//------------------------------------------------------------------------
struct PSOutPaperSize {
- PSOutPaperSize(int wA, int hA) { w = wA; h = hA; }
+ PSOutPaperSize(GooString *nameA, int wA, int hA) { name = nameA; w = wA; h = hA; }
+ ~PSOutPaperSize() { delete name; }
+ GooString *name;
int w, h;
};
@@ -1052,7 +1054,8 @@ static void outputToFile(void *stream, const char *data, int len) {
PSOutputDev::PSOutputDev(const char *fileName, PDFDoc *doc,
char *psTitle,
int firstPage, int lastPage, PSOutMode modeA,
- int paperWidthA, int paperHeightA, GBool duplexA,
+ int paperWidthA, int paperHeightA,
+ GBool noCropA, GBool duplexA,
int imgLLXA, int imgLLYA, int imgURXA, int imgURYA,
GBool forceRasterizeA,
GBool manualCtrlA,
@@ -1114,14 +1117,15 @@ PSOutputDev::PSOutputDev(const char *fileName, PDFDoc *doc,
init(outputToFile, f, fileTypeA, psTitle,
doc, firstPage, lastPage, modeA,
imgLLXA, imgLLYA, imgURXA, imgURYA, manualCtrlA,
- paperWidthA, paperHeightA, duplexA);
+ paperWidthA, paperHeightA, noCropA, duplexA);
}
PSOutputDev::PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA,
char *psTitle,
PDFDoc *doc,
int firstPage, int lastPage, PSOutMode modeA,
- int paperWidthA, int paperHeightA, GBool duplexA,
+ int paperWidthA, int paperHeightA,
+ GBool noCropA, GBool duplexA,
int imgLLXA, int imgLLYA, int imgURXA, int imgURYA,
GBool forceRasterizeA,
GBool manualCtrlA,
@@ -1151,7 +1155,40 @@ PSOutputDev::PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA,
init(outputFuncA, outputStreamA, psGeneric, psTitle,
doc, firstPage, lastPage, modeA,
imgLLXA, imgLLYA, imgURXA, imgURYA, manualCtrlA,
- paperWidthA, paperHeightA, duplexA);
+ paperWidthA, paperHeightA, noCropA, duplexA);
+}
+
+struct StandardMedia {
+ const char *name;
+ int width;
+ int height;
+};
+
+static const StandardMedia standardMedia[] =
+{
+ { "A0", 2384, 3371 },
+ { "A1", 1685, 2384 },
+ { "A2", 1190, 1684 },
+ { "A3", 842, 1190 },
+ { "A4", 595, 842 },
+ { "A5", 420, 595 },
+ { "B4", 729, 1032 },
+ { "B5", 516, 729 },
+ { "Letter", 612, 792 },
+ { "Tabloid", 792, 1224 },
+ { "Ledger", 1224, 792 },
+ { "Legal", 612, 1008 },
+ { "Statement", 396, 612 },
+ { "Executive", 540, 720 },
+ { "Folio", 612, 936 },
+ { "Quarto", 610, 780 },
+ { "10x14", 720, 1008 },
+ { NULL, 0, 0 }
+};
+
+/* PLRM specifies a tolerance of 5 points when matching page sizes */
+static bool pageDimensionEqual(int a, int b) {
+ return (abs (a - b) < 5);
}
void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
@@ -1159,7 +1196,7 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
int firstPage, int lastPage, PSOutMode modeA,
int imgLLXA, int imgLLYA, int imgURXA, int imgURYA,
GBool manualCtrlA, int paperWidthA, int paperHeightA,
- GBool duplexA) {
+ GBool noCropA, GBool duplexA) {
Catalog *catalog;
PDFRectangle *box;
PSOutPaperSize *size;
@@ -1184,39 +1221,61 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
imgURX = imgURXA;
imgURY = imgURYA;
if (paperWidth < 0 || paperHeight < 0) {
- Page *page;
paperMatch = gTrue;
- paperSizes = new GooList();
- paperWidth = paperHeight = 1; // in case the document has zero pages
- for (pg = (firstPage >= 1) ? firstPage : 1;
- pg <= lastPage && pg <= catalog->getNumPages();
- ++pg) {
- page = catalog->getPage(pg);
- if (page == NULL) {
- paperMatch = gFalse;
- break;
- }
+ } else {
+ paperMatch = gFalse;
+ }
+ Page *page;
+ paperSizes = new GooList();
+ for (pg = (firstPage >= 1) ? firstPage : 1;
+ pg <= lastPage && pg <= catalog->getNumPages();
+ ++pg) {
+ page = catalog->getPage(pg);
+ if (page == NULL)
+ paperMatch = gFalse;
+ if (!paperMatch) {
+ w = paperWidth;
+ h = paperHeight;
+ } else if (noCropA) {
w = (int)ceil(page->getMediaWidth());
h = (int)ceil(page->getMediaHeight());
- for (i = 0; i < paperSizes->getLength(); ++i) {
- size = (PSOutPaperSize *)paperSizes->get(i);
- if (size->w == w && size->h == h) {
- break;
- }
- }
- if (i == paperSizes->getLength()) {
- paperSizes->append(new PSOutPaperSize(w, h));
- }
- if (w > paperWidth) {
- paperWidth = w;
- }
- if (h > paperHeight) {
- paperHeight = h;
+ } else {
+ w = (int)ceil(page->getCropWidth());
+ h = (int)ceil(page->getCropHeight());
+ }
+ if (paperMatch) {
+ int rotate = page->getRotate();
+ if (rotate == 90 || rotate == 270)
+ std::swap(w, h);
+ }
+ if (w > paperWidth)
+ paperWidth = w;
+ if (h > paperHeight)
+ paperHeight = h;
+ for (i = 0; i < paperSizes->getLength(); ++i) {
+ size = (PSOutPaperSize *)paperSizes->get(i);
+ if (pageDimensionEqual(w, size->w) && pageDimensionEqual(h, size->h))
+ break;
+ }
+ if (i == paperSizes->getLength()) {
+ const StandardMedia *media = standardMedia;
+ GooString *name = NULL;
+ while (media->name) {
+ if (pageDimensionEqual(w, media->width) && pageDimensionEqual(h, media->height)) {
+ name = new GooString(media->name);
+ w = media->width;
+ h = media->height;
+ break;
+ }
+ media++;
}
+ if (!name)
+ name = GooString::format("{0:d}x{1:d}mm", int(w*25.4/72), int(h*25.4/72));
+ paperSizes->append(new PSOutPaperSize(name, w, h));
}
- // NB: img{LLX,LLY,URX,URY} will be set by startPage()
- } else {
- paperMatch = gFalse;
+ pagePaperSize.insert(std::pair<int,int>(pg, i));
+ if (!paperMatch)
+ break; // we only need one entry when all pages are the same size
}
preload = globalParams->getPSPreload();
if (imgLLX == 0 && imgURX == 0 && imgLLY == 0 && imgURY == 0) {
@@ -1224,11 +1283,6 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
imgURX = paperWidth;
imgURY = paperHeight;
}
- if (imgLLX == 0 && imgURX == 0 && imgLLY == 0 && imgURY == 0) {
- imgLLX = imgLLY = 0;
- imgURX = paperWidth;
- imgURY = paperHeight;
- }
manualCtrl = manualCtrlA;
if (mode == psModeForm) {
lastPage = firstPage;
@@ -1436,22 +1490,18 @@ void PSOutputDev::writeHeader(int firstPage, int lastPage,
prevWidth = 0;
prevHeight = 0;
case psModePS:
- if (paperMatch) {
- for (i = 0; i < paperSizes->getLength(); ++i) {
- size = (PSOutPaperSize *)paperSizes->get(i);
- writePSFmt("%%{0:s} {1:d}x{2:d} {1:d} {2:d} 0 () ()\n",
- i==0 ? "DocumentMedia:" : "+", size->w, size->h);
- }
- } else {
- writePSFmt("%%DocumentMedia: plain {0:d} {1:d} 0 () ()\n",
- paperWidth, paperHeight);
+ for (i = 0; i < paperSizes->getLength(); ++i) {
+ size = (PSOutPaperSize *)paperSizes->get(i);
+ writePSFmt("%%{0:s} {1:t} {2:d} {3:d} 0 () ()\n",
+ i==0 ? "DocumentMedia:" : "+", size->name, size->w, size->h);
}
writePSFmt("%%BoundingBox: 0 0 {0:d} {1:d}\n", paperWidth, paperHeight);
writePSFmt("%%Pages: {0:d}\n", lastPage - firstPage + 1);
writePS("%%EndComments\n");
if (!paperMatch) {
+ size = (PSOutPaperSize *)paperSizes->get(0);
writePS("%%BeginDefaults\n");
- writePS("%%PageMedia: plain\n");
+ writePSFmt("%%PageMedia: {0:t}\n", size->name);
writePS("%%EndDefaults\n");
}
break;
@@ -3504,6 +3554,7 @@ void PSOutputDev::startPage(int pageNum, GfxState *state, XRef *xrefA) {
int imgWidth, imgHeight, imgWidth2, imgHeight2;
GBool landscape;
GooString *s;
+ PSOutPaperSize *paperSize;
xref = xrefA;
if (mode == psModePS || mode == psModePSOrigPageSizes) {
@@ -3532,11 +3583,7 @@ void PSOutputDev::startPage(int pageNum, GfxState *state, XRef *xrefA) {
imgURX = imgURY;
imgURY = t;
}
- writePSFmt("%%PageMedia: {0:d}x{1:d}\n", imgURX, imgURY);
- writePSFmt("%%PageBoundingBox: 0 0 {0:d} {1:d}\n", imgURX, imgURY);
}
- if (mode != psModePSOrigPageSizes)
- writePS("%%BeginPageSetup\n");
}
// underlays
@@ -3589,8 +3636,18 @@ 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);
if (mode == psModePSOrigPageSizes) {
@@ -3729,9 +3786,7 @@ void PSOutputDev::startPage(int pageNum, GfxState *state, XRef *xrefA) {
}
}
- if (mode == psModePS) {
- writePS("%%EndPageSetup\n");
- }
+ writePS("%%EndPageSetup\n");
}
void PSOutputDev::endPage() {
diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h
index 92b007ea..f14f03fb 100644
--- a/poppler/PSOutputDev.h
+++ b/poppler/PSOutputDev.h
@@ -44,6 +44,7 @@
#include "GlobalParams.h"
#include "OutputDev.h"
#include <set>
+#include <map>
class GHooash;
class PDFDoc;
@@ -97,6 +98,7 @@ public:
char *psTitle,
int firstPage, int lastPage, PSOutMode modeA,
int paperWidthA = -1, int paperHeightA = -1,
+ GBool noCrop = gFalse,
GBool duplexA = gTrue,
int imgLLXA = 0, int imgLLYA = 0,
int imgURXA = 0, int imgURYA = 0,
@@ -111,6 +113,7 @@ public:
PDFDoc *docA,
int firstPage, int lastPage, PSOutMode modeA,
int paperWidthA = -1, int paperHeightA = -1,
+ GBool noCrop = gFalse,
GBool duplexA = gTrue,
int imgLLXA = 0, int imgLLYA = 0,
int imgURXA = 0, int imgURYA = 0,
@@ -311,7 +314,7 @@ private:
int firstPage, int lastPage, PSOutMode modeA,
int imgLLXA, int imgLLYA, int imgURXA, int imgURYA,
GBool manualCtrlA, int paperWidthA, int paperHeightA,
- GBool duplexA);
+ GBool noCropA, GBool duplexA);
void setupResources(Dict *resDict);
void setupFonts(Dict *resDict);
void setupFont(GfxFont *font, Dict *parentResDict);
@@ -452,6 +455,7 @@ private:
GooList *paperSizes; // list of used paper sizes, if paperMatch
// is true [PSOutPaperSize]
+ std::map<int,int> pagePaperSize; // page num to paperSize entry mapping
double tx0, ty0; // global translation
double xScale0, yScale0; // global scaling
int rotate0; // rotation angle (0, 90, 180, 270)
diff --git a/qt4/src/poppler-ps-converter.cc b/qt4/src/poppler-ps-converter.cc
index ff8af65d..1847eef9 100644
--- a/qt4/src/poppler-ps-converter.cc
+++ b/qt4/src/poppler-ps-converter.cc
@@ -224,6 +224,7 @@ bool PSConverter::convert()
d->paperWidth,
d->paperHeight,
gFalse,
+ gFalse,
d->marginLeft,
d->marginBottom,
d->paperWidth - d->marginRight,
diff --git a/qt5/src/poppler-ps-converter.cc b/qt5/src/poppler-ps-converter.cc
index 30f53fae..241d2a4b 100644
--- a/qt5/src/poppler-ps-converter.cc
+++ b/qt5/src/poppler-ps-converter.cc
@@ -224,6 +224,7 @@ bool PSConverter::convert()
d->paperWidth,
d->paperHeight,
gFalse,
+ gFalse,
d->marginLeft,
d->marginBottom,
d->paperWidth - d->marginRight,
diff --git a/utils/pdftops.cc b/utils/pdftops.cc
index cbe1d367..b54fd425 100644
--- a/utils/pdftops.cc
+++ b/utils/pdftops.cc
@@ -399,6 +399,7 @@ int main(int argc, char *argv[]) {
NULL, firstPage, lastPage, mode,
paperWidth,
paperHeight,
+ noCrop,
duplex);
if (psOut->isOk()) {
doc->displayPages(psOut, firstPage, lastPage, 72, 72,