From 3aaae763a07585b3935ad78470eafab15edfb381 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Sun, 15 Dec 2013 18:00:41 +1030 Subject: [PATCH 2/3] pdftps: fix DocumentMedia/Page/Media/PageBBox DSC comments Bug 72312 --- poppler/PSOutputDev.cc | 102 ++++++++++++++++++++++++++++++++-------- poppler/PSOutputDev.h | 6 ++- qt5/src/poppler-ps-converter.cc | 1 + utils/pdftops.cc | 1 + 4 files changed, 89 insertions(+), 21 deletions(-) diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc index 32be0a3..85f2b93 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; @@ -1196,17 +1233,39 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA, paperMatch = gFalse; break; } - w = (int)ceil(page->getMediaWidth()); - h = (int)ceil(page->getMediaHeight()); + if (noCropA) { + w = page->getMediaWidth(); + h = page->getMediaHeight(); + } else { + w = page->getCropWidth(); + h = page->getCropHeight(); + } + int rotate = page->getRotate(); + if (rotate == 90 || rotate == 270) + std::swap(w, h); + for (i = 0; i < paperSizes->getLength(); ++i) { size = (PSOutPaperSize *)paperSizes->get(i); - if (size->w == w && size->h == h) { + if (pageDimensionEqual(w, size->w) && pageDimensionEqual(h, size->h)) break; - } } if (i == paperSizes->getLength()) { - paperSizes->append(new PSOutPaperSize(w, h)); + 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)); } + pagePaperSize.insert(std::pair(pg, i)); if (w > paperWidth) { paperWidth = w; } @@ -1439,8 +1498,8 @@ void PSOutputDev::writeHeader(int firstPage, int lastPage, 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); + writePSFmt("%%{0:s} {1:t} {2:d} {3:d} 0 () ()\n", + i==0 ? "DocumentMedia:" : "+", size->name, size->w, size->h); } } else { writePSFmt("%%DocumentMedia: plain {0:d} {1:d} 0 () ()\n", @@ -3504,6 +3563,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 +3592,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 +3645,16 @@ void PSOutputDev::startPage(int pageNum, GfxState *state, XRef *xrefA) { } } } + 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 +3793,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 92b007e..f14f03f 100644 --- a/poppler/PSOutputDev.h +++ b/poppler/PSOutputDev.h @@ -44,6 +44,7 @@ #include "GlobalParams.h" #include "OutputDev.h" #include +#include 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 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/qt5/src/poppler-ps-converter.cc b/qt5/src/poppler-ps-converter.cc index 30f53fa..241d2a4 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 cbe1d36..b54fd42 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, -- 1.8.3.2