Qt 4.8
qprintengine_win.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef QT_NO_PRINTER
43 
44 #include "qprinter_p.h"
45 #include "qprintengine_win_p.h"
46 
47 #include <limits.h>
48 
49 #include <private/qfont_p.h>
50 #include <private/qfontengine_p.h>
51 #include <private/qpainter_p.h>
52 
53 #include <qbitmap.h>
54 #include <qdebug.h>
55 #include <qvector.h>
56 #include <qpicture.h>
57 #include <private/qpicture_p.h>
58 
60 
61 extern QPainterPath qt_regionToPath(const QRegion &region);
62 
63 // #define QT_DEBUG_DRAW
64 
65 static void draw_text_item_win(const QPointF &_pos, const QTextItemInt &ti, HDC hdc,
66  bool convertToText, const QTransform &xform, const QPointF &topLeft);
67 
68 static const struct {
71 } dmMapping[] = {
72  { DMPAPER_LETTER, QPrinter::Letter },
73  { DMPAPER_LETTERSMALL, QPrinter::Letter },
74  { DMPAPER_TABLOID, QPrinter::Tabloid },
75  { DMPAPER_LEDGER, QPrinter::Ledger },
76  { DMPAPER_LEGAL, QPrinter::Legal },
77  { DMPAPER_EXECUTIVE, QPrinter::Executive },
78  { DMPAPER_A3, QPrinter::A3 },
79  { DMPAPER_A4, QPrinter::A4 },
80  { DMPAPER_A4SMALL, QPrinter::A4 },
81  { DMPAPER_A5, QPrinter::A5 },
82  { DMPAPER_B4, QPrinter::B4 },
83  { DMPAPER_B5, QPrinter::B5 },
84  { DMPAPER_FOLIO, QPrinter::Folio },
85  { DMPAPER_ENV_10, QPrinter::Comm10E },
86  { DMPAPER_ENV_DL, QPrinter::DLE },
87  { DMPAPER_ENV_C3, QPrinter::C5E },
88  { DMPAPER_LETTER_EXTRA, QPrinter::Letter },
89  { DMPAPER_LEGAL_EXTRA, QPrinter::Legal },
90  { DMPAPER_TABLOID_EXTRA, QPrinter::Tabloid },
91  { DMPAPER_A4_EXTRA, QPrinter::A4},
92  { DMPAPER_LETTER_TRANSVERSE, QPrinter::Letter},
93  { DMPAPER_A4_TRANSVERSE, QPrinter::A4},
94  { DMPAPER_LETTER_EXTRA_TRANSVERSE, QPrinter::Letter },
95  { DMPAPER_A_PLUS, QPrinter::A4 },
96  { DMPAPER_B_PLUS, QPrinter::A3 },
97  { DMPAPER_LETTER_PLUS, QPrinter::Letter },
98  { DMPAPER_A4_PLUS, QPrinter::A4 },
99  { DMPAPER_A5_TRANSVERSE, QPrinter::A5 },
100  { DMPAPER_B5_TRANSVERSE, QPrinter::B5 },
101  { DMPAPER_A3_EXTRA, QPrinter::A3 },
102  { DMPAPER_A5_EXTRA, QPrinter::A5 },
103  { DMPAPER_B5_EXTRA, QPrinter::B5 },
104  { DMPAPER_A2, QPrinter::A2 },
105  { DMPAPER_A3_TRANSVERSE, QPrinter::A3 },
106  { DMPAPER_A3_EXTRA_TRANSVERSE,QPrinter::A3 },
107  { 0, QPrinter::Custom }
108 };
109 
111 {
112  int i = 0;
113  while ((dmMapping[i].winSizeName > 0) && (dmMapping[i].winSizeName != s))
114  i++;
115  return dmMapping[i].qtSizeName;
116 }
117 
119 {
120  int i = 0;
121  while ((dmMapping[i].winSizeName > 0) && (dmMapping[i].qtSizeName != s))
122  i++;
123  return dmMapping[i].winSizeName;
124 }
125 
126 static const struct {
129 } sources[] = {
130  { DMBIN_ONLYONE, QPrinter::OnlyOne },
131  { DMBIN_LOWER, QPrinter::Lower },
132  { DMBIN_MIDDLE, QPrinter::Middle },
133  { DMBIN_MANUAL, QPrinter::Manual },
134  { DMBIN_ENVELOPE, QPrinter::Envelope },
135  { DMBIN_ENVMANUAL, QPrinter::EnvelopeManual },
136  { DMBIN_AUTO, QPrinter::Auto },
137  { DMBIN_TRACTOR, QPrinter::Tractor },
138  { DMBIN_SMALLFMT, QPrinter::SmallFormat },
139  { DMBIN_LARGEFMT, QPrinter::LargeFormat },
140  { DMBIN_LARGECAPACITY, QPrinter::LargeCapacity },
141  { DMBIN_CASSETTE, QPrinter::Cassette },
142  { DMBIN_FORMSOURCE, QPrinter::FormSource },
143  { 0, (QPrinter::PaperSource) -1 }
144 };
145 
147 {
148  int i = 0;
149  while ((sources[i].winSourceName > 0) && (sources[i].winSourceName != s))
150  i++;
151  return sources[i].winSourceName ? sources[i].qtSourceName : (QPrinter::PaperSource) s;
152 }
153 
155 {
156  int i = 0;
157  while ((sources[i].qtSourceName >= 0) && (sources[i].qtSourceName != s))
158  i++;
159  return sources[i].winSourceName ? sources[i].winSourceName : s;
160 }
161 
164  PaintEngineFeatures(PrimitiveTransform
165  | PixmapTransform
166  | PerspectiveTransform
167  | PainterPaths
168  | Antialiasing
169  | PaintOutsidePaintEvent))
170 {
172  d->docName = QLatin1String("document1");
173  d->mode = mode;
174  d->queryDefault();
175  d->initialize();
176 }
177 
179 {
181 
183  if (!continueCall())
184  return true;
185 
186  if (d->reinit) {
187  d->resetDC();
188  d->reinit = false;
189  }
190 
191  // ### set default colors and stuff...
192 
193  bool ok = d->state == QPrinter::Idle;
194 
195  if (!d->hdc)
196  return false;
197 
198  // Assign the FILE: to get the query...
199  if (d->printToFile && d->fileName.isEmpty())
200  d->fileName = d->port;
201 
202  d->devMode->dmCopies = d->num_copies;
203 
204  DOCINFO di;
205  memset(&di, 0, sizeof(DOCINFO));
206  di.cbSize = sizeof(DOCINFO);
207  di.lpszDocName = reinterpret_cast<const wchar_t *>(d->docName.utf16());
208  if (d->printToFile && !d->fileName.isEmpty())
209  di.lpszOutput = reinterpret_cast<const wchar_t *>(d->fileName.utf16());
210  if (ok && StartDoc(d->hdc, &di) == SP_ERROR) {
211  qErrnoWarning("QWin32PrintEngine::begin: StartDoc failed");
212  ok = false;
213  }
214 
215  if (StartPage(d->hdc) <= 0) {
216  qErrnoWarning("QWin32PrintEngine::begin: StartPage failed");
217  ok = false;
218  }
219 
220  if (!ok) {
221  d->state = QPrinter::Idle;
222  } else {
223  d->state = QPrinter::Active;
224  }
225 
226  d->matrix = QTransform();
227  d->has_pen = true;
228  d->pen = QColor(Qt::black);
229  d->has_brush = false;
230 
231  d->complex_xform = false;
232 
233  updateMatrix(d->matrix);
234 
235  if (!ok)
236  cleanUp();
237 
238  return ok;
239 }
240 
242 {
244 
245  if (d->hdc) {
246  if (d->state == QPrinter::Aborted) {
247  cleanUp();
248  AbortDoc(d->hdc);
249  return true;
250  }
251  }
252 
254  if (!continueCall())
255  return true;
256 
257  if (d->hdc) {
258  EndPage(d->hdc); // end; printing done
259  EndDoc(d->hdc);
260  }
261 
262  d->state = QPrinter::Idle;
263  d->reinit = true;
264  return true;
265 }
266 
268 {
270  Q_ASSERT(isActive());
271 
272  Q_ASSERT(d->hdc);
273 
274  flushAndInit();
275 
276  bool transparent = GetBkMode(d->hdc) == TRANSPARENT;
277 
278  if (!EndPage(d->hdc)) {
279  qErrnoWarning("QWin32PrintEngine::newPage: EndPage failed");
280  return false;
281  }
282 
283  if (d->reinit) {
284  if (!d->resetDC()) {
285  qErrnoWarning("QWin32PrintEngine::newPage: ResetDC failed");
286  return false;
287  }
288  d->reinit = false;
289  }
290 
291  if (!StartPage(d->hdc)) {
292  qErrnoWarning("Win32PrintEngine::newPage: StartPage failed");
293  return false;
294  }
295 
296  SetTextAlign(d->hdc, TA_BASELINE);
297  if (transparent)
298  SetBkMode(d->hdc, TRANSPARENT);
299 
300  // ###
301  return true;
302 
303  bool success = false;
304  if (d->hdc && d->state == QPrinter::Active) {
305  if (EndPage(d->hdc) != SP_ERROR) {
306  // reinitialize the DC before StartPage if needed,
307  // because resetdc is disabled between calls to the StartPage and EndPage functions
308  // (see StartPage documentation in the Platform SDK:Windows GDI)
309 // state = PST_ACTIVEDOC;
310 // reinit();
311 // state = PST_ACTIVE;
312  // start the new page now
313  if (d->reinit) {
314  if (!d->resetDC())
315  qErrnoWarning("QWin32PrintEngine::newPage(), ResetDC failed (2)");
316  d->reinit = false;
317  }
318  success = (StartPage(d->hdc) != SP_ERROR);
319  }
320  if (!success) {
321  d->state = QPrinter::Aborted;
322  return false;
323  }
324  }
325  return true;
326 }
327 
329 {
330  // do nothing loop.
331  return false;
332 }
333 
334 void QWin32PrintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
335 {
336  Q_D(const QWin32PrintEngine);
337 
338  QAlphaPaintEngine::drawTextItem(p, textItem);
339  if (!continueCall())
340  return;
341 
342  const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
343  QRgb brushColor = state->pen().brush().color().rgb();
344  bool fallBack = state->pen().brush().style() != Qt::SolidPattern
345  || qAlpha(brushColor) != 0xff
346  || d->txop >= QTransform::TxProject
347  || ti.fontEngine->type() != QFontEngine::Win;
348 
349 
350  if (!fallBack) {
351  QFontEngineWin *fe = static_cast<QFontEngineWin *>(ti.fontEngine);
352 
353  // Try selecting the font to see if we get a substitution font
354  SelectObject(d->hdc, fe->hfont);
355 
356  if (GetDeviceCaps(d->hdc, TECHNOLOGY) != DT_CHARSTREAM) {
357  wchar_t n[64];
358  GetTextFace(d->hdc, 64, n);
359  fallBack = QString::fromWCharArray(n)
360  != QString::fromWCharArray(fe->logfont.lfFaceName);
361  }
362  }
363 
364 
365  if (fallBack) {
366  QPaintEngine::drawTextItem(p, textItem);
367  return ;
368  }
369 
370  // We only want to convert the glyphs to text if the entire string is compatible with ASCII
371  // and if we actually have access to the chars.
372  bool convertToText = ti.chars != 0;
373  for (int i=0; i < ti.num_chars; ++i) {
374  if (ti.chars[i].unicode() >= 0x80) {
375  convertToText = false;
376  break;
377  }
378 
379  if (ti.logClusters[i] != i) {
380  convertToText = false;
381  break;
382  }
383  }
384 
385  COLORREF cf = RGB(qRed(brushColor), qGreen(brushColor), qBlue(brushColor));
386  SelectObject(d->hdc, CreateSolidBrush(cf));
387  SelectObject(d->hdc, CreatePen(PS_SOLID, 1, cf));
388  SetTextColor(d->hdc, cf);
389 
390  draw_text_item_win(p, ti, d->hdc, convertToText, d->matrix, d->devPaperRect.topLeft());
391  DeleteObject(SelectObject(d->hdc,GetStockObject(HOLLOW_BRUSH)));
392  DeleteObject(SelectObject(d->hdc,GetStockObject(BLACK_PEN)));
393 }
394 
395 static inline qreal mmToInches(double mm)
396 {
397  return mm*0.039370147;
398 }
399 
400 static inline qreal inchesToMM(double in)
401 {
402  return in/0.039370147;
403 }
404 
406 {
407  Q_D(const QWin32PrintEngine);
408 
409  if (!d->hdc)
410  return 0;
411 
412  int val;
413  int res = d->resolution;
414 
415  switch (m) {
417  if (d->has_custom_paper_size) {
418  val = qRound(d->paper_size.width() * res / 72.0);
419  } else {
420  int logPixelsX = GetDeviceCaps(d->hdc, LOGPIXELSX);
421  if (logPixelsX == 0) {
422  qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, "
423  "might be a driver problem");
424  logPixelsX = 600; // Reasonable default
425  }
426  val = res
427  * GetDeviceCaps(d->hdc, d->fullPage ? PHYSICALWIDTH : HORZRES)
428  / logPixelsX;
429  }
430  if (d->pageMarginsSet)
431  val -= int(mmToInches((d->previousDialogMargins.left() +
432  d->previousDialogMargins.width()) / 100.0) * res);
433  break;
435  if (d->has_custom_paper_size) {
436  val = qRound(d->paper_size.height() * res / 72.0);
437  } else {
438  int logPixelsY = GetDeviceCaps(d->hdc, LOGPIXELSY);
439  if (logPixelsY == 0) {
440  qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, "
441  "might be a driver problem");
442  logPixelsY = 600; // Reasonable default
443  }
444  val = res
445  * GetDeviceCaps(d->hdc, d->fullPage ? PHYSICALHEIGHT : VERTRES)
446  / logPixelsY;
447  }
448  if (d->pageMarginsSet)
449  val -= int(mmToInches((d->previousDialogMargins.top() +
450  d->previousDialogMargins.height()) / 100.0) * res);
451  break;
453  val = res;
454  break;
456  val = res;
457  break;
459  val = GetDeviceCaps(d->hdc, LOGPIXELSX);
460  break;
462  val = GetDeviceCaps(d->hdc, LOGPIXELSY);
463  break;
465  if (d->has_custom_paper_size) {
466  val = qRound(d->paper_size.width()*25.4/72);
467  } else {
468  if (!d->fullPage) {
469  val = GetDeviceCaps(d->hdc, HORZSIZE);
470  } else {
471  float wi = 25.4 * GetDeviceCaps(d->hdc, PHYSICALWIDTH);
472  int logPixelsX = GetDeviceCaps(d->hdc, LOGPIXELSX);
473  if (logPixelsX == 0) {
474  qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, "
475  "might be a driver problem");
476  logPixelsX = 600; // Reasonable default
477  }
478  val = qRound(wi / logPixelsX);
479  }
480  }
481  if (d->pageMarginsSet)
482  val -= (d->previousDialogMargins.left() +
483  d->previousDialogMargins.width()) / 100.0;
484  break;
486  if (d->has_custom_paper_size) {
487  val = qRound(d->paper_size.height()*25.4/72);
488  } else {
489  if (!d->fullPage) {
490  val = GetDeviceCaps(d->hdc, VERTSIZE);
491  } else {
492  float hi = 25.4 * GetDeviceCaps(d->hdc, PHYSICALHEIGHT);
493  int logPixelsY = GetDeviceCaps(d->hdc, LOGPIXELSY);
494  if (logPixelsY == 0) {
495  qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, "
496  "might be a driver problem");
497  logPixelsY = 600; // Reasonable default
498  }
499  val = qRound(hi / logPixelsY);
500  }
501  }
502  if (d->pageMarginsSet)
503  val -= (d->previousDialogMargins.top() +
504  d->previousDialogMargins.height()) / 100.0;
505  break;
507  {
508  int bpp = GetDeviceCaps(d->hdc, BITSPIXEL);
509  if(bpp==32)
510  val = INT_MAX;
511  else if(bpp<=8)
512  val = GetDeviceCaps(d->hdc, NUMCOLORS);
513  else
514  val = 1 << (bpp * GetDeviceCaps(d->hdc, PLANES));
515  }
516  break;
518  val = GetDeviceCaps(d->hdc, PLANES);
519  break;
520  default:
521  qWarning("QPrinter::metric: Invalid metric command");
522  return 0;
523  }
524  return val;
525 }
526 
528 {
530 
532  if (!continueCall())
533  return;
534 
535  if (state.state() & DirtyTransform) {
536  updateMatrix(state.transform());
537  }
538 
539  if (state.state() & DirtyPen) {
540  d->pen = state.pen();
541  d->has_pen = d->pen.style() != Qt::NoPen && d->pen.isSolid();
542  }
543 
544  if (state.state() & DirtyBrush) {
545  QBrush brush = state.brush();
546  d->has_brush = brush.style() == Qt::SolidPattern;
547  d->brush_color = brush.color();
548  }
549 
550  if (state.state() & DirtyClipEnabled) {
551  if (state.isClipEnabled())
553  else
555  }
556 
557  if (state.state() & DirtyClipPath) {
558  updateClipPath(state.clipPath(), state.clipOperation());
559  }
560 
561  if (state.state() & DirtyClipRegion) {
562  QRegion clipRegion = state.clipRegion();
563  QPainterPath clipPath = qt_regionToPath(clipRegion);
564  updateClipPath(clipPath, state.clipOperation());
565  }
566 }
567 
569 {
571 
572  bool doclip = true;
573  if (op == Qt::NoClip) {
574  SelectClipRgn(d->hdc, 0);
575  doclip = false;
576  }
577 
578  if (doclip) {
579  QPainterPath xformed = clipPath * d->matrix;
580 
581  if (xformed.isEmpty()) {
582  QRegion empty(-0x1000000, -0x1000000, 1, 1);
583  SelectClipRgn(d->hdc, empty.handle());
584  } else {
585  d->composeGdiPath(xformed);
586  const int ops[] = {
587  -1, // Qt::NoClip, covered above
588  RGN_COPY, // Qt::ReplaceClip
589  RGN_AND, // Qt::IntersectClip
590  RGN_OR // Qt::UniteClip
591  };
592  Q_ASSERT(op > 0 && unsigned(op) <= sizeof(ops) / sizeof(int));
593  SelectClipPath(d->hdc, ops[op]);
594  }
595  }
596 
598  if (!aclip.isEmpty()) {
599  QTransform tx(d->stretch_x, 0, 0, d->stretch_y, d->origin_x, d->origin_y);
600  d->composeGdiPath(tx.map(aclip));
601  SelectClipPath(d->hdc, RGN_DIFF);
602  }
603 }
604 
606 {
608 
609  QTransform stretch(d->stretch_x, 0, 0, d->stretch_y, d->origin_x, d->origin_y);
610  d->painterMatrix = m;
611  d->matrix = d->painterMatrix * stretch;
612  d->txop = d->matrix.type();
613  d->complex_xform = (d->txop > QTransform::TxScale);
614 }
615 
616 void QWin32PrintEngine::drawPixmap(const QRectF &targetRect,
617  const QPixmap &originalPixmap,
618  const QRectF &sourceRect)
619 {
621 
622  QAlphaPaintEngine::drawPixmap(targetRect, originalPixmap, sourceRect);
623  if (!continueCall())
624  return;
625 
626  const int tileSize = 2048;
627 
628  QRectF r = targetRect;
629  QRectF sr = sourceRect;
630 
631  QPixmap pixmap = originalPixmap;
632  if (sr.size() != pixmap.size()) {
633  pixmap = pixmap.copy(sr.toRect());
634  }
635 
636  qreal scaleX = 1.0f;
637  qreal scaleY = 1.0f;
638 
639  QTransform scaleMatrix = QTransform::fromScale(r.width() / pixmap.width(), r.height() / pixmap.height());
640  QTransform adapted = QPixmap::trueMatrix(d->painterMatrix * scaleMatrix,
641  pixmap.width(), pixmap.height());
642 
643  qreal xform_offset_x = adapted.dx();
644  qreal xform_offset_y = adapted.dy();
645 
646  if (d->complex_xform) {
647  pixmap = pixmap.transformed(adapted);
648  scaleX = d->stretch_x;
649  scaleY = d->stretch_y;
650  } else {
651  scaleX = d->stretch_x * (r.width() / pixmap.width()) * d->painterMatrix.m11();
652  scaleY = d->stretch_y * (r.height() / pixmap.height()) * d->painterMatrix.m22();
653  }
654 
655  QPointF topLeft = r.topLeft() * d->painterMatrix;
656  int tx = int(topLeft.x() * d->stretch_x + d->origin_x);
657  int ty = int(topLeft.y() * d->stretch_y + d->origin_y);
658  int tw = qAbs(int(pixmap.width() * scaleX));
659  int th = qAbs(int(pixmap.height() * scaleY));
660 
661  xform_offset_x *= d->stretch_x;
662  xform_offset_y *= d->stretch_y;
663 
664  int dc_state = SaveDC(d->hdc);
665 
666  int tilesw = pixmap.width() / tileSize;
667  int tilesh = pixmap.height() / tileSize;
668  ++tilesw;
669  ++tilesh;
670 
671  int txinc = tileSize*scaleX;
672  int tyinc = tileSize*scaleY;
673 
674  for (int y = 0; y < tilesh; ++y) {
675  int tposy = ty + (y * tyinc);
676  int imgh = tileSize;
677  int height = tyinc;
678  if (y == (tilesh - 1)) {
679  imgh = pixmap.height() - (y * tileSize);
680  height = (th - (y * tyinc));
681  }
682  for (int x = 0; x < tilesw; ++x) {
683  int tposx = tx + (x * txinc);
684  int imgw = tileSize;
685  int width = txinc;
686  if (x == (tilesw - 1)) {
687  imgw = pixmap.width() - (x * tileSize);
688  width = (tw - (x * txinc));
689  }
690 
691  QPixmap p = pixmap.copy(tileSize * x, tileSize * y, imgw, imgh);
692  HBITMAP hbitmap = p.toWinHBITMAP(QPixmap::NoAlpha);
693  HDC display_dc = GetDC(0);
694  HDC hbitmap_hdc = CreateCompatibleDC(display_dc);
695  HGDIOBJ null_bitmap = SelectObject(hbitmap_hdc, hbitmap);
696 
697  ReleaseDC(0, display_dc);
698 
699  if (!StretchBlt(d->hdc, qRound(tposx - xform_offset_x), qRound(tposy - xform_offset_y), width, height,
700  hbitmap_hdc, 0, 0, p.width(), p.height(), SRCCOPY))
701  qErrnoWarning("QWin32PrintEngine::drawPixmap, StretchBlt failed");
702 
703  SelectObject(hbitmap_hdc, null_bitmap);
704  DeleteObject(hbitmap);
705  DeleteDC(hbitmap_hdc);
706  }
707  }
708 
709  RestoreDC(d->hdc, dc_state);
710 }
711 
712 
713 void QWin32PrintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &pos)
714 {
716 
718  if (!continueCall())
719  return;
720 
721  if (d->complex_xform || !pos.isNull()) {
722  QPaintEngine::drawTiledPixmap(r, pm, pos);
723  } else {
724  int dc_state = SaveDC(d->hdc);
725 
726  HDC display_dc = GetDC(0);
727  HBITMAP hbitmap = pm.toWinHBITMAP(QPixmap::NoAlpha);
728  HDC hbitmap_hdc = CreateCompatibleDC(display_dc);
729  HGDIOBJ null_bitmap = SelectObject(hbitmap_hdc, hbitmap);
730 
731  ReleaseDC(0, display_dc);
732 
733  QRectF trect = d->painterMatrix.mapRect(r);
734  int tx = int(trect.left() * d->stretch_x + d->origin_x);
735  int ty = int(trect.top() * d->stretch_y + d->origin_y);
736 
737  int xtiles = int(trect.width() / pm.width()) + 1;
738  int ytiles = int(trect.height() / pm.height()) + 1;
739  int xinc = int(pm.width() * d->stretch_x);
740  int yinc = int(pm.height() * d->stretch_y);
741 
742  for (int y = 0; y < ytiles; ++y) {
743  int ity = ty + (yinc * y);
744  int ith = pm.height();
745  if (y == (ytiles - 1)) {
746  ith = int(trect.height() - (pm.height() * y));
747  }
748 
749  for (int x = 0; x < xtiles; ++x) {
750  int itx = tx + (xinc * x);
751  int itw = pm.width();
752  if (x == (xtiles - 1)) {
753  itw = int(trect.width() - (pm.width() * x));
754  }
755 
756  if (!StretchBlt(d->hdc, itx, ity, int(itw * d->stretch_x), int(ith * d->stretch_y),
757  hbitmap_hdc, 0, 0, itw, ith, SRCCOPY))
758  qErrnoWarning("QWin32PrintEngine::drawPixmap, StretchBlt failed");
759 
760  }
761  }
762 
763  SelectObject(hbitmap_hdc, null_bitmap);
764  DeleteObject(hbitmap);
765  DeleteDC(hbitmap_hdc);
766 
767  RestoreDC(d->hdc, dc_state);
768  }
769 }
770 
771 
773 {
774  if (!BeginPath(hdc))
775  qErrnoWarning("QWin32PrintEnginePrivate::drawPath: BeginPath failed");
776 
777  // Drawing the subpaths
778  int start = -1;
779  for (int i=0; i<path.elementCount(); ++i) {
780  const QPainterPath::Element &elm = path.elementAt(i);
781  switch (elm.type) {
783  if (start >= 0
784  && path.elementAt(start).x == path.elementAt(i-1).x
785  && path.elementAt(start).y == path.elementAt(i-1).y)
786  CloseFigure(hdc);
787  start = i;
788  MoveToEx(hdc, qRound(elm.x), qRound(elm.y), 0);
789  break;
791  LineTo(hdc, qRound(elm.x), qRound(elm.y));
792  break;
794  POINT pts[3] = {
795  { qRound(elm.x), qRound(elm.y) },
796  { qRound(path.elementAt(i+1).x), qRound(path.elementAt(i+1).y) },
797  { qRound(path.elementAt(i+2).x), qRound(path.elementAt(i+2).y) }
798  };
799  i+=2;
800  PolyBezierTo(hdc, pts, 3);
801  break;
802  }
803  default:
804  qFatal("QWin32PaintEngine::drawPath: Unhandled type: %d", elm.type);
805  }
806  }
807 
808  if (start >= 0
809  && path.elementAt(start).x == path.elementAt(path.elementCount()-1).x
810  && path.elementAt(start).y == path.elementAt(path.elementCount()-1).y)
811  CloseFigure(hdc);
812 
813  if (!EndPath(hdc))
814  qErrnoWarning("QWin32PaintEngine::drawPath: EndPath failed");
815 
816  SetPolyFillMode(hdc, path.fillRule() == Qt::WindingFill ? WINDING : ALTERNATE);
817 }
818 
819 
821 {
822 #ifdef QT_DEBUG_DRAW
823  qDebug() << " --- QWin32PrintEnginePrivate::fillPath() bound:" << path.boundingRect() << color;
824 #endif
825 
826  composeGdiPath(path);
827 
828  HBRUSH brush = CreateSolidBrush(RGB(color.red(), color.green(), color.blue()));
829  HGDIOBJ old_brush = SelectObject(hdc, brush);
830  FillPath(hdc);
831  DeleteObject(SelectObject(hdc, old_brush));
832 }
833 
834 void QWin32PrintEnginePrivate::strokePath_dev(const QPainterPath &path, const QColor &color, qreal penWidth)
835 {
836  composeGdiPath(path);
837  LOGBRUSH brush;
838  brush.lbStyle = BS_SOLID;
839  brush.lbColor = RGB(color.red(), color.green(), color.blue());
840  DWORD capStyle = PS_ENDCAP_SQUARE;
841  DWORD joinStyle = PS_JOIN_BEVEL;
842  if (pen.capStyle() == Qt::FlatCap)
843  capStyle = PS_ENDCAP_FLAT;
844  else if (pen.capStyle() == Qt::RoundCap)
845  capStyle = PS_ENDCAP_ROUND;
846 
847  if (pen.joinStyle() == Qt::MiterJoin)
848  joinStyle = PS_JOIN_MITER;
849  else if (pen.joinStyle() == Qt::RoundJoin)
850  joinStyle = PS_JOIN_ROUND;
851 
852  HPEN pen = ExtCreatePen(((penWidth == 0) ? PS_COSMETIC : PS_GEOMETRIC)
853  | PS_SOLID | capStyle | joinStyle,
854  (penWidth == 0) ? 1 : penWidth, &brush, 0, 0);
855 
856  HGDIOBJ old_pen = SelectObject(hdc, pen);
857  StrokePath(hdc);
858  DeleteObject(SelectObject(hdc, old_pen));
859 }
860 
861 
863 {
864  fillPath_dev(path * matrix, color);
865 }
866 
868 {
869  QPainterPathStroker stroker;
870  if (pen.style() == Qt::CustomDashLine) {
871  stroker.setDashPattern(pen.dashPattern());
872  stroker.setDashOffset(pen.dashOffset());
873  } else {
874  stroker.setDashPattern(pen.style());
875  }
876  stroker.setCapStyle(pen.capStyle());
877  stroker.setJoinStyle(pen.joinStyle());
878  stroker.setMiterLimit(pen.miterLimit());
879 
880  QPainterPath stroke;
881  qreal width = pen.widthF();
882  if (pen.style() == Qt::SolidLine && (pen.isCosmetic() || matrix.type() < QTransform::TxScale)) {
883  strokePath_dev(path * matrix, color, width);
884  } else {
885  stroker.setWidth(width);
886  if (pen.isCosmetic()) {
887  stroke = stroker.createStroke(path * matrix);
888  } else {
889  stroke = stroker.createStroke(path) * painterMatrix;
890  QTransform stretch(stretch_x, 0, 0, stretch_y, origin_x, origin_y);
891  stroke = stroke * stretch;
892  }
893 
894  if (stroke.isEmpty())
895  return;
896 
897  fillPath_dev(stroke, color);
898  }
899 }
900 
901 
903 {
904 #ifdef QT_DEBUG_DRAW
905  qDebug() << " - QWin32PrintEngine::drawPath(), bounds: " << path.boundingRect();
906 #endif
907 
909 
911  if (!continueCall())
912  return;
913 
914  if (d->has_brush)
915  d->fillPath(path, d->brush_color);
916 
917  if (d->has_pen)
918  d->strokePath(path, d->pen.color());
919 }
920 
921 
922 void QWin32PrintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
923 {
924 #ifdef QT_DEBUG_DRAW
925  qDebug() << " - QWin32PrintEngine::drawPolygon(), pointCount: " << pointCount;
926 #endif
927 
928  QAlphaPaintEngine::drawPolygon(points, pointCount, mode);
929  if (!continueCall())
930  return;
931 
932  Q_ASSERT(pointCount > 1);
933 
934  QPainterPath path(points[0]);
935 
936  for (int i=1; i<pointCount; ++i) {
937  path.lineTo(points[i]);
938  }
939 
941 
942  bool has_brush = d->has_brush;
943 
944  if (mode == PolylineMode)
945  d->has_brush = false; // No brush for polylines
946  else
947  path.closeSubpath(); // polygons are should always be closed.
948 
949  drawPath(path);
950  d->has_brush = has_brush;
951 }
952 
954 {
955  /* Read the default printer name, driver and port with the intuitive function
956  * Strings "windows" and "device" are specified in the MSDN under EnumPrinters()
957  */
958  QString noPrinters(QLatin1String("qt_no_printers"));
959  wchar_t buffer[256];
960  GetProfileString(L"windows", L"device",
961  reinterpret_cast<const wchar_t *>(noPrinters.utf16()),
962  buffer, 256);
963  QString output = QString::fromWCharArray(buffer);
964  if (output.isEmpty() || output == noPrinters) // no printers
965  return;
966 
967  QStringList info = output.split(QLatin1Char(','));
968  int infoSize = info.size();
969  if (infoSize > 0) {
970  if (name.isEmpty())
971  name = info.at(0);
972  if (program.isEmpty() && infoSize > 1)
973  program = info.at(1);
974  if (port.isEmpty() && infoSize > 2)
975  port = info.at(2);
976  }
977 }
978 
980 {
981  if (hdc)
982  release();
983 }
984 
986 {
987  if (hdc)
988  release();
989  Q_ASSERT(!hPrinter);
990  Q_ASSERT(!hdc);
991  Q_ASSERT(!devMode);
992  Q_ASSERT(!pInfo);
993 
994  if (name.isEmpty())
995  return;
996 
997  txop = QTransform::TxNone;
998 
999  bool ok = OpenPrinter((LPWSTR)name.utf16(), (LPHANDLE)&hPrinter, 0);
1000  if (!ok) {
1001  qErrnoWarning("QWin32PrintEngine::initialize: OpenPrinter failed");
1002  return;
1003  }
1004 
1005  // Fetch the PRINTER_INFO_2 with DEVMODE data containing the
1006  // printer settings.
1007  DWORD infoSize, numBytes;
1008  GetPrinter(hPrinter, 2, NULL, 0, &infoSize);
1009  hMem = GlobalAlloc(GHND, infoSize);
1010  pInfo = (PRINTER_INFO_2*) GlobalLock(hMem);
1011  ok = GetPrinter(hPrinter, 2, (LPBYTE)pInfo, infoSize, &numBytes);
1012 
1013  if (!ok) {
1014  qErrnoWarning("QWin32PrintEngine::initialize: GetPrinter failed");
1015  GlobalUnlock(pInfo);
1016  GlobalFree(hMem);
1017  ClosePrinter(hPrinter);
1018  pInfo = 0;
1019  hMem = 0;
1020  hPrinter = 0;
1021  return;
1022  }
1023 
1024  devMode = pInfo->pDevMode;
1025  hdc = CreateDC(reinterpret_cast<const wchar_t *>(program.utf16()),
1026  reinterpret_cast<const wchar_t *>(name.utf16()), 0, devMode);
1027 
1028  Q_ASSERT(hPrinter);
1029  Q_ASSERT(pInfo);
1030 
1031  if (devMode) {
1032  num_copies = devMode->dmCopies;
1033  }
1034 
1035  initHDC();
1036 
1037 #ifdef QT_DEBUG_DRAW
1038  qDebug() << "QWin32PrintEngine::initialize()" << endl
1039  << " - paperRect" << devPaperRect << endl
1040  << " - pageRect" << devPageRect << endl
1041  << " - stretch_x" << stretch_x << endl
1042  << " - stretch_y" << stretch_y << endl
1043  << " - origin_x" << origin_x << endl
1044  << " - origin_y" << origin_y << endl;
1045 #endif
1046 }
1047 
1049 {
1050  Q_ASSERT(hdc);
1051 
1052  HDC display_dc = GetDC(0);
1053  dpi_x = GetDeviceCaps(hdc, LOGPIXELSX);
1054  dpi_y = GetDeviceCaps(hdc, LOGPIXELSY);
1055  dpi_display = GetDeviceCaps(display_dc, LOGPIXELSY);
1056  ReleaseDC(0, display_dc);
1057  if (dpi_display == 0) {
1058  qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, "
1059  "might be a driver problem");
1060  dpi_display = 96; // Reasonable default
1061  }
1062 
1063  switch(mode) {
1065  resolution = dpi_display;
1066  stretch_x = dpi_x / double(dpi_display);
1067  stretch_y = dpi_y / double(dpi_display);
1068  break;
1071  resolution = dpi_y;
1072  stretch_x = 1;
1073  stretch_y = 1;
1074  break;
1075  default:
1076  break;
1077  }
1078 
1079  initDevRects();
1080 }
1081 
1083 {
1084  devPaperRect = QRect(0, 0,
1085  GetDeviceCaps(hdc, PHYSICALWIDTH),
1086  GetDeviceCaps(hdc, PHYSICALHEIGHT));
1087  devPhysicalPageRect = QRect(GetDeviceCaps(hdc, PHYSICALOFFSETX),
1088  GetDeviceCaps(hdc, PHYSICALOFFSETY),
1089  GetDeviceCaps(hdc, HORZRES),
1090  GetDeviceCaps(hdc, VERTRES));
1091  if (!pageMarginsSet)
1092  devPageRect = devPhysicalPageRect;
1093  else
1094  devPageRect = devPaperRect.adjusted(qRound(mmToInches(previousDialogMargins.left() / 100.0) * dpi_x),
1095  qRound(mmToInches(previousDialogMargins.top() / 100.0) * dpi_y),
1096  -qRound(mmToInches(previousDialogMargins.width() / 100.0) * dpi_x),
1097  -qRound(mmToInches(previousDialogMargins.height() / 100.0) * dpi_y));
1098  updateOrigin();
1099 }
1100 
1101 void QWin32PrintEnginePrivate::setPageMargins(int marginLeft, int marginTop, int marginRight, int marginBottom)
1102 {
1103  pageMarginsSet = true;
1104  previousDialogMargins = QRect(marginLeft, marginTop, marginRight, marginBottom);
1105 
1106  devPageRect = devPaperRect.adjusted(qRound(mmToInches(marginLeft / 100.0) * dpi_x),
1107  qRound(mmToInches(marginTop / 100.0) * dpi_y),
1108  - qRound(mmToInches(marginRight / 100.0) * dpi_x),
1109  - qRound(mmToInches(marginBottom / 100.0) * dpi_y));
1110  updateOrigin();
1111 }
1112 
1114 {
1115  if (pageMarginsSet)
1116  return previousDialogMargins;
1117  else
1118  return QRect(qRound(inchesToMM(devPhysicalPageRect.left()) * 100.0 / dpi_x),
1119  qRound(inchesToMM(devPhysicalPageRect.top()) * 100.0 / dpi_y),
1120  qRound(inchesToMM(devPaperRect.right() - devPhysicalPageRect.right()) * 100.0 / dpi_x),
1121  qRound(inchesToMM(devPaperRect.bottom() - devPhysicalPageRect.bottom()) * 100.0 / dpi_y));
1122 }
1123 
1125 {
1126  if (hdc == 0)
1127  return;
1128 
1129  if (globalDevMode) { // Devmode comes from print dialog
1130  GlobalUnlock(globalDevMode);
1131  } else { // Devmode comes from initialize...
1132  // devMode is a part of the same memory block as pInfo so one free is enough...
1133  GlobalUnlock(hMem);
1134  GlobalFree(hMem);
1135  }
1136  if (hPrinter)
1137  ClosePrinter(hPrinter);
1138  DeleteDC(hdc);
1139 
1140  hdc = 0;
1141  hPrinter = 0;
1142  pInfo = 0;
1143  hMem = 0;
1144  devMode = 0;
1145 }
1146 
1148 {
1149  // Read the supported resolutions of the printer.
1150  QList<QVariant> list;
1151 
1152  DWORD numRes = DeviceCapabilities(reinterpret_cast<const wchar_t *>(name.utf16()),
1153  reinterpret_cast<const wchar_t *>(port.utf16()),
1154  DC_ENUMRESOLUTIONS, 0, 0);
1155  if (numRes == (DWORD)-1)
1156  return list;
1157 
1158  LONG *enumRes = (LONG*)malloc(numRes * 2 * sizeof(LONG));
1159  DWORD errRes = DeviceCapabilities(reinterpret_cast<const wchar_t *>(name.utf16()),
1160  reinterpret_cast<const wchar_t *>(port.utf16()),
1161  DC_ENUMRESOLUTIONS, (LPWSTR)enumRes, 0);
1162 
1163  if (errRes == (DWORD)-1) {
1164  qErrnoWarning("QWin32PrintEngine::queryResolutions: DeviceCapabilities failed");
1165  return list;
1166  }
1167 
1168  for (uint i=0; i<numRes; ++i)
1169  list.append(int(enumRes[i * 2]));
1170 
1171  return list;
1172 }
1173 
1175 {
1176  if (state == QPrinter::Active) {
1177  reinit = true;
1178  } else {
1179  resetDC();
1180  initDevRects();
1181  reinit = false;
1182  }
1183 }
1184 
1186 {
1187  if (fullPage) {
1188  // subtract physical margins to make (0,0) absolute top corner of paper
1189  // then add user defined margins
1190  origin_x = -devPhysicalPageRect.x();
1191  origin_y = -devPhysicalPageRect.y();
1192  if (pageMarginsSet) {
1193  origin_x += devPageRect.left();
1194  origin_y += devPageRect.top();
1195  }
1196  } else {
1197  origin_x = 0;
1198  origin_y = 0;
1199  if (pageMarginsSet) {
1200  origin_x = devPageRect.left() - devPhysicalPageRect.x();
1201  origin_y = devPageRect.top() - devPhysicalPageRect.y();
1202  }
1203  }
1204 }
1205 
1207 {
1209  switch (key) {
1210  case PPK_CollateCopies:
1211  {
1212  if (!d->devMode)
1213  break;
1214  d->devMode->dmCollate = value.toBool() ? DMCOLLATE_TRUE : DMCOLLATE_FALSE;
1215  d->doReinit();
1216  }
1217  break;
1218 
1219  case PPK_ColorMode:
1220  {
1221  if (!d->devMode)
1222  break;
1223  d->devMode->dmColor = (value.toInt() == QPrinter::Color) ? DMCOLOR_COLOR : DMCOLOR_MONOCHROME;
1224  d->doReinit();
1225  }
1226  break;
1227 
1228  case PPK_Creator:
1229 
1230  break;
1231 
1232  case PPK_DocumentName:
1233  if (isActive()) {
1234  qWarning("QWin32PrintEngine: Cannot change document name while printing is active");
1235  return;
1236  }
1237  d->docName = value.toString();
1238  break;
1239 
1240  case PPK_FullPage:
1241  d->fullPage = value.toBool();
1242  d->updateOrigin();
1243  break;
1244 
1245  case PPK_CopyCount: // fallthrough
1246  case PPK_NumberOfCopies:
1247  if (!d->devMode)
1248  break;
1249  d->num_copies = value.toInt();
1250  d->devMode->dmCopies = d->num_copies;
1251  d->doReinit();
1252  break;
1253 
1254  case PPK_Orientation:
1255  {
1256  if (!d->devMode)
1257  break;
1258  int orientation = value.toInt() == QPrinter::Landscape ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT;
1259  int old_orientation = d->devMode->dmOrientation;
1260  d->devMode->dmOrientation = orientation;
1261  if (d->has_custom_paper_size && old_orientation != orientation)
1262  d->paper_size = QSizeF(d->paper_size.height(), d->paper_size.width());
1263  d->doReinit();
1264  }
1265  break;
1266 
1267  case PPK_OutputFileName:
1268  if (isActive()) {
1269  qWarning("QWin32PrintEngine: Cannot change filename while printing");
1270  } else {
1271  d->fileName = value.toString();
1272  d->printToFile = !value.toString().isEmpty();
1273  }
1274  break;
1275 
1276  case PPK_PaperSize:
1277  if (!d->devMode)
1278  break;
1279  d->devMode->dmPaperSize = mapPaperSizeDevmode(QPrinter::PaperSize(value.toInt()));
1280  d->has_custom_paper_size = (QPrinter::PaperSize(value.toInt()) == QPrinter::Custom);
1281  d->doReinit();
1282  break;
1283 
1284  case PPK_PaperSource:
1285  {
1286  if (!d->devMode)
1287  break;
1288  int dmMapped = DMBIN_AUTO;
1289 
1291  if (v.contains(value))
1292  dmMapped = mapPaperSourceDevmode(QPrinter::PaperSource(value.toInt()));
1293 
1294  d->devMode->dmDefaultSource = dmMapped;
1295  d->doReinit();
1296  }
1297  break;
1298 
1299  case PPK_PrinterName:
1300  d->name = value.toString();
1301  if(d->name.isEmpty())
1302  d->queryDefault();
1303  d->initialize();
1304  break;
1305 
1306  case PPK_Resolution:
1307  {
1308  d->resolution = value.toInt();
1309 
1310  d->stretch_x = d->dpi_x / double(d->resolution);
1311  d->stretch_y = d->dpi_y / double(d->resolution);
1312  }
1313  break;
1314 
1315  case PPK_SelectionOption:
1316 
1317  break;
1318 
1320 
1321  break;
1322 
1323 
1324  case PPK_WindowsPageSize:
1325  if (!d->devMode)
1326  break;
1327  d->has_custom_paper_size = false;
1328  d->devMode->dmPaperSize = value.toInt();
1329  d->doReinit();
1330  break;
1331 
1332  case PPK_CustomPaperSize:
1333  {
1334  d->has_custom_paper_size = true;
1335  d->paper_size = value.toSizeF();
1336  if (!d->devMode)
1337  break;
1338  int orientation = d->devMode->dmOrientation;
1339  DWORD needed = 0;
1340  DWORD returned = 0;
1341  if (!EnumForms(d->hPrinter, 1, 0, 0, &needed, &returned)) {
1342  BYTE *forms = (BYTE *) malloc(needed);
1343  if (EnumForms(d->hPrinter, 1, forms, needed, &needed, &returned)) {
1344  for (DWORD i=0; i< returned; ++i) {
1345  FORM_INFO_1 *formArray = reinterpret_cast<FORM_INFO_1 *>(forms);
1346  // the form sizes are specified in 1000th of a mm,
1347  // convert the size to Points
1348  QSizeF size((formArray[i].Size.cx * 72/25.4)/1000.0,
1349  (formArray[i].Size.cy * 72/25.4)/1000.0);
1350  if (qAbs(d->paper_size.width() - size.width()) <= 2
1351  && qAbs(d->paper_size.height() - size.height()) <= 2)
1352  {
1353  d->devMode->dmPaperSize = i + 1;
1354  break;
1355  }
1356  }
1357  }
1358  free(forms);
1359  }
1360  if (orientation != DMORIENT_PORTRAIT)
1361  d->paper_size = QSizeF(d->paper_size.height(), d->paper_size.width());
1362  break;
1363  }
1364 
1365  case PPK_PageMargins:
1366  {
1367  QList<QVariant> margins(value.toList());
1368  Q_ASSERT(margins.size() == 4);
1369  int left, top, right, bottom;
1370  // specified in 1/100 mm
1371  left = (margins.at(0).toReal()*25.4/72.0) * 100;
1372  top = (margins.at(1).toReal()*25.4/72.0) * 100;
1373  right = (margins.at(2).toReal()*25.4/72.0) * 100;
1374  bottom = (margins.at(3).toReal()*25.4/72.0) * 100;
1375  d->setPageMargins(left, top, right, bottom);
1376  break;
1377  }
1378  default:
1379  // Do nothing
1380  break;
1381  }
1382 }
1383 
1385 {
1386  Q_D(const QWin32PrintEngine);
1387  QVariant value;
1388  switch (key) {
1389 
1390  case PPK_CollateCopies:
1391  value = false;
1392  break;
1393 
1394  case PPK_ColorMode:
1395  {
1396  if (!d->devMode) {
1397  value = QPrinter::Color;
1398  } else {
1399  value = (d->devMode->dmColor == DMCOLOR_COLOR) ? QPrinter::Color : QPrinter::GrayScale;
1400  }
1401  }
1402  break;
1403 
1404  case PPK_DocumentName:
1405  value = d->docName;
1406  break;
1407 
1408  case PPK_FullPage:
1409  value = d->fullPage;
1410  break;
1411 
1412  case PPK_CopyCount:
1413  value = d->num_copies;
1414  break;
1415 
1417  value = true;
1418  break;
1419 
1420  case PPK_NumberOfCopies:
1421  value = 1;
1422  break;
1423 
1424  case PPK_Orientation:
1425  {
1426  if (!d->devMode) {
1427  value = QPrinter::Portrait;
1428  } else {
1429  value = (d->devMode->dmOrientation == DMORIENT_LANDSCAPE) ? QPrinter::Landscape : QPrinter::Portrait;
1430  }
1431  }
1432  break;
1433 
1434  case PPK_OutputFileName:
1435  value = d->fileName;
1436  break;
1437 
1438  case PPK_PageRect:
1439  if (d->has_custom_paper_size) {
1440  QRect rect(0, 0,
1441  qRound(d->paper_size.width() * d->resolution / 72.0),
1442  qRound(d->paper_size.height() * d->resolution / 72.0));
1443  if (d->pageMarginsSet) {
1444  rect = rect.adjusted(qRound(mmToInches(d->previousDialogMargins.left()/100.0) * d->resolution),
1445  qRound(mmToInches(d->previousDialogMargins.top()/100.0) * d->resolution),
1446  -qRound(mmToInches(d->previousDialogMargins.width()/100.0) * d->resolution),
1447  -qRound(mmToInches(d->previousDialogMargins.height()/100.0) * d->resolution));
1448  }
1449  value = rect;
1450  } else {
1451  value = QTransform(1/d->stretch_x, 0, 0, 1/d->stretch_y, 0, 0)
1452  .mapRect(d->fullPage ? d->devPhysicalPageRect : d->devPageRect);
1453  }
1454  break;
1455 
1456  case PPK_PaperSize:
1457  if (d->has_custom_paper_size) {
1458  value = QPrinter::Custom;
1459  } else {
1460  if (!d->devMode) {
1461  value = QPrinter::A4;
1462  } else {
1463  value = mapDevmodePaperSize(d->devMode->dmPaperSize);
1464  }
1465  }
1466  break;
1467 
1468  case PPK_PaperRect:
1469  if (d->has_custom_paper_size) {
1470  value = QRect(0, 0,
1471  qRound(d->paper_size.width() * d->resolution / 72.0),
1472  qRound(d->paper_size.height() * d->resolution / 72.0));
1473  } else {
1474  value = QTransform(1/d->stretch_x, 0, 0, 1/d->stretch_y, 0, 0).mapRect(d->devPaperRect);
1475  }
1476  break;
1477 
1478  case PPK_PaperSource:
1479  if (!d->devMode) {
1480  value = QPrinter::Auto;
1481  } else {
1482  value = mapDevmodePaperSource(d->devMode->dmDefaultSource);
1483  }
1484  break;
1485 
1486  case PPK_PrinterName:
1487  value = d->name;
1488  break;
1489 
1490  case PPK_Resolution:
1491  if (d->resolution || !d->name.isEmpty())
1492  value = d->resolution;
1493  break;
1494 
1496  value = d->queryResolutions();
1497  break;
1498 
1499  case PPK_WindowsPageSize:
1500  if (!d->devMode) {
1501  value = -1;
1502  } else {
1503  value = d->devMode->dmPaperSize;
1504  }
1505  break;
1506 
1507  case PPK_PaperSources:
1508  {
1509  int available = DeviceCapabilities((const wchar_t *)d->name.utf16(),
1510  (const wchar_t *)d->port.utf16(), DC_BINS, 0, d->devMode);
1511 
1512  if (available <= 0)
1513  break;
1514 
1515  wchar_t *data = new wchar_t[available];
1516  int count = DeviceCapabilities((const wchar_t *)d->name.utf16(),
1517  (const wchar_t *)d->port.utf16(), DC_BINS, data, d->devMode);
1518 
1519  QList<QVariant> out;
1520  for (int i=0; i<count; ++i) {
1522  if (src != -1)
1523  out << (int) src;
1524  }
1525  value = out;
1526 
1527  delete [] data;
1528  }
1529  break;
1530 
1531  case PPK_CustomPaperSize:
1532  value = d->paper_size;
1533  break;
1534 
1535  case PPK_PageMargins:
1536  {
1537  QList<QVariant> margins;
1538  QRect pageMargins(d->getPageMargins());
1539 
1540  // specified in 1/100 mm
1541  margins << (mmToInches(pageMargins.left()/100.0) * 72)
1542  << (mmToInches(pageMargins.top()/100.0) * 72)
1543  << (mmToInches(pageMargins.width()/100.0) * 72)
1544  << (mmToInches(pageMargins.height()/100.0) * 72);
1545  value = margins;
1546  break;
1547  }
1548  default:
1549  // Do nothing
1550  break;
1551  }
1552  return value;
1553 }
1554 
1556 {
1557  return d_func()->state;
1558 }
1559 
1561 {
1562  return d_func()->hdc;
1563 }
1564 
1566 {
1567 
1568 }
1569 
1571 {
1572  int size = sizeof(DEVNAMES)
1573  + program.length() * 2 + 2
1574  + name.length() * 2 + 2
1575  + port.length() * 2 + 2;
1576  HGLOBAL *hGlobal = (HGLOBAL *) GlobalAlloc(GMEM_MOVEABLE, size);
1577  DEVNAMES *dn = (DEVNAMES*) GlobalLock(hGlobal);
1578 
1579  dn->wDriverOffset = sizeof(DEVNAMES) / sizeof(wchar_t);
1580  dn->wDeviceOffset = dn->wDriverOffset + program.length() + 1;
1581  dn->wOutputOffset = dn->wDeviceOffset + name.length() + 1;
1582 
1583  memcpy((ushort*)dn + dn->wDriverOffset, program.utf16(), program.length() * 2 + 2);
1584  memcpy((ushort*)dn + dn->wDeviceOffset, name.utf16(), name.length() * 2 + 2);
1585  memcpy((ushort*)dn + dn->wOutputOffset, port.utf16(), port.length() * 2 + 2);
1586  dn->wDefault = 0;
1587 
1588  GlobalUnlock(hGlobal);
1589 
1590 // printf("QPrintDialogWinPrivate::createDevNames()\n"
1591 // " -> wDriverOffset: %d\n"
1592 // " -> wDeviceOffset: %d\n"
1593 // " -> wOutputOffset: %d\n",
1594 // dn->wDriverOffset,
1595 // dn->wDeviceOffset,
1596 // dn->wOutputOffset);
1597 
1598 // printf("QPrintDialogWinPrivate::createDevNames(): %s, %s, %s\n",
1599 // QString::fromWCharArray((wchar_t*)(dn) + dn->wDriverOffset).latin1(),
1600 // QString::fromWCharArray((wchar_t*)(dn) + dn->wDeviceOffset).latin1(),
1601 // QString::fromWCharArray((wchar_t*)(dn) + dn->wOutputOffset).latin1());
1602 
1603  return hGlobal;
1604 }
1605 
1606 void QWin32PrintEnginePrivate::readDevnames(HGLOBAL globalDevnames)
1607 {
1608  if (globalDevnames) {
1609  DEVNAMES *dn = (DEVNAMES*) GlobalLock(globalDevnames);
1610  name = QString::fromWCharArray((wchar_t*)(dn) + dn->wDeviceOffset);
1611  port = QString::fromWCharArray((wchar_t*)(dn) + dn->wOutputOffset);
1612  program = QString::fromWCharArray((wchar_t*)(dn) + dn->wDriverOffset);
1613  GlobalUnlock(globalDevnames);
1614  }
1615 }
1616 
1617 void QWin32PrintEnginePrivate::readDevmode(HGLOBAL globalDevmode)
1618 {
1619  if (globalDevmode) {
1620  DEVMODE *dm = (DEVMODE*) GlobalLock(globalDevmode);
1621  release();
1622  globalDevMode = globalDevmode;
1623  devMode = dm;
1624  hdc = CreateDC(reinterpret_cast<const wchar_t *>(program.utf16()),
1625  reinterpret_cast<const wchar_t *>(name.utf16()), 0, dm);
1626 
1627  num_copies = devMode->dmCopies;
1628  if (!OpenPrinter((wchar_t*)name.utf16(), &hPrinter, 0))
1629  qWarning("QPrinter: OpenPrinter() failed after reading DEVMODE.");
1630  }
1631 
1632  if (hdc)
1633  initHDC();
1634 }
1635 
1636 static void draw_text_item_win(const QPointF &pos, const QTextItemInt &ti, HDC hdc,
1637  bool convertToText, const QTransform &xform, const QPointF &topLeft)
1638 {
1639  QFontEngine *fe = ti.fontEngine;
1640  QPointF baseline_pos = xform.inverted().map(xform.map(pos) - topLeft);
1641 
1642  SetTextAlign(hdc, TA_BASELINE);
1643  SetBkMode(hdc, TRANSPARENT);
1644 
1645  bool has_kerning = ti.f && ti.f->kerning();
1646  QFontEngineWin *winfe = (fe->type() == QFontEngine::Win) ? static_cast<QFontEngineWin *>(fe) : 0;
1647 
1648  HFONT hfont;
1649  bool ttf = false;
1650 
1651  if (winfe) {
1652  hfont = winfe->hfont;
1653  ttf = winfe->ttf;
1654  } else {
1655  hfont = (HFONT)GetStockObject(ANSI_VAR_FONT);
1656  }
1657 
1658  HGDIOBJ old_font = SelectObject(hdc, hfont);
1659  unsigned int options = (ttf && !convertToText) ? ETO_GLYPH_INDEX : 0;
1660  wchar_t *convertedGlyphs = (wchar_t *)ti.chars;
1661  QGlyphLayout glyphs = ti.glyphs;
1662 
1663  bool fast = !has_kerning && !(ti.flags & QTextItem::RightToLeft);
1664  for (int i = 0; fast && i < glyphs.numGlyphs; i++) {
1665  if (glyphs.offsets[i].x != 0 || glyphs.offsets[i].y != 0 || glyphs.justifications[i].space_18d6 != 0
1666  || glyphs.attributes[i].dontPrint) {
1667  fast = false;
1668  break;
1669  }
1670  }
1671 
1672 #if !defined(Q_OS_WINCE)
1673  // Scale, rotate and translate here.
1674  XFORM win_xform;
1675  win_xform.eM11 = xform.m11();
1676  win_xform.eM12 = xform.m12();
1677  win_xform.eM21 = xform.m21();
1678  win_xform.eM22 = xform.m22();
1679  win_xform.eDx = xform.dx();
1680  win_xform.eDy = xform.dy();
1681 
1682  SetGraphicsMode(hdc, GM_ADVANCED);
1683  SetWorldTransform(hdc, &win_xform);
1684 #endif
1685 
1686  if (fast) {
1687  // fast path
1688  QVarLengthArray<wchar_t> g(glyphs.numGlyphs);
1689  for (int i = 0; i < glyphs.numGlyphs; ++i)
1690  g[i] = glyphs.glyphs[i];
1691  ExtTextOut(hdc,
1692  qRound(baseline_pos.x() + glyphs.offsets[0].x.toReal()),
1693  qRound(baseline_pos.y() + glyphs.offsets[0].y.toReal()),
1694  options, 0, convertToText ? convertedGlyphs : g.data(), glyphs.numGlyphs, 0);
1695  } else {
1697  QVarLengthArray<glyph_t> _glyphs;
1698 
1699  QTransform matrix = QTransform::fromTranslate(baseline_pos.x(), baseline_pos.y());
1700  ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags,
1701  _glyphs, positions);
1702  if (_glyphs.size() == 0) {
1703  SelectObject(hdc, old_font);
1704  return;
1705  }
1706 
1707  convertToText = convertToText && glyphs.numGlyphs == _glyphs.size();
1708  bool outputEntireItem = _glyphs.size() > 0;
1709 
1710  if (outputEntireItem) {
1711  options |= ETO_PDY;
1712  QVarLengthArray<INT> glyphDistances(_glyphs.size() * 2);
1713  QVarLengthArray<wchar_t> g(_glyphs.size());
1714  for (int i=0; i<_glyphs.size() - 1; ++i) {
1715  glyphDistances[i * 2] = qRound(positions[i + 1].x) - qRound(positions[i].x);
1716  glyphDistances[i * 2 + 1] = qRound(positions[i + 1].y) - qRound(positions[i].y);
1717  g[i] = _glyphs[i];
1718  }
1719  glyphDistances[(_glyphs.size() - 1) * 2] = 0;
1720  glyphDistances[(_glyphs.size() - 1) * 2 + 1] = 0;
1721  g[_glyphs.size() - 1] = _glyphs[_glyphs.size() - 1];
1722  ExtTextOut(hdc, qRound(positions[0].x), qRound(positions[0].y), options, 0,
1723  convertToText ? convertedGlyphs : g.data(), _glyphs.size(),
1724  glyphDistances.data());
1725  } else {
1726  int i = 0;
1727  while(i < _glyphs.size()) {
1728  wchar_t g = _glyphs[i];
1729 
1730  ExtTextOut(hdc, qRound(positions[i].x),
1731  qRound(positions[i].y), options, 0,
1732  convertToText ? convertedGlyphs + i : &g, 1, 0);
1733  ++i;
1734  }
1735  }
1736  }
1737 
1738 #if !defined(Q_OS_WINCE)
1739  win_xform.eM11 = win_xform.eM22 = 1.0;
1740  win_xform.eM12 = win_xform.eM21 = win_xform.eDx = win_xform.eDy = 0.0;
1741  SetWorldTransform(hdc, &win_xform);
1742 #endif
1743 
1744  SelectObject(hdc, old_font);
1745 }
1746 
1747 
1749 {
1750  uint paperSize = devMode->dmPaperSize;
1751  if (paperSize > 0 && mapDevmodePaperSize(paperSize) == QPrinter::Custom) {
1752  has_custom_paper_size = true;
1753  DWORD needed = 0;
1754  DWORD returned = 0;
1755  if (!EnumForms(hPrinter, 1, 0, 0, &needed, &returned)) {
1756  BYTE *forms = (BYTE *) malloc(needed);
1757  if (EnumForms(hPrinter, 1, forms, needed, &needed, &returned)) {
1758  if (paperSize <= returned) {
1759  FORM_INFO_1 *formArray = (FORM_INFO_1 *) forms;
1760  int width = formArray[paperSize - 1].Size.cx; // 1/1000 of a mm
1761  int height = formArray[paperSize - 1].Size.cy; // 1/1000 of a mm
1762  paper_size = QSizeF((width * 72 /25.4) / 1000.0, (height * 72 / 25.4) / 1000.0);
1763  } else {
1764  has_custom_paper_size = false;
1765  }
1766  }
1767  free(forms);
1768  }
1769  } else {
1770  has_custom_paper_size = false;
1771  }
1772 }
1773 
1775 
1776 #endif // QT_NO_PRINTER
ElementType type
the type of element
Definition: qpainterpath.h:81
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
QPainterPath clipPath() const
Returns the currently clip as a path.
Definition: qpainter.cpp:2690
static QString fromWCharArray(const wchar_t *, int size=-1)
Returns a copy of the string, where the encoding of string depends on the size of wchar...
Definition: qstring.cpp:1019
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
void strokePath_dev(const QPainterPath &path, const QColor &color, qreal width)
void setDashOffset(qreal offset)
Sets the dash offset for the generated outlines to offset.
double d
Definition: qnumeric_p.h:62
The QPainterPath::Element class specifies the position and type of a subpath.
Definition: qpainterpath.h:77
QFontEngine * fontEngine
bool isEmpty() const
Returns true if either there are no elements in this path, or if the only element is a MoveToElement;...
Definition: qpainterpath.h:392
QPaintEngine::DirtyFlags state() const
Returns a combination of flags identifying the set of properties that need to be updated when updatin...
Definition: qpaintengine.h:292
qreal dy() const
Returns the vertical translation factor.
Definition: qtransform.h:277
unsigned int QRgb
Definition: qrgb.h:53
QRect adjusted(int x1, int y1, int x2, int y2) const
Returns a new rectangle with dx1, dy1, dx2 and dy2 added respectively to the existing coordinates of ...
Definition: qrect.h:431
PaperSize paperSize(QPrinter::PaperSize paperSize)
Definition: qpdf.cpp:905
#define ETO_PDY
Definition: qt_windows.h:122
double qreal
Definition: qglobal.h:1193
QList< QVariant > queryResolutions() const
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...
static mach_timebase_info_data_t info
PrinterState
Definition: qprinter.h:119
static QMatrix trueMatrix(const QMatrix &m, int w, int h)
This convenience function loads the matrix m into a QTransform and calls the overloaded function with...
Definition: qpixmap.cpp:584
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
const QColor & color() const
Returns the brush color.
Definition: qbrush.h:183
QPrinter::PaperSize qtSizeName
#define WINDING
int width() const
Returns the width of the pixmap.
Definition: qpixmap.cpp:630
QSize size() const
Returns the size of the pixmap.
Definition: qpixmap.cpp:661
#define BYTE
virtual void drawPath(const QPainterPath &path)
The default implementation ignores the path and does nothing.
ushort unicode() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qchar.h:251
const QChar * chars
Q_GUI_EXPORT_INLINE int qAlpha(QRgb rgb)
Definition: qrgb.h:66
The QPainterPath class provides a container for painting operations, enabling graphical shapes to be ...
Definition: qpainterpath.h:67
QPaintEngineState * state
Definition: qpaintengine.h:239
void releaseDC(HDC) const
Empty default implementation.
static const struct @249 dmMapping[]
qreal width() const
Returns the width.
Definition: qsize.h:284
PrinterMode
This enum describes the mode the printer should work in.
Definition: qprinter.h:70
static void draw_text_item_win(const QPointF &_pos, const QTextItemInt &ti, HDC hdc, bool convertToText, const QTransform &xform, const QPointF &topLeft)
qreal m21() const
Returns the horizontal shearing factor.
Definition: qtransform.h:249
qreal dx() const
Returns the horizontal translation factor.
Definition: qmatrix.h:77
RenderFlags flags
QTransform transform() const
Returns the matrix in the current paint engine state.
Definition: qpainter.cpp:9377
void setCapStyle(Qt::PenCapStyle style)
Sets the cap style of the generated outlines to style.
void readDevmode(HGLOBAL globalDevmode)
#define ETO_GLYPH_INDEX
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
qreal height() const
Returns the height.
Definition: qsize.h:287
void closeSubpath()
Closes the current subpath by drawing a line to the beginning of the subpath, automatically starting ...
qreal left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:525
qreal m22() const
Returns the vertical scaling factor.
Definition: qtransform.h:253
QString toString() const
Returns the variant as a QString if the variant has type() String , Bool , ByteArray ...
Definition: qvariant.cpp:2270
QPrinter::PaperSource qtSourceName
QPointF topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:539
QPixmap transformed(const QMatrix &, Qt::TransformationMode mode=Qt::FastTransformation) const
This convenience function loads the matrix into a QTransform and calls the overloaded function...
Definition: qpixmap.cpp:1723
QList< QVariant > toList() const
Returns the variant as a QVariantList if the variant has type() List or StringList ; otherwise return...
Definition: qvariant.cpp:2751
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
bool toBool() const
Returns the variant as a bool if the variant has type() Bool.
Definition: qvariant.cpp:2691
void updateState(const QPaintEngineState &state)
Reimplement this function to update the state of a paint engine.
const unsigned short * logClusters
ushort red
Returns the red color component of this color.
Definition: qcolor.h:243
static QPrinter::PaperSource mapDevmodePaperSource(int s)
bool begin(QPaintDevice *dev)
Reimplement this function to initialise your paint engine when painting is to start on the paint devi...
qreal y
the y coordinate of the element&#39;s position.
Definition: qpainterpath.h:80
bool isClipEnabled() const
Returns whether clipping is enabled or not in the current paint engine state.
Definition: qpainter.cpp:9473
The QString class provides a Unicode character string.
Definition: qstring.h:83
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...
int winSourceName
#define ALTERNATE
virtual bool end()
Reimplement this function to finish painting on the current paint device.
Q_DECL_CONSTEXPR T qAbs(const T &t)
Definition: qglobal.h:1201
void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &p)
Reimplement this function to draw the pixmap in the given rect, starting at the given p...
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
#define Q_D(Class)
Definition: qglobal.h:2482
bool kerning() const
Returns true if kerning should be used when drawing text with this font.
Definition: qfont.cpp:1416
#define ANSI_VAR_FONT
virtual Type type() const =0
QVariant property(PrintEnginePropertyKey key) const
Returns the print engine&#39;s property specified by key.
The QSizeF class defines the size of a two-dimensional object using floating point precision...
Definition: qsize.h:202
void setMiterLimit(qreal length)
Sets the miter limit of the generated outlines to limit.
const QPainterPath::Element & elementAt(int i) const
Returns the element at the given index in the painter path.
Definition: qpainterpath.h:402
Q_CORE_EXPORT QTextStream & right(QTextStream &s)
QTransform inverted(bool *invertible=0) const
Returns an inverted copy of this matrix.
Definition: qtransform.cpp:364
QPrinter::PrinterState printerState() const
Returns the current state of the printer being used by the print engine.
Q_GUI_EXPORT_INLINE int qRed(QRgb rgb)
Definition: qrgb.h:57
qreal x() const
Returns the x-coordinate of this point.
Definition: qpoint.h:282
QRectF boundingRect() const
Returns the bounding rectangle of this painter path as a rectangle with floating point precision...
int toInt(bool *ok=0) const
Returns the variant as an int if the variant has type() Int , Bool , ByteArray , Char ...
Definition: qvariant.cpp:2625
void setDashPattern(Qt::PenStyle)
Sets the dash pattern for the generated outlines to style.
void updateMatrix(const QTransform &matrix)
static int mapPaperSizeDevmode(QPrinter::PaperSize s)
void lineTo(const QPointF &p)
Adds a straight line from the current position to the given endPoint.
Q_CORE_EXPORT void qDebug(const char *,...)
QPrinter::PaperSize mapDevmodePaperSize(int s)
QGlyphLayout glyphs
qreal m12() const
Returns the vertical shearing factor.
Definition: qtransform.h:241
QRect mapRect(const QRect &) const
Creates and returns a QRect object that is a copy of the given rectangle, mapped into the coordinate ...
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
QPainter * painter() const
Returns the paint engine&#39;s painter.
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QBrush brush() const
Returns the brush in the current paint engine state.
Definition: qpainter.cpp:9273
void setPageMargins(int margin_left, int margin_top, int margin_right, int margin_bottom)
bool isActive() const
Returns true if the paint engine is actively drawing; otherwise returns false.
Definition: qpaintengine.h:154
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
QBool contains(const T &t) const
Returns true if the list contains an occurrence of value; otherwise returns false.
Definition: qlist.h:880
QPainterPath createStroke(const QPainterPath &path) const
Generates a new path that is a fillable area representing the outline of the given path...
bool newPage()
Instructs the print engine to start a new page.
Qt::ClipOperation clipOperation() const
Returns the clip operation in the current paint engine state.
Definition: qpainter.cpp:9396
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
static const QCssKnownValue positions[NumKnownPositionModes - 1]
Definition: qcssparser.cpp:329
qreal height() const
Returns the height of the rectangle.
Definition: qrect.h:710
const char * name
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
void getGlyphPositions(const QGlyphLayout &glyphs, const QTransform &matrix, QTextItem::RenderFlags flags, QVarLengthArray< glyph_t > &glyphs_out, QVarLengthArray< QFixedPoint > &positions)
Q_CORE_EXPORT void qWarning(const char *,...)
QPoint map(const QPoint &p) const
Creates and returns a QPoint object that is a copy of the given point, mapped into the coordinate sys...
Internal QTextItem.
int metric(QPaintDevice::PaintDeviceMetric) const
Returns the metric for the given id.
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
static const struct @250 sources[]
void fillPath(const QPainterPath &path, const QColor &color)
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...
qreal width() const
Returns the width of the rectangle.
Definition: qrect.h:707
void composeGdiPath(const QPainterPath &path)
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:68
The QPainterPathStroker class is used to generate fillable outlines for a given painter path...
Definition: qpainterpath.h:264
QPainterPath clipPath() const
Returns the clip path in the current paint engine state.
Definition: qpainter.cpp:9457
QBrush brush() const
Returns the brush used to fill strokes generated with this pen.
Definition: qpen.cpp:797
Qt::FillRule fillRule() const
Returns the painter path&#39;s currently set fill rule.
Qt::BrushStyle style() const
Returns the brush style.
Definition: qbrush.h:182
Q_GUI_EXPORT_INLINE int qBlue(QRgb rgb)
Definition: qrgb.h:63
QRect toRect() const
Returns a QRect based on the values of this rectangle.
Definition: qrect.h:845
QSizeF toSizeF() const
Returns the variant as a QSizeF if the variant has type() SizeF ; otherwise returns an invalid QSizeF...
Definition: qvariant.cpp:2447
The QBrush class defines the fill pattern of shapes drawn by QPainter.
Definition: qbrush.h:76
static int mapPaperSourceDevmode(QPrinter::PaperSource s)
Q_CORE_EXPORT void qFatal(const char *,...)
void updateClipPath(const QPainterPath &clip, Qt::ClipOperation op)
ushort blue
Returns the blue color component of this color.
Definition: qcolor.h:245
HBITMAP toWinHBITMAP(HBitmapFormat format=NoAlpha) const
It is the caller&#39;s responsibility to free the HBITMAP data after use.
bool abort()
Instructs the print engine to abort the printing process.
unsigned short ushort
Definition: qglobal.h:995
PaperSize
This enum type specifies what paper size QPrinter should use.
Definition: qprinter.h:91
int winSizeName
bool end()
Reimplement this function to finish painting on the current paint device.
int key
void setJoinStyle(Qt::PenJoinStyle style)
Sets the join style of the generated outlines to style.
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
virtual bool begin(QPaintDevice *pdev)
Reimplement this function to initialise your paint engine when painting is to start on the paint devi...
static qreal mmToInches(double mm)
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
bool isNull() const
Returns true if both the x and y coordinates are set to +0.
Definition: qpoint.h:277
QSizeF size() const
Returns the size of the rectangle.
Definition: qrect.h:713
qreal dx() const
Returns the horizontal translation factor.
Definition: qtransform.h:273
qreal x
the x coordinate of the element&#39;s position.
Definition: qpainterpath.h:79
qreal y() const
Returns the y-coordinate of this point.
Definition: qpoint.h:287
The QPixmap class is an off-screen image representation that can be used as a paint device...
Definition: qpixmap.h:71
Q_GUI_EXPORT_INLINE int qGreen(QRgb rgb)
Definition: qrgb.h:60
return(isPopup||isToolTip)
QRegion clipRegion() const
Returns the clip region in the current paint engine state.
Definition: qpainter.cpp:9443
HDC getDC() const
Empty default implementation.
static qreal inchesToMM(double in)
qreal top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:526
int height() const
Returns the height of the pixmap.
Definition: qpixmap.cpp:645
The QPaintEngineState class provides information about the active paint engine&#39;s current state...
Definition: qpaintengine.h:289
static QTransform fromTranslate(qreal dx, qreal dy)
Creates a matrix which corresponds to a translation of dx along the x axis and dy along the y axis...
Definition: qtransform.cpp:462
QStringList split(const QString &sep, SplitBehavior behavior=KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const Q_REQUIRED_RESULT
Splits the string into substrings wherever sep occurs, and returns the list of those strings...
Definition: qstring.cpp:6526
static QTransform fromScale(qreal dx, qreal dy)
Creates a matrix which corresponds to a scaling of sx horizontally and sy vertically.
Definition: qtransform.cpp:528
int elementCount() const
Returns the number of path elements in the painter path.
Definition: qpainterpath.h:397
virtual void drawTextItem(const QPointF &p, const QTextItem &textItem)
This function draws the text item textItem at position p.
QPen pen() const
Returns the pen in the current paint engine state.
Definition: qpainter.cpp:9259
QPainterPath qt_regionToPath(const QRegion &region)
Definition: qregion.cpp:1160
void flushAndInit(bool init=true)
virtual void updateState(const QPaintEngineState &state)
Reimplement this function to update the state of a paint engine.
The QTextItem class provides all the information required to draw text in a custom paint engine...
Definition: qpaintengine.h:68
QPixmap copy(int x, int y, int width, int height) const
Returns a deep copy of the subset of the pixmap that is specified by the rectangle QRect( x...
Definition: qpixmap.h:302
void readDevnames(HGLOBAL globalDevnames)
QRegion alphaClipping() const
void strokePath(const QPainterPath &path, const QColor &color)
const QFont * f
void drawTextItem(const QPointF &p, const QTextItem &textItem)
This function draws the text item textItem at position p.
Q_CORE_EXPORT QTextStream & left(QTextStream &s)
ushort green
Returns the green color component of this color.
Definition: qcolor.h:244
static const int tileSize
Definition: qmemrotate.cpp:47
void fillPath_dev(const QPainterPath &path, const QColor &color)
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
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...
#define INT_MAX
void setProperty(PrintEnginePropertyKey key, const QVariant &value)
Sets the print engine&#39;s property specified by key to the given value.
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...
QRgb rgb() const
Returns the RGB value of the color.
Definition: qcolor.cpp:1051
Q_DECL_CONSTEXPR int qRound(qreal d)
Definition: qglobal.h:1203
#define GMEM_MOVEABLE
qreal m11() const
Returns the horizontal scaling factor.
Definition: qtransform.h:237
Handle handle() const
Returns a platform-specific region handle.
QWin32PrintEngine(QPrinter::PrinterMode mode)
int size() const
PaperSource
This enum type specifies what paper source QPrinter is to use.
Definition: qprinter.h:103
The QTransform class specifies 2D transformations of a coordinate system.
Definition: qtransform.h:65
void setWidth(qreal width)
Sets the width of the generated outline painter path to width.
const ushort * utf16() const
Returns the QString as a &#39;\0\&#39;-terminated array of unsigned shorts.
Definition: qstring.cpp:5290
PrintEnginePropertyKey
This enum is used to communicate properties between the print engine and QPrinter.
Definition: qprintengine.h:60
void qErrnoWarning(const char *msg,...)
Definition: qglobal.cpp:2954
ClipOperation
Definition: qnamespace.h:1495
void drawPath(const QPainterPath &path)
The default implementation ignores the path and does nothing.
virtual void drawTextItem(const QPointF &p, const QTextItem &textItem)
This function draws the text item textItem at position p.
Q_CORE_EXPORT QTextStream & endl(QTextStream &s)
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...