Skip to content

Commit

Permalink
PDF generation: disentangle native pen from transforms
Browse files Browse the repository at this point in the history
In the PDF engine, transforms are implented with a global pdf
transform if and only if the current pen is "simple", that is,
renderable by a native pdf pen. For non-simple pens, the painted
objects are transformed by QTransform instead. Hence, the internal
simplePen flag was used to indicate both a pen state and a transform
state.

This commit splits these two states into separate flags. No behavior
is changed, but it prepares for an improved implementation of cosmetic
pen rendering.

Task-number: QTBUG-86094
Change-Id: If02e1dfc021778e3db7c9ff9a1ed35b3d6cbf3f8
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: André de la Rocha <andre.rocha@qt.io>
(cherry picked from commit 2cb42cd)
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
  • Loading branch information
aavit committed Oct 13, 2021
1 parent b40593f commit c43db6f
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 7 deletions.
21 changes: 14 additions & 7 deletions src/gui/painting/qpdf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -920,7 +920,8 @@ void QPdfEngine::drawPath (const QPainterPath &p)

if (d->simplePen) {
// draw strokes natively in this case for better output
*d->currentPage << QPdf::generatePath(p, QTransform(), d->hasBrush ? QPdf::FillAndStrokePath : QPdf::StrokePath);
*d->currentPage << QPdf::generatePath(p, d->needsTransform ? d->stroker.matrix : QTransform(),
d->hasBrush ? QPdf::FillAndStrokePath : QPdf::StrokePath);
} else {
if (d->hasBrush)
*d->currentPage << QPdf::generatePath(p, d->stroker.matrix, QPdf::FillPath);
Expand Down Expand Up @@ -967,7 +968,7 @@ void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, con

*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));
rectangle.x(), rectangle.y()) * (!d->needsTransform ? QTransform() : d->stroker.matrix));
if (bitmap) {
// set current pen as d->brush
d->brush = d->pen.brush();
Expand Down Expand Up @@ -1007,7 +1008,7 @@ void QPdfEngine::drawImage(const QRectF &rectangle, const QImage &image, const Q

*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));
rectangle.x(), rectangle.y()) * (!d->needsTransform ? QTransform() : d->stroker.matrix));
setBrush();
d->currentPage->streamImage(im.width(), im.height(), object);
*d->currentPage << "Q\n";
Expand Down Expand Up @@ -1056,7 +1057,7 @@ void QPdfEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
}

*d->currentPage << "q\n";
if(!d->simplePen)
if (d->needsTransform)
*d->currentPage << QPdf::generateMatrix(d->stroker.matrix);

bool hp = d->hasPen;
Expand Down Expand Up @@ -1224,8 +1225,13 @@ void QPdfEngine::setupGraphicsState(QPaintEngine::DirtyFlags flags)

if (flags & DirtyTransform) {
*d->currentPage << "q\n";
if (d->simplePen && !d->stroker.matrix.isIdentity())
*d->currentPage << QPdf::generateMatrix(d->stroker.matrix);
d->needsTransform = false;
if (!d->stroker.matrix.isIdentity()) {
if (d->simplePen)
*d->currentPage << QPdf::generateMatrix(d->stroker.matrix);
else
d->needsTransform = true; // I.e. page-wide xf not set, local xf needed
}
}
if (flags & DirtyBrush)
setBrush();
Expand Down Expand Up @@ -1480,7 +1486,7 @@ int QPdfEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const

QPdfEnginePrivate::QPdfEnginePrivate()
: clipEnabled(false), allClipped(false), hasPen(true), hasBrush(false), simplePen(false),
pdfVersion(QPdfEngine::Version_1_4),
needsTransform(false), pdfVersion(QPdfEngine::Version_1_4),
outDevice(nullptr), ownsDevice(false),
embedFonts(true),
grayscale(false),
Expand Down Expand Up @@ -1539,6 +1545,7 @@ bool QPdfEngine::begin(QPaintDevice *pdev)
d->graphicsState = 0;
d->patternColorSpace = 0;
d->simplePen = false;
d->needsTransform = false;

d->pages.clear();
d->imageCache.clear();
Expand Down
1 change: 1 addition & 0 deletions src/gui/painting/qpdf_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ class Q_GUI_EXPORT QPdfEnginePrivate : public QPaintEnginePrivate
bool hasPen;
bool hasBrush;
bool simplePen;
bool needsTransform;
qreal opacity;
QPdfEngine::PdfVersion pdfVersion;

Expand Down

0 comments on commit c43db6f

Please sign in to comment.