QPainter draw semi-transparent overlay watermark changes lines underneath in PDF
-
I'm trying to draw a watermark on top of some existing lines and texts. The watermark is drawn semi-transparently so the watermark text should blend with lines underneath. It looks fine in Print Preview. But when I send it to the Microsoft Print to PDF printer, the resulting PDF shows thinned lines underneath the watermark. I expected the lines that do not intersect with the watermark text to be unchanged.
Qt Creator 11
Qt 6.5.1 mingw64
Windows 10QT += core gui printsupport greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++17 # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ main.cpp \ mainwindow.cpp HEADERS += \ mainwindow.h FORMS += \ mainwindow.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target
mainwindow.h:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QPrinter> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void onBtnPrintClicked(); void onBtnPrintPreviewClicked(); private: Ui::MainWindow *ui; void print(QPrinter *printer); }; #endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QPrintDialog> #include <QPrintPreviewDialog> #include <QPainter> #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); connect(ui->btnPrint, &QPushButton::clicked, this, &MainWindow::onBtnPrintClicked); connect(ui->btnPrintPreview, &QPushButton::clicked, this, &MainWindow::onBtnPrintPreviewClicked); } MainWindow::~MainWindow() { delete ui; } void MainWindow::onBtnPrintClicked() { QPrinter printer(QPrinter::HighResolution); QPrintDialog dialog(&printer, this); dialog.setFromTo(1, 2); if (dialog.exec() != QDialog::Accepted) return; print(&printer); } void MainWindow::onBtnPrintPreviewClicked() { QPrinter printer(QPrinter::HighResolution); printer.setFromTo(1, 2); QPrintPreviewDialog preview(&printer, this); preview.setWindowFlags(preview.windowFlags() & ~Qt::WindowContextHelpButtonHint); connect(&preview, &QPrintPreviewDialog::paintRequested, this, &MainWindow::print); preview.exec(); } void MainWindow::print(QPrinter *printer) { QPainter painter; if (!painter.begin(printer)) { return; } QRectF pageRect = printer->pageRect(QPrinter::DevicePixel); double pageMargin = 0.04 * pageRect.width(); QRect contentRect = QRect(0, 0, pageRect.width() - 2 * pageMargin, pageRect.height() - 2 * pageMargin); painter.translate(pageMargin, pageMargin); painter.setPen(QPen(Qt::black, 1)); // Draw some horizontal lines int y = contentRect.height() / 3; while (y < contentRect.height() - contentRect.height() / 3) { painter.drawLine(0, y, contentRect.width(), y); y += 100; } // Draw a watermark that's on top of the lines QFont font; font.setPointSize(50); font.setWeight(QFont::Bold); float a = -qRadiansToDegrees(atan2(pageRect.height(), pageRect.width())); QString text = "W A T E R M A R K"; painter.setBrush(Qt::transparent); painter.setFont(font); painter.translate(pageRect.width()/2, pageRect.height()/2); painter.rotate(a); painter.setPen(QColor(175, 175, 175, 75)); painter.drawText(-painter.fontMetrics().horizontalAdvance(text)/2, painter.fontMetrics().height()/2, text); painter.end(); }
mainwindow.ui:
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>474</width> <height>478</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralwidget"> <widget class="QPushButton" name="btnPrintPreview"> <property name="geometry"> <rect> <x>150</x> <y>140</y> <width>181</width> <height>71</height> </rect> </property> <property name="text"> <string>Print Preview</string> </property> </widget> <widget class="QPushButton" name="btnPrint"> <property name="geometry"> <rect> <x>150</x> <y>230</y> <width>181</width> <height>71</height> </rect> </property> <property name="text"> <string>Print</string> </property> </widget> </widget> <widget class="QMenuBar" name="menubar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>474</width> <height>22</height> </rect> </property> </widget> <widget class="QStatusBar" name="statusbar"/> </widget> <resources/> <connections/> </ui>
main.cpp:
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }