4#include <QtPrintSupport/qtprintsupportglobal.h>
12#include <private/qprinter_p.h>
13#include <private/qfont_p.h>
14#include <private/qfontengine_p.h>
15#include <private/qpainter_p.h>
16#if QT_CONFIG(directwrite)
17# include <private/qwindowsfontenginedirectwrite_p.h>
20#include <qpa/qplatformprintplugin.h>
21#include <qpa/qplatformprintersupport.h>
27#include <qpa/qplatformpixmap.h>
28#include <private/qpicture_p.h>
29#include <private/qpixmap_raster_p.h>
30#include <QtCore/QMetaType>
31#include <QtCore/qt_windows.h>
32#include <QtGui/qpagelayout.h>
33#include <QtGui/private/qpixmap_win_p.h>
48 PaintEngineFeatures(PrimitiveTransform
50 | PerspectiveTransform
53 | PaintOutsidePaintEvent))
60 d->m_pageLayout.setPageSize(
d->m_printDevice.defaultPageSize());
68 str <<
"QWin32PrintEngine::begin: " << function <<
" failed";
69 if (
d.lpszDocName &&
d.lpszDocName[0])
71 if (
d.lpszOutput &&
d.lpszOutput[0])
73 return std::move(
result).toLocal8Bit();
96 d->devMode->dmCopies =
d->num_copies;
99 memset(&di, 0,
sizeof(DOCINFO));
100 di.cbSize =
sizeof(DOCINFO);
101 if (
d->docName.isEmpty())
102 di.lpszDocName = L
"document1";
104 di.lpszDocName =
reinterpret_cast<const wchar_t *
>(
d->docName.utf16());
105 if (
d->printToFile && !
d->fileName.isEmpty())
106 di.lpszOutput =
reinterpret_cast<const wchar_t *
>(
d->fileName.utf16());
108 di.lpszOutput =
d->fileName.isEmpty() ? L
"FILE:" :
reinterpret_cast<const wchar_t *
>(
d->fileName.utf16());
109 if (
ok && StartDoc(
d->hdc, &di) == SP_ERROR) {
114 if (StartPage(
d->hdc) <= 0) {
128 d->has_brush =
false;
130 d->complex_xform =
false;
137#ifdef QT_DEBUG_METRICS
138 qDebug(
"QWin32PrintEngine::begin()");
162 if (EndPage(
d->hdc) <= 0)
163 qErrnoWarning(
"QWin32PrintEngine::end: EndPage failed (%p)",
d->hdc);
164 if (EndDoc(
d->hdc) <= 0)
182 bool transparent = GetBkMode(
d->hdc) == TRANSPARENT;
184 if (EndPage(
d->hdc) <= 0) {
195 if (StartPage(
d->hdc) <= 0) {
196 qErrnoWarning(
"Win32PrintEngine::newPage: StartPage failed");
200 SetTextAlign(
d->hdc, TA_BASELINE);
202 SetBkMode(
d->hdc, TRANSPARENT);
204#ifdef QT_DEBUG_METRICS
205 qDebug(
"QWin32PrintEngine::newPage()");
212 bool success =
false;
214 if (EndPage(
d->hdc) > 0) {
224 qErrnoWarning(
"QWin32PrintEngine::newPage(), ResetDC failed (2)");
227 success = (StartPage(
d->hdc) > 0);
229 qErrnoWarning(
"Win32PrintEngine::newPage: StartPage failed (2)");
256 ||
qAlpha(brushColor) != 0xff
261 bool deleteFont =
false;
262 HFONT hfont =
nullptr;
264 hfont =
static_cast<HFONT
>(ti.fontEngine->handle());
266#if QT_CONFIG(directwrite)
269 hfont = fedw->createHFONT();
277 SelectObject(
d->hdc, hfont);
278 if (GetDeviceCaps(
d->hdc, TECHNOLOGY) != DT_CHARSTREAM) {
280 GetObject(hfont,
sizeof(LOGFONT), &logFont);
283 GetTextFace(
d->hdc, 64,
n);
301 COLORREF cf = RGB(
qRed(brushColor),
qGreen(brushColor),
qBlue(brushColor));
302 SelectObject(
d->hdc, CreateSolidBrush(cf));
303 SelectObject(
d->hdc, CreatePen(PS_SOLID, 1, cf));
304 SetTextColor(
d->hdc, cf);
307 DeleteObject(SelectObject(
d->hdc,GetStockObject(HOLLOW_BRUSH)));
308 DeleteObject(SelectObject(
d->hdc,GetStockObject(BLACK_PEN)));
319 int res =
d->resolution;
323 val =
d->m_paintRectPixels.width();
324#ifdef QT_DEBUG_METRICS
325 qDebug() <<
"QWin32PrintEngine::metric(PdmWidth) = " <<
val;
330 val =
d->m_paintRectPixels.height();
331#ifdef QT_DEBUG_METRICS
332 qDebug() <<
"QWin32PrintEngine::metric(PdmHeight) = " <<
val;
343 val = GetDeviceCaps(
d->hdc, LOGPIXELSX);
346 val = GetDeviceCaps(
d->hdc, LOGPIXELSY);
349 val =
d->m_paintSizeMM.width();
350#ifdef QT_DEBUG_METRICS
351 qDebug() <<
"QWin32PrintEngine::metric(PdmWidthMM) = " <<
val;
356 val =
d->m_paintSizeMM.height();
357#ifdef QT_DEBUG_METRICS
358 qDebug() <<
"QWin32PrintEngine::metric(PdmHeightMM) = " <<
val;
364 int bpp = GetDeviceCaps(
d->hdc, BITSPIXEL);
368 val = GetDeviceCaps(
d->hdc, NUMCOLORS);
370 val = 1 << (bpp * GetDeviceCaps(
d->hdc, PLANES));
374 val = GetDeviceCaps(
d->hdc, PLANES);
383 qWarning(
"QPrinter::metric: Invalid metric command");
409 d->brush_color =
brush.color();
436 SelectClipRgn(
d->hdc,
nullptr);
443 if (xformed.isEmpty()) {
445 HRGN empty = CreateRectRgn(-0x1000000, -0x1000000, -0x0fffffff, -0x0ffffff);
446 SelectClipRgn(
d->hdc, empty);
449 d->composeGdiPath(xformed);
456 Q_ASSERT(op > 0 &&
unsigned(op) <=
sizeof(ops) /
sizeof(
int));
457 SelectClipPath(
d->hdc, ops[op]);
462 if (!aclip.isEmpty()) {
463 QTransform tx(
d->stretch_x, 0, 0,
d->stretch_y,
d->origin_x,
d->origin_y);
464 d->composeGdiPath(tx.
map(aclip));
465 SelectClipPath(
d->hdc, RGN_DIFF);
473 QTransform stretch(
d->stretch_x, 0, 0,
d->stretch_y,
d->origin_x,
d->origin_y);
474 d->painterMatrix =
m;
475 d->matrix =
d->painterMatrix * stretch;
476 d->txop =
d->matrix.
type();
503 if (sr.size() !=
pixmap.size()) {
514 qreal xform_offset_x = adapted.dx();
515 qreal xform_offset_y = adapted.dy();
517 if (
d->complex_xform) {
519 scaleX =
d->stretch_x;
520 scaleY =
d->stretch_y;
522 scaleX =
d->stretch_x * (
r.width() /
pixmap.width()) *
d->painterMatrix.m11();
523 scaleY =
d->stretch_y * (
r.height() /
pixmap.height()) *
d->painterMatrix.m22();
526 QPointF topLeft =
r.topLeft() *
d->painterMatrix;
527 int tx = int(topLeft.
x() *
d->stretch_x +
d->origin_x);
528 int ty = int(topLeft.
y() *
d->stretch_y +
d->origin_y);
532 xform_offset_x *=
d->stretch_x;
533 xform_offset_y *=
d->stretch_y;
535 int dc_state = SaveDC(
d->hdc);
545 for (
int y = 0;
y < tilesh; ++
y) {
546 int tposy =
ty + (
y * tyinc);
549 if (
y == (tilesh - 1)) {
553 for (
int x = 0;
x < tilesw; ++
x) {
554 int tposx = tx + (
x * txinc);
557 if (
x == (tilesw - 1)) {
559 width = (tw - (
x * txinc));
564 img.setDevicePixelRatio(
pixmap.devicePixelRatio());
571 HDC hbitmap_hdc = CreateCompatibleDC(
d->hdc);
572 HGDIOBJ null_bitmap = SelectObject(hbitmap_hdc, hbitmap);
575 hbitmap_hdc, 0, 0,
p.width(),
p.height(), SRCCOPY))
576 qErrnoWarning(
"QWin32PrintEngine::drawPixmap, StretchBlt failed");
578 SelectObject(hbitmap_hdc, null_bitmap);
579 DeleteObject(hbitmap);
580 DeleteDC(hbitmap_hdc);
584 RestoreDC(
d->hdc, dc_state);
596 if (
d->complex_xform || !
pos.isNull()) {
599 int dc_state = SaveDC(
d->hdc);
602 HDC hbitmap_hdc = CreateCompatibleDC(
d->hdc);
603 HGDIOBJ null_bitmap = SelectObject(hbitmap_hdc, hbitmap);
605 QRectF trect =
d->painterMatrix.mapRect(
r);
606 int tx = int(trect.left() *
d->stretch_x +
d->origin_x);
607 int ty = int(trect.top() *
d->stretch_y +
d->origin_y);
609 int xtiles = int(trect.width() / pm.
width()) + 1;
610 int ytiles = int(trect.height() / pm.
height()) + 1;
611 int xinc = int(pm.
width() *
d->stretch_x);
612 int yinc = int(pm.
height() *
d->stretch_y);
614 for (
int y = 0;
y < ytiles; ++
y) {
615 int ity =
ty + (yinc *
y);
617 if (
y == (ytiles - 1)) {
618 ith = int(trect.height() - (pm.
height() *
y));
621 for (
int x = 0;
x < xtiles; ++
x) {
622 int itx = tx + (xinc *
x);
623 int itw = pm.
width();
624 if (
x == (xtiles - 1)) {
625 itw = int(trect.width() - (pm.
width() *
x));
628 if (!StretchBlt(
d->hdc, itx, ity,
int(itw *
d->stretch_x),
int(ith *
d->stretch_y),
629 hbitmap_hdc, 0, 0, itw, ith, SRCCOPY))
630 qErrnoWarning(
"QWin32PrintEngine::drawPixmap, StretchBlt failed");
635 SelectObject(hbitmap_hdc, null_bitmap);
636 DeleteObject(hbitmap);
637 DeleteDC(hbitmap_hdc);
639 RestoreDC(
d->hdc, dc_state);
647 qErrnoWarning(
"QWin32PrintEnginePrivate::drawPath: BeginPath failed");
651 for (
int i=0;
i<
path.elementCount(); ++
i) {
672 PolyBezierTo(
hdc, pts, 3);
676 qFatal(
"QWin32PaintEngine::drawPath: Unhandled type: %d", elm.type);
686 qErrnoWarning(
"QWin32PaintEngine::drawPath: EndPath failed");
695 qDebug() <<
" --- QWin32PrintEnginePrivate::fillPath() bound:" <<
path.boundingRect() <<
color;
701 HGDIOBJ old_brush = SelectObject(
hdc,
brush);
703 DeleteObject(SelectObject(
hdc, old_brush));
710 brush.lbStyle = BS_SOLID;
712 DWORD capStyle = PS_ENDCAP_SQUARE;
713 DWORD joinStyle = PS_JOIN_BEVEL;
715 capStyle = PS_ENDCAP_FLAT;
717 capStyle = PS_ENDCAP_ROUND;
720 joinStyle = PS_JOIN_MITER;
722 joinStyle = PS_JOIN_ROUND;
724 HPEN
pen = ExtCreatePen(PS_GEOMETRIC | PS_SOLID | capStyle | joinStyle,
725 (penWidth == 0) ? 1 : penWidth, &
brush, 0,
nullptr);
727 HGDIOBJ old_pen = SelectObject(
hdc,
pen);
729 DeleteObject(SelectObject(
hdc, old_pen));
763 stroke = stroke * stretch;
777 qDebug() <<
" - QWin32PrintEngine::drawPath(), bounds: " <<
path.boundingRect();
787 d->fillPath(
path,
d->brush_color);
790 d->strokePath(
path,
d->pen.color());
797 qDebug() <<
" - QWin32PrintEngine::drawPolygon(), pointCount: " << pointCount;
808 for (
int i=1;
i<pointCount; ++
i) {
814 bool has_brush =
d->has_brush;
817 d->has_brush =
false;
822 d->has_brush = has_brush;
845 bool ok = OpenPrinter(
reinterpret_cast<LPWSTR
>(
const_cast<ushort *
>(printerName.
utf16())),
846 reinterpret_cast<LPHANDLE
>(&
hPrinter),
nullptr);
848 qErrnoWarning(
"QWin32PrintEngine::initialize: OpenPrinter failed");
854 DWORD infoSize, numBytes;
855 GetPrinter(
hPrinter, 2,
nullptr, 0, &infoSize);
856 hMem = GlobalAlloc(GHND, infoSize);
857 pInfo =
reinterpret_cast<PRINTER_INFO_2*
>(GlobalLock(
hMem));
858 ok = GetPrinter(
hPrinter, 2,
reinterpret_cast<LPBYTE
>(
pInfo), infoSize, &numBytes);
861 qErrnoWarning(
"QWin32PrintEngine::initialize: GetPrinter failed");
876 auto *lpwPrinterName =
reinterpret_cast<LPWSTR
>(
const_cast<ushort *
>(printerName.
utf16()));
877 LONG
result = DocumentProperties(
nullptr,
hPrinter, lpwPrinterName,
878 nullptr,
nullptr, 0);
885 devMode,
nullptr, DM_OUT_BUFFER);
887 qErrnoWarning(
"QWin32PrintEngine::initialize: Failed to obtain devMode");
894 hdc = CreateDC(
nullptr,
reinterpret_cast<LPCWSTR
>(printerName.
utf16()),
898 qErrnoWarning(
"QWin32PrintEngine::initialize: CreateDC failed");
910 devMode->dmCollate = DMCOLLATE_TRUE;
914#if defined QT_DEBUG_DRAW || defined QT_DEBUG_METRICS
915 qDebug(
"QWin32PrintEngine::initialize()");
922 memset(
devMode, 0,
sizeof(DEVMODE));
923 devMode->dmSize =
sizeof(DEVMODE);
924 devMode->dmSpecVersion = DM_SPECVERSION;
931 HDC display_dc = GetDC(
nullptr);
932 dpi_x = GetDeviceCaps(
hdc, LOGPIXELSX);
933 dpi_y = GetDeviceCaps(
hdc, LOGPIXELSY);
934 dpi_display = GetDeviceCaps(display_dc, LOGPIXELSY);
935 ReleaseDC(
nullptr, display_dc);
937 qWarning(
"QWin32PrintEngine::metric: GetDeviceCaps() failed, "
938 "might be a driver problem");
999 qWarning(
"ResetDC() called with null hdc.");
1002 const HDC oldHdc =
hdc;
1005 const int lastError = GetLastError();
1006 qErrnoWarning(lastError,
"ResetDC() on %p failed (%d)", oldHdc, lastError);
1013 for (
int i = 0;
i < inputSlots.size(); ++
i) {
1014 if (inputSlots.at(
i).id ==
id)
1022 for (
int i = 0;
i < inputSlots.size(); ++
i) {
1023 if (inputSlots.at(
i).windowsId == windowsId)
1058 d->embed_fonts =
value.toBool();
1065 d->devMode->dmCollate =
value.toBool() ? DMCOLLATE_TRUE : DMCOLLATE_FALSE;
1066 d->devMode->dmFields |= DM_COLLATE;
1076 d->devMode->dmFields |= DM_COLOR;
1082 d->m_creator =
value.toString();
1087 qWarning(
"QWin32PrintEngine: Cannot change document name while printing is active");
1090 d->docName =
value.toString();
1101 d->devMode->dmDuplex = DMDUP_SIMPLEX;
1102 d->devMode->dmFields |= DM_DUPLEX;
1105 d->devMode->dmDuplex =
d->m_pageLayout.orientation() ==
QPageLayout::Landscape ? DMDUP_HORIZONTAL : DMDUP_VERTICAL;
1106 d->devMode->dmFields |= DM_DUPLEX;
1109 d->devMode->dmDuplex = DMDUP_VERTICAL;
1110 d->devMode->dmFields |= DM_DUPLEX;
1113 d->devMode->dmDuplex = DMDUP_HORIZONTAL;
1114 d->devMode->dmFields |= DM_DUPLEX;
1130#ifdef QT_DEBUG_METRICS
1131 qDebug() <<
"QWin32PrintEngine::setProperty(PPK_FullPage," <<
value.toBool() << +
")";
1140 d->num_copies =
value.toInt();
1141 d->devMode->dmCopies =
d->num_copies;
1142 d->devMode->dmFields |= DM_COPIES;
1151 d->devMode->dmFields |= DM_ORIENTATION;
1152 d->m_pageLayout.setOrientation(orientation);
1155#ifdef QT_DEBUG_METRICS
1156 qDebug() <<
"QWin32PrintEngine::setProperty(PPK_Orientation," << orientation <<
')';
1164 qWarning(
"QWin32PrintEngine: Cannot change filename while printing");
1166 d->fileName =
value.toString();
1167 d->printToFile = !
value.toString().isEmpty();
1176 d->setPageSize(pageSize);
1178#ifdef QT_DEBUG_METRICS
1179 qDebug() <<
"QWin32PrintEngine::setProperty(PPK_PageSize," <<
value.toInt() <<
')';
1190 const QPageSize pageSize =
d->m_printDevice.supportedPageSize(
value.toString());
1192 d->setPageSize(pageSize);
1194#ifdef QT_DEBUG_METRICS
1195 qDebug() <<
"QWin32PrintEngine::setProperty(PPK_PaperName," <<
value.toString() <<
')';
1205 const auto inputSlots =
d->m_printDevice.supportedInputSlots();
1206 const int paperSource =
value.toInt();
1224 QPair<QMarginsF, QPageLayout::Unit>(
d->m_pageLayout.margins(),
d->m_pageLayout.units()));
1226 if (printDevice.isValid()) {
1227 d->m_printDevice = printDevice;
1229 if (
d->m_printDevice.supportedPageSize(pageSize.
value<
QPageSize>()).isValid())
1241 d->resolution =
value.toInt();
1242 d->stretch_x =
d->dpi_x / double(
d->resolution);
1243 d->stretch_y =
d->dpi_y / double(
d->resolution);
1245#ifdef QT_DEBUG_METRICS
1246 qDebug() <<
"QWin32PrintEngine::setProperty(PPK_Resolution," <<
value.toInt() <<
')';
1257 d->setPageSize(pageSize);
1259#ifdef QT_DEBUG_METRICS
1260 qDebug() <<
"QWin32PrintEngine::setProperty(PPK_WindowsPageSize," <<
value.toInt() <<
')';
1273 d->setPageSize(pageSize);
1275#ifdef QT_DEBUG_METRICS
1276 qDebug() <<
"QWin32PrintEngine::setProperty(PPK_CustomPaperSize," <<
value.toSizeF() <<
')';
1284 QList<QVariant> margins(
value.toList());
1287 d->m_pageLayout.setMargins(
QMarginsF(margins.at(0).toReal(), margins.at(1).toReal(),
1288 margins.at(2).toReal(), margins.at(3).toReal()),
1291#ifdef QT_DEBUG_METRICS
1292 qDebug() <<
"QWin32PrintEngine::setProperty(PPK_PageMargins," << margins <<
')';
1304 d->setPageSize(pageSize);
1306#ifdef QT_DEBUG_METRICS
1307 qDebug() <<
"QWin32PrintEngine::setProperty(PPK_QPageSize," << pageSize <<
')';
1315 QPair<QMarginsF, QPageLayout::Unit> pair =
value.value<QPair<QMarginsF, QPageLayout::Unit> >();
1316 d->m_pageLayout.setUnits(pair.second);
1319#ifdef QT_DEBUG_METRICS
1320 qDebug() <<
"QWin32PrintEngine::setProperty(PPK_QPageMargins," << pair.first << pair.second <<
')';
1328 if (pageLayout.
isValid() &&
d->m_printDevice.isValidPageLayout(pageLayout,
d->resolution)) {
1332 d->m_pageLayout.setUnits(pageLayout.
units());
1335#ifdef QT_DEBUG_METRICS
1336 qDebug() <<
"QWin32PrintEngine::setProperty(PPK_QPageLayout," << pageLayout <<
')';
1374 value =
d->devMode->dmCollate == DMCOLLATE_TRUE;
1399 switch (
d->devMode->dmDuplex) {
1400 case DMDUP_VERTICAL:
1403 case DMDUP_HORIZONTAL:
1432 value =
d->m_pageLayout.orientation();
1441 value =
d->m_pageLayout.paintRectPixels(
d->resolution);
1445 value =
d->m_pageLayout.pageSize().id();
1450 value =
d->m_pageLayout.fullRectPixels(
d->resolution);
1454 value =
d->m_pageLayout.pageSize().name();
1459 value =
d->m_printDevice.defaultInputSlot().id;
1462 value = int(
d->devMode->dmDefaultSource);
1464 const auto inputSlots =
d->m_printDevice.supportedInputSlots();
1472 value =
d->m_printDevice.id();
1476 if (
d->resolution ||
d->m_printDevice.isValid())
1481 QList<QVariant>
list;
1482 const auto resolutions =
d->m_printDevice.supportedResolutions();
1484 for (
int resolution : resolutions)
1491 value =
d->m_pageLayout.pageSize().windowsId();
1495 QList<QVariant>
out;
1496 const auto inputSlots =
d->m_printDevice.supportedInputSlots();
1497 out.reserve(inputSlots.size());
1505 value =
d->m_pageLayout.fullRectPoints().size();
1509 QList<QVariant>
list;
1517 value.setValue(
d->m_pageLayout.pageSize());
1521 QPair<QMarginsF, QPageLayout::Unit> pair =
qMakePair(
d->m_pageLayout.margins(),
d->m_pageLayout.units());
1522 value.setValue(pair);
1527 value.setValue(
d->m_pageLayout);
1540 return d_func()->state;
1545 return d_func()->hdc;
1557 const size_t size =
sizeof(DEVNAMES) +
d->m_printDevice.id().length() * 2 + 2;
1558 auto hGlobal =
reinterpret_cast<HGLOBAL *
>(GlobalAlloc(GMEM_MOVEABLE,
size));
1559 auto dn =
reinterpret_cast<DEVNAMES*
>(GlobalLock(hGlobal));
1561 dn->wDriverOffset = 0;
1562 dn->wDeviceOffset =
sizeof(DEVNAMES) /
sizeof(
wchar_t);
1563 dn->wOutputOffset = 0;
1565 memcpy(
reinterpret_cast<ushort*
>(dn) + dn->wDeviceOffset,
1566 d->m_printDevice.id().utf16(),
d->m_printDevice.id().length() * 2 + 2);
1569 GlobalUnlock(hGlobal);
1576 if (globalDevNames) {
1577 auto dn =
reinterpret_cast<DEVNAMES*
>(GlobalLock(globalDevNames));
1583 GlobalUnlock(globalDevNames);
1587 auto dm =
reinterpret_cast<DEVMODE*
>(GlobalLock(
globalDevMode));
1590 if (
d->ownsDevMode) {
1592 d->ownsDevMode =
false;
1595 d->hdc = CreateDC(
nullptr,
reinterpret_cast<LPCWSTR
>(
d->m_printDevice.id().utf16()),
nullptr, dm);
1597 d->num_copies =
d->devMode->dmCopies;
1598 d->updatePageLayout();
1600 if (!OpenPrinter((
wchar_t*)
d->m_printDevice.id().utf16(), &
d->hPrinter, 0))
1601 qWarning(
"QPrinter: OpenPrinter() failed after reading DEVMODE.");
1607#if defined QT_DEBUG_DRAW || defined QT_DEBUG_METRICS
1608 qDebug(
"QWin32PrintEngine::setGlobalDevMode()");
1616 return d->globalDevMode;
1628 const QPageSize usePageSize = printerPageSize.
isValid() ? printerPageSize : pageSize;
1634 if (printerPageSize.isValid()) {
1637 devMode->dmFields &= ~(DM_PAPERLENGTH | DM_PAPERWIDTH);
1642 devMode->dmFields |= DM_PAPERLENGTH | DM_PAPERWIDTH;
1661 bool hasCustom =
false;
1662 int feature = PSIDENT_GDICENTRIC;
1663 if (ExtEscape(
hdc, POSTSCRIPT_IDENTIFY,
1664 sizeof(DWORD),
reinterpret_cast<LPCSTR
>(&feature), 0, 0) >= 0) {
1665 PSFEATURE_CUSTPAPER custPaper;
1666 feature = FEATURESETTING_CUSTPAPER;
1667 if (ExtEscape(
hdc, GET_PS_FEATURESETTING,
sizeof(INT),
reinterpret_cast<LPCSTR
>(&feature),
1668 sizeof(custPaper),
reinterpret_cast<LPSTR
>(&custPaper)) > 0) {
1670 if (!(custPaper.lOrientation == 1 && custPaper.lWidth == 0 && custPaper.lHeight == 0)) {
1671 if (custPaper.lOrientation == 0 || custPaper.lOrientation == 2)
1699 const int devWidth = GetDeviceCaps(
hdc, PHYSICALWIDTH);
1700 const int devHeight = GetDeviceCaps(
hdc, PHYSICALHEIGHT);
1703 const qreal pageScaleX = (devWidth && pageWidth) ?
qreal(devWidth) / pageWidth : 1;
1704 const qreal pageScaleY = (devHeight && pageHeight) ?
qreal(devHeight) / pageHeight : 1;
1734 SetTextAlign(hdc, TA_BASELINE);
1735 SetBkMode(hdc, TRANSPARENT);
1737 const bool has_kerning = ti.f && ti.f->kerning();
1739 HFONT hfont =
nullptr;
1740 bool deleteFont =
false;
1744 hfont =
static_cast<HFONT
>(ti.fontEngine->handle());
1746#if QT_CONFIG(directwrite)
1749 hfont = fedw->createHFONT();
1756 hfont = (HFONT)GetStockObject(ANSI_VAR_FONT);
1758 HGDIOBJ old_font = SelectObject(hdc, hfont);
1759 unsigned int options = ETO_GLYPH_INDEX;
1780 SetGraphicsMode(hdc, GM_ADVANCED);
1781 SetWorldTransform(hdc, &win_xform);
1785 QVarLengthArray<wchar_t>
g(glyphs.
numGlyphs);
1791 options, 0,
g.constData(), glyphs.
numGlyphs, 0);
1794 QVarLengthArray<glyph_t> _glyphs;
1797 ti.fontEngine->getGlyphPositions(ti.glyphs,
matrix, ti.flags,
1799 if (_glyphs.isEmpty()) {
1800 SelectObject(hdc, old_font);
1805 QVarLengthArray<INT> glyphDistances(_glyphs.size() * 2);
1806 QVarLengthArray<wchar_t>
g(_glyphs.size());
1807 const int lastGlyph = _glyphs.size() - 1;
1808 for (
int i = 0;
i < lastGlyph; ++
i) {
1813 glyphDistances[lastGlyph * 2] = 0;
1814 glyphDistances[lastGlyph * 2 + 1] = 0;
1815 g[lastGlyph] = _glyphs[lastGlyph];
1817 g.constData(), _glyphs.size(),
1818 glyphDistances.data());
1821 win_xform.eM11 = win_xform.eM22 = 1.0;
1822 win_xform.eM12 = win_xform.eM21 = win_xform.eDx = win_xform.eDy = 0.0;
1823 SetWorldTransform(hdc, &win_xform);
1825 SelectObject(hdc, old_font);
1828 DeleteObject(hfont);
QRegion alphaClipping() const
void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) override
Reimplement this function to draw the part of the pm specified by the sr rectangle in the given r.
bool continueCall() const
bool end() override
Reimplement this function to finish painting on the current paint device.
void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) override
Reimplement this virtual function to draw the polygon defined by the pointCount first points in point...
void drawTextItem(const QPointF &p, const QTextItem &textItem) override
This function draws the text item textItem at position p.
bool begin(QPaintDevice *pdev) override
Reimplement this function to initialise your paint engine when painting is to start on the paint devi...
void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s) override
Reimplement this function to draw the pixmap in the given rect, starting at the given p.
void updateState(const QPaintEngineState &state) override
Reimplement this function to update the state of a paint engine.
void drawPath(const QPainterPath &path) override
The default implementation ignores the path and does nothing.
void flushAndInit(bool init=true)
const QColor & color() const
Returns the brush color.
Qt::BrushStyle style() const
Returns the brush style.
The QColor class provides colors based on RGB, HSV or CMYK values.
QRgb rgb() const noexcept
Returns the RGB value of the color.
void reserve(qsizetype size)
constexpr qreal right() const noexcept
Returns the right margin.
constexpr qreal left() const noexcept
Returns the left margin.
constexpr qreal top() const noexcept
Returns the top margin.
constexpr qreal bottom() const noexcept
Returns the bottom margin.
void setOrientation(Orientation orientation)
Sets the page orientation of the page layout to orientation.
Mode mode() const
Returns the page layout mode.
Unit units() const
Returns the units the page layout is currently defined in.
bool isValid() const
Returns true if this page layout is valid.
QRectF paintRect() const
Returns the page rectangle in the current layout units.
Unit
This enum type is used to specify the measurement unit for page layout and margins.
QMarginsF margins() const
Returns the margins of the page layout using the currently set units.
Orientation orientation() const
Returns the page orientation of the page layout.
QRect paintRectPixels(int resolution) const
Returns the paintable rectangle in rounded device pixels for the given resolution.
void setPageSize(const QPageSize &pageSize, const QMarginsF &minMargins=QMarginsF(0, 0, 0, 0))
Sets the page size of the page layout to pageSize.
Orientation
This enum type defines the page orientation.
QRect fullRectPixels(int resolution) const
Returns the full page rectangle in device pixels for the given resolution.
QPageSize pageSize() const
Returns the page size of the page layout.
bool isValid() const
Returns true if this page size is valid.
int windowsId() const
Returns the Windows DMPAPER enum value for the page size.
QSizeF size(Unit units) const
Returns the size of the page in the required units.
PageSizeId id() const
Returns the standard QPageSize::PageSizeId of the page, or QPageSize::Custom.
PageSizeId
This enum type lists the available page sizes as defined in the Postscript PPD standard.
@ PdmDevicePixelRatioScaled
static qreal devicePixelRatioFScale()
The QPaintEngineState class provides information about the active paint engine's current state....
QTransform transform() const
QPainterPath clipPath() const
Returns the clip path in the current paint engine state.
Qt::ClipOperation clipOperation() const
Returns the clip operation in the current paint engine state.
bool isClipEnabled() const
Returns whether clipping is enabled or not in the current paint engine state.
QBrush brush() const
Returns the brush in the current paint engine state.
QRegion clipRegion() const
Returns the clip region in the current paint engine state.
QPen pen() const
Returns the pen in the current paint engine state.
QPaintEngine::DirtyFlags state() const
Returns a combination of flags identifying the set of properties that need to be updated when updatin...
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 drawTextItem(const QPointF &p, const QTextItem &textItem)
This function draws the text item textItem at position p.
PolygonDrawMode
\value OddEvenMode The polygon should be drawn using OddEven fill rule.
QPainter * painter() const
Returns the paint engine's painter.
QPaintEngineState * state
bool isActive() const
Returns true if the paint engine is actively drawing; otherwise returns false.
The QPainterPathStroker class is used to generate fillable outlines for a given painter path.
void setDashPattern(Qt::PenStyle)
Sets the dash pattern for the generated outlines to style.
void setDashOffset(qreal offset)
Sets the dash offset for the generated outlines to offset.
void setCapStyle(Qt::PenCapStyle style)
Sets the cap style of the generated outlines to style.
void setWidth(qreal width)
Sets the width of the generated outline painter path to width.
QPainterPath createStroke(const QPainterPath &path) const
Generates a new path that is a fillable area representing the outline of the given path.
void setJoinStyle(Qt::PenJoinStyle style)
Sets the join style of the generated outlines to style.
void setMiterLimit(qreal length)
Sets the miter limit of the generated outlines to limit.
bool isEmpty() const
Returns true if either there are no elements in this path, or if the only element is a MoveToElement;...
The QPainter class performs low-level painting on widgets and other paint devices.
void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect)
Draws the rectangular portion source of the given pixmap into the given target in the paint device.
qreal widthF() const
Returns the pen width with floating point precision.
QList< qreal > dashPattern() const
Returns the dash pattern of this pen.
bool isCosmetic() const
Returns true if the pen is cosmetic; otherwise returns false.
Qt::PenCapStyle capStyle() const
Returns the pen's cap style.
Qt::PenJoinStyle joinStyle() const
Returns the pen's join style.
qreal miterLimit() const
Returns the miter limit of the pen.
QBrush brush() const
Returns the brush used to fill strokes generated with this pen.
qreal dashOffset() const
Returns the dash offset for the pen.
Qt::PenStyle style() const
Returns the pen style.
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
int height() const
Returns the height of the pixmap.
static QTransform trueMatrix(const QTransform &m, int w, int h)
Returns the actual matrix used for transforming a pixmap with the given width, height and matrix.
int width() const
Returns the width of the pixmap.
QPixmap copy(int x, int y, int width, int height) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
Converts the given image to a pixmap using the specified flags to control the conversion.
\inmodule QtCore\reentrant
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
QPageSize supportedPageSize(const QPageSize &pageSize) const
QMarginsF printableMargins(const QPageSize &pageSize, QPageLayout::Orientation orientation, int resolution) const
PrintEnginePropertyKey
This enum is used to communicate properties between the print engine and QPrinter.
@ PPK_SupportedResolutions
@ PPK_SupportsMultipleCopies
PrinterMode
This enum describes the mode the printer should work in.
PrinterState
\value Idle \value Active \value Aborted \value Error
\inmodule QtCore\reentrant
constexpr QSizeF size() const noexcept
Returns the size of the rectangle.
constexpr int height() const noexcept
Returns the height of the rectangle.
constexpr int width() const noexcept
Returns the width of the rectangle.
The QRegion class specifies a clip region for a painter.
\macro QT_RESTRICTED_CAST_FROM_ASCII
const ushort * utf16() const
Returns the QString as a '\0\'-terminated array of unsigned shorts.
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
static QString fromWCharArray(const wchar_t *string, qsizetype size=-1)
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
QPrinter::PrinterState state
void fillPath_dev(const QPainterPath &path, const QColor &color)
void strokePath_dev(const QPainterPath &path, const QColor &color, qreal width)
void composeGdiPath(const QPainterPath &path)
QPrintDevice m_printDevice
void debugMetrics() const
uint has_custom_paper_size
void strokePath(const QPainterPath &path, const QColor &color)
~QWin32PrintEnginePrivate()
static void initializeDevMode(DEVMODE *)
void setPageSize(const QPageSize &pageSize)
void fillPath(const QPainterPath &path, const QColor &color)
void setGlobalDevMode(HGLOBAL globalDevNames, HGLOBAL globalDevMode)
void updateClipPath(const QPainterPath &clip, Qt::ClipOperation op)
void updateState(const QPaintEngineState &state) override
Reimplement this function to update the state of a paint engine.
void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &p) override
Reimplement this function to draw the pixmap in the given rect, starting at the given p.
QWin32PrintEngine(QPrinter::PrinterMode mode, const QString &deviceId)
void updateMatrix(const QTransform &matrix)
void drawPath(const QPainterPath &path) override
The default implementation ignores the path and does nothing.
bool begin(QPaintDevice *dev) override
Reimplement this function to initialise your paint engine when painting is to start on the paint devi...
QVariant property(PrintEnginePropertyKey key) const override
Returns the print engine's property specified by key.
void drawTextItem(const QPointF &p, const QTextItem &textItem) override
This function draws the text item textItem at position p.
QPrinter::PrinterState printerState() const override
Returns the current state of the printer being used by the print engine.
bool end() override
Reimplement this function to finish painting on the current paint device.
void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) override
Reimplement this virtual function to draw the polygon defined by the pointCount first points in point...
bool newPage() override
Instructs the print engine to start a new page.
void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) override
Reimplement this function to draw the part of the pm specified by the sr rectangle in the given r.
bool abort() override
Instructs the print engine to abort the printing process.
int metric(QPaintDevice::PaintDeviceMetric) const override
Returns the metric for the given id.
void releaseDC(HDC) const
void setProperty(PrintEnginePropertyKey key, const QVariant &value) override
Sets the print engine's property specified by key to the given value.
HGLOBAL * createGlobalDevNames()
Windows font engine using Direct Write.
void qErrnoWarning(const char *msg,...)
Combined button and popup list for selecting options.
static const QCssKnownValue positions[NumKnownPositionModes - 1]
static const short indexOfId[NumKnownValues]
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
int qRound(qfloat16 d) noexcept
static QT_BEGIN_NAMESPACE const int tileSize
constexpr T qAbs(const T &t)
GLint GLint GLint GLint GLint x
[0]
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLfixed GLfixed GLint GLint GLfixed points
GLsizei const GLchar *const * path
Q_GUI_EXPORT QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits)
QPainterPath qt_regionToPath(const QRegion ®ion)
QT_BEGIN_NAMESPACE constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) noexcept(noexcept(std::make_pair(std::forward< T1 >(value1), std::forward< T2 >(value2))))
HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat)
QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits)
static void draw_text_item_win(const QPointF &_pos, const QTextItemInt &ti, HDC hdc, const QTransform &xform, const QPointF &topLeft)
@ HBitmapPremultipliedAlpha
static int indexOfWindowsId(const QList< QPrint::InputSlot > &inputSlots, int windowsId)
QT_BEGIN_NAMESPACE QPainterPath qt_regionToPath(const QRegion ®ion)
static QByteArray msgBeginFailed(const char *function, const DOCINFO &d)
QT_BEGIN_NAMESPACE typedef unsigned int QRgb
constexpr int qRed(QRgb rgb)
constexpr int qGreen(QRgb rgb)
constexpr int qBlue(QRgb rgb)
constexpr int qAlpha(QRgb rgb)
static int toInt(const QChar &qc, int R)
QTextStream out(stdout)
[7]
args<< 1<< 2;QJSValue threeAgain=fun.call(args);QString fileName="helloworld.qs";QFile scriptFile(fileName);if(!scriptFile.open(QIODevice::ReadOnly)) QTextStream stream(&scriptFile);QString contents=stream.readAll();scriptFile.close();myEngine.evaluate(contents, fileName);myEngine.globalObject().setProperty("myNumber", 123);...QJSValue myNumberPlusOne=myEngine.evaluate("myNumber + 1");QJSValue result=myEngine.evaluate(...);if(result.isError()) qDebug()<< "Uncaught exception at line"<< result.property("lineNumber").toInt()<< ":"<< result.toString();QPushButton *button=new QPushButton;QJSValue scriptButton=myEngine.newQObject(button);myEngine.globalObject().setProperty("button", scriptButton);myEngine.evaluate("button.checkable = true");qDebug()<< scriptButton.property("checkable").toBool();scriptButton.property("show").call();QJSEngine engine;QObject *myQObject=new QObject();myQObject- setProperty)("dynamicProperty", 3)
constexpr qreal toReal() const
QGlyphJustification * justifications
QGlyphAttributes * attributes