diff options
Diffstat (limited to 'src/printsupport/platform/windows')
4 files changed, 91 insertions, 74 deletions
diff --git a/src/printsupport/platform/windows/qprintengine_win.cpp b/src/printsupport/platform/windows/qprintengine_win.cpp index d6dd5eae5c..fa8d03a615 100644 --- a/src/printsupport/platform/windows/qprintengine_win.cpp +++ b/src/printsupport/platform/windows/qprintengine_win.cpp @@ -30,10 +30,10 @@ #include <QtCore/QMetaType> #include <QtCore/qt_windows.h> #include <QtGui/qpagelayout.h> +#include <QtGui/private/qpixmap_win_p.h> QT_BEGIN_NAMESPACE -Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = 0); extern QPainterPath qt_regionToPath(const QRegion ®ion); extern QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits); @@ -259,7 +259,7 @@ void QWin32PrintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem if (!fallBack) { bool deleteFont = false; - HFONT hfont = NULL; + HFONT hfont = nullptr; if (ti.fontEngine->type() == QFontEngine::Win) { hfont = static_cast<HFONT>(ti.fontEngine->handle()); } @@ -433,7 +433,7 @@ void QWin32PrintEngine::updateClipPath(const QPainterPath &clipPath, Qt::ClipOpe bool doclip = true; if (op == Qt::NoClip) { - SelectClipRgn(d->hdc, 0); + SelectClipRgn(d->hdc, nullptr); doclip = false; } @@ -561,6 +561,7 @@ void QWin32PrintEngine::drawPixmap(const QRectF &targetRect, QImage img(QSize(imgw, imgh), QImage::Format_RGB32); + img.setDevicePixelRatio(pixmap.devicePixelRatio()); img.fill(Qt::white); QPainter painter(&img); painter.drawPixmap(0,0, pixmap, tileSize * x, tileSize * y, imgw, imgh); @@ -721,7 +722,7 @@ void QWin32PrintEnginePrivate::strokePath_dev(const QPainterPath &path, const QC joinStyle = PS_JOIN_ROUND; HPEN pen = ExtCreatePen(PS_GEOMETRIC | PS_SOLID | capStyle | joinStyle, - (penWidth == 0) ? 1 : penWidth, &brush, 0, 0); + (penWidth == 0) ? 1 : penWidth, &brush, 0, nullptr); HGDIOBJ old_pen = SelectObject(hdc, pen); StrokePath(hdc); @@ -841,7 +842,8 @@ void QWin32PrintEnginePrivate::initialize() txop = QTransform::TxNone; QString printerName = m_printDevice.id(); - bool ok = OpenPrinter((LPWSTR)printerName.utf16(), (LPHANDLE)&hPrinter, 0); + bool ok = OpenPrinter(reinterpret_cast<LPWSTR>(const_cast<ushort *>(printerName.utf16())), + reinterpret_cast<LPHANDLE>(&hPrinter), nullptr); if (!ok) { qErrnoWarning("QWin32PrintEngine::initialize: OpenPrinter failed"); return; @@ -850,10 +852,10 @@ void QWin32PrintEnginePrivate::initialize() // Fetch the PRINTER_INFO_2 with DEVMODE data containing the // printer settings. DWORD infoSize, numBytes; - GetPrinter(hPrinter, 2, NULL, 0, &infoSize); + GetPrinter(hPrinter, 2, nullptr, 0, &infoSize); hMem = GlobalAlloc(GHND, infoSize); - pInfo = (PRINTER_INFO_2*) GlobalLock(hMem); - ok = GetPrinter(hPrinter, 2, (LPBYTE)pInfo, infoSize, &numBytes); + pInfo = reinterpret_cast<PRINTER_INFO_2*>(GlobalLock(hMem)); + ok = GetPrinter(hPrinter, 2, reinterpret_cast<LPBYTE>(pInfo), infoSize, &numBytes); if (!ok) { qErrnoWarning("QWin32PrintEngine::initialize: GetPrinter failed"); @@ -871,23 +873,26 @@ void QWin32PrintEnginePrivate::initialize() // Attempt to get the DEVMODE a different way. // Allocate the required buffer - LONG result = DocumentProperties(NULL, hPrinter, (LPWSTR)printerName.utf16(), - NULL, NULL, 0); - devMode = (DEVMODE *) malloc(result); + auto *lpwPrinterName = reinterpret_cast<LPWSTR>(const_cast<ushort *>(printerName.utf16())); + LONG result = DocumentProperties(nullptr, hPrinter, lpwPrinterName, + nullptr, nullptr, 0); + devMode = reinterpret_cast<DEVMODE *>(malloc(result)); + initializeDevMode(devMode); ownsDevMode = true; // Get the default DevMode - result = DocumentProperties(NULL, hPrinter, (LPWSTR)printerName.utf16(), - devMode, NULL, DM_OUT_BUFFER); + result = DocumentProperties(nullptr, hPrinter, lpwPrinterName, + devMode, nullptr, DM_OUT_BUFFER); if (result != IDOK) { qErrnoWarning("QWin32PrintEngine::initialize: Failed to obtain devMode"); free(devMode); - devMode = NULL; + devMode = nullptr; ownsDevMode = false; } } - hdc = CreateDC(NULL, (LPCWSTR)printerName.utf16(), 0, devMode); + hdc = CreateDC(nullptr, reinterpret_cast<LPCWSTR>(printerName.utf16()), + nullptr, devMode); if (!hdc) { qErrnoWarning("QWin32PrintEngine::initialize: CreateDC failed"); @@ -912,15 +917,22 @@ void QWin32PrintEnginePrivate::initialize() #endif // QT_DEBUG_DRAW || QT_DEBUG_METRICS } +void QWin32PrintEnginePrivate::initializeDevMode(DEVMODE *devMode) +{ + memset(devMode, 0, sizeof(DEVMODE)); + devMode->dmSize = sizeof(DEVMODE); + devMode->dmSpecVersion = DM_SPECVERSION; +} + void QWin32PrintEnginePrivate::initHDC() { Q_ASSERT(hdc); - HDC display_dc = GetDC(0); + HDC display_dc = GetDC(nullptr); dpi_x = GetDeviceCaps(hdc, LOGPIXELSX); dpi_y = GetDeviceCaps(hdc, LOGPIXELSY); dpi_display = GetDeviceCaps(display_dc, LOGPIXELSY); - ReleaseDC(0, display_dc); + ReleaseDC(nullptr, display_dc); if (dpi_display == 0) { qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, " "might be a driver problem"); @@ -963,11 +975,11 @@ void QWin32PrintEnginePrivate::release() if (ownsDevMode) free(devMode); - hdc = 0; - hPrinter = 0; - pInfo = 0; - hMem = 0; - devMode = 0; + hdc = nullptr; + hPrinter = nullptr; + pInfo = nullptr; + hMem = nullptr; + devMode = nullptr; ownsDevMode = false; } @@ -1051,6 +1063,7 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & if (!d->devMode) break; d->devMode->dmCollate = value.toBool() ? DMCOLLATE_TRUE : DMCOLLATE_FALSE; + d->devMode->dmFields |= DM_COLLATE; d->doReinit(); } break; @@ -1060,6 +1073,7 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & if (!d->devMode) break; d->devMode->dmColor = (value.toInt() == QPrinter::Color) ? DMCOLOR_COLOR : DMCOLOR_MONOCHROME; + d->devMode->dmFields |= DM_COLOR; d->doReinit(); } break; @@ -1085,15 +1099,19 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & switch (mode) { case QPrint::DuplexNone: d->devMode->dmDuplex = DMDUP_SIMPLEX; + d->devMode->dmFields |= DM_DUPLEX; break; case QPrint::DuplexAuto: d->devMode->dmDuplex = d->m_pageLayout.orientation() == QPageLayout::Landscape ? DMDUP_HORIZONTAL : DMDUP_VERTICAL; + d->devMode->dmFields |= DM_DUPLEX; break; case QPrint::DuplexLongSide: d->devMode->dmDuplex = DMDUP_VERTICAL; + d->devMode->dmFields |= DM_DUPLEX; break; case QPrint::DuplexShortSide: d->devMode->dmDuplex = DMDUP_HORIZONTAL; + d->devMode->dmFields |= DM_DUPLEX; break; default: // Don't change @@ -1121,6 +1139,7 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & break; d->num_copies = value.toInt(); d->devMode->dmCopies = d->num_copies; + d->devMode->dmFields |= DM_COPIES; d->doReinit(); break; @@ -1129,9 +1148,10 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & break; QPageLayout::Orientation orientation = QPageLayout::Orientation(value.toInt()); d->devMode->dmOrientation = orientation == QPageLayout::Landscape ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT; + d->devMode->dmFields |= DM_ORIENTATION; d->m_pageLayout.setOrientation(orientation); - d->updateMetrics(); d->doReinit(); + d->updateMetrics(); #ifdef QT_DEBUG_METRICS qDebug() << "QWin32PrintEngine::setProperty(PPK_Orientation," << orientation << ')'; d->debugMetrics(); @@ -1265,7 +1285,8 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & Q_ASSERT(margins.size() == 4); d->m_pageLayout.setUnits(QPageLayout::Point); d->m_pageLayout.setMargins(QMarginsF(margins.at(0).toReal(), margins.at(1).toReal(), - margins.at(2).toReal(), margins.at(3).toReal())); + margins.at(2).toReal(), margins.at(3).toReal()), + QPageLayout::OutOfBoundsPolicy::Clamp); d->updateMetrics(); #ifdef QT_DEBUG_METRICS qDebug() << "QWin32PrintEngine::setProperty(PPK_PageMargins," << margins << ')'; @@ -1293,7 +1314,7 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & case PPK_QPageMargins: { QPair<QMarginsF, QPageLayout::Unit> pair = value.value<QPair<QMarginsF, QPageLayout::Unit> >(); d->m_pageLayout.setUnits(pair.second); - d->m_pageLayout.setMargins(pair.first); + d->m_pageLayout.setMargins(pair.first, QPageLayout::OutOfBoundsPolicy::Clamp); d->updateMetrics(); #ifdef QT_DEBUG_METRICS qDebug() << "QWin32PrintEngine::setProperty(PPK_QPageMargins," << pair.first << pair.second << ')'; @@ -1309,7 +1330,7 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant & setProperty(PPK_FullPage, pageLayout.mode() == QPageLayout::FullPageMode); setProperty(PPK_Orientation, QVariant::fromValue(pageLayout.orientation())); d->m_pageLayout.setUnits(pageLayout.units()); - d->m_pageLayout.setMargins(pageLayout.margins()); + d->m_pageLayout.setMargins(pageLayout.margins(), QPageLayout::OutOfBoundsPolicy::Clamp); d->updateMetrics(); #ifdef QT_DEBUG_METRICS qDebug() << "QWin32PrintEngine::setProperty(PPK_QPageLayout," << pageLayout << ')'; @@ -1571,7 +1592,7 @@ void QWin32PrintEngine::setGlobalDevMode(HGLOBAL globalDevNames, HGLOBAL globalD d->ownsDevMode = false; } d->devMode = dm; - d->hdc = CreateDC(NULL, reinterpret_cast<const wchar_t *>(d->m_printDevice.id().utf16()), 0, dm); + d->hdc = CreateDC(nullptr, reinterpret_cast<LPCWSTR>(d->m_printDevice.id().utf16()), nullptr, dm); d->num_copies = d->devMode->dmCopies; d->updatePageLayout(); @@ -1585,7 +1606,7 @@ void QWin32PrintEngine::setGlobalDevMode(HGLOBAL globalDevNames, HGLOBAL globalD #if defined QT_DEBUG_DRAW || defined QT_DEBUG_METRICS qDebug("QWin32PrintEngine::setGlobalDevMode()"); - debugMetrics(); + d->debugMetrics(); #endif // QT_DEBUG_DRAW || QT_DEBUG_METRICS } @@ -1674,13 +1695,23 @@ void QWin32PrintEnginePrivate::updatePageLayout() void QWin32PrintEnginePrivate::updateMetrics() { m_paintRectPixels = m_pageLayout.paintRectPixels(resolution); + // Some print devices allow scaling, so that "virtual" page size != current paper size + const int devWidth = GetDeviceCaps(hdc, PHYSICALWIDTH); + const int devHeight = GetDeviceCaps(hdc, PHYSICALHEIGHT); + const int pageWidth = m_pageLayout.fullRectPixels(dpi_x).width(); + const int pageHeight = m_pageLayout.fullRectPixels(dpi_y).height(); + const qreal pageScaleX = (devWidth && pageWidth) ? qreal(devWidth) / pageWidth : 1; + const qreal pageScaleY = (devHeight && pageHeight) ? qreal(devHeight) / pageHeight : 1; + m_paintRectPixels = QTransform::fromScale(pageScaleX, pageScaleY).mapRect(m_paintRectPixels); + QSizeF sizeMM = m_pageLayout.paintRect(QPageLayout::Millimeter).size(); m_paintSizeMM = QSize(qRound(sizeMM.width()), qRound(sizeMM.height())); // Calculate the origin using the physical device pixels, not our paint pixels // Origin is defined as User Margins - Device Margins - QMarginsF margins = m_pageLayout.margins(QPageLayout::Millimeter) / 25.4; - origin_x = qRound(margins.left() * dpi_x) - GetDeviceCaps(hdc, PHYSICALOFFSETX); - origin_y = qRound(margins.top() * dpi_y) - GetDeviceCaps(hdc, PHYSICALOFFSETY); + const bool isFullPage = (m_pageLayout.mode() == QPageLayout::FullPageMode); + const QMarginsF margins = isFullPage ? QMarginsF() : (m_pageLayout.margins(QPageLayout::Millimeter) / 25.4); + origin_x = qRound(pageScaleX * margins.left() * dpi_x) - GetDeviceCaps(hdc, PHYSICALOFFSETX); + origin_y = qRound(pageScaleY * margins.top() * dpi_y) - GetDeviceCaps(hdc, PHYSICALOFFSETY); } void QWin32PrintEnginePrivate::debugMetrics() const @@ -1705,7 +1736,7 @@ static void draw_text_item_win(const QPointF &pos, const QTextItemInt &ti, HDC h const bool has_kerning = ti.f && ti.f->kerning(); - HFONT hfont = 0; + HFONT hfont = nullptr; bool deleteFont = false; if (ti.fontEngine->type() == QFontEngine::Win) { diff --git a/src/printsupport/platform/windows/qprintengine_win_p.h b/src/printsupport/platform/windows/qprintengine_win_p.h index 54e3cf2814..995c31ff1e 100644 --- a/src/printsupport/platform/windows/qprintengine_win_p.h +++ b/src/printsupport/platform/windows/qprintengine_win_p.h @@ -83,25 +83,9 @@ class QWin32PrintEnginePrivate : public QAlphaPaintEnginePrivate Q_DECLARE_PUBLIC(QWin32PrintEngine) public: QWin32PrintEnginePrivate() : - hPrinter(0), - globalDevMode(0), - devMode(0), - pInfo(0), - hMem(0), - hdc(0), - ownsDevMode(false), - mode(QPrinter::ScreenResolution), - state(QPrinter::Idle), - resolution(0), - m_pageLayout(QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0, 0, 0, 0))), - stretch_x(1), stretch_y(1), origin_x(0), origin_y(0), - dpi_x(96), dpi_y(96), dpi_display(96), - num_copies(1), - printToFile(false), - reinit(false), + printToFile(false), reinit(false), complex_xform(false), has_pen(false), has_brush(false), has_custom_paper_size(false), - embed_fonts(true), - txop(0 /* QTransform::TxNone */) + embed_fonts(true) { } @@ -127,6 +111,8 @@ public: is handled in the next begin or newpage. */ void doReinit(); + static void initializeDevMode(DEVMODE *); + bool resetDC(); void strokePath(const QPainterPath &path, const QColor &color); @@ -142,19 +128,19 @@ public: void debugMetrics() const; // Windows GDI printer references. - HANDLE hPrinter; + HANDLE hPrinter = nullptr; - HGLOBAL globalDevMode; - DEVMODE *devMode; - PRINTER_INFO_2 *pInfo; - HGLOBAL hMem; + HGLOBAL globalDevMode = nullptr; + DEVMODE *devMode = nullptr; + PRINTER_INFO_2 *pInfo = nullptr; + HGLOBAL hMem = nullptr; - HDC hdc; + HDC hdc = nullptr; // True if devMode was allocated separately from pInfo. - bool ownsDevMode; + bool ownsDevMode = false; - QPrinter::PrinterMode mode; + QPrinter::PrinterMode mode = QPrinter::ScreenResolution; // Print Device QPrintDevice m_printDevice; @@ -164,26 +150,26 @@ public: QString m_creator; QString fileName; - QPrinter::PrinterState state; - int resolution; + QPrinter::PrinterState state = QPrinter::Idle; + int resolution = 0; // Page Layout - QPageLayout m_pageLayout; - + QPageLayout m_pageLayout{QPageSize(QPageSize::A4), + QPageLayout::Portrait, QMarginsF{0, 0, 0, 0}}; // Page metrics cache QRect m_paintRectPixels; QSize m_paintSizeMM; // Windows painting - qreal stretch_x; - qreal stretch_y; - int origin_x; - int origin_y; + qreal stretch_x = 1; + qreal stretch_y = 1; + int origin_x = 0; + int origin_y = 0; - int dpi_x; - int dpi_y; - int dpi_display; - int num_copies; + int dpi_x = 96; + int dpi_y = 96; + int dpi_display = 96; + int num_copies = 1; uint printToFile : 1; uint reinit : 1; @@ -194,7 +180,7 @@ public: uint has_custom_paper_size : 1; uint embed_fonts : 1; - uint txop; + uint txop = 0; // QTransform::TxNone QColor brush_color; QPen pen; diff --git a/src/printsupport/platform/windows/qwindowsprintdevice.cpp b/src/printsupport/platform/windows/qwindowsprintdevice.cpp index 65784e62ca..9445871ed7 100644 --- a/src/printsupport/platform/windows/qwindowsprintdevice.cpp +++ b/src/printsupport/platform/windows/qwindowsprintdevice.cpp @@ -328,7 +328,7 @@ void QWindowsPrintDevice::loadInputSlots() const QPrint::InputSlot QWindowsPrintDevice::defaultInputSlot() const { - QPrint::InputSlot inputSlot = QPlatformPrintDevice::defaultInputSlot();; + QPrint::InputSlot inputSlot = QPlatformPrintDevice::defaultInputSlot(); if (LPDEVMODE pDevMode = getDevmode(m_hPrinter, m_id)) { // Get the default input slot diff --git a/src/printsupport/platform/windows/qwindowsprintersupport.cpp b/src/printsupport/platform/windows/qwindowsprintersupport.cpp index db55573a0b..7cbd4dc491 100644 --- a/src/printsupport/platform/windows/qwindowsprintersupport.cpp +++ b/src/printsupport/platform/windows/qwindowsprintersupport.cpp @@ -69,8 +69,8 @@ QPlatformPrinterSupport *QWindowsPrinterSupportPlugin::create(const QString &key return nullptr; } -#include "qwindowsprintersupport.moc" - QT_END_NAMESPACE +#include "qwindowsprintersupport.moc" + #endif // QT_NO_PRINTER |