Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qprintengine_mac.mm
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include <AppKit/AppKit.h>
6#include <ApplicationServices/ApplicationServices.h>
7
10#include <quuid.h>
11#include <QtGui/qpagelayout.h>
12#include <QtCore/qcoreapplication.h>
13#include <QtCore/qdebug.h>
14
15#include <QtCore/private/qcore_mac_p.h>
16
17#ifndef QT_NO_PRINTER
18
20
21extern QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits);
22
23QMacPrintEngine::QMacPrintEngine(QPrinter::PrinterMode mode, const QString &deviceId)
24 : QPaintEngine(*(new QMacPrintEnginePrivate))
25{
26 Q_D(QMacPrintEngine);
27 d->mode = mode;
28 QString id = deviceId;
29 if (id.isEmpty())
30 id = QCocoaPrinterSupport().defaultPrintDeviceId();
31 else
32 setProperty(QPrintEngine::PPK_PrinterName, deviceId);
33 d->m_printDevice.reset(new QCocoaPrintDevice(id));
34 d->m_pageLayout.setPageSize(d->m_printDevice->defaultPageSize());
35 d->initialize();
36}
37
38bool QMacPrintEngine::begin(QPaintDevice *dev)
39{
40 Q_D(QMacPrintEngine);
41
42 Q_ASSERT(dev && dev->devType() == QInternal::Printer);
43 if (!static_cast<QPrinter *>(dev)->isValid())
44 return false;
45
46 if (d->state == QPrinter::Idle && !d->isPrintSessionInitialized()) // Need to reinitialize
47 d->initialize();
48
49 d->paintEngine->state = state;
50 d->paintEngine->begin(dev);
51 Q_ASSERT_X(d->state == QPrinter::Idle, "QMacPrintEngine", "printer already active");
52
53 if (PMSessionValidatePrintSettings(d->session(), d->settings(), kPMDontWantBoolean) != noErr
54 || PMSessionValidatePageFormat(d->session(), d->format(), kPMDontWantBoolean) != noErr) {
55 d->state = QPrinter::Error;
56 return false;
57 }
58
59 if (!d->outputFilename.isEmpty()) {
60 QCFType<CFURLRef> outFile = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault,
61 QCFString(d->outputFilename),
62 kCFURLPOSIXPathStyle,
63 false);
64 if (PMSessionSetDestination(d->session(), d->settings(), kPMDestinationFile,
65 kPMDocumentFormatPDF, outFile) != noErr) {
66 qWarning("QMacPrintEngine::begin: Problem setting file [%s]", d->outputFilename.toUtf8().constData());
67 return false;
68 }
69 }
70
71 OSStatus status = PMSessionBeginCGDocumentNoDialog(d->session(), d->settings(), d->format());
72 if (status != noErr) {
73 d->state = QPrinter::Error;
74 return false;
75 }
76
77 d->state = QPrinter::Active;
78 setActive(true);
79 d->newPage_helper();
80 return true;
81}
82
84{
85 Q_D(QMacPrintEngine);
86 if (d->state == QPrinter::Aborted)
87 return true; // I was just here a function call ago :)
88 if (d->paintEngine->type() == QPaintEngine::CoreGraphics) {
89 // We don't need the paint engine to call restoreGraphicsState()
90 static_cast<QCoreGraphicsPaintEngine*>(d->paintEngine)->d_func()->stackCount = 0;
91 static_cast<QCoreGraphicsPaintEngine*>(d->paintEngine)->d_func()->hd = nullptr;
92 }
93 d->paintEngine->end();
94 if (d->state != QPrinter::Idle)
95 d->releaseSession();
96 d->state = QPrinter::Idle;
97 return true;
98}
99
102{
103 return d_func()->paintEngine;
104}
105
107{
108 QCoreGraphicsPaintEngine *cgEngine = static_cast<QCoreGraphicsPaintEngine*>(paintEngine());
109 return cgEngine->d_func()->hd;
110}
111
113{
114 [printInfo release];
115 delete paintEngine;
116}
117
119{
120 return d_func()->state;
121}
122
124{
125 Q_D(QMacPrintEngine);
126 Q_ASSERT(d->state == QPrinter::Active);
127 OSStatus err = PMSessionEndPageNoDialog(d->session());
128 if (err != noErr) {
129 if (err == kPMCancel) {
130 // User canceled, we need to abort!
131 abort();
132 } else {
133 // Not sure what the problem is...
134 qWarning("QMacPrintEngine::newPage: Cannot end current page. %ld", long(err));
135 d->state = QPrinter::Error;
136 }
137 return false;
138 }
139 return d->newPage_helper();
140}
141
143{
144 Q_D(QMacPrintEngine);
145 if (d->state != QPrinter::Active)
146 return false;
147 bool ret = end();
148 d->state = QPrinter::Aborted;
149 return ret;
150}
151
152int QMacPrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const
153{
154 Q_D(const QMacPrintEngine);
155 int val = 1;
156 switch (m) {
157 case QPaintDevice::PdmWidth:
158 val = d->m_pageLayout.paintRectPixels(d->resolution.hRes).width();
159 break;
160 case QPaintDevice::PdmHeight:
161 val = d->m_pageLayout.paintRectPixels(d->resolution.hRes).height();
162 break;
163 case QPaintDevice::PdmWidthMM:
164 val = qRound(d->m_pageLayout.paintRect(QPageLayout::Millimeter).width());
165 break;
166 case QPaintDevice::PdmHeightMM:
167 val = qRound(d->m_pageLayout.paintRect(QPageLayout::Millimeter).height());
168 break;
169 case QPaintDevice::PdmPhysicalDpiX:
170 case QPaintDevice::PdmPhysicalDpiY: {
171 PMPrinter printer;
172 if (PMSessionGetCurrentPrinter(d->session(), &printer) == noErr) {
173 PMResolution resolution;
174 PMPrinterGetOutputResolution(printer, d->settings(), &resolution);
175 val = (int)resolution.vRes;
176 break;
177 }
178 Q_FALLTHROUGH();
179 }
180 case QPaintDevice::PdmDpiY:
181 val = (int)d->resolution.vRes;
182 break;
183 case QPaintDevice::PdmDpiX:
184 val = (int)d->resolution.hRes;
185 break;
186 case QPaintDevice::PdmNumColors:
187 val = (1 << metric(QPaintDevice::PdmDepth));
188 break;
189 case QPaintDevice::PdmDepth:
190 val = 24;
191 break;
192 case QPaintDevice::PdmDevicePixelRatio:
193 val = 1;
194 break;
195 case QPaintDevice::PdmDevicePixelRatioScaled:
196 val = 1 * QPaintDevice::devicePixelRatioFScale();
197 break;
198 default:
199 val = 0;
200 qWarning("QPrinter::metric: Invalid metric command");
201 }
202 return val;
203}
204
206{
207 Q_Q(QMacPrintEngine);
208
209 Q_ASSERT(!printInfo);
210
211 if (!paintEngine)
212 paintEngine = new QCoreGraphicsPaintEngine();
213
214 q->gccaps = paintEngine->gccaps;
215
216 QMacAutoReleasePool pool;
217 printInfo = [[NSPrintInfo alloc] initWithDictionary:[NSDictionary dictionary]];
218
219 QList<int> resolutions = m_printDevice->supportedResolutions();
220 if (!resolutions.isEmpty() && mode != QPrinter::ScreenResolution) {
221 std::sort(resolutions.begin(), resolutions.end());
222 if (resolutions.count() > 1 && mode == QPrinter::HighResolution)
223 resolution.hRes = resolution.vRes = resolutions.constLast();
224 else
225 resolution.hRes = resolution.vRes = resolutions.constFirst();
226 if (resolution.hRes == 0)
227 resolution.hRes = resolution.vRes = 600;
228 } else {
229 resolution.hRes = resolution.vRes = qt_defaultDpi();
230 }
231
232 setPageSize(m_pageLayout.pageSize());
233
234 QHash<QMacPrintEngine::PrintEnginePropertyKey, QVariant>::const_iterator propC;
235 for (propC = valueCache.constBegin(); propC != valueCache.constEnd(); ++propC) {
236 q->setProperty(propC.key(), propC.value());
237 }
238}
239
241{
242 PMSessionEndPageNoDialog(session());
243 PMSessionEndDocumentNoDialog(session());
244 [printInfo release];
245 printInfo = nil;
246}
247
249{
250 Q_Q(QMacPrintEngine);
251 Q_ASSERT(state == QPrinter::Active);
252
253 if (PMSessionError(session()) != noErr) {
254 q->abort();
255 return false;
256 }
257
258 // pop the stack of saved graphic states, in case we get the same
259 // context back - either way, the stack count should be 0 when we
260 // get the new one
261 QCoreGraphicsPaintEngine *cgEngine = static_cast<QCoreGraphicsPaintEngine*>(paintEngine);
262 while (cgEngine->d_func()->stackCount > 0)
263 cgEngine->d_func()->restoreGraphicsState();
264
265 OSStatus status = PMSessionBeginPageNoDialog(session(), format(), nullptr);
266 if (status != noErr) {
267 state = QPrinter::Error;
268 return false;
269 }
270
271 QRect page = m_pageLayout.paintRectPixels(resolution.hRes);
272 QRect paper = m_pageLayout.fullRectPixels(resolution.hRes);
273
274 CGContextRef cgContext;
275 OSStatus err = noErr;
276 err = PMSessionGetCGGraphicsContext(session(), &cgContext);
277 if (err != noErr) {
278 qWarning("QMacPrintEngine::newPage: Cannot retrieve CoreGraphics context: %ld", long(err));
279 state = QPrinter::Error;
280 return false;
281 }
282 cgEngine->d_func()->hd = cgContext;
283
284 // Set the resolution as a scaling ration of 72 (the default).
285 CGContextScaleCTM(cgContext, 72 / resolution.hRes, 72 / resolution.vRes);
286
287 CGContextScaleCTM(cgContext, 1, -1);
288 CGContextTranslateCTM(cgContext, 0, -paper.height());
289 if (m_pageLayout.mode() != QPageLayout::FullPageMode)
290 CGContextTranslateCTM(cgContext, page.x() - paper.x(), page.y() - paper.y());
291 cgEngine->d_func()->orig_xform = CGContextGetCTM(cgContext);
292 cgEngine->d_func()->setClip(nullptr);
293 cgEngine->state->dirtyFlags = QPaintEngine::DirtyFlags(QPaintEngine::AllDirty)
294 & ~(QPaintEngine::DirtyClipEnabled
295 | QPaintEngine::DirtyClipRegion
296 | QPaintEngine::DirtyClipPath);
297 if (cgEngine->painter()->hasClipping())
298 cgEngine->state->dirtyFlags |= QPaintEngine::DirtyClipEnabled;
299 cgEngine->syncState();
300 return true;
301}
302
303void QMacPrintEnginePrivate::setPageSize(const QPageSize &pageSize)
304{
305 if (!pageSize.isValid())
306 return;
307
308 // Get the matching printer paper
309 QPageSize printerPageSize = m_printDevice->supportedPageSize(pageSize);
310 QPageSize usePageSize = printerPageSize.isValid() ? printerPageSize : pageSize;
311
312 // Get the PMPaper and check it is valid
313 PMPaper macPaper = m_printDevice->macPaper(usePageSize);
314 if (!macPaper) {
315 qWarning() << "QMacPrintEngine: Invalid PMPaper returned for " << pageSize;
316 return;
317 }
318
319 QMarginsF printable = m_printDevice->printableMargins(usePageSize, m_pageLayout.orientation(), resolution.hRes);
320 m_pageLayout.setPageSize(usePageSize, qt_convertMargins(printable, QPageLayout::Point, m_pageLayout.units()));
321
322 // You cannot set the page size on a PMPageFormat, you must create a new PMPageFormat
323 PMPageFormat pageFormat;
324 PMCreatePageFormatWithPMPaper(&pageFormat, macPaper);
325 PMSetOrientation(pageFormat, m_pageLayout.orientation() == QPageLayout::Landscape ? kPMLandscape : kPMPortrait, kPMUnlocked);
326 PMCopyPageFormat(pageFormat, format());
327 if (PMSessionValidatePageFormat(session(), format(), kPMDontWantBoolean) != noErr)
328 qWarning("QMacPrintEngine: Invalid page format");
329 PMRelease(pageFormat);
330}
331
332void QMacPrintEngine::updateState(const QPaintEngineState &state)
333{
334 d_func()->paintEngine->updateState(state);
335}
336
337void QMacPrintEngine::drawRects(const QRectF *r, int num)
338{
339 Q_D(QMacPrintEngine);
340 Q_ASSERT(d->state == QPrinter::Active);
341 d->paintEngine->drawRects(r, num);
342}
343
344void QMacPrintEngine::drawPoints(const QPointF *points, int pointCount)
345{
346 Q_D(QMacPrintEngine);
347 Q_ASSERT(d->state == QPrinter::Active);
348 d->paintEngine->drawPoints(points, pointCount);
349}
350
351void QMacPrintEngine::drawEllipse(const QRectF &r)
352{
353 Q_D(QMacPrintEngine);
354 Q_ASSERT(d->state == QPrinter::Active);
355 d->paintEngine->drawEllipse(r);
356}
357
358void QMacPrintEngine::drawLines(const QLineF *lines, int lineCount)
359{
360 Q_D(QMacPrintEngine);
361 Q_ASSERT(d->state == QPrinter::Active);
362 d->paintEngine->drawLines(lines, lineCount);
363}
364
365void QMacPrintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
366{
367 Q_D(QMacPrintEngine);
368 Q_ASSERT(d->state == QPrinter::Active);
369 d->paintEngine->drawPolygon(points, pointCount, mode);
370}
371
372void QMacPrintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
373{
374 Q_D(QMacPrintEngine);
375 Q_ASSERT(d->state == QPrinter::Active);
376 d->paintEngine->drawPixmap(r, pm, sr);
377}
378
379void QMacPrintEngine::drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags)
380{
381 Q_D(QMacPrintEngine);
382 Q_ASSERT(d->state == QPrinter::Active);
383 d->paintEngine->drawImage(r, pm, sr, flags);
384}
385
386void QMacPrintEngine::drawTextItem(const QPointF &p, const QTextItem &ti)
387{
388 Q_D(QMacPrintEngine);
389 Q_ASSERT(d->state == QPrinter::Active);
390 if (!d->embedFonts)
391 QPaintEngine::drawTextItem(p, ti);
392 else
393 d->paintEngine->drawTextItem(p, ti);
394}
395
396void QMacPrintEngine::drawTiledPixmap(const QRectF &dr, const QPixmap &pixmap, const QPointF &sr)
397{
398 Q_D(QMacPrintEngine);
399 Q_ASSERT(d->state == QPrinter::Active);
400 d->paintEngine->drawTiledPixmap(dr, pixmap, sr);
401}
402
403void QMacPrintEngine::drawPath(const QPainterPath &path)
404{
405 Q_D(QMacPrintEngine);
406 Q_ASSERT(d->state == QPrinter::Active);
407 d->paintEngine->drawPath(path);
408}
409
410
411void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value)
412{
413 Q_D(QMacPrintEngine);
414
415 d->valueCache.insert(key, value);
416 if (!d->printInfo)
417 return;
418
419 switch (key) {
420
421 // The following keys are properties or derived values and so cannot be set
422 case PPK_PageRect:
423 break;
424 case PPK_PaperRect:
425 break;
426 case PPK_PaperSources:
427 break;
428 case PPK_SupportsMultipleCopies:
429 break;
430 case PPK_SupportedResolutions:
431 break;
432
433 // The following keys are settings that are unsupported by the Mac PrintEngine
434 case PPK_ColorMode:
435 break;
436 case PPK_CustomBase:
437 break;
438 case PPK_PageOrder:
439 // TODO Check if can be supported via Cups Options
440 break;
441 case PPK_PaperSource:
442 // TODO Check if can be supported via Cups Options
443 break;
444 case PPK_PrinterProgram:
445 break;
446 case PPK_SelectionOption:
447 break;
448
449 // The following keys are properties and settings that are supported by the Mac PrintEngine
450 case PPK_FontEmbedding:
451 d->embedFonts = value.toBool();
452 break;
453 case PPK_Resolution: {
454 int bestResolution = 0;
455 int dpi = value.toInt();
456 int bestDistance = INT_MAX;
457 for (int resolution : d->m_printDevice->supportedResolutions()) {
458 if (dpi == resolution) {
459 bestResolution = resolution;
460 break;
461 } else {
462 int distance = qAbs(dpi - resolution);
463 if (distance < bestDistance) {
464 bestDistance = distance;
465 bestResolution = resolution;
466 }
467 }
468 }
469 PMResolution resolution;
470 resolution.hRes = resolution.vRes = bestResolution;
471 if (PMPrinterSetOutputResolution(d->m_printDevice->macPrinter(), d->settings(), &resolution) == noErr) {
472 // Setting the resolution succeeded.
473 // Now try to read the actual resolution selected by the OS.
474 if (PMPrinterGetOutputResolution(d->m_printDevice->macPrinter(), d->settings(), &d->resolution) != noErr) {
475 // Reading the resolution somehow failed; d->resolution is in undefined state.
476 // So use the value which was acceptable to PMPrinterSetOutputResolution.
477 d->resolution = resolution;
478 }
479 }
480 break;
481 }
482 case PPK_CollateCopies:
483 PMSetCollate(d->settings(), value.toBool());
484 break;
485 case PPK_Creator:
486 d->m_creator = value.toString();
487 break;
488 case PPK_DocumentName:
489 PMPrintSettingsSetJobName(d->settings(), QCFString(value.toString()));
490 break;
491 case PPK_Duplex: {
492 QPrint::DuplexMode mode = QPrint::DuplexMode(value.toInt());
493 if (mode == property(PPK_Duplex).toInt() || !d->m_printDevice->supportedDuplexModes().contains(mode))
494 break;
495 switch (mode) {
496 case QPrint::DuplexNone:
497 PMSetDuplex(d->settings(), kPMDuplexNone);
498 break;
499 case QPrint::DuplexAuto:
500 PMSetDuplex(d->settings(), d->m_pageLayout.orientation() == QPageLayout::Landscape ? kPMDuplexTumble : kPMDuplexNoTumble);
501 break;
502 case QPrint::DuplexLongSide:
503 PMSetDuplex(d->settings(), kPMDuplexNoTumble);
504 break;
505 case QPrint::DuplexShortSide:
506 PMSetDuplex(d->settings(), kPMDuplexTumble);
507 break;
508 default:
509 // Don't change
510 break;
511 }
512 break;
513 }
514 case PPK_FullPage:
515 if (value.toBool())
516 d->m_pageLayout.setMode(QPageLayout::FullPageMode);
517 else
518 d->m_pageLayout.setMode(QPageLayout::StandardMode);
519 break;
520 case PPK_CopyCount: // fallthrough
521 case PPK_NumberOfCopies:
522 PMSetCopies(d->settings(), value.toInt(), false);
523 break;
524 case PPK_Orientation: {
525 // First try set the Mac format orientation, then set our orientation to match result
526 QPageLayout::Orientation newOrientation = QPageLayout::Orientation(value.toInt());
527 PMOrientation macOrientation = (newOrientation == QPageLayout::Landscape) ? kPMLandscape : kPMPortrait;
528 PMSetOrientation(d->format(), macOrientation, kPMUnlocked);
529 PMSessionValidatePageFormat(d->session(), d->format(), kPMDontWantBoolean);
530 PMGetOrientation(d->format(), &macOrientation);
531 d->m_pageLayout.setOrientation(macOrientation == kPMLandscape ? QPageLayout::Landscape : QPageLayout::Portrait);
532 break;
533 }
534 case PPK_OutputFileName:
535 d->outputFilename = value.toString();
536 break;
537 case PPK_PageSize:
538 d->setPageSize(QPageSize(QPageSize::PageSizeId(value.toInt())));
539 break;
540 case PPK_PaperName:
541 // Get the named page size from the printer if supported
542 d->setPageSize(d->m_printDevice->supportedPageSize(value.toString()));
543 break;
544 case PPK_WindowsPageSize:
545 d->setPageSize(QPageSize(QPageSize::id(value.toInt())));
546 break;
547 case PPK_PrinterName: {
548 QVariant pageSize = QVariant::fromValue(d->m_pageLayout.pageSize());
549 const bool isFullPage = d->m_pageLayout.mode() == QPageLayout::FullPageMode;
550 QVariant orientation = QVariant::fromValue(d->m_pageLayout.orientation());
551 QVariant margins = QVariant::fromValue(QPair<QMarginsF, QPageLayout::Unit>(d->m_pageLayout.margins(),
552 d->m_pageLayout.units()));
553 QString id = value.toString();
554 if (id.isEmpty())
555 id = QCocoaPrinterSupport().defaultPrintDeviceId();
556 else if (!QCocoaPrinterSupport().availablePrintDeviceIds().contains(id))
557 break;
558 d->m_printDevice.reset(new QCocoaPrintDevice(id));
559 PMPrinter printer = d->m_printDevice->macPrinter();
560 PMRetain(printer);
561 PMSessionSetCurrentPMPrinter(d->session(), printer);
562 // Ensure the settings are up to date and valid
563 if (d->m_printDevice->supportedPageSize(pageSize.value<QPageSize>()).isValid())
564 setProperty(PPK_QPageSize, pageSize);
565 else
566 setProperty(PPK_CustomPaperSize, pageSize.value<QPageSize>().size(QPageSize::Point));
567 setProperty(PPK_FullPage, QVariant(isFullPage));
568 setProperty(PPK_Orientation, orientation);
569 setProperty(PPK_QPageMargins, margins);
570 break;
571 }
572 case PPK_CustomPaperSize:
573 d->setPageSize(QPageSize(value.toSizeF(), QPageSize::Point));
574 break;
575 case PPK_PageMargins:
576 {
577 QList<QVariant> margins(value.toList());
578 Q_ASSERT(margins.size() == 4);
579 d->m_pageLayout.setMargins(QMarginsF(margins.at(0).toReal(), margins.at(1).toReal(),
580 margins.at(2).toReal(), margins.at(3).toReal()),
581 QPageLayout::OutOfBoundsPolicy::Clamp);
582 break;
583 }
584 case PPK_QPageSize:
585 d->setPageSize(value.value<QPageSize>());
586 break;
587 case PPK_QPageMargins: {
588 QPair<QMarginsF, QPageLayout::Unit> pair = value.value<QPair<QMarginsF, QPageLayout::Unit> >();
589 d->m_pageLayout.setUnits(pair.second);
590 d->m_pageLayout.setMargins(pair.first, QPageLayout::OutOfBoundsPolicy::Clamp);
591 break;
592 }
593 case PPK_QPageLayout: {
594 QPageLayout pageLayout = value.value<QPageLayout>();
595 if (pageLayout.isValid() && d->m_printDevice->isValidPageLayout(pageLayout, d->resolution.hRes)) {
596 setProperty(PPK_QPageSize, QVariant::fromValue(pageLayout.pageSize()));
597 setProperty(PPK_FullPage, pageLayout.mode() == QPageLayout::FullPageMode);
598 setProperty(PPK_Orientation, QVariant::fromValue(pageLayout.orientation()));
599 d->m_pageLayout.setUnits(pageLayout.units());
600 d->m_pageLayout.setMargins(pageLayout.margins(), QPageLayout::OutOfBoundsPolicy::Clamp);
601 }
602 break;
603 }
604 // No default so that compiler will complain if new keys added and not handled in this engine
605 }
606}
607
608QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const
609{
610 Q_D(const QMacPrintEngine);
611 QVariant ret;
612
613 if (!d->printInfo && d->valueCache.contains(key))
614 return *d->valueCache.find(key);
615
616 switch (key) {
617
618 // The following keys are settings that are unsupported by the Mac PrintEngine
619 // Return sensible default values to ensure consistent behavior across platforms
620 case PPK_ColorMode:
621 ret = QPrinter::Color;
622 break;
623 case PPK_CustomBase:
624 // Special case, leave null
625 break;
626 case PPK_PageOrder:
627 // TODO Check if can be supported via Cups Options
628 ret = QPrinter::FirstPageFirst;
629 break;
630 case PPK_PaperSource:
631 // TODO Check if can be supported via Cups Options
632 ret = QPrinter::Auto;
633 break;
634 case PPK_PaperSources: {
635 // TODO Check if can be supported via Cups Options
636 QList<QVariant> out;
637 out << int(QPrinter::Auto);
638 ret = out;
639 break;
640 }
641 case PPK_PrinterProgram:
642 ret = QString();
643 break;
644 case PPK_SelectionOption:
645 ret = QString();
646 break;
647
648 // The following keys are properties and settings that are supported by the Mac PrintEngine
649 case PPK_FontEmbedding:
650 ret = d->embedFonts;
651 break;
652 case PPK_CollateCopies: {
653 Boolean status;
654 PMGetCollate(d->settings(), &status);
655 ret = bool(status);
656 break;
657 }
658 case PPK_Creator:
659 ret = d->m_creator;
660 break;
661 case PPK_DocumentName: {
662 CFStringRef name;
663 PMPrintSettingsGetJobName(d->settings(), &name);
664 ret = QString::fromCFString(name);
665 break;
666 }
667 case PPK_Duplex: {
668 PMDuplexMode mode = kPMDuplexNone;
669 PMGetDuplex(d->settings(), &mode);
670 switch (mode) {
671 case kPMDuplexNoTumble:
672 ret = QPrinter::DuplexLongSide;
673 break;
674 case kPMDuplexTumble:
675 ret = QPrinter::DuplexShortSide;
676 break;
677 case kPMDuplexNone:
678 default:
679 ret = QPrinter::DuplexNone;
680 break;
681 }
682 break;
683 }
684 case PPK_FullPage:
685 ret = d->m_pageLayout.mode() == QPageLayout::FullPageMode;
686 break;
687 case PPK_NumberOfCopies:
688 ret = 1;
689 break;
690 case PPK_CopyCount: {
691 UInt32 copies = 1;
692 PMGetCopies(d->settings(), &copies);
693 ret = (uint) copies;
694 break;
695 }
696 case PPK_SupportsMultipleCopies:
697 ret = true;
698 break;
699 case PPK_Orientation:
700 ret = d->m_pageLayout.orientation();
701 break;
702 case PPK_OutputFileName:
703 ret = d->outputFilename;
704 break;
705 case PPK_PageRect:
706 // PageRect is returned in device pixels
707 ret = d->m_pageLayout.paintRectPixels(d->resolution.hRes);
708 break;
709 case PPK_PageSize:
710 ret = d->m_pageLayout.pageSize().id();
711 break;
712 case PPK_PaperName:
713 ret = d->m_pageLayout.pageSize().name();
714 break;
715 case PPK_WindowsPageSize:
716 ret = d->m_pageLayout.pageSize().windowsId();
717 break;
718 case PPK_PaperRect:
719 // PaperRect is returned in device pixels
720 ret = d->m_pageLayout.fullRectPixels(d->resolution.hRes);
721 break;
722 case PPK_PrinterName:
723 return d->m_printDevice->id();
724 break;
725 case PPK_Resolution: {
726 ret = d->resolution.hRes;
727 break;
728 }
729 case PPK_SupportedResolutions: {
730 QList<QVariant> list;
731 for (int resolution : d->m_printDevice->supportedResolutions())
732 list << resolution;
733 ret = list;
734 break;
735 }
736 case PPK_CustomPaperSize:
737 ret = d->m_pageLayout.fullRectPoints().size();
738 break;
739 case PPK_PageMargins: {
740 QList<QVariant> list;
741 QMarginsF margins = d->m_pageLayout.margins(QPageLayout::Point);
742 list << margins.left() << margins.top() << margins.right() << margins.bottom();
743 ret = list;
744 break;
745 }
746 case PPK_QPageSize:
747 ret.setValue(d->m_pageLayout.pageSize());
748 break;
749 case PPK_QPageMargins: {
750 QPair<QMarginsF, QPageLayout::Unit> pair = qMakePair(d->m_pageLayout.margins(), d->m_pageLayout.units());
751 ret.setValue(pair);
752 break;
753 }
754 case PPK_QPageLayout:
755 ret.setValue(d->m_pageLayout);
756 // No default so that compiler will complain if new keys added and not handled in this engine
757 }
758 return ret;
759}
760
762{
763 Q_D(QMacPrintEngine);
764 if (d->state == QPrinter::Idle && !d->isPrintSessionInitialized())
765 d->initialize();
766 return d->printInfo;
767}
768
769QT_END_NAMESPACE
770
771#endif // QT_NO_PRINTER
void setPageSize(const QPageSize &pageSize)
virtual void drawPoints(const QPointF *p, int pointCount)
Draws the first pointCount points in the buffer points.
void updateState(const QPaintEngineState &state)
Reimplement this function to update the state of a paint engine.
QPaintEngine * paintEngine() const
virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags)
Reimplement this function to draw the part of the image specified by the sr rectangle in the given re...
virtual void drawTextItem(const QPointF &p, const QTextItem &ti)
This function draws the text item textItem at position p.
QVariant property(PrintEnginePropertyKey key) const
Returns the print engine's property specified by key.
virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s)
Reimplement this function to draw the pixmap in the given rect, starting at the given p.
virtual void drawPath(const QPainterPath &)
The default implementation ignores the path and does nothing.
bool newPage()
Instructs the print engine to start a new page.
Qt::HANDLE handle() const
virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
Reimplement this virtual function to draw the polygon defined by the pointCount first points in point...
QPrinter::PrinterState printerState() const
Returns the current state of the printer being used by the print engine.
virtual void drawRects(const QRectF *r, int num)
Draws the first rectCount rectangles in the buffer rects.
NSPrintInfo * printInfo()
bool end()
Reimplement this function to finish painting on the current paint device.
bool begin(QPaintDevice *dev)
Reimplement this function to initialise your paint engine when painting is to start on the paint devi...
virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
Reimplement this function to draw the part of the pm specified by the sr rectangle in the given r.
bool abort()
Instructs the print engine to abort the printing process.
int metric(QPaintDevice::PaintDeviceMetric) const
Returns the metric for the given id.
virtual void drawEllipse(const QRectF &r)
Reimplement this function to draw the largest ellipse that can be contained within rectangle rect.
void setProperty(PrintEnginePropertyKey key, const QVariant &value)
Sets the print engine's property specified by key to the given value.
virtual void drawLines(const QLineF *lines, int lineCount)
The default implementation splits the list of lines in lines into lineCount separate calls to drawPat...
QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits)
struct CGContext * CGContextRef