Qt 4.8
qprintengine_ps.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 #include "qplatformdefs.h"
43 
44 #include <private/qprintengine_ps_p.h>
45 #include <private/qpainter_p.h>
46 #include <private/qfontengine_p.h>
47 #include <private/qpaintengine_p.h>
48 #include <private/qpdf_p.h>
49 
50 #ifndef QT_NO_PRINTER
51 
52 #include "qprinter.h"
53 #include "qpainter.h"
54 #include "qapplication.h"
55 #include "qpixmap.h"
56 #include "qimage.h"
57 #include "qdatetime.h"
58 #include "qstring.h"
59 #include "qbytearray.h"
60 #include "qhash.h"
61 #include "qbuffer.h"
62 #include "qsettings.h"
63 #include "qmap.h"
64 #include "qbitmap.h"
65 #include "qregion.h"
66 #include "qimagewriter.h"
67 #include <private/qpainterpath_p.h>
68 #include <qdebug.h>
69 #include <private/qdrawhelper_p.h>
70 #include <private/qmutexpool_p.h>
71 
72 #ifndef Q_OS_WIN
73 #include <unistd.h>
74 #endif
75 #include <stdlib.h>
76 #include <limits.h>
77 
79 
80 static bool qt_gen_epsf = false;
81 
82 void qt_generate_epsf(bool b)
83 {
84  qt_gen_epsf = b;
85 }
86 
87 static const char *const ps_header =
88 "/BD{bind def}bind def/d2{dup dup}BD/ED{exch def}BD/D0{0 ED}BD/F{setfont}BD\n"
89 "/RL{rlineto}BD/CM{currentmatrix}BD/SM{setmatrix}BD/TR{translate}BD/SD\n"
90 "{setdash}BD/SC{aload pop setrgbcolor}BD/CR{currentfile read pop}BD/i{index}\n"
91 "BD/scs{setcolorspace}BD/DB{dict dup begin}BD/DE{end def}BD/ie{ifelse}BD/gs\n"
92 "{gsave}BD/gr{grestore}BD/w{setlinewidth}BD/d{setdash}BD/J{setlinecap}BD/j\n"
93 "{setlinejoin}BD/scn{3 array astore/BCol exch def}BD/SCN{3 array astore/PCol\n"
94 "exch def}BD/cm{6 array astore concat}BD/m{moveto}BD/l{lineto}BD/c{curveto}BD\n"
95 "/h{closepath}BD/W{clip}BD/W*{eoclip}BD/n{newpath}BD/q{gsave 10 dict begin}BD\n"
96 "/Q{end grestore}BD/re{4 2 roll m dup 0 exch RL exch 0 RL 0 exch neg RL h}BD\n"
97 "/S{gs PCol SC stroke gr n}BD/BT{gsave 10 dict begin/_m matrix CM def BCol\n"
98 "SC}BD/ET{end grestore}BD/Tf{/_fs ED findfont[_fs 0 0 _fs 0 0]makefont F}BD\n"
99 "/Tm{6 array astore concat}BD/Td{translate}BD/Tj{0 0 m show}BD/BDC{pop pop}BD\n"
100 "/EMC{}BD/BSt 0 def/WFi false def/BCol[1 1 1]def/PCol[0 0 0]def/BDArr[0.94\n"
101 "0.88 0.63 0.50 0.37 0.12 0.06]def/level3{/languagelevel where{pop\n"
102 "languagelevel 3 ge}{false}ie}BD/QCIgray D0/QCIcolor D0/QCIindex D0/QCI{\n"
103 "/colorimage where{pop false 3 colorimage}{exec/QCIcolor ED/QCIgray QCIcolor\n"
104 "length 3 idiv string def 0 1 QCIcolor length 3 idiv 1 sub{/QCIindex ED/_x\n"
105 "QCIindex 3 mul def QCIgray QCIindex QCIcolor _x get 0.30 mul QCIcolor _x 1\n"
106 "add get 0.59 mul QCIcolor _x 2 add get 0.11 mul add add cvi put}for QCIgray\n"
107 "image}ie}BD/di{gs TR 1 i 1 eq{pop pop false 3 1 roll BCol SC imagemask}{dup\n"
108 "false ne{level3}{false}ie{/_ma ED 8 eq{/_dc[0 1]def/DeviceGray}{/_dc[0 1 0 1\n"
109 "0 1]def/DeviceRGB}ie scs/_im ED/_mt ED/_h ED/_w ED <</ImageType 3/DataDict\n"
110 "<</ImageType 1/Width _w/Height _h/ImageMatrix _mt/DataSource _im\n"
111 "/BitsPerComponent 8/Decode _dc >>/MaskDict <</ImageType 1/Width _w/Height _h\n"
112 "/ImageMatrix _mt/DataSource _ma/BitsPerComponent 1/Decode[0 1]>>\n"
113 "/InterleaveType 3 >> image}{pop 8 4 1 roll 8 eq{image}{QCI}ie}ie}ie gr}BD/BF\n"
114 "{gs BSt 1 eq{BCol SC WFi{fill}{eofill}ie}if BSt 2 ge BSt 8 le and{BDArr BSt\n"
115 "2 sub get/_sc ED BCol{1. exch sub _sc mul 1. exch sub}forall 3 array astore\n"
116 "SC WFi{fill}{eofill}ie}if BSt 9 ge BSt 14 le and{WFi{W}{W*}ie pathbbox 3 i 3\n"
117 "i TR 4 2 roll 3 2 roll exch sub/_h ED sub/_w ED BCol SC 0.3 w n BSt 9 eq BSt\n"
118 "11 eq or{0 4 _h{dup 0 exch m _w exch l}for}if BSt 10 eq BSt 11 eq or{0 4 _w{\n"
119 "dup 0 m _h l}for}if BSt 12 eq BSt 14 eq or{_w _h gt{0 6 _w _h add{dup 0 m _h\n"
120 "sub _h l}for}{0 6 _w _h add{dup 0 exch m _w sub _w exch l}for}ie}if BSt 13\n"
121 "eq BSt 14 eq or{_w _h gt{0 6 _w _h add{dup _h m _h sub 0 l}for}{0 6 _w _h\n"
122 "add{dup _w exch m _w sub 0 exch l}for}ie}if stroke}if BSt 15 eq{}if BSt 24\n"
123 "eq{}if gr}BD/f{/WFi true def BF n}BD/f*{/WFi false def BF n}BD/B{/WFi true\n"
124 "def BF S n}BD/B*{/WFi false def BF S n}BD/QI{/C save def pageinit q n}BD/QP{\n"
125 "Q C restore showpage}BD/SPD{/setpagedevice where{<< 3 1 roll >>\n"
126 "setpagedevice}{pop pop}ie}BD/T1AddMapping{10 dict begin/glyphs ED/fnt ED\n"
127 "/current fnt/NumGlyphs get def/CMap fnt/CMap get def 0 1 glyphs length 1 sub\n"
128 "{glyphs exch get/gn ED current dup 256 mod/min ED 256 idiv/maj ED CMap dup\n"
129 "maj get dup null eq{pop 256 array 0 1 255{1 i exch/.notdef put}for}if dup\n"
130 "min gn put maj exch put/current current 1 add def}for fnt/CMap CMap put fnt\n"
131 "/NumGlyphs current put end}def/T1AddGlyphs{10 dict begin/glyphs ED/fnt ED\n"
132 "/current fnt/NumGlyphs get def/CMap fnt/CMap get def/CharStrings fnt\n"
133 "/CharStrings get def 0 1 glyphs length 2 idiv 1 sub{2 mul dup glyphs exch\n"
134 "get/gn ED 1 add glyphs exch get/cs ED current dup 256 mod/min ED 256 idiv\n"
135 "/maj ED CMap dup maj get dup null eq{pop 256 array 0 1 255{1 i exch/.notdef\n"
136 "put}for}if dup min gn put maj exch put CharStrings gn cs put/current current\n"
137 "1 add def}for fnt/CharStrings CharStrings put fnt/CMap CMap put fnt\n"
138 "/NumGlyphs current put end}def/StringAdd{1 i length 1 i length add string 3\n"
139 "1 roll 2 i 0 3 i putinterval 2 i 2 i length 2 i putinterval pop pop}def\n"
140 "/T1Setup{10 dict begin dup/FontName ED (-Base) StringAdd cvx cvn/Font ED\n"
141 "/MaxPage Font/NumGlyphs get 1 sub 256 idiv def/FDepVector MaxPage 1 add\n"
142 "array def/Encoding MaxPage 1 add array def 0 1 MaxPage{dup Encoding exch dup\n"
143 "put dup/Page ED FontName (-) StringAdd exch 20 string cvs StringAdd cvn Font\n"
144 "0 dict copy d2/CMap get Page get/Encoding exch put definefont FDepVector\n"
145 "exch Page exch put}for FontName cvn <</FontType 0/FMapType 2/FontMatrix[1 0\n"
146 "0 1 0 0]/Encoding Encoding/FDepVector FDepVector >> definefont pop end}def\n";
147 
148 
149 
150 // ------------------------------End of static data ----------------------------------
151 
152 // make sure DSC comments are not longer than 255 chars per line.
153 static QByteArray wrapDSC(const QByteArray &str)
154 {
155  QByteArray dsc = str.simplified();
156  const int wrapAt = 254;
157  QByteArray wrapped;
158  if (dsc.length() < wrapAt)
159  wrapped = dsc;
160  else {
161  wrapped = dsc.left(wrapAt);
162  QByteArray tmp = dsc.mid(wrapAt);
163  while (tmp.length() > wrapAt-3) {
164  wrapped += "\n%%+" + tmp.left(wrapAt-3);
165  tmp = tmp.mid(wrapAt-3);
166  }
167  wrapped += "\n%%+" + tmp;
168  }
169  return wrapped + '\n';
170 }
171 
172 // ----------------------------- Internal class declarations -----------------------------
173 
176  printerState(QPrinter::Idle), hugeDocument(false), headerDone(false)
177 {
178  useAlphaEngine = true;
179  postscript = true;
180 
181  firstPage = true;
182 
183 #ifndef QT_NO_SETTINGS
184  QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
185  settings.beginGroup(QLatin1String("Qt"));
186  embedFonts = settings.value(QLatin1String("embedFonts"), true).toBool();
187 #else
188  embedFonts = true;
189 #endif
190 }
191 
193 {
194 }
195 
197 #include <qdebug.h>
199 
200 static void ps_r7(QPdf::ByteStream& stream, const char * s, int l)
201 {
202  int i = 0;
203  uchar line[84];
204  int col = 0;
205 
206  while(i < l) {
207  line[col++] = s[i++];
208  if (i < l - 1 && col >= 76) {
209  line[col++] = '\n';
210  line[col++] = '\0';
211  stream << (const char *)line;
212  col = 0;
213  }
214  }
215  if (col > 0) {
216  while((col&3) != 0)
217  line[col++] = '%'; // use a comment as padding
218  line[col++] = '\n';
219  line[col++] = '\0';
220  stream << (const char *)line;
221  }
222 }
223 
225 {
226  if (!input.length())
227  return input;
228 
229  const char *data = input.constData();
230 
231  QByteArray out;
232  int start = 0;
233  char last = *data;
234 
235  enum State {
236  Undef,
237  Equal,
238  Diff
239  };
240  State state = Undef;
241 
242  int i = 1;
243  int written = 0;
244  while (1) {
245  bool flush = (i == input.size());
246  if (!flush) {
247  switch(state) {
248  case Undef:
249  state = (last == data[i]) ? Equal : Diff;
250  break;
251  case Equal:
252  if (data[i] != last)
253  flush = true;
254  break;
255  case Diff:
256  if (data[i] == last) {
257  --i;
258  flush = true;
259  }
260  }
261  }
262  if (flush || i - start == 128) {
263  int size = i - start;
264  if (state == Equal) {
265  out.append((char)(uchar)(257-size));
266  out.append(last);
267  written += size;
268  } else {
269  out.append((char)(uchar)size-1);
270  while (start < i)
271  out.append(data[start++]);
272  written += size;
273  }
274  state = Undef;
275  start = i;
276  if (i == input.size())
277  break;
278  }
279  last = data[i];
280  ++i;
281  };
282  out.append((char)(uchar)128);
283  return out;
284 }
285 
286 enum format {
290 };
291 static const char *const filters[3] = {
292  " ",
293  "/RunLengthDecode filter ",
294  "/DCTDecode filter "
295 };
296 
297 static QByteArray compressHelper(const QImage &image, bool gray, int *format)
298 {
299  // we can't use premultiplied here
300  QByteArray pixelData;
301  int depth = image.depth();
302 
304 
305  if (depth != 1 && !gray && QImageWriter::supportedImageFormats().contains("jpeg")) {
306  QBuffer buffer(&pixelData);
307  QImageWriter writer(&buffer, "jpeg");
308  writer.setQuality(94);
309  writer.write(image);
310  *format = DCT;
311  } else {
312  int width = image.width();
313  int height = image.height();
314  int size = width*height;
315 
316  if (depth == 1)
317  size = (width+7)/8*height;
318  else if (!gray)
319  size = size*3;
320 
321  pixelData.resize(size);
322  uchar *pixel = (uchar *)pixelData.data();
323  int i = 0;
324  if (depth == 1) {
325  QImage::Format format = image.format();
326  memset(pixel, 0xff, size);
327  for(int y=0; y < height; y++) {
328  const uchar * s = image.scanLine(y);
329  for(int x=0; x < width; x++) {
330  // need to copy bit for bit...
331  bool b = (format == QImage::Format_MonoLSB) ?
332  (*(s + (x >> 3)) >> (x & 7)) & 1 :
333  (*(s + (x >> 3)) << (x & 7)) & 0x80 ;
334  if (b)
335  pixel[i >> 3] ^= (0x80 >> (i & 7));
336  i++;
337  }
338  // we need to align to 8 bit here
339  i = (i+7) & 0xffffff8;
340  }
341  } else if (depth == 8) {
342  for(int y=0; y < height; y++) {
343  const uchar * s = image.scanLine(y);
344  for(int x=0; x < width; x++) {
345  QRgb rgb = image.color(s[x]);
346  if (gray) {
347  pixel[i] = (unsigned char) qGray(rgb);
348  i++;
349  } else {
350  pixel[i] = (unsigned char) qRed(rgb);
351  pixel[i+1] = (unsigned char) qGreen(rgb);
352  pixel[i+2] = (unsigned char) qBlue(rgb);
353  i += 3;
354  }
355  }
356  }
357  } else {
358  for(int y=0; y < height; y++) {
359  QRgb * s = (QRgb*)(image.scanLine(y));
360  for(int x=0; x < width; x++) {
361  QRgb rgb = (*s++);
362  if (gray) {
363  pixel[i] = (unsigned char) qGray(rgb);
364  i++;
365  } else {
366  pixel[i] = (unsigned char) qRed(rgb);
367  pixel[i+1] = (unsigned char) qGreen(rgb);
368  pixel[i+2] = (unsigned char) qBlue(rgb);
369  i += 3;
370  }
371  }
372  }
373  }
374  *format = Raw;
375  if (depth == 1) {
376  pixelData = runlengthEncode(pixelData);
377  *format = Runlength;
378  }
379  }
380  QByteArray outarr = QPdf::ascii85Encode(pixelData);
381  return outarr;
382 }
383 
385  const QImage &mask, bool gray, qreal scaleX, qreal scaleY)
386 {
387  Q_UNUSED(h);
388  Q_UNUSED(w);
389  int width = img.width();
390  int height = img.height();
391 
392  QByteArray out;
393  int size = 0;
394  const char *bits;
395 
396  if (!mask.isNull()) {
397  int format;
398  out = compressHelper(mask, true, &format);
399  size = (width+7)/8*height;
400  *currentPage << "/mask currentfile/ASCII85Decode filter"
401  << filters[format]
402  << size << " string readstring\n";
403  ps_r7(*currentPage, out, out.size());
404  *currentPage << " pop def\n";
405  }
406  if (img.depth() == 1) {
407  size = (width+7)/8*height;
408  bits = "1 ";
409  } else if (gray) {
410  size = width*height;
411  bits = "8 ";
412  } else {
413  size = width*height*3;
414  bits = "24 ";
415  }
416 
417  int format;
418  out = compressHelper(img, gray, &format);
419  *currentPage << "/sl currentfile/ASCII85Decode filter"
420  << filters[format]
421  << size << " string readstring\n";
422  ps_r7(*currentPage, out, out.size());
423  *currentPage << " pop def\n";
424  *currentPage << width << ' ' << height << '[' << scaleX << " 0 0 " << scaleY << " 0 0]sl "
425  << bits << (!mask.isNull() ? "mask " : "false ")
426  << x << ' ' << y << " di\n";
427 }
428 
429 
431  const QImage &image, const QImage &msk)
432 {
433  if (!w || !h || image.isNull()) return;
434 
435  QImage img(image);
436  QImage mask(msk);
437 
440 
441  if (!msk.isNull() && msk.format() == QImage::Format_ARGB32_Premultiplied)
443 
444  int width = img.width();
445  int height = img.height();
446  qreal scaleX = width/w;
447  qreal scaleY = height/h;
448 
449  bool gray = (colorMode == QPrinter::GrayScale) || img.allGray();
450  int splitSize = 21830 * (gray ? 3 : 1);
451  if (width * height > splitSize) { // 65535/3, tolerance for broken printers
452  int images, subheight;
453  images = (width * height + splitSize - 1) / splitSize;
454  subheight = (height + images-1) / images;
455  while (subheight * width > splitSize) {
456  images++;
457  subheight = (height + images-1) / images;
458  }
459  int suby = 0;
460  const QImage constImg(img);
461  const QImage constMask(mask);
462  while(suby < height) {
463  qreal subImageHeight = qMin(subheight, height-suby);
464  const QImage subImage(constImg.scanLine(suby), width, subImageHeight,
465  constImg.bytesPerLine(), constImg.format());
466  const QImage subMask = mask.isNull() ? mask : QImage(constMask.scanLine(suby), width, subImageHeight,
467  constMask.bytesPerLine(), constMask.format());
468  drawImageHelper(x, y + suby/scaleY, w, subImageHeight/scaleY,
469  subImage, subMask, gray, scaleX, scaleY);
470  suby += subheight;
471  }
472  } else {
473  drawImageHelper(x, y, width, height, img, mask, gray, scaleX, scaleY);
474  }
475 }
476 
478 {
479  QPSPrintEngine *q = static_cast<QPSPrintEngine *>(q_ptr);
480  QPrinter *printer = static_cast<QPrinter*>(pdev);
481 
482  if (creator.isEmpty())
484 
485  QByteArray header;
486  QPdf::ByteStream s(&header);
487 
488  qreal scale = 72. / ((qreal) q->metric(QPaintDevice::PdmDpiY));
489  QRect pageRect = this->pageRect();
490  QRect paperRect = this->paperRect();
491  int mtop = pageRect.top() - paperRect.top();
492  int mleft = pageRect.left() - paperRect.left();
493  int mbottom = paperRect.bottom() - pageRect.bottom();
494  int mright = paperRect.right() - pageRect.right();
495  int width = pageRect.width();
496  int height = pageRect.height();
497  if (finished && pageCount == 1 && copies == 1 &&
499  {
500  // According to the EPSF 3.0 spec it is required that the PS
501  // version is PS-Adobe-3.0
502  s << "%!PS-Adobe-3.0";
503  if (!boundingBox.isValid())
504  boundingBox.setRect(0, 0, width, height);
506  if (!fullPage)
507  boundingBox.translate(-mleft, -mtop);
508  s << " EPSF-3.0\n%%BoundingBox: "
509  << int((printer->height() - boundingBox.bottom())*scale) // llx
510  << int((printer->width() - boundingBox.right())*scale - 1) // lly
511  << int((printer->height() - boundingBox.top())*scale + 1) // urx
512  << int((printer->width() - boundingBox.left())*scale); // ury
513  } else {
514  if (!fullPage)
515  boundingBox.translate(mleft, -mtop);
516  s << " EPSF-3.0\n%%BoundingBox: "
517  << int((boundingBox.left())*scale)
518  << int((printer->height() - boundingBox.bottom())*scale - 1)
519  << int((boundingBox.right())*scale + 1)
520  << int((printer->height() - boundingBox.top())*scale);
521  }
522  } else {
523  s << "%!PS-Adobe-1.0";
524  int w = width + (fullPage ? 0 : mleft + mright);
525  int h = height + (fullPage ? 0 : mtop + mbottom);
526  w = (int)(w*scale);
527  h = (int)(h*scale);
528  // set a bounding box according to the DSC
530  s << "\n%%BoundingBox: 0 0 " << h << w;
531  else
532  s << "\n%%BoundingBox: 0 0 " << w << h;
533  }
534  s << '\n' << wrapDSC("%%Creator: " + creator.toUtf8());
535  if (!title.isEmpty())
536  s << wrapDSC("%%Title: " + title.toUtf8());
537 #ifndef QT_NO_DATESTRING
538  s << "%%CreationDate: " << QDateTime::currentDateTime().toString().toUtf8();
539 #endif
540  s << "\n%%Orientation: ";
542  s << "Landscape";
543  else
544  s << "Portrait";
545 
546  s << "\n%%Pages: (atend)"
547  "\n%%DocumentFonts: (atend)"
548  "\n%%EndComments\n"
549 
550  "%%BeginProlog\n"
551  "% Prolog copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).\n"
552  "% You may copy this prolog in any way that is directly related to this document.\n"
553  "% For other use of this prolog, see your licensing agreement for Qt.\n"
554  << ps_header << '\n';
555 
556 
557  s << "/pageinit {\n";
558  if (!fullPage) {
560  s << mleft*scale << mbottom*scale << "translate\n";
561  else
562  s << mtop*scale << mleft*scale << "translate\n";
563  }
565  s << "% " << printer->widthMM() << '*' << printer->heightMM()
566  << "mm (portrait)\n0 " << height*scale
567  << "translate " << scale << '-' << scale << "scale } def\n";
568  } else {
569  s << "% " << printer->heightMM() << '*' << printer->widthMM()
570  << " mm (landscape)\n 90 rotate " << scale << '-' << scale << "scale } def\n";
571  }
572  s << "%%EndProlog\n";
573 
574  outDevice->write(header);
575  headerDone = true;
576 }
577 
578 
580 {
581  if (!hugeDocument) {
583  it != fonts.constEnd(); ++it)
584  outDevice->write((*it)->toType1());
585  }
586 
587  QIODevice *content = buffer.stream();
588  // Write the page contents in chunks.
589  while (!content->atEnd()) {
590  QByteArray buf = content->read(currentPage->chunkSize());
591  if (!buf.isEmpty())
592  outDevice->write(buf);
593  }
594  content = currentPage->stream();
595  // Write the page contents in chunks.
596  while (!content->atEnd()) {
597  QByteArray buf = content->read(currentPage->chunkSize());
598  if (!buf.isEmpty())
599  outDevice->write(buf);
600  }
602 
603  buffer.clear();
604  currentPage->clear();
605  trailer = QByteArray();
606  hugeDocument = true;
607 }
608 
609 
610 #ifdef Q_WS_QWS
611 static const int max_in_memory_size = 2000000;
612 #else
613 static const int max_in_memory_size = 32000000;
614 #endif
615 
617 {
618  if (!last && currentPage->stream()->size() == 0)
619  return;
620 
622  buffer << "%%Page: "
623  << pageCount << pageCount << "\n"
624  "%%BeginPageSetup\n"
625  "QI\n";
626  if (hugeDocument) {
628  it != fonts.constEnd(); ++it) {
629  if (currentPage->fonts.contains((*it)->object_id)) {
630  if ((*it)->downloaded_glyphs == 0) {
631  buffer << (*it)->toType1();
632  (*it)->downloaded_glyphs = 0;
633  } else {
634  buffer << (*it)->type1AddedGlyphs();
635  }
636  }
637  }
638  }
639  for (int i = 0; i < currentPage->fonts.size(); ++i)
640  buffer << "(F" << QByteArray::number(currentPage->fonts.at(i)) << ") T1Setup\n";
641 
642  buffer << "%%EndPageSetup\nq\n";
643  e << "\nQ QP\n";
644  if (last || hugeDocument
646 // qDebug("emiting header at page %d", pageCount);
647  if (!headerDone)
648  emitHeader(last);
649  emitPages();
650  } else {
651  buffer << *currentPage << e;
652  currentPage->clear();
653  trailer.clear();
654  }
655  pageCount++;
656 }
657 
658 // ================ PSPrinter class ========================
659 
662  PrimitiveTransform
663  | PatternTransform
664  | PixmapTransform
665  | PainterPaths
666  | PatternBrush
667  )
668 {
669 }
670 
671 static void ignoreSigPipe(bool b)
672 {
673 #ifndef QT_NO_LPR
674  static struct sigaction *users_sigpipe_handler = 0;
675  static int lockCount = 0;
676 
677 #ifndef QT_NO_THREAD
678  QMutexLocker locker(QMutexPool::globalInstanceGet(&users_sigpipe_handler));
679 #endif
680 
681  if (b) {
682  if (lockCount++ > 0)
683  return;
684 
685  if (users_sigpipe_handler != 0)
686  return; // already ignoring sigpipe
687 
688  users_sigpipe_handler = new struct sigaction;
689  struct sigaction tmp_sigpipe_handler;
690  tmp_sigpipe_handler.sa_handler = SIG_IGN;
691  sigemptyset(&tmp_sigpipe_handler.sa_mask);
692  tmp_sigpipe_handler.sa_flags = 0;
693 
694  if (sigaction(SIGPIPE, &tmp_sigpipe_handler, users_sigpipe_handler) == -1) {
695  delete users_sigpipe_handler;
696  users_sigpipe_handler = 0;
697  }
698  }
699  else {
700  if (--lockCount > 0)
701  return;
702 
703  if (users_sigpipe_handler == 0)
704  return; // not ignoring sigpipe
705 
706  if (sigaction(SIGPIPE, users_sigpipe_handler, 0) == -1)
707  qWarning("QPSPrintEngine: Could not restore SIGPIPE handler");
708 
709  delete users_sigpipe_handler;
710  users_sigpipe_handler = 0;
711  }
712 #else
713  Q_UNUSED(b);
714 #endif
715 }
717 {
719  if (d->fd >= 0)
720 #if defined(Q_OS_WIN) && defined(_MSC_VER) && _MSC_VER >= 1400
721  ::_close(d->fd);
722 #else
723  ::close(d->fd);
724 #endif
725 }
726 
728 {
730 
731  if (d->fd >= 0)
732  return true;
733 
734  if (d->useAlphaEngine) {
736  if (!continueCall())
737  return true;
738  }
739 
740  if(!QPdfBaseEngine::begin(pdev)) {
741  d->printerState = QPrinter::Error;
742  return false;
743  }
744 
745  d->pageCount = 1; // initialize state
746 
747  d->pen = QPen(Qt::black);
748  d->brush = Qt::NoBrush;
749  d->hasPen = true;
750  d->hasBrush = false;
751  d->clipEnabled = false;
752  d->allClipped = false;
753  d->boundingBox = QRect();
754  d->fontsUsed = "";
755  d->hugeDocument = false;
756  d->simplePen = false;
757 
758  setActive(true);
759  d->printerState = QPrinter::Active;
760 
761  newPage();
762 
763  return true;
764 }
765 
767 {
769 
770  if (d->useAlphaEngine) {
772  if (!continueCall())
773  return true;
774  }
775 
776  // we're writing to lp/lpr through a pipe, we don't want to crash with SIGPIPE
777  // if lp/lpr dies
778  ignoreSigPipe(true);
779  d->flushPage(true);
780  QByteArray trailer;
781  QPdf::ByteStream s(&trailer);
782  s << "%%Trailer\n"
783  "%%Pages: " << d->pageCount - 1 << '\n' <<
784  wrapDSC("%%DocumentFonts: " + d->fontsUsed);
785  s << "%%EOF\n";
786  d->outDevice->write(trailer);
787 
789  ignoreSigPipe(false);
790 
791  d->firstPage = true;
792  d->headerDone = false;
793 
794  setActive(false);
795  d->printerState = QPrinter::Idle;
796  d->pdev = 0;
797 
798  return true;
799 }
800 
802 {
804 #if 0
805  bool specifyColor;
806  int gStateObject = 0;
807  int patternObject = d->addBrushPattern(brush, d->stroker.matrix, brushOrigin, &specifyColor, &gStateObject);
808 
809  *d->currentPage << (patternObject ? "/PCSp cs " : "/CSp cs ");
810  if (specifyColor) {
811  QColor rgba = brush.color();
812  *d->currentPage << rgba.redF()
813  << rgba.greenF()
814  << rgba.blueF();
815  }
816  if (patternObject)
817  *d->currentPage << "/Pat" << patternObject;
818  *d->currentPage << "scn\n";
819 #endif
820  QColor rgba = d->brush.color();
821  if (d->colorMode == QPrinter::GrayScale) {
822  qreal gray = qGray(rgba.rgba())/255.;
823  *d->currentPage << gray << gray << gray;
824  } else {
825  *d->currentPage << rgba.redF()
826  << rgba.greenF()
827  << rgba.blueF();
828  }
829  *d->currentPage << "scn\n"
830  << "/BSt " << d->brush.style() << "def\n";
831 }
832 
833 void QPSPrintEngine::drawImageInternal(const QRectF &r, QImage image, bool bitmap)
834 {
836  if (d->clipEnabled && d->allClipped)
837  return;
838  if (bitmap && image.depth() != 1)
839  bitmap = false;
840  QImage mask;
841  // the below is not necessary since it's handled by the alpha
842  // engine
843  if (!d->useAlphaEngine && !bitmap) {
844  if (image.format() == QImage::Format_Mono || image.format() == QImage::Format_MonoLSB)
846  if (image.hasAlphaChannel()) {
847  // get better alpha dithering
848  int xscale = image.width();
849  xscale *= xscale <= 800 ? 4 : (xscale <= 1600 ? 2 : 1);
850  int yscale = image.height();
851  yscale *= yscale <= 800 ? 4 : (yscale <= 1600 ? 2 : 1);
852  image = image.scaled(xscale, yscale);
854  }
855  }
856  *d->currentPage << "q\n";
857  if(!d->simplePen)
858  *d->currentPage << QPdf::generateMatrix(d->stroker.matrix);
859  QBrush b = d->brush;
860  if (image.depth() == 1) {
861  // set current pen as brush
862  d->brush = d->pen.brush();
863  setBrush();
864  }
865  d->drawImage(r.x(), r.y(), r.width(), r.height(), image, mask);
866  *d->currentPage << "Q\n";
867  d->brush = b;
868 }
869 
870 
871 void QPSPrintEngine::drawImage(const QRectF &r, const QImage &img, const QRectF &sr,
872  Qt::ImageConversionFlags)
873 {
875 
876  if (d->useAlphaEngine) {
877  QAlphaPaintEngine::drawImage(r, img, sr);
878  if (!continueCall())
879  return;
880  }
881  QImage image = img.copy(sr.toRect());
882  drawImageInternal(r, image, false);
883 }
884 
885 void QPSPrintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
886 {
888 
889  if (d->useAlphaEngine) {
891  if (!continueCall())
892  return;
893  }
894 
895  QImage img = pm.copy(sr.toRect()).toImage();
896  drawImageInternal(r, img, true);
897 }
898 
899 void QPSPrintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &p)
900 {
902 
903  if (d->useAlphaEngine) {
905  if (!continueCall())
906  return;
907  }
908 
909  if (d->clipEnabled && d->allClipped)
910  return;
911  // ### Optimize implementation!
912  qreal yPos = r.y();
913  qreal yOff = p.y();
914  while(yPos < r.y() + r.height()) {
915  qreal drawH = pixmap.height() - yOff; // Cropping first row
916  if (yPos + drawH > r.y() + r.height()) // Cropping last row
917  drawH = r.y() + r.height() - yPos;
918  qreal xPos = r.x();
919  qreal xOff = p.x();
920  while(xPos < r.x() + r.width()) {
921  qreal drawW = pixmap.width() - xOff; // Cropping first column
922  if (xPos + drawW > r.x() + r.width()) // Cropping last column
923  drawW = r.x() + r.width() - xPos;
924  // ########
925  painter()->drawPixmap(QPointF(xPos, yPos).toPoint(), pixmap,
926  QRectF(xOff, yOff, drawW, drawH).toRect());
927  xPos += drawW;
928  xOff = 0;
929  }
930  yPos += drawH;
931  yOff = 0;
932  }
933 
934 }
935 
937 {
939 
940  if (!d->firstPage && d->useAlphaEngine)
941  flushAndInit();
942 
943  // we're writing to lp/lpr through a pipe, we don't want to crash with SIGPIPE
944  // if lp/lpr dies
945  ignoreSigPipe(true);
946  if (!d->firstPage)
947  d->flushPage();
948  d->firstPage = false;
949  ignoreSigPipe(false);
950 
951  delete d->currentPage;
952  d->currentPage = new QPdfPage;
953  d->stroker.stream = d->currentPage;
954 
955  return QPdfBaseEngine::newPage();
956 }
957 
959 {
960  // ### abort!?!
961  return false;
962 }
963 
965 {
966  Q_D(const QPSPrintEngine);
967  return d->printerState;
968 }
969 
971 
972 #endif // QT_NO_PRINTER
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
double d
Definition: qnumeric_p.h:62
Format
The following image formats are available in Qt.
Definition: qimage.h:91
qreal y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:667
virtual qint64 size() const
For open random-access devices, this function returns the size of the device.
Definition: qiodevice.cpp:642
unsigned int QRgb
Definition: qrgb.h:53
QImage copy(const QRect &rect=QRect()) const
Returns a sub-area of the image as a new image.
Definition: qimage.cpp:1410
The QHash::const_iterator class provides an STL-style const iterator for QHash and QMultiHash...
Definition: qhash.h:395
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Returns the value for setting key.
Definition: qsettings.cpp:3460
double qreal
Definition: qglobal.h:1193
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...
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
PrinterState
Definition: qprinter.h:119
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
static QByteArray compressHelper(const QImage &image, bool gray, int *format)
static int chunkSize()
Definition: qpdf_p.h:102
int width() const
Returns the width of the pixmap.
Definition: qpixmap.cpp:630
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
QPSPrintEngine(QPrinter::PrinterMode m)
qreal greenF() const
Returns the green color component of this color.
Definition: qcolor.cpp:1241
QByteArray generateMatrix(const QTransform &matrix)
Definition: qpdf.cpp:334
#define it(className, varName)
QPrinter::Orientation orientation
Definition: qpdf_p.h:276
QByteArray & append(char c)
Appends the character ch to this byte array.
The QSettings class provides persistent platform-independent application settings.
Definition: qsettings.h:73
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...
QByteArray toUtf8() const Q_REQUIRED_RESULT
Returns a UTF-8 representation of the string as a QByteArray.
Definition: qstring.cpp:4074
virtual QPrinter::PrinterState printerState() const
Returns the current state of the printer being used by the print engine.
PrinterMode
This enum describes the mode the printer should work in.
Definition: qprinter.h:70
bool isNull() const
Returns true if it is a null image, otherwise returns false.
Definition: qimage.cpp:1542
QPSPrintEnginePrivate(QPrinter::PrinterMode m)
int height() const
Definition: qpaintdevice.h:92
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
virtual bool end()
Reimplement this function to finish painting on the current paint device.
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
static QByteArray wrapDSC(const QByteArray &str)
static bool qt_gen_epsf
void beginGroup(const QString &prefix)
Appends prefix to the current group.
Definition: qsettings.cpp:3073
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
void setQuality(int quality)
This is an image format specific function that sets the quality level of the image to quality...
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
QPaintDevice * pdev
Definition: qpdf_p.h:256
#define QT_END_INCLUDE_NAMESPACE
This macro is equivalent to QT_BEGIN_NAMESPACE.
Definition: qglobal.h:92
bool hasAlphaChannel() const
Returns true if the image has a format that respects the alpha channel, otherwise returns false...
Definition: qimage.cpp:6495
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
int bytesPerLine() const
Returns the number of bytes per image scanline.
Definition: qimage.cpp:1812
static void ignoreSigPipe(bool b)
The QBuffer class provides a QIODevice interface for a QByteArray.
Definition: qbuffer.h:57
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
virtual bool end()
Reimplement this function to finish painting on the current paint device.
QVector< uint > fonts
Definition: qpdf_p.h:170
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
void emitHeader(bool finished)
#define Q_D(Class)
Definition: qglobal.h:2482
The QPen class defines how a QPainter should draw lines and outlines of shapes.
Definition: qpen.h:64
virtual bool atEnd() const
Returns true if the current read and write position is at the end of the device (i.e.
Definition: qiodevice.cpp:711
QString toString(Qt::DateFormat f=Qt::TextDate) const
Returns the datetime as a string in the format given.
Definition: qdatetime.cpp:2628
Format format() const
Returns the format of the image.
Definition: qimage.cpp:2305
virtual void drawImage(const QRectF &r, const QImage &image, const QRectF &sr)
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
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read...
Definition: qiodevice.cpp:791
QByteArray simplified() const
Returns a byte array that has whitespace removed from the start and the end, and which has each seque...
bool newPage()
Instructs the print engine to start a new page.
Definition: qpdf.cpp:1340
unsigned char uchar
Definition: qglobal.h:994
QPainter * painter() const
Returns the paint engine&#39;s painter.
bool begin(QPaintDevice *pdev)
Reimplement this function to initialise your paint engine when painting is to start on the paint devi...
Definition: qpdf.cpp:1617
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
int width() const
Definition: qpaintdevice.h:91
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
static FILE * stream
bool end()
Reimplement this function to finish painting on the current paint device.
Definition: qpdf.cpp:1632
QRect pageRect() const
Definition: qpdf.cpp:2057
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
The QImageWriter class provides a format independent interface for writing images to files or other d...
Definition: qimagewriter.h:59
void setActive(bool newState)
Sets the active state of the paint engine to state.
Definition: qpaintengine.h:155
qreal height() const
Returns the height of the rectangle.
Definition: qrect.h:710
The QPrinter class is a paint device that paints on a printer.
Definition: qprinter.h:66
virtual bool begin(QPaintDevice *pdev)
Reimplement this function to initialise your paint engine when painting is to start on the paint devi...
static const char *const ps_header
Q_CORE_EXPORT void qWarning(const char *,...)
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
int metric(QPaintDevice::PaintDeviceMetric metricType) const
Returns the metric for the given id.
Definition: qpdf.cpp:1351
static const char * data(const QByteArray &arr)
#define QT_VERSION_STR
This macro expands to a string that specifies Qt&#39;s version number (for example, "4.
Definition: qglobal.h:47
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
QImage createAlphaMask(Qt::ImageConversionFlags flags=Qt::AutoColor) const
Builds and returns a 1-bpp mask from the alpha buffer in this image.
Definition: qimage.cpp:4720
qreal width() const
Returns the width of the rectangle.
Definition: qrect.h:707
int depth() const
Returns the depth of the image.
Definition: qimage.cpp:1620
QByteArray left(int len) const
Returns a byte array that contains the leftmost len bytes of this byte array.
The State element defines configurations of objects and properties.
QIODevice * stream()
Definition: qpdf.cpp:225
QByteArray mid(int index, int len=-1) const
Returns a byte array containing len bytes from this byte array, starting at position pos...
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
QHash< QFontEngine::FaceId, QFontSubset * > fonts
Definition: qpdf_p.h:254
QString outputFileName
Definition: qpdf_p.h:263
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
static void ps_r7(QPdf::ByteStream &stream, const char *s, int l)
virtual void drawImage(const QRectF &r, const QImage &img, const QRectF &sr, Qt::ImageConversionFlags)
Reimplement this function to draw the part of the image specified by the sr rectangle in the given re...
QPrinter::ColorMode colorMode
Definition: qpdf_p.h:278
#define rgb(r, g, b)
Definition: qcolor_p.cpp:130
int length() const
Same as size().
Definition: qbytearray.h:356
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
The QBrush class defines the fill pattern of shapes drawn by QPainter.
Definition: qbrush.h:76
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the hash.
Definition: qhash.h:466
Q_GUI_EXPORT_INLINE int qGray(int r, int g, int b)
Definition: qrgb.h:75
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:469
void flushPage(bool last=false)
static const char *const filters[3]
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
int width() const
Returns the width of the image.
Definition: qimage.cpp:1557
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
QImage convertToFormat(Format f, Qt::ImageConversionFlags flags=Qt::AutoColor) const Q_REQUIRED_RESULT
Returns a copy of the image in the given format.
Definition: qimage.cpp:3966
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
virtual void drawImageInternal(const QRectF &r, QImage img, bool bitmap)
qreal x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:664
void clear()
Definition: qpdf.cpp:232
static const int max_in_memory_size
qreal redF() const
Returns the red color component of this color.
Definition: qcolor.cpp:1213
int sigaction(int, const struct sigaction *, struct sigaction *)
void setRect(int x, int y, int w, int h)
Sets the coordinates of the rectangle&#39;s top-left corner to ({x}, {y}), and its size to the given widt...
Definition: qrect.h:400
void resize(int size)
Sets the size of the byte array to size bytes.
virtual bool begin(QPaintDevice *pdev)
Reimplement this function to initialise your paint engine when painting is to start on the paint devi...
virtual bool newPage()
Instructs the print engine to start a new page.
qreal blueF() const
Returns the blue color component of this color.
Definition: qcolor.cpp:1269
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
static QDateTime currentDateTime()
Returns the current datetime, as reported by the system clock, in the local time zone.
Definition: qdatetime.cpp:3138
QFactoryLoader * l
int height() const
Returns the height of the image.
Definition: qimage.cpp:1572
QIODevice * outDevice
Definition: qpdf_p.h:259
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
bool contains(const T &t) const
Returns true if the vector contains an occurrence of value; otherwise returns false.
Definition: qvector.h:731
QPdfPage * currentPage
Definition: qpdf_p.h:239
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
void drawImageHelper(qreal x, qreal y, qreal w, qreal h, const QImage &img, const QImage &mask, bool gray, qreal scaleX, qreal scaleY)
Q_GUI_EXPORT_INLINE int qGreen(QRgb rgb)
Definition: qrgb.h:60
#define QT_BEGIN_INCLUDE_NAMESPACE
This macro is equivalent to QT_END_NAMESPACE.
Definition: qglobal.h:91
Q_CORE_EXPORT QTextStream & flush(QTextStream &s)
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...
Definition: qpainter.cpp:5619
int height() const
Returns the height of the pixmap.
Definition: qpixmap.cpp:645
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
QRect paperRect() const
Definition: qpdf.cpp:2028
QRgb rgba() const
Returns the RGB value of the color, including its alpha.
Definition: qcolor.cpp:1019
static QList< QByteArray > supportedImageFormats()
Returns the list of image formats supported by QImageWriter.
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
Definition: qiodevice.cpp:1342
void flushAndInit(bool init=true)
static QByteArray runlengthEncode(const QByteArray &input)
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
QImage scaled(int w, int h, Qt::AspectRatioMode aspectMode=Qt::IgnoreAspectRatio, Qt::TransformationMode mode=Qt::FastTransformation) const
Definition: qimage.h:232
bool isValid() const
Returns true if the rectangle is valid, otherwise returns false.
Definition: qrect.h:237
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition: qstring.cpp:3796
void translate(int dx, int dy)
Moves the rectangle dx along the x axis and dy along the y axis, relative to the current position...
Definition: qrect.h:312
The QIODevice class is the base interface class of all I/O devices in Qt.
Definition: qiodevice.h:66
bool write(const QImage &image)
Writes the image image to the assigned device or file name.
void qt_generate_epsf(bool b)
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
void drawImage(qreal x, qreal y, qreal w, qreal h, const QImage &img, const QImage &mask)
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
virtual bool abort()
Instructs the print engine to abort the printing process.
static QByteArray number(int, int base=10)
Returns a byte array containing the string equivalent of the number n to base base (10 by default)...
static QMutex * globalInstanceGet(const void *address)
Returns a QMutex from the global mutex pool.
Definition: qmutexpool.cpp:150
QRgb color(int i) const
Returns the color in the color table at index i.
Definition: qimage.cpp:1829
int heightMM() const
Definition: qpaintdevice.h:94
int widthMM() const
Definition: qpaintdevice.h:93
void clear()
Clears the contents of the byte array and makes it empty.
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
Definition: qimage.cpp:1886
QPdf::ByteStream buffer
virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
Reimplement this function to draw the part of the pm specified by the sr rectangle in the given r...
bool allGray() const
Returns true if all the colors in the image are shades of gray (i.e.
Definition: qimage.cpp:4435
QByteArray ascii85Encode(const QByteArray &input)
Definition: qpdf.cpp:806
QPaintEngine * q_ptr
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...