QPrinter to PDF does not respect composition modes
-
I am using a
QGraphicsView
where I subclassed someQGraphicsItem
to use composition mode "Darken". TheQGraphicsView
displays perfectly when rendering on screen, but when I render to aQPrinter
to export to PDF the composition modes are completely ignored.Below is a MWE using PyQt5.
from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtPrintSupport import * class QGraphicsRectItemD(QGraphicsRectItem): def paint(self, painter, sty, w): painter.setCompositionMode(QPainter.CompositionMode_Darken) QGraphicsRectItem.paint(self, painter, sty, w) class QGraphicsPathItemD(QGraphicsPathItem): def paint(self, painter, sty, w): painter.setCompositionMode(QPainter.CompositionMode_Darken) QGraphicsPathItem.paint(self, painter, sty, w) class Test(QGraphicsView): def __init__(self): QGraphicsView.__init__(self) self.scene = QGraphicsScene() self.setScene(self.scene) r = self.scene.addRect(0, 0, 1404, 1872) # r.setBrush(Qt.green) r.setFlag(QGraphicsItem.ItemClipsChildrenToShape) pen = QPen() pen.setWidth(50) pen.setCapStyle(Qt.RoundCap) pen.setJoinStyle(Qt.RoundJoin) pen.setColor(Qt.black) path = QPainterPath(QPointF(100, 100)) path.lineTo(300, 300) path.lineTo(300, 1000) path.lineTo(700, 700) self.pathItem = pathItem = QGraphicsPathItem(path, r) pathItem.setPen(pen) # pen = QPen() pen.setWidth(150) pen.setCapStyle(Qt.RoundCap) pen.setJoinStyle(Qt.RoundJoin) pen.setColor(Qt.red) path = QPainterPath(QPointF(200, 200)) path.lineTo(300, 300) path.lineTo(300, 1000) path.lineTo(700, 700) self.pathItem2 = pathItem2 = QGraphicsPathItemD(path, r) pathItem2.setPen(pen) def resizeEvent(self, event): self.fitInView(self.sceneRect(), Qt.KeepAspectRatio) def mouseDoubleClickEvent(self, event): print("PRINTING") printer = QPrinter(QPrinter.HighResolution) printer.setOutputFormat(QPrinter.PdfFormat) # printer.setPageSize(QPrinter.A4) printer.setOutputFileName("test.pdf") printer.setPaperSize(QSizeF(1404, 1872), QPrinter.Millimeter) printer.setPageMargins(0, 0, 0, 0, QPrinter.Millimeter) p = QPainter() p.begin(printer) self.scene.render(p) p.end() if __name__ == '__main__': app = QApplication([]) print(QT_VERSION_STR) print(PYQT_VERSION_STR) viewer = Test() viewer.show() app.exec_()
Is this a bug? A known limitation? I could not find anything in the docs.
In principle PDFs support blend modes so I don't see why this would be particularly difficult to preserve. -
The PDF Format outputs a V1.4 PDF file by default. It seems this PDF version supports a Darken blend mode that applies when rendering independent PDF objects. The image in the output PDF appears to me to be a single blob (zlib compressed PDF commands I think); i.e. one object.
QPdfWriter also produces the same result.Bug? Possibly just a primitive implementation.
If you "print" to a QImage you get a result more like the screen. Perhaps you can then put that in a PDF?
-
Thanks for looking into this!
One of the goals of my tool was to obtain vector output so rendering to a raster image is not a solution.
I could try rendering only the objects that need the Darken composition mode on a image overlay but that is not the same thing...