diff options
Diffstat (limited to 'src/gui/painting/qpdf.cpp')
-rw-r--r-- | src/gui/painting/qpdf.cpp | 70 |
1 files changed, 60 insertions, 10 deletions
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 8a0020bd2d..e69726b617 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -953,7 +953,18 @@ void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, con if (object < 0) return; - *d->currentPage << "q\n/GSa gs\n"; + *d->currentPage << "q\n"; + + if ((d->pdfVersion != QPdfEngine::Version_A1b) && (d->opacity != 1.0)) { + int stateObject = d->addConstantAlphaObject(qRound(255 * d->opacity), qRound(255 * d->opacity)); + if (stateObject) + *d->currentPage << "/GState" << stateObject << "gs\n"; + else + *d->currentPage << "/GSa gs\n"; + } else { + *d->currentPage << "/GSa gs\n"; + } + *d->currentPage << QPdf::generateMatrix(QTransform(rectangle.width() / sr.width(), 0, 0, rectangle.height() / sr.height(), rectangle.x(), rectangle.y()) * (d->simplePen ? QTransform() : d->stroker.matrix)); @@ -981,7 +992,18 @@ void QPdfEngine::drawImage(const QRectF &rectangle, const QImage &image, const Q if (object < 0) return; - *d->currentPage << "q\n/GSa gs\n"; + *d->currentPage << "q\n"; + + if ((d->pdfVersion != QPdfEngine::Version_A1b) && (d->opacity != 1.0)) { + int stateObject = d->addConstantAlphaObject(qRound(255 * d->opacity), qRound(255 * d->opacity)); + if (stateObject) + *d->currentPage << "/GState" << stateObject << "gs\n"; + else + *d->currentPage << "/GSa gs\n"; + } else { + *d->currentPage << "/GSa gs\n"; + } + *d->currentPage << QPdf::generateMatrix(QTransform(rectangle.width() / sr.width(), 0, 0, rectangle.height() / sr.height(), rectangle.x(), rectangle.y()) * (d->simplePen ? QTransform() : d->stroker.matrix)); @@ -1114,8 +1136,9 @@ void QPdfEngine::updateState(const QPaintEngineState &state) d->hasPen = d->pen.style() != Qt::NoPen; d->stroker.setPen(d->pen, state.renderHints()); QBrush penBrush = d->pen.brush(); + bool cosmeticPen = qt_pen_is_cosmetic(d->pen, state.renderHints()); bool oldSimple = d->simplePen; - d->simplePen = (d->hasPen && (penBrush.style() == Qt::SolidPattern) && penBrush.isOpaque() && d->opacity == 1.0); + d->simplePen = (d->hasPen && !cosmeticPen && (penBrush.style() == Qt::SolidPattern) && penBrush.isOpaque() && d->opacity == 1.0); if (oldSimple != d->simplePen) flags |= DirtyTransform; } else if (flags & DirtyHints) { @@ -1546,7 +1569,14 @@ void QPdfEnginePrivate::writeHeader() { addXrefEntry(0,false); - xprintf("%%PDF-1.4\n"); + static const QHash<QPdfEngine::PdfVersion, const char *> mapping { + {QPdfEngine::Version_1_4, "1.4"}, + {QPdfEngine::Version_A1b, "1.4"}, + {QPdfEngine::Version_1_6, "1.6"} + }; + const char *verStr = mapping.value(pdfVersion, "1.4"); + + xprintf("%%PDF-%s\n", verStr); xprintf("%%\303\242\303\243\n"); writeInfo(); @@ -1879,6 +1909,19 @@ void QPdfEnginePrivate::embedFont(QFontSubset *font) } } +qreal QPdfEnginePrivate::calcUserUnit() const +{ + // PDF standards < 1.6 support max 200x200in pages (no UserUnit) + if (pdfVersion < QPdfEngine::Version_1_6) + return 1.0; + + const int maxLen = qMax(currentPage->pageSize.width(), currentPage->pageSize.height()); + if (maxLen <= 14400) + return 1.0; // for pages up to 200x200in (14400x14400 units) use default scaling + + // for larger pages, rescale units so we can have up to 381x381km + return qMin(maxLen / 14400.0, 75000.0); +} void QPdfEnginePrivate::writeFonts() { @@ -1901,6 +1944,8 @@ void QPdfEnginePrivate::writePage() uint resources = requestObject(); uint annots = requestObject(); + qreal userUnit = calcUserUnit(); + addXrefEntry(pages.constLast()); xprintf("<<\n" "/Type /Page\n" @@ -1908,12 +1953,16 @@ void QPdfEnginePrivate::writePage() "/Contents %d 0 R\n" "/Resources %d 0 R\n" "/Annots %d 0 R\n" - "/MediaBox [0 0 %d %d]\n" - ">>\n" - "endobj\n", + "/MediaBox [0 0 %f %f]\n", pageRoot, pageStream, resources, annots, // make sure we use the pagesize from when we started the page, since the user may have changed it - currentPage->pageSize.width(), currentPage->pageSize.height()); + currentPage->pageSize.width() / userUnit, currentPage->pageSize.height() / userUnit); + + if (pdfVersion >= QPdfEngine::Version_1_6) + xprintf("/UserUnit %f\n", userUnit); + + xprintf(">>\n" + "endobj\n"); addXrefEntry(resources); xprintf("<<\n" @@ -2982,8 +3031,9 @@ void QPdfEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &ti) QTransform QPdfEnginePrivate::pageMatrix() const { - qreal scale = 72./resolution; - QTransform tmp(scale, 0.0, 0.0, -scale, 0.0, m_pageLayout.fullRectPoints().height()); + qreal userUnit = calcUserUnit(); + qreal scale = 72. / userUnit / resolution; + QTransform tmp(scale, 0.0, 0.0, -scale, 0.0, m_pageLayout.fullRectPoints().height() / userUnit); if (m_pageLayout.mode() != QPageLayout::FullPageMode) { QRect r = m_pageLayout.paintRectPixels(resolution); tmp.translate(r.left(), r.top()); |