/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or (at your option) the GNU General ** Public license version 3 or any later version approved by the KDE Free ** Qt Foundation. The licenses are as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-2.0.html and ** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qprintengine_mac_p.h" #include "qcocoaprintersupport.h" #include #include #include #include #ifndef QT_NO_PRINTER QT_BEGIN_NAMESPACE extern QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits); QMacPrintEngine::QMacPrintEngine(QPrinter::PrinterMode mode, const QString &deviceId) : QPaintEngine(*(new QMacPrintEnginePrivate)) { Q_D(QMacPrintEngine); d->mode = mode; QString id = deviceId; if (id.isEmpty()) id = QCocoaPrinterSupport().defaultPrintDeviceId(); else setProperty(QPrintEngine::PPK_PrinterName, deviceId); d->m_printDevice.reset(new QCocoaPrintDevice(id)); d->m_pageLayout.setPageSize(d->m_printDevice->defaultPageSize()); d->initialize(); } bool QMacPrintEngine::begin(QPaintDevice *dev) { Q_D(QMacPrintEngine); Q_ASSERT(dev && dev->devType() == QInternal::Printer); if (!static_cast(dev)->isValid()) return false; if (d->state == QPrinter::Idle && !d->isPrintSessionInitialized()) // Need to reinitialize d->initialize(); d->paintEngine->state = state; d->paintEngine->begin(dev); Q_ASSERT_X(d->state == QPrinter::Idle, "QMacPrintEngine", "printer already active"); if (PMSessionValidatePrintSettings(d->session(), d->settings(), kPMDontWantBoolean) != noErr || PMSessionValidatePageFormat(d->session(), d->format(), kPMDontWantBoolean) != noErr) { d->state = QPrinter::Error; return false; } if (!d->outputFilename.isEmpty()) { QCFType outFile = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, QCFString(d->outputFilename), kCFURLPOSIXPathStyle, false); if (PMSessionSetDestination(d->session(), d->settings(), kPMDestinationFile, kPMDocumentFormatPDF, outFile) != noErr) { qWarning("QMacPrintEngine::begin: Problem setting file [%s]", d->outputFilename.toUtf8().constData()); return false; } } OSStatus status = PMSessionBeginCGDocumentNoDialog(d->session(), d->settings(), d->format()); if (status != noErr) { d->state = QPrinter::Error; return false; } d->state = QPrinter::Active; setActive(true); d->newPage_helper(); return true; } bool QMacPrintEngine::end() { Q_D(QMacPrintEngine); if (d->state == QPrinter::Aborted) return true; // I was just here a function call ago :) if (d->paintEngine->type() == QPaintEngine::CoreGraphics) { // We don't need the paint engine to call restoreGraphicsState() static_cast(d->paintEngine)->d_func()->stackCount = 0; static_cast(d->paintEngine)->d_func()->hd = nullptr; } d->paintEngine->end(); if (d->state != QPrinter::Idle) d->releaseSession(); d->state = QPrinter::Idle; return true; } QPaintEngine * QMacPrintEngine::paintEngine() const { return d_func()->paintEngine; } Qt::HANDLE QMacPrintEngine::handle() const { QCoreGraphicsPaintEngine *cgEngine = static_cast(paintEngine()); return cgEngine->d_func()->hd; } QMacPrintEnginePrivate::~QMacPrintEnginePrivate() { [printInfo release]; delete paintEngine; } QPrinter::PrinterState QMacPrintEngine::printerState() const { return d_func()->state; } bool QMacPrintEngine::newPage() { Q_D(QMacPrintEngine); Q_ASSERT(d->state == QPrinter::Active); OSStatus err = PMSessionEndPageNoDialog(d->session()); if (err != noErr) { if (err == kPMCancel) { // User canceled, we need to abort! abort(); } else { // Not sure what the problem is... qWarning("QMacPrintEngine::newPage: Cannot end current page. %ld", long(err)); d->state = QPrinter::Error; } return false; } return d->newPage_helper(); } bool QMacPrintEngine::abort() { Q_D(QMacPrintEngine); if (d->state != QPrinter::Active) return false; bool ret = end(); d->state = QPrinter::Aborted; return ret; } int QMacPrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const { Q_D(const QMacPrintEngine); int val = 1; switch (m) { case QPaintDevice::PdmWidth: val = d->m_pageLayout.paintRectPixels(d->resolution.hRes).width(); break; case QPaintDevice::PdmHeight: val = d->m_pageLayout.paintRectPixels(d->resolution.hRes).height(); break; case QPaintDevice::PdmWidthMM: val = qRound(d->m_pageLayout.paintRect(QPageLayout::Millimeter).width()); break; case QPaintDevice::PdmHeightMM: val = qRound(d->m_pageLayout.paintRect(QPageLayout::Millimeter).height()); break; case QPaintDevice::PdmPhysicalDpiX: case QPaintDevice::PdmPhysicalDpiY: { PMPrinter printer; if (PMSessionGetCurrentPrinter(d->session(), &printer) == noErr) { PMResolution resolution; PMPrinterGetOutputResolution(printer, d->settings(), &resolution); val = (int)resolution.vRes; break; } Q_FALLTHROUGH(); } case QPaintDevice::PdmDpiY: val = (int)d->resolution.vRes; break; case QPaintDevice::PdmDpiX: val = (int)d->resolution.hRes; break; case QPaintDevice::PdmNumColors: val = (1 << metric(QPaintDevice::PdmDepth)); break; case QPaintDevice::PdmDepth: val = 24; break; case QPaintDevice::PdmDevicePixelRatio: val = 1; break; case QPaintDevice::PdmDevicePixelRatioScaled: val = 1 * QPaintDevice::devicePixelRatioFScale(); break; default: val = 0; qWarning("QPrinter::metric: Invalid metric command"); } return val; } void QMacPrintEnginePrivate::initialize() { Q_Q(QMacPrintEngine); Q_ASSERT(!printInfo); if (!paintEngine) paintEngine = new QCoreGraphicsPaintEngine(); q->gccaps = paintEngine->gccaps; QMacAutoReleasePool pool; printInfo = [[NSPrintInfo alloc] initWithDictionary:[NSDictionary dictionary]]; QList resolutions = m_printDevice->supportedResolutions(); if (!resolutions.isEmpty() && mode != QPrinter::ScreenResolution) { std::sort(resolutions.begin(), resolutions.end()); if (resolutions.count() > 1 && mode == QPrinter::HighResolution) resolution.hRes = resolution.vRes = resolutions.last(); else resolution.hRes = resolution.vRes = resolutions.first(); if (resolution.hRes == 0) resolution.hRes = resolution.vRes = 600; } else { resolution.hRes = resolution.vRes = qt_defaultDpi(); } setPageSize(m_pageLayout.pageSize()); QHash::const_iterator propC; for (propC = valueCache.constBegin(); propC != valueCache.constEnd(); ++propC) { q->setProperty(propC.key(), propC.value()); } } void QMacPrintEnginePrivate::releaseSession() { PMSessionEndPageNoDialog(session()); PMSessionEndDocumentNoDialog(session()); [printInfo release]; printInfo = nil; } bool QMacPrintEnginePrivate::newPage_helper() { Q_Q(QMacPrintEngine); Q_ASSERT(state == QPrinter::Active); if (PMSessionError(session()) != noErr) { q->abort(); return false; } // pop the stack of saved graphic states, in case we get the same // context back - either way, the stack count should be 0 when we // get the new one QCoreGraphicsPaintEngine *cgEngine = static_cast(paintEngine); while (cgEngine->d_func()->stackCount > 0) cgEngine->d_func()->restoreGraphicsState(); OSStatus status = PMSessionBeginPageNoDialog(session(), format(), nullptr); if (status != noErr) { state = QPrinter::Error; return false; } QRect page = m_pageLayout.paintRectPixels(resolution.hRes); QRect paper = m_pageLayout.fullRectPixels(resolution.hRes); CGContextRef cgContext; OSStatus err = noErr; err = PMSessionGetCGGraphicsContext(session(), &cgContext); if (err != noErr) { qWarning("QMacPrintEngine::newPage: Cannot retrieve CoreGraphics context: %ld", long(err)); state = QPrinter::Error; return false; } cgEngine->d_func()->hd = cgContext; // Set the resolution as a scaling ration of 72 (the default). CGContextScaleCTM(cgContext, 72 / resolution.hRes, 72 / resolution.vRes); CGContextScaleCTM(cgContext, 1, -1); CGContextTranslateCTM(cgContext, 0, -paper.height()); if (m_pageLayout.mode() != QPageLayout::FullPageMode) CGContextTranslateCTM(cgContext, page.x() - paper.x(), page.y() - paper.y()); cgEngine->d_func()->orig_xform = CGContextGetCTM(cgContext); cgEngine->d_func()->setClip(nullptr); cgEngine->state->dirtyFlags = QPaintEngine::DirtyFlag(QPaintEngine::AllDirty & ~(QPaintEngine::DirtyClipEnabled | QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyClipPath)); if (cgEngine->painter()->hasClipping()) cgEngine->state->dirtyFlags |= QPaintEngine::DirtyClipEnabled; cgEngine->syncState(); return true; } void QMacPrintEnginePrivate::setPageSize(const QPageSize &pageSize) { if (!pageSize.isValid()) return; // Get the matching printer paper QPageSize printerPageSize = m_printDevice->supportedPageSize(pageSize); QPageSize usePageSize = printerPageSize.isValid() ? printerPageSize : pageSize; // Get the PMPaper and check it is valid PMPaper macPaper = m_printDevice->macPaper(usePageSize); if (!macPaper) { qWarning() << "QMacPrintEngine: Invalid PMPaper returned for " << pageSize; return; } QMarginsF printable = m_printDevice->printableMargins(usePageSize, m_pageLayout.orientation(), resolution.hRes); m_pageLayout.setPageSize(usePageSize, qt_convertMargins(printable, QPageLayout::Point, m_pageLayout.units())); // You cannot set the page size on a PMPageFormat, you must create a new PMPageFormat PMPageFormat pageFormat; PMCreatePageFormatWithPMPaper(&pageFormat, macPaper); PMSetOrientation(pageFormat, m_pageLayout.orientation() == QPageLayout::Landscape ? kPMLandscape : kPMPortrait, kPMUnlocked); PMCopyPageFormat(pageFormat, format()); if (PMSessionValidatePageFormat(session(), format(), kPMDontWantBoolean) != noErr) qWarning("QMacPrintEngine: Invalid page format"); PMRelease(pageFormat); } void QMacPrintEngine::updateState(const QPaintEngineState &state) { d_func()->paintEngine->updateState(state); } void QMacPrintEngine::drawRects(const QRectF *r, int num) { Q_D(QMacPrintEngine); Q_ASSERT(d->state == QPrinter::Active); d->paintEngine->drawRects(r, num); } void QMacPrintEngine::drawPoints(const QPointF *points, int pointCount) { Q_D(QMacPrintEngine); Q_ASSERT(d->state == QPrinter::Active); d->paintEngine->drawPoints(points, pointCount); } void QMacPrintEngine::drawEllipse(const QRectF &r) { Q_D(QMacPrintEngine); Q_ASSERT(d->state == QPrinter::Active); d->paintEngine->drawEllipse(r); } void QMacPrintEngine::drawLines(const QLineF *lines, int lineCount) { Q_D(QMacPrintEngine); Q_ASSERT(d->state == QPrinter::Active); d->paintEngine->drawLines(lines, lineCount); } void QMacPrintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) { Q_D(QMacPrintEngine); Q_ASSERT(d->state == QPrinter::Active); d->paintEngine->drawPolygon(points, pointCount, mode); } void QMacPrintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) { Q_D(QMacPrintEngine); Q_ASSERT(d->state == QPrinter::Active); d->paintEngine->drawPixmap(r, pm, sr); } void QMacPrintEngine::drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags) { Q_D(QMacPrintEngine); Q_ASSERT(d->state == QPrinter::Active); d->paintEngine->drawImage(r, pm, sr, flags); } void QMacPrintEngine::drawTextItem(const QPointF &p, const QTextItem &ti) { Q_D(QMacPrintEngine); Q_ASSERT(d->state == QPrinter::Active); if (!d->embedFonts) QPaintEngine::drawTextItem(p, ti); else d->paintEngine->drawTextItem(p, ti); } void QMacPrintEngine::drawTiledPixmap(const QRectF &dr, const QPixmap &pixmap, const QPointF &sr) { Q_D(QMacPrintEngine); Q_ASSERT(d->state == QPrinter::Active); d->paintEngine->drawTiledPixmap(dr, pixmap, sr); } void QMacPrintEngine::drawPath(const QPainterPath &path) { Q_D(QMacPrintEngine); Q_ASSERT(d->state == QPrinter::Active); d->paintEngine->drawPath(path); } void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value) { Q_D(QMacPrintEngine); d->valueCache.insert(key, value); if (!d->printInfo) return; switch (key) { // The following keys are properties or derived values and so cannot be set case PPK_PageRect: break; case PPK_PaperRect: break; case PPK_PaperSources: break; case PPK_SupportsMultipleCopies: break; case PPK_SupportedResolutions: break; // The following keys are settings that are unsupported by the Mac PrintEngine case PPK_ColorMode: break; case PPK_CustomBase: break; case PPK_PageOrder: // TODO Check if can be supported via Cups Options break; case PPK_PaperSource: // TODO Check if can be supported via Cups Options break; case PPK_PrinterProgram: break; case PPK_SelectionOption: break; // The following keys are properties and settings that are supported by the Mac PrintEngine case PPK_FontEmbedding: d->embedFonts = value.toBool(); break; case PPK_Resolution: { int bestResolution = 0; int dpi = value.toInt(); int bestDistance = INT_MAX; foreach (int resolution, d->m_printDevice->supportedResolutions()) { if (dpi == resolution) { bestResolution = resolution; break; } else { int distance = qAbs(dpi - resolution); if (distance < bestDistance) { bestDistance = distance; bestResolution = resolution; } } } PMResolution resolution; resolution.hRes = resolution.vRes = bestResolution; if (PMPrinterSetOutputResolution(d->m_printDevice->macPrinter(), d->settings(), &resolution) == noErr) { // Setting the resolution succeeded. // Now try to read the actual resolution selected by the OS. if (PMPrinterGetOutputResolution(d->m_printDevice->macPrinter(), d->settings(), &d->resolution) != noErr) { // Reading the resolution somehow failed; d->resolution is in undefined state. // So use the value which was acceptable to PMPrinterSetOutputResolution. d->resolution = resolution; } } break; } case PPK_CollateCopies: PMSetCollate(d->settings(), value.toBool()); break; case PPK_Creator: d->m_creator = value.toString(); break; case PPK_DocumentName: PMPrintSettingsSetJobName(d->settings(), QCFString(value.toString())); break; case PPK_Duplex: { QPrint::DuplexMode mode = QPrint::DuplexMode(value.toInt()); if (mode == property(PPK_Duplex).toInt() || !d->m_printDevice->supportedDuplexModes().contains(mode)) break; switch (mode) { case QPrint::DuplexNone: PMSetDuplex(d->settings(), kPMDuplexNone); break; case QPrint::DuplexAuto: PMSetDuplex(d->settings(), d->m_pageLayout.orientation() == QPageLayout::Landscape ? kPMDuplexTumble : kPMDuplexNoTumble); break; case QPrint::DuplexLongSide: PMSetDuplex(d->settings(), kPMDuplexNoTumble); break; case QPrint::DuplexShortSide: PMSetDuplex(d->settings(), kPMDuplexTumble); break; default: // Don't change break; } break; } case PPK_FullPage: if (value.toBool()) d->m_pageLayout.setMode(QPageLayout::FullPageMode); else d->m_pageLayout.setMode(QPageLayout::StandardMode); break; case PPK_CopyCount: // fallthrough case PPK_NumberOfCopies: PMSetCopies(d->settings(), value.toInt(), false); break; case PPK_Orientation: { // First try set the Mac format orientation, then set our orientation to match result QPageLayout::Orientation newOrientation = QPageLayout::Orientation(value.toInt()); PMOrientation macOrientation = (newOrientation == QPageLayout::Landscape) ? kPMLandscape : kPMPortrait; PMSetOrientation(d->format(), macOrientation, kPMUnlocked); PMSessionValidatePageFormat(d->session(), d->format(), kPMDontWantBoolean); PMGetOrientation(d->format(), &macOrientation); d->m_pageLayout.setOrientation(macOrientation == kPMLandscape ? QPageLayout::Landscape : QPageLayout::Portrait); break; } case PPK_OutputFileName: d->outputFilename = value.toString(); break; case PPK_PageSize: d->setPageSize(QPageSize(QPageSize::PageSizeId(value.toInt()))); break; case PPK_PaperName: // Get the named page size from the printer if supported d->setPageSize(d->m_printDevice->supportedPageSize(value.toString())); break; case PPK_WindowsPageSize: d->setPageSize(QPageSize(QPageSize::id(value.toInt()))); break; case PPK_PrinterName: { QVariant pageSize = QVariant::fromValue(d->m_pageLayout.pageSize()); const bool isFullPage = d->m_pageLayout.mode() == QPageLayout::FullPageMode; QVariant orientation = QVariant::fromValue(d->m_pageLayout.orientation()); QVariant margins = QVariant::fromValue(QPair(d->m_pageLayout.margins(), d->m_pageLayout.units())); QString id = value.toString(); if (id.isEmpty()) id = QCocoaPrinterSupport().defaultPrintDeviceId(); else if (!QCocoaPrinterSupport().availablePrintDeviceIds().contains(id)) break; d->m_printDevice.reset(new QCocoaPrintDevice(id)); PMPrinter printer = d->m_printDevice->macPrinter(); PMRetain(printer); PMSessionSetCurrentPMPrinter(d->session(), printer); // Ensure the settings are up to date and valid if (d->m_printDevice->supportedPageSize(pageSize.value()).isValid()) setProperty(PPK_QPageSize, pageSize); else setProperty(PPK_CustomPaperSize, pageSize.value().size(QPageSize::Point)); setProperty(PPK_FullPage, QVariant(isFullPage)); setProperty(PPK_Orientation, orientation); setProperty(PPK_QPageMargins, margins); break; } case PPK_CustomPaperSize: d->setPageSize(QPageSize(value.toSizeF(), QPageSize::Point)); break; case PPK_PageMargins: { QList margins(value.toList()); Q_ASSERT(margins.size() == 4); d->m_pageLayout.setMargins(QMarginsF(margins.at(0).toReal(), margins.at(1).toReal(), margins.at(2).toReal(), margins.at(3).toReal())); break; } case PPK_QPageSize: d->setPageSize(value.value()); break; case PPK_QPageMargins: { QPair pair = value.value >(); d->m_pageLayout.setUnits(pair.second); d->m_pageLayout.setMargins(pair.first); break; } case PPK_QPageLayout: { QPageLayout pageLayout = value.value(); if (pageLayout.isValid() && d->m_printDevice->isValidPageLayout(pageLayout, d->resolution.hRes)) { setProperty(PPK_QPageSize, QVariant::fromValue(pageLayout.pageSize())); 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()); } break; } // No default so that compiler will complain if new keys added and not handled in this engine } } QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const { Q_D(const QMacPrintEngine); QVariant ret; if (!d->printInfo && d->valueCache.contains(key)) return *d->valueCache.find(key); switch (key) { // The following keys are settings that are unsupported by the Mac PrintEngine // Return sensible default values to ensure consistent behavior across platforms case PPK_ColorMode: ret = QPrinter::Color; break; case PPK_CustomBase: // Special case, leave null break; case PPK_PageOrder: // TODO Check if can be supported via Cups Options ret = QPrinter::FirstPageFirst; break; case PPK_PaperSource: // TODO Check if can be supported via Cups Options ret = QPrinter::Auto; break; case PPK_PaperSources: { // TODO Check if can be supported via Cups Options QList out; out << int(QPrinter::Auto); ret = out; break; } case PPK_PrinterProgram: ret = QString(); break; case PPK_SelectionOption: ret = QString(); break; // The following keys are properties and settings that are supported by the Mac PrintEngine case PPK_FontEmbedding: ret = d->embedFonts; break; case PPK_CollateCopies: { Boolean status; PMGetCollate(d->settings(), &status); ret = bool(status); break; } case PPK_Creator: ret = d->m_creator; break; case PPK_DocumentName: { CFStringRef name; PMPrintSettingsGetJobName(d->settings(), &name); ret = QString::fromCFString(name); break; } case PPK_Duplex: { PMDuplexMode mode = kPMDuplexNone; PMGetDuplex(d->settings(), &mode); switch (mode) { case kPMDuplexNoTumble: ret = QPrinter::DuplexLongSide; break; case kPMDuplexTumble: ret = QPrinter::DuplexShortSide; break; case kPMDuplexNone: default: ret = QPrinter::DuplexNone; break; } break; } case PPK_FullPage: ret = d->m_pageLayout.mode() == QPageLayout::FullPageMode; break; case PPK_NumberOfCopies: ret = 1; break; case PPK_CopyCount: { UInt32 copies = 1; PMGetCopies(d->settings(), &copies); ret = (uint) copies; break; } case PPK_SupportsMultipleCopies: ret = true; break; case PPK_Orientation: ret = d->m_pageLayout.orientation(); break; case PPK_OutputFileName: ret = d->outputFilename; break; case PPK_PageRect: // PageRect is returned in device pixels ret = d->m_pageLayout.paintRectPixels(d->resolution.hRes); break; case PPK_PageSize: ret = d->m_pageLayout.pageSize().id(); break; case PPK_PaperName: ret = d->m_pageLayout.pageSize().name(); break; case PPK_WindowsPageSize: ret = d->m_pageLayout.pageSize().windowsId(); break; case PPK_PaperRect: // PaperRect is returned in device pixels ret = d->m_pageLayout.fullRectPixels(d->resolution.hRes); break; case PPK_PrinterName: return d->m_printDevice->id(); break; case PPK_Resolution: { ret = d->resolution.hRes; break; } case PPK_SupportedResolutions: { QList list; foreach (int resolution, d->m_printDevice->supportedResolutions()) list << resolution; ret = list; break; } case PPK_CustomPaperSize: ret = d->m_pageLayout.fullRectPoints().size(); break; case PPK_PageMargins: { QList list; QMarginsF margins = d->m_pageLayout.margins(QPageLayout::Point); list << margins.left() << margins.top() << margins.right() << margins.bottom(); ret = list; break; } case PPK_QPageSize: ret.setValue(d->m_pageLayout.pageSize()); break; case PPK_QPageMargins: { QPair pair = qMakePair(d->m_pageLayout.margins(), d->m_pageLayout.units()); ret.setValue(pair); break; } case PPK_QPageLayout: ret.setValue(d->m_pageLayout); // No default so that compiler will complain if new keys added and not handled in this engine } return ret; } QT_END_NAMESPACE #endif // QT_NO_PRINTER