qpdf.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/painting/qpdf.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
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 The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/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 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qpdf_p.h"-
41-
42#ifndef QT_NO_PDF-
43-
44#include "qplatformdefs.h"-
45#include <qdebug.h>-
46#include <qfile.h>-
47#include <qtemporaryfile.h>-
48#include <private/qmath_p.h>-
49#include <private/qpainter_p.h>-
50#include <qnumeric.h>-
51#include "private/qfont_p.h"-
52#include <qimagewriter.h>-
53#include "qbuffer.h"-
54#include "QtCore/qdatetime.h"-
55-
56#ifndef QT_NO_COMPRESS-
57#include <zlib.h>-
58#endif-
59-
60#ifdef QT_NO_COMPRESS-
61static const bool do_compress = false;-
62#else-
63static const bool do_compress = true;-
64#endif-
65-
66// might be helpful for smooth transforms of images-
67// Can't use it though, as gs generates completely wrong images if this is true.-
68static const bool interpolateImages = false;-
69-
70QT_BEGIN_NAMESPACE-
71-
72inline QPaintEngine::PaintEngineFeatures qt_pdf_decide_features()-
73{-
74 QPaintEngine::PaintEngineFeatures f = QPaintEngine::AllFeatures;-
75 f &= ~(QPaintEngine::PorterDuff-
76 | QPaintEngine::PerspectiveTransform-
77 | QPaintEngine::ObjectBoundingModeGradients-
78 | QPaintEngine::ConicalGradientFill);-
79 return f;
never executed: return f;
0
80}-
81-
82-
83-
84/* also adds a space at the end of the number */-
85const char *qt_real_to_string(qreal val, char *buf) {-
86 const char *ret = buf;-
87-
88 if (qIsNaN(val)) {
qIsNaN(val)Description
TRUEnever evaluated
FALSEnever evaluated
0
89 *(buf++) = '0';-
90 *(buf++) = ' ';-
91 *buf = 0;-
92 return ret;
never executed: return ret;
0
93 }-
94-
95 if (val < 0) {
val < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
96 *(buf++) = '-';-
97 val = -val;-
98 }
never executed: end of block
0
99 unsigned int ival = (unsigned int) val;-
100 qreal frac = val - (qreal)ival;-
101-
102 int ifrac = (int)(frac * 1000000000);-
103 if (ifrac == 1000000000) {
ifrac == 1000000000Description
TRUEnever evaluated
FALSEnever evaluated
0
104 ++ival;-
105 ifrac = 0;-
106 }
never executed: end of block
0
107 char output[256];-
108 int i = 0;-
109 while (ival) {
ivalDescription
TRUEnever evaluated
FALSEnever evaluated
0
110 output[i] = '0' + (ival % 10);-
111 ++i;-
112 ival /= 10;-
113 }
never executed: end of block
0
114 int fact = 100000000;-
115 if (i == 0) {
i == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
116 *(buf++) = '0';-
117 } else {
never executed: end of block
0
118 while (i) {
iDescription
TRUEnever evaluated
FALSEnever evaluated
0
119 *(buf++) = output[--i];-
120 fact /= 10;-
121 ifrac /= 10;-
122 }
never executed: end of block
0
123 }
never executed: end of block
0
124-
125 if (ifrac) {
ifracDescription
TRUEnever evaluated
FALSEnever evaluated
0
126 *(buf++) = '.';-
127 while (fact) {
factDescription
TRUEnever evaluated
FALSEnever evaluated
0
128 *(buf++) = '0' + ((ifrac/fact) % 10);-
129 fact /= 10;-
130 }
never executed: end of block
0
131 }
never executed: end of block
0
132 *(buf++) = ' ';-
133 *buf = 0;-
134 return ret;
never executed: return ret;
0
135}-
136-
137const char *qt_int_to_string(int val, char *buf) {-
138 const char *ret = buf;-
139 if (val < 0) {
val < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
140 *(buf++) = '-';-
141 val = -val;-
142 }
never executed: end of block
0
143 char output[256];-
144 int i = 0;-
145 while (val) {
valDescription
TRUEnever evaluated
FALSEnever evaluated
0
146 output[i] = '0' + (val % 10);-
147 ++i;-
148 val /= 10;-
149 }
never executed: end of block
0
150 if (i == 0) {
i == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
151 *(buf++) = '0';-
152 } else {
never executed: end of block
0
153 while (i)
iDescription
TRUEnever evaluated
FALSEnever evaluated
0
154 *(buf++) = output[--i];
never executed: *(buf++) = output[--i];
0
155 }
never executed: end of block
0
156 *(buf++) = ' ';-
157 *buf = 0;-
158 return ret;
never executed: return ret;
0
159}-
160-
161-
162namespace QPdf {-
163 ByteStream::ByteStream(QByteArray *byteArray, bool fileBacking)-
164 : dev(new QBuffer(byteArray)),-
165 fileBackingEnabled(fileBacking),-
166 fileBackingActive(false),-
167 handleDirty(false)-
168 {-
169 dev->open(QIODevice::ReadWrite | QIODevice::Append);-
170 }
never executed: end of block
0
171-
172 ByteStream::ByteStream(bool fileBacking)-
173 : dev(new QBuffer(&ba)),-
174 fileBackingEnabled(fileBacking),-
175 fileBackingActive(false),-
176 handleDirty(false)-
177 {-
178 dev->open(QIODevice::ReadWrite);-
179 }
never executed: end of block
0
180-
181 ByteStream::~ByteStream()-
182 {-
183 delete dev;-
184 }
never executed: end of block
0
185-
186 ByteStream &ByteStream::operator <<(char chr)-
187 {-
188 if (handleDirty) prepareBuffer();
never executed: prepareBuffer();
handleDirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
189 dev->write(&chr, 1);-
190 return *this;
never executed: return *this;
0
191 }-
192-
193 ByteStream &ByteStream::operator <<(const char *str)-
194 {-
195 if (handleDirty) prepareBuffer();
never executed: prepareBuffer();
handleDirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
196 dev->write(str, strlen(str));-
197 return *this;
never executed: return *this;
0
198 }-
199-
200 ByteStream &ByteStream::operator <<(const QByteArray &str)-
201 {-
202 if (handleDirty) prepareBuffer();
never executed: prepareBuffer();
handleDirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
203 dev->write(str);-
204 return *this;
never executed: return *this;
0
205 }-
206-
207 ByteStream &ByteStream::operator <<(const ByteStream &src)-
208 {-
209 Q_ASSERT(!src.dev->isSequential());-
210 if (handleDirty) prepareBuffer();
never executed: prepareBuffer();
handleDirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
211 // We do play nice here, even though it looks ugly.-
212 // We save the position and restore it afterwards.-
213 ByteStream &s = const_cast<ByteStream&>(src);-
214 qint64 pos = s.dev->pos();-
215 s.dev->reset();-
216 while (!s.dev->atEnd()) {
!s.dev->atEnd()Description
TRUEnever evaluated
FALSEnever evaluated
0
217 QByteArray buf = s.dev->read(chunkSize());-
218 dev->write(buf);-
219 }
never executed: end of block
0
220 s.dev->seek(pos);-
221 return *this;
never executed: return *this;
0
222 }-
223-
224 ByteStream &ByteStream::operator <<(qreal val) {-
225 char buf[256];-
226 qt_real_to_string(val, buf);-
227 *this << buf;-
228 return *this;
never executed: return *this;
0
229 }-
230-
231 ByteStream &ByteStream::operator <<(int val) {-
232 char buf[256];-
233 qt_int_to_string(val, buf);-
234 *this << buf;-
235 return *this;
never executed: return *this;
0
236 }-
237-
238 ByteStream &ByteStream::operator <<(const QPointF &p) {-
239 char buf[256];-
240 qt_real_to_string(p.x(), buf);-
241 *this << buf;-
242 qt_real_to_string(p.y(), buf);-
243 *this << buf;-
244 return *this;
never executed: return *this;
0
245 }-
246-
247 QIODevice *ByteStream::stream()-
248 {-
249 dev->reset();-
250 handleDirty = true;-
251 return dev;
never executed: return dev;
0
252 }-
253-
254 void ByteStream::clear()-
255 {-
256 dev->open(QIODevice::ReadWrite | QIODevice::Truncate);-
257 }
never executed: end of block
0
258-
259 void ByteStream::constructor_helper(QByteArray *ba)-
260 {-
261 delete dev;-
262 dev = new QBuffer(ba);-
263 dev->open(QIODevice::ReadWrite);-
264 }
never executed: end of block
0
265-
266 void ByteStream::prepareBuffer()-
267 {-
268 Q_ASSERT(!dev->isSequential());-
269 qint64 size = dev->size();-
270 if (fileBackingEnabled && !fileBackingActive
fileBackingEnabledDescription
TRUEnever evaluated
FALSEnever evaluated
!fileBackingActiveDescription
TRUEnever evaluated
FALSEnever evaluated
0
271 && size > maxMemorySize()) {
size > maxMemorySize()Description
TRUEnever evaluated
FALSEnever evaluated
0
272 // Switch to file backing.-
273 QTemporaryFile *newFile = new QTemporaryFile;-
274 newFile->open();-
275 dev->reset();-
276 while (!dev->atEnd()) {
!dev->atEnd()Description
TRUEnever evaluated
FALSEnever evaluated
0
277 QByteArray buf = dev->read(chunkSize());-
278 newFile->write(buf);-
279 }
never executed: end of block
0
280 delete dev;-
281 dev = newFile;-
282 ba.clear();-
283 fileBackingActive = true;-
284 }
never executed: end of block
0
285 if (dev->pos() != size) {
dev->pos() != sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
286 dev->seek(size);-
287 handleDirty = false;-
288 }
never executed: end of block
0
289 }
never executed: end of block
0
290}-
291-
292#define QT_PATH_ELEMENT(elm)-
293-
294QByteArray QPdf::generatePath(const QPainterPath &path, const QTransform &matrix, PathFlags flags)-
295{-
296 QByteArray result;-
297 if (!path.elementCount())
!path.elementCount()Description
TRUEnever evaluated
FALSEnever evaluated
0
298 return result;
never executed: return result;
0
299-
300 ByteStream s(&result);-
301-
302 int start = -1;-
303 for (int i = 0; i < path.elementCount(); ++i) {
i < path.elementCount()Description
TRUEnever evaluated
FALSEnever evaluated
0
304 const QPainterPath::Element &elm = path.elementAt(i);-
305 switch (elm.type) {-
306 case QPainterPath::MoveToElement:
never executed: case QPainterPath::MoveToElement:
0
307 if (start >= 0
start >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
308 && path.elementAt(start).x == path.elementAt(i-1).x
path.elementAt...ementAt(i-1).xDescription
TRUEnever evaluated
FALSEnever evaluated
0
309 && path.elementAt(start).y == path.elementAt(i-1).y)
path.elementAt...ementAt(i-1).yDescription
TRUEnever evaluated
FALSEnever evaluated
0
310 s << "h\n";
never executed: s << "h\n";
0
311 s << matrix.map(QPointF(elm.x, elm.y)) << "m\n";-
312 start = i;-
313 break;
never executed: break;
0
314 case QPainterPath::LineToElement:
never executed: case QPainterPath::LineToElement:
0
315 s << matrix.map(QPointF(elm.x, elm.y)) << "l\n";-
316 break;
never executed: break;
0
317 case QPainterPath::CurveToElement:
never executed: case QPainterPath::CurveToElement:
0
318 Q_ASSERT(path.elementAt(i+1).type == QPainterPath::CurveToDataElement);-
319 Q_ASSERT(path.elementAt(i+2).type == QPainterPath::CurveToDataElement);-
320 s << matrix.map(QPointF(elm.x, elm.y))-
321 << matrix.map(QPointF(path.elementAt(i+1).x, path.elementAt(i+1).y))-
322 << matrix.map(QPointF(path.elementAt(i+2).x, path.elementAt(i+2).y))-
323 << "c\n";-
324 i += 2;-
325 break;
never executed: break;
0
326 default:
never executed: default:
0
327 qFatal("QPdf::generatePath(), unhandled type: %d", elm.type);-
328 }
never executed: end of block
0
329 }-
330 if (start >= 0
start >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
331 && path.elementAt(start).x == path.elementAt(path.elementCount()-1).x
path.elementAt...ntCount()-1).xDescription
TRUEnever evaluated
FALSEnever evaluated
0
332 && path.elementAt(start).y == path.elementAt(path.elementCount()-1).y)
path.elementAt...ntCount()-1).yDescription
TRUEnever evaluated
FALSEnever evaluated
0
333 s << "h\n";
never executed: s << "h\n";
0
334-
335 Qt::FillRule fillRule = path.fillRule();-
336-
337 const char *op = "";-
338 switch (flags) {-
339 case ClipPath:
never executed: case ClipPath:
0
340 op = (fillRule == Qt::WindingFill) ? "W n\n" : "W* n\n";
(fillRule == Qt::WindingFill)Description
TRUEnever evaluated
FALSEnever evaluated
0
341 break;
never executed: break;
0
342 case FillPath:
never executed: case FillPath:
0
343 op = (fillRule == Qt::WindingFill) ? "f\n" : "f*\n";
(fillRule == Qt::WindingFill)Description
TRUEnever evaluated
FALSEnever evaluated
0
344 break;
never executed: break;
0
345 case StrokePath:
never executed: case StrokePath:
0
346 op = "S\n";-
347 break;
never executed: break;
0
348 case FillAndStrokePath:
never executed: case FillAndStrokePath:
0
349 op = (fillRule == Qt::WindingFill) ? "B\n" : "B*\n";
(fillRule == Qt::WindingFill)Description
TRUEnever evaluated
FALSEnever evaluated
0
350 break;
never executed: break;
0
351 }-
352 s << op;-
353 return result;
never executed: return result;
0
354}-
355-
356QByteArray QPdf::generateMatrix(const QTransform &matrix)-
357{-
358 QByteArray result;-
359 ByteStream s(&result);-
360 s << matrix.m11()-
361 << matrix.m12()-
362 << matrix.m21()-
363 << matrix.m22()-
364 << matrix.dx()-
365 << matrix.dy()-
366 << "cm\n";-
367 return result;
never executed: return result;
0
368}-
369-
370QByteArray QPdf::generateDashes(const QPen &pen)-
371{-
372 QByteArray result;-
373 ByteStream s(&result);-
374 s << '[';-
375-
376 QVector<qreal> dasharray = pen.dashPattern();-
377 qreal w = pen.widthF();-
378 if (w < 0.001)
w < 0.001Description
TRUEnever evaluated
FALSEnever evaluated
0
379 w = 1;
never executed: w = 1;
0
380 for (int i = 0; i < dasharray.size(); ++i) {
i < dasharray.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
381 qreal dw = dasharray.at(i)*w;-
382 if (dw < 0.0001) dw = 0.0001;
never executed: dw = 0.0001;
dw < 0.0001Description
TRUEnever evaluated
FALSEnever evaluated
0
383 s << dw;-
384 }
never executed: end of block
0
385 s << ']';-
386 s << pen.dashOffset() * w;-
387 s << " d\n";-
388 return result;
never executed: return result;
0
389}-
390-
391-
392-
393static const char* const pattern_for_brush[] = {-
394 0, // NoBrush-
395 0, // SolidPattern-
396 "0 J\n"-
397 "6 w\n"-
398 "[] 0 d\n"-
399 "4 0 m\n"-
400 "4 8 l\n"-
401 "0 4 m\n"-
402 "8 4 l\n"-
403 "S\n", // Dense1Pattern-
404-
405 "0 J\n"-
406 "2 w\n"-
407 "[6 2] 1 d\n"-
408 "0 0 m\n"-
409 "0 8 l\n"-
410 "8 0 m\n"-
411 "8 8 l\n"-
412 "S\n"-
413 "[] 0 d\n"-
414 "2 0 m\n"-
415 "2 8 l\n"-
416 "6 0 m\n"-
417 "6 8 l\n"-
418 "S\n"-
419 "[6 2] -3 d\n"-
420 "4 0 m\n"-
421 "4 8 l\n"-
422 "S\n", // Dense2Pattern-
423-
424 "0 J\n"-
425 "2 w\n"-
426 "[6 2] 1 d\n"-
427 "0 0 m\n"-
428 "0 8 l\n"-
429 "8 0 m\n"-
430 "8 8 l\n"-
431 "S\n"-
432 "[2 2] -1 d\n"-
433 "2 0 m\n"-
434 "2 8 l\n"-
435 "6 0 m\n"-
436 "6 8 l\n"-
437 "S\n"-
438 "[6 2] -3 d\n"-
439 "4 0 m\n"-
440 "4 8 l\n"-
441 "S\n", // Dense3Pattern-
442-
443 "0 J\n"-
444 "2 w\n"-
445 "[2 2] 1 d\n"-
446 "0 0 m\n"-
447 "0 8 l\n"-
448 "8 0 m\n"-
449 "8 8 l\n"-
450 "S\n"-
451 "[2 2] -1 d\n"-
452 "2 0 m\n"-
453 "2 8 l\n"-
454 "6 0 m\n"-
455 "6 8 l\n"-
456 "S\n"-
457 "[2 2] 1 d\n"-
458 "4 0 m\n"-
459 "4 8 l\n"-
460 "S\n", // Dense4Pattern-
461-
462 "0 J\n"-
463 "2 w\n"-
464 "[2 6] -1 d\n"-
465 "0 0 m\n"-
466 "0 8 l\n"-
467 "8 0 m\n"-
468 "8 8 l\n"-
469 "S\n"-
470 "[2 2] 1 d\n"-
471 "2 0 m\n"-
472 "2 8 l\n"-
473 "6 0 m\n"-
474 "6 8 l\n"-
475 "S\n"-
476 "[2 6] 3 d\n"-
477 "4 0 m\n"-
478 "4 8 l\n"-
479 "S\n", // Dense5Pattern-
480-
481 "0 J\n"-
482 "2 w\n"-
483 "[2 6] -1 d\n"-
484 "0 0 m\n"-
485 "0 8 l\n"-
486 "8 0 m\n"-
487 "8 8 l\n"-
488 "S\n"-
489 "[2 6] 3 d\n"-
490 "4 0 m\n"-
491 "4 8 l\n"-
492 "S\n", // Dense6Pattern-
493-
494 "0 J\n"-
495 "2 w\n"-
496 "[2 6] -1 d\n"-
497 "0 0 m\n"-
498 "0 8 l\n"-
499 "8 0 m\n"-
500 "8 8 l\n"-
501 "S\n", // Dense7Pattern-
502-
503 "1 w\n"-
504 "0 4 m\n"-
505 "8 4 l\n"-
506 "S\n", // HorPattern-
507-
508 "1 w\n"-
509 "4 0 m\n"-
510 "4 8 l\n"-
511 "S\n", // VerPattern-
512-
513 "1 w\n"-
514 "4 0 m\n"-
515 "4 8 l\n"-
516 "0 4 m\n"-
517 "8 4 l\n"-
518 "S\n", // CrossPattern-
519-
520 "1 w\n"-
521 "-1 5 m\n"-
522 "5 -1 l\n"-
523 "3 9 m\n"-
524 "9 3 l\n"-
525 "S\n", // BDiagPattern-
526-
527 "1 w\n"-
528 "-1 3 m\n"-
529 "5 9 l\n"-
530 "3 -1 m\n"-
531 "9 5 l\n"-
532 "S\n", // FDiagPattern-
533-
534 "1 w\n"-
535 "-1 3 m\n"-
536 "5 9 l\n"-
537 "3 -1 m\n"-
538 "9 5 l\n"-
539 "-1 5 m\n"-
540 "5 -1 l\n"-
541 "3 9 m\n"-
542 "9 3 l\n"-
543 "S\n", // DiagCrossPattern-
544};-
545-
546QByteArray QPdf::patternForBrush(const QBrush &b)-
547{-
548 int style = b.style();-
549 if (style > Qt::DiagCrossPattern)
style > Qt::DiagCrossPatternDescription
TRUEnever evaluated
FALSEnever evaluated
0
550 return QByteArray();
never executed: return QByteArray();
0
551 return pattern_for_brush[style];
never executed: return pattern_for_brush[style];
0
552}-
553-
554-
555static void moveToHook(qfixed x, qfixed y, void *data)-
556{-
557 QPdf::Stroker *t = (QPdf::Stroker *)data;-
558 if (!t->first)
!t->firstDescription
TRUEnever evaluated
FALSEnever evaluated
0
559 *t->stream << "h\n";
never executed: *t->stream << "h\n";
0
560 if (!t->cosmeticPen)
!t->cosmeticPenDescription
TRUEnever evaluated
FALSEnever evaluated
0
561 t->matrix.map(x, y, &x, &y);
never executed: t->matrix.map(x, y, &x, &y);
0
562 *t->stream << x << y << "m\n";-
563 t->first = false;-
564}
never executed: end of block
0
565-
566static void lineToHook(qfixed x, qfixed y, void *data)-
567{-
568 QPdf::Stroker *t = (QPdf::Stroker *)data;-
569 if (!t->cosmeticPen)
!t->cosmeticPenDescription
TRUEnever evaluated
FALSEnever evaluated
0
570 t->matrix.map(x, y, &x, &y);
never executed: t->matrix.map(x, y, &x, &y);
0
571 *t->stream << x << y << "l\n";-
572}
never executed: end of block
0
573-
574static void cubicToHook(qfixed c1x, qfixed c1y,-
575 qfixed c2x, qfixed c2y,-
576 qfixed ex, qfixed ey,-
577 void *data)-
578{-
579 QPdf::Stroker *t = (QPdf::Stroker *)data;-
580 if (!t->cosmeticPen) {
!t->cosmeticPenDescription
TRUEnever evaluated
FALSEnever evaluated
0
581 t->matrix.map(c1x, c1y, &c1x, &c1y);-
582 t->matrix.map(c2x, c2y, &c2x, &c2y);-
583 t->matrix.map(ex, ey, &ex, &ey);-
584 }
never executed: end of block
0
585 *t->stream << c1x << c1y-
586 << c2x << c2y-
587 << ex << ey-
588 << "c\n";-
589}
never executed: end of block
0
590-
591QPdf::Stroker::Stroker()-
592 : stream(0),-
593 first(true),-
594 dashStroker(&basicStroker)-
595{-
596 stroker = &basicStroker;-
597 basicStroker.setMoveToHook(moveToHook);-
598 basicStroker.setLineToHook(lineToHook);-
599 basicStroker.setCubicToHook(cubicToHook);-
600 cosmeticPen = true;-
601 basicStroker.setStrokeWidth(.1);-
602}
never executed: end of block
0
603-
604void QPdf::Stroker::setPen(const QPen &pen, QPainter::RenderHints hints)-
605{-
606 if (pen.style() == Qt::NoPen) {
pen.style() == Qt::NoPenDescription
TRUEnever evaluated
FALSEnever evaluated
0
607 stroker = 0;-
608 return;
never executed: return;
0
609 }-
610 qreal w = pen.widthF();-
611 bool zeroWidth = w < 0.0001;-
612 cosmeticPen = qt_pen_is_cosmetic(pen, hints);-
613 if (zeroWidth)
zeroWidthDescription
TRUEnever evaluated
FALSEnever evaluated
0
614 w = .1;
never executed: w = .1;
0
615-
616 basicStroker.setStrokeWidth(w);-
617 basicStroker.setCapStyle(pen.capStyle());-
618 basicStroker.setJoinStyle(pen.joinStyle());-
619 basicStroker.setMiterLimit(pen.miterLimit());-
620-
621 QVector<qreal> dashpattern = pen.dashPattern();-
622 if (zeroWidth) {
zeroWidthDescription
TRUEnever evaluated
FALSEnever evaluated
0
623 for (int i = 0; i < dashpattern.size(); ++i)
i < dashpattern.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
624 dashpattern[i] *= 10.;
never executed: dashpattern[i] *= 10.;
0
625 }
never executed: end of block
0
626 if (!dashpattern.isEmpty()) {
!dashpattern.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
627 dashStroker.setDashPattern(dashpattern);-
628 dashStroker.setDashOffset(pen.dashOffset());-
629 stroker = &dashStroker;-
630 } else {
never executed: end of block
0
631 stroker = &basicStroker;-
632 }
never executed: end of block
0
633}-
634-
635void QPdf::Stroker::strokePath(const QPainterPath &path)-
636{-
637 if (!stroker)
!strokerDescription
TRUEnever evaluated
FALSEnever evaluated
0
638 return;
never executed: return;
0
639 first = true;-
640-
641 stroker->strokePath(path, this, cosmeticPen ? matrix : QTransform());-
642 *stream << "h f\n";-
643}
never executed: end of block
0
644-
645QByteArray QPdf::ascii85Encode(const QByteArray &input)-
646{-
647 int isize = input.size()/4*4;-
648 QByteArray output;-
649 output.resize(input.size()*5/4+7);-
650 char *out = output.data();-
651 const uchar *in = (const uchar *)input.constData();-
652 for (int i = 0; i < isize; i += 4) {
i < isizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
653 uint val = (((uint)in[i])<<24) + (((uint)in[i+1])<<16) + (((uint)in[i+2])<<8) + (uint)in[i+3];-
654 if (val == 0) {
val == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
655 *out = 'z';-
656 ++out;-
657 } else {
never executed: end of block
0
658 char base[5];-
659 base[4] = val % 85;-
660 val /= 85;-
661 base[3] = val % 85;-
662 val /= 85;-
663 base[2] = val % 85;-
664 val /= 85;-
665 base[1] = val % 85;-
666 val /= 85;-
667 base[0] = val % 85;-
668 *(out++) = base[0] + '!';-
669 *(out++) = base[1] + '!';-
670 *(out++) = base[2] + '!';-
671 *(out++) = base[3] + '!';-
672 *(out++) = base[4] + '!';-
673 }
never executed: end of block
0
674 }-
675 //write the last few bytes-
676 int remaining = input.size() - isize;-
677 if (remaining) {
remainingDescription
TRUEnever evaluated
FALSEnever evaluated
0
678 uint val = 0;-
679 for (int i = isize; i < input.size(); ++i)
i < input.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
680 val = (val << 8) + in[i];
never executed: val = (val << 8) + in[i];
0
681 val <<= 8*(4-remaining);-
682 char base[5];-
683 base[4] = val % 85;-
684 val /= 85;-
685 base[3] = val % 85;-
686 val /= 85;-
687 base[2] = val % 85;-
688 val /= 85;-
689 base[1] = val % 85;-
690 val /= 85;-
691 base[0] = val % 85;-
692 for (int i = 0; i < remaining+1; ++i)
i < remaining+1Description
TRUEnever evaluated
FALSEnever evaluated
0
693 *(out++) = base[i] + '!';
never executed: *(out++) = base[i] + '!';
0
694 }
never executed: end of block
0
695 *(out++) = '~';-
696 *(out++) = '>';-
697 output.resize(out-output.data());-
698 return output;
never executed: return output;
0
699}-
700-
701const char *QPdf::toHex(ushort u, char *buffer)-
702{-
703 int i = 3;-
704 while (i >= 0) {
i >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
705 ushort hex = (u & 0x000f);-
706 if (hex < 0x0a)
hex < 0x0aDescription
TRUEnever evaluated
FALSEnever evaluated
0
707 buffer[i] = '0'+hex;
never executed: buffer[i] = '0'+hex;
0
708 else-
709 buffer[i] = 'A'+(hex-0x0a);
never executed: buffer[i] = 'A'+(hex-0x0a);
0
710 u = u >> 4;-
711 i--;-
712 }
never executed: end of block
0
713 buffer[4] = '\0';-
714 return buffer;
never executed: return buffer;
0
715}-
716-
717const char *QPdf::toHex(uchar u, char *buffer)-
718{-
719 int i = 1;-
720 while (i >= 0) {
i >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
721 ushort hex = (u & 0x000f);-
722 if (hex < 0x0a)
hex < 0x0aDescription
TRUEnever evaluated
FALSEnever evaluated
0
723 buffer[i] = '0'+hex;
never executed: buffer[i] = '0'+hex;
0
724 else-
725 buffer[i] = 'A'+(hex-0x0a);
never executed: buffer[i] = 'A'+(hex-0x0a);
0
726 u = u >> 4;-
727 i--;-
728 }
never executed: end of block
0
729 buffer[2] = '\0';-
730 return buffer;
never executed: return buffer;
0
731}-
732-
733-
734QPdfPage::QPdfPage()-
735 : QPdf::ByteStream(true) // Enable file backing-
736{-
737}
never executed: end of block
0
738-
739void QPdfPage::streamImage(int w, int h, int object)-
740{-
741 *this << w << "0 0 " << -h << "0 " << h << "cm /Im" << object << " Do\n";-
742 if (!images.contains(object))
!images.contains(object)Description
TRUEnever evaluated
FALSEnever evaluated
0
743 images.append(object);
never executed: images.append(object);
0
744}
never executed: end of block
0
745-
746-
747QPdfEngine::QPdfEngine(QPdfEnginePrivate &dd)-
748 : QPaintEngine(dd, qt_pdf_decide_features())-
749{-
750}
never executed: end of block
0
751-
752QPdfEngine::QPdfEngine()-
753 : QPaintEngine(*new QPdfEnginePrivate(), qt_pdf_decide_features())-
754{-
755}
never executed: end of block
0
756-
757void QPdfEngine::setOutputFilename(const QString &filename)-
758{-
759 Q_D(QPdfEngine);-
760 d->outputFileName = filename;-
761}
never executed: end of block
0
762-
763-
764void QPdfEngine::drawPoints (const QPointF *points, int pointCount)-
765{-
766 if (!points)
!pointsDescription
TRUEnever evaluated
FALSEnever evaluated
0
767 return;
never executed: return;
0
768-
769 Q_D(QPdfEngine);-
770 QPainterPath p;-
771 for (int i=0; i!=pointCount;++i) {
i!=pointCountDescription
TRUEnever evaluated
FALSEnever evaluated
0
772 p.moveTo(points[i]);-
773 p.lineTo(points[i] + QPointF(0, 0.001));-
774 }
never executed: end of block
0
775-
776 bool hadBrush = d->hasBrush;-
777 d->hasBrush = false;-
778 drawPath(p);-
779 d->hasBrush = hadBrush;-
780}
never executed: end of block
0
781-
782void QPdfEngine::drawLines (const QLineF *lines, int lineCount)-
783{-
784 if (!lines)
!linesDescription
TRUEnever evaluated
FALSEnever evaluated
0
785 return;
never executed: return;
0
786-
787 Q_D(QPdfEngine);-
788 QPainterPath p;-
789 for (int i=0; i!=lineCount;++i) {
i!=lineCountDescription
TRUEnever evaluated
FALSEnever evaluated
0
790 p.moveTo(lines[i].p1());-
791 p.lineTo(lines[i].p2());-
792 }
never executed: end of block
0
793 bool hadBrush = d->hasBrush;-
794 d->hasBrush = false;-
795 drawPath(p);-
796 d->hasBrush = hadBrush;-
797}
never executed: end of block
0
798-
799void QPdfEngine::drawRects (const QRectF *rects, int rectCount)-
800{-
801 if (!rects)
!rectsDescription
TRUEnever evaluated
FALSEnever evaluated
0
802 return;
never executed: return;
0
803-
804 Q_D(QPdfEngine);-
805-
806 if (d->clipEnabled && d->allClipped)
d->clipEnabledDescription
TRUEnever evaluated
FALSEnever evaluated
d->allClippedDescription
TRUEnever evaluated
FALSEnever evaluated
0
807 return;
never executed: return;
0
808 if (!d->hasPen && !d->hasBrush)
!d->hasPenDescription
TRUEnever evaluated
FALSEnever evaluated
!d->hasBrushDescription
TRUEnever evaluated
FALSEnever evaluated
0
809 return;
never executed: return;
0
810-
811 QBrush penBrush = d->pen.brush();-
812 if (d->simplePen || !d->hasPen) {
d->simplePenDescription
TRUEnever evaluated
FALSEnever evaluated
!d->hasPenDescription
TRUEnever evaluated
FALSEnever evaluated
0
813 // draw strokes natively in this case for better output-
814 if(!d->simplePen && !d->stroker.matrix.isIdentity())
!d->simplePenDescription
TRUEnever evaluated
FALSEnever evaluated
!d->stroker.ma...x.isIdentity()Description
TRUEnever evaluated
FALSEnever evaluated
0
815 *d->currentPage << "q\n" << QPdf::generateMatrix(d->stroker.matrix);
never executed: *d->currentPage << "q\n" << QPdf::generateMatrix(d->stroker.matrix);
0
816 for (int i = 0; i < rectCount; ++i)
i < rectCountDescription
TRUEnever evaluated
FALSEnever evaluated
0
817 *d->currentPage << rects[i].x() << rects[i].y() << rects[i].width() << rects[i].height() << "re\n";
never executed: *d->currentPage << rects[i].x() << rects[i].y() << rects[i].width() << rects[i].height() << "re\n";
0
818 *d->currentPage << (d->hasPen ? (d->hasBrush ? "B\n" : "S\n") : "f\n");-
819 if(!d->simplePen && !d->stroker.matrix.isIdentity())
!d->simplePenDescription
TRUEnever evaluated
FALSEnever evaluated
!d->stroker.ma...x.isIdentity()Description
TRUEnever evaluated
FALSEnever evaluated
0
820 *d->currentPage << "Q\n";
never executed: *d->currentPage << "Q\n";
0
821 } else {
never executed: end of block
0
822 QPainterPath p;-
823 for (int i=0; i!=rectCount; ++i)
i!=rectCountDescription
TRUEnever evaluated
FALSEnever evaluated
0
824 p.addRect(rects[i]);
never executed: p.addRect(rects[i]);
0
825 drawPath(p);-
826 }
never executed: end of block
0
827}-
828-
829void QPdfEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)-
830{-
831 Q_D(QPdfEngine);-
832-
833 if (!points || !pointCount)
!pointsDescription
TRUEnever evaluated
FALSEnever evaluated
!pointCountDescription
TRUEnever evaluated
FALSEnever evaluated
0
834 return;
never executed: return;
0
835-
836 bool hb = d->hasBrush;-
837 QPainterPath p;-
838-
839 switch(mode) {-
840 case OddEvenMode:
never executed: case OddEvenMode:
0
841 p.setFillRule(Qt::OddEvenFill);-
842 break;
never executed: break;
0
843 case ConvexMode:
never executed: case ConvexMode:
0
844 case WindingMode:
never executed: case WindingMode:
0
845 p.setFillRule(Qt::WindingFill);-
846 break;
never executed: break;
0
847 case PolylineMode:
never executed: case PolylineMode:
0
848 d->hasBrush = false;-
849 break;
never executed: break;
0
850 default:
never executed: default:
0
851 break;
never executed: break;
0
852 }-
853-
854 p.moveTo(points[0]);-
855 for (int i = 1; i < pointCount; ++i)
i < pointCountDescription
TRUEnever evaluated
FALSEnever evaluated
0
856 p.lineTo(points[i]);
never executed: p.lineTo(points[i]);
0
857-
858 if (mode != PolylineMode)
mode != PolylineModeDescription
TRUEnever evaluated
FALSEnever evaluated
0
859 p.closeSubpath();
never executed: p.closeSubpath();
0
860 drawPath(p);-
861-
862 d->hasBrush = hb;-
863}
never executed: end of block
0
864-
865void QPdfEngine::drawPath (const QPainterPath &p)-
866{-
867 Q_D(QPdfEngine);-
868-
869 if (d->clipEnabled && d->allClipped)
d->clipEnabledDescription
TRUEnever evaluated
FALSEnever evaluated
d->allClippedDescription
TRUEnever evaluated
FALSEnever evaluated
0
870 return;
never executed: return;
0
871 if (!d->hasPen && !d->hasBrush)
!d->hasPenDescription
TRUEnever evaluated
FALSEnever evaluated
!d->hasBrushDescription
TRUEnever evaluated
FALSEnever evaluated
0
872 return;
never executed: return;
0
873-
874 if (d->simplePen) {
d->simplePenDescription
TRUEnever evaluated
FALSEnever evaluated
0
875 // draw strokes natively in this case for better output-
876 *d->currentPage << QPdf::generatePath(p, QTransform(), d->hasBrush ? QPdf::FillAndStrokePath : QPdf::StrokePath);-
877 } else {
never executed: end of block
0
878 if (d->hasBrush)
d->hasBrushDescription
TRUEnever evaluated
FALSEnever evaluated
0
879 *d->currentPage << QPdf::generatePath(p, d->stroker.matrix, QPdf::FillPath);
never executed: *d->currentPage << QPdf::generatePath(p, d->stroker.matrix, QPdf::FillPath);
0
880 if (d->hasPen) {
d->hasPenDescription
TRUEnever evaluated
FALSEnever evaluated
0
881 *d->currentPage << "q\n";-
882 QBrush b = d->brush;-
883 d->brush = d->pen.brush();-
884 setBrush();-
885 d->stroker.strokePath(p);-
886 *d->currentPage << "Q\n";-
887 d->brush = b;-
888 }
never executed: end of block
0
889 }
never executed: end of block
0
890}-
891-
892void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, const QRectF &sr)-
893{-
894 if (sr.isEmpty() || rectangle.isEmpty() || pixmap.isNull())
sr.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
rectangle.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
pixmap.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
895 return;
never executed: return;
0
896 Q_D(QPdfEngine);-
897-
898 QBrush b = d->brush;-
899-
900 QRect sourceRect = sr.toRect();-
901 QPixmap pm = sourceRect != pixmap.rect() ? pixmap.copy(sourceRect) : pixmap;
sourceRect != pixmap.rect()Description
TRUEnever evaluated
FALSEnever evaluated
0
902 QImage image = pm.toImage();-
903 bool bitmap = true;-
904 const int object = d->addImage(image, &bitmap, pm.cacheKey());-
905 if (object < 0)
object < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
906 return;
never executed: return;
0
907-
908 *d->currentPage << "q\n/GSa gs\n";-
909 *d->currentPage-
910 << QPdf::generateMatrix(QTransform(rectangle.width() / sr.width(), 0, 0, rectangle.height() / sr.height(),-
911 rectangle.x(), rectangle.y()) * (d->simplePen ? QTransform() : d->stroker.matrix));-
912 if (bitmap) {
bitmapDescription
TRUEnever evaluated
FALSEnever evaluated
0
913 // set current pen as d->brush-
914 d->brush = d->pen.brush();-
915 }
never executed: end of block
0
916 setBrush();-
917 d->currentPage->streamImage(image.width(), image.height(), object);-
918 *d->currentPage << "Q\n";-
919-
920 d->brush = b;-
921}
never executed: end of block
0
922-
923void QPdfEngine::drawImage(const QRectF &rectangle, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags)-
924{-
925 if (sr.isEmpty() || rectangle.isEmpty() || image.isNull())
sr.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
rectangle.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
image.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
926 return;
never executed: return;
0
927 Q_D(QPdfEngine);-
928-
929 QRect sourceRect = sr.toRect();-
930 QImage im = sourceRect != image.rect() ? image.copy(sourceRect) : image;
sourceRect != image.rect()Description
TRUEnever evaluated
FALSEnever evaluated
0
931 bool bitmap = true;-
932 const int object = d->addImage(im, &bitmap, im.cacheKey());-
933 if (object < 0)
object < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
934 return;
never executed: return;
0
935-
936 *d->currentPage << "q\n/GSa gs\n";-
937 *d->currentPage-
938 << QPdf::generateMatrix(QTransform(rectangle.width() / sr.width(), 0, 0, rectangle.height() / sr.height(),-
939 rectangle.x(), rectangle.y()) * (d->simplePen ? QTransform() : d->stroker.matrix));-
940 setBrush();-
941 d->currentPage->streamImage(im.width(), im.height(), object);-
942 *d->currentPage << "Q\n";-
943}
never executed: end of block
0
944-
945void QPdfEngine::drawTiledPixmap (const QRectF &rectangle, const QPixmap &pixmap, const QPointF &point)-
946{-
947 Q_D(QPdfEngine);-
948-
949 bool bitmap = (pixmap.depth() == 1);-
950 QBrush b = d->brush;-
951 QPointF bo = d->brushOrigin;-
952 bool hp = d->hasPen;-
953 d->hasPen = false;-
954 bool hb = d->hasBrush;-
955 d->hasBrush = true;-
956-
957 d->brush = QBrush(pixmap);-
958 if (bitmap)
bitmapDescription
TRUEnever evaluated
FALSEnever evaluated
0
959 // #### fix bitmap case where we have a brush pen-
960 d->brush.setColor(d->pen.color());
never executed: d->brush.setColor(d->pen.color());
0
961-
962 d->brushOrigin = -point;-
963 *d->currentPage << "q\n";-
964 setBrush();-
965-
966 drawRects(&rectangle, 1);-
967 *d->currentPage << "Q\n";-
968-
969 d->hasPen = hp;-
970 d->hasBrush = hb;-
971 d->brush = b;-
972 d->brushOrigin = bo;-
973}
never executed: end of block
0
974-
975void QPdfEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)-
976{-
977 Q_D(QPdfEngine);-
978-
979 if (!d->hasPen || (d->clipEnabled && d->allClipped))
!d->hasPenDescription
TRUEnever evaluated
FALSEnever evaluated
d->clipEnabledDescription
TRUEnever evaluated
FALSEnever evaluated
d->allClippedDescription
TRUEnever evaluated
FALSEnever evaluated
0
980 return;
never executed: return;
0
981-
982 if (d->stroker.matrix.type() >= QTransform::TxProject) {
d->stroker.mat...orm::TxProjectDescription
TRUEnever evaluated
FALSEnever evaluated
0
983 QPaintEngine::drawTextItem(p, textItem);-
984 return;
never executed: return;
0
985 }-
986-
987 *d->currentPage << "q\n";-
988 if(!d->simplePen)
!d->simplePenDescription
TRUEnever evaluated
FALSEnever evaluated
0
989 *d->currentPage << QPdf::generateMatrix(d->stroker.matrix);
never executed: *d->currentPage << QPdf::generateMatrix(d->stroker.matrix);
0
990-
991 bool hp = d->hasPen;-
992 d->hasPen = false;-
993 QBrush b = d->brush;-
994 d->brush = d->pen.brush();-
995 setBrush();-
996-
997 const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);-
998 Q_ASSERT(ti.fontEngine->type() != QFontEngine::Multi);-
999 d->drawTextItem(p, ti);-
1000 d->hasPen = hp;-
1001 d->brush = b;-
1002 *d->currentPage << "Q\n";-
1003}
never executed: end of block
0
1004-
1005void QPdfEngine::drawHyperlink(const QRectF &r, const QUrl &url)-
1006{-
1007 Q_D(QPdfEngine);-
1008-
1009 const uint annot = d->addXrefEntry(-1);-
1010 const QByteArray urlascii = url.toEncoded();-
1011 int len = urlascii.size();-
1012 QVarLengthArray<char> url_esc;-
1013 url_esc.reserve(len + 1);-
1014 for (int j = 0; j < len; j++) {
j < lenDescription
TRUEnever evaluated
FALSEnever evaluated
0
1015 if (urlascii[j] == '(' || urlascii[j] == ')' || urlascii[j] == '\\')
urlascii[j] == '('Description
TRUEnever evaluated
FALSEnever evaluated
urlascii[j] == ')'Description
TRUEnever evaluated
FALSEnever evaluated
urlascii[j] == '\\'Description
TRUEnever evaluated
FALSEnever evaluated
0
1016 url_esc.append('\\');
never executed: url_esc.append('\\');
0
1017 url_esc.append(urlascii[j]);-
1018 }
never executed: end of block
0
1019 url_esc.append('\0');-
1020-
1021 char buf[256];-
1022 const QRectF rr = d->pageMatrix().mapRect(r);-
1023 d->xprintf("<<\n/Type /Annot\n/Subtype /Link\n/Rect [");-
1024 d->xprintf("%s ", qt_real_to_string(rr.left(), buf));-
1025 d->xprintf("%s ", qt_real_to_string(rr.top(), buf));-
1026 d->xprintf("%s ", qt_real_to_string(rr.right(), buf));-
1027 d->xprintf("%s", qt_real_to_string(rr.bottom(), buf));-
1028 d->xprintf("]\n/Border [0 0 0]\n/A <<\n");-
1029 d->xprintf("/Type /Action\n/S /URI\n/URI (%s)\n", url_esc.constData());-
1030 d->xprintf(">>\n>>\n");-
1031 d->xprintf("endobj\n");-
1032 d->currentPage->annotations.append(annot);-
1033}
never executed: end of block
0
1034-
1035void QPdfEngine::updateState(const QPaintEngineState &state)-
1036{-
1037 Q_D(QPdfEngine);-
1038-
1039 QPaintEngine::DirtyFlags flags = state.state();-
1040-
1041 if (flags & DirtyTransform)
flags & DirtyTransformDescription
TRUEnever evaluated
FALSEnever evaluated
0
1042 d->stroker.matrix = state.transform();
never executed: d->stroker.matrix = state.transform();
0
1043-
1044 if (flags & DirtyPen) {
flags & DirtyPenDescription
TRUEnever evaluated
FALSEnever evaluated
0
1045 d->pen = state.pen();-
1046 d->hasPen = d->pen.style() != Qt::NoPen;-
1047 d->stroker.setPen(d->pen, state.renderHints());-
1048 QBrush penBrush = d->pen.brush();-
1049 bool oldSimple = d->simplePen;-
1050 d->simplePen = (d->hasPen && (penBrush.style() == Qt::SolidPattern) && penBrush.isOpaque() && d->opacity == 1.0);
d->hasPenDescription
TRUEnever evaluated
FALSEnever evaluated
(penBrush.styl...:SolidPattern)Description
TRUEnever evaluated
FALSEnever evaluated
penBrush.isOpaque()Description
TRUEnever evaluated
FALSEnever evaluated
d->opacity == 1.0Description
TRUEnever evaluated
FALSEnever evaluated
0
1051 if (oldSimple != d->simplePen)
oldSimple != d->simplePenDescription
TRUEnever evaluated
FALSEnever evaluated
0
1052 flags |= DirtyTransform;
never executed: flags |= DirtyTransform;
0
1053 } else if (flags & DirtyHints) {
never executed: end of block
flags & DirtyHintsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1054 d->stroker.setPen(d->pen, state.renderHints());-
1055 }
never executed: end of block
0
1056 if (flags & DirtyBrush) {
flags & DirtyBrushDescription
TRUEnever evaluated
FALSEnever evaluated
0
1057 d->brush = state.brush();-
1058 if (d->brush.color().alpha() == 0 && d->brush.style() == Qt::SolidPattern)
d->brush.color().alpha() == 0Description
TRUEnever evaluated
FALSEnever evaluated
d->brush.style...::SolidPatternDescription
TRUEnever evaluated
FALSEnever evaluated
0
1059 d->brush.setStyle(Qt::NoBrush);
never executed: d->brush.setStyle(Qt::NoBrush);
0
1060 d->hasBrush = d->brush.style() != Qt::NoBrush;-
1061 }
never executed: end of block
0
1062 if (flags & DirtyBrushOrigin) {
flags & DirtyBrushOriginDescription
TRUEnever evaluated
FALSEnever evaluated
0
1063 d->brushOrigin = state.brushOrigin();-
1064 flags |= DirtyBrush;-
1065 }
never executed: end of block
0
1066 if (flags & DirtyOpacity) {
flags & DirtyOpacityDescription
TRUEnever evaluated
FALSEnever evaluated
0
1067 d->opacity = state.opacity();-
1068 if (d->simplePen && d->opacity != 1.0) {
d->simplePenDescription
TRUEnever evaluated
FALSEnever evaluated
d->opacity != 1.0Description
TRUEnever evaluated
FALSEnever evaluated
0
1069 d->simplePen = false;-
1070 flags |= DirtyTransform;-
1071 }
never executed: end of block
0
1072 }
never executed: end of block
0
1073-
1074 bool ce = d->clipEnabled;-
1075 if (flags & DirtyClipPath) {
flags & DirtyClipPathDescription
TRUEnever evaluated
FALSEnever evaluated
0
1076 d->clipEnabled = true;-
1077 updateClipPath(state.clipPath(), state.clipOperation());-
1078 } else if (flags & DirtyClipRegion) {
never executed: end of block
flags & DirtyClipRegionDescription
TRUEnever evaluated
FALSEnever evaluated
0
1079 d->clipEnabled = true;-
1080 QPainterPath path;-
1081 QVector<QRect> rects = state.clipRegion().rects();-
1082 for (int i = 0; i < rects.size(); ++i)
i < rects.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1083 path.addRect(rects.at(i));
never executed: path.addRect(rects.at(i));
0
1084 updateClipPath(path, state.clipOperation());-
1085 flags |= DirtyClipPath;-
1086 } else if (flags & DirtyClipEnabled) {
never executed: end of block
flags & DirtyClipEnabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
1087 d->clipEnabled = state.isClipEnabled();-
1088 }
never executed: end of block
0
1089-
1090 if (ce != d->clipEnabled)
ce != d->clipEnabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
1091 flags |= DirtyClipPath;
never executed: flags |= DirtyClipPath;
0
1092 else if (!d->clipEnabled)
!d->clipEnabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
1093 flags &= ~DirtyClipPath;
never executed: flags &= ~DirtyClipPath;
0
1094-
1095 setupGraphicsState(flags);-
1096}
never executed: end of block
0
1097-
1098void QPdfEngine::setupGraphicsState(QPaintEngine::DirtyFlags flags)-
1099{-
1100 Q_D(QPdfEngine);-
1101 if (flags & DirtyClipPath)
flags & DirtyClipPathDescription
TRUEnever evaluated
FALSEnever evaluated
0
1102 flags |= DirtyTransform|DirtyPen|DirtyBrush;
never executed: flags |= DirtyTransform|DirtyPen|DirtyBrush;
0
1103-
1104 if (flags & DirtyTransform) {
flags & DirtyTransformDescription
TRUEnever evaluated
FALSEnever evaluated
0
1105 *d->currentPage << "Q\n";-
1106 flags |= DirtyPen|DirtyBrush;-
1107 }
never executed: end of block
0
1108-
1109 if (flags & DirtyClipPath) {
flags & DirtyClipPathDescription
TRUEnever evaluated
FALSEnever evaluated
0
1110 *d->currentPage << "Q q\n";-
1111-
1112 d->allClipped = false;-
1113 if (d->clipEnabled && !d->clips.isEmpty()) {
d->clipEnabledDescription
TRUEnever evaluated
FALSEnever evaluated
!d->clips.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1114 for (int i = 0; i < d->clips.size(); ++i) {
i < d->clips.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1115 if (d->clips.at(i).isEmpty()) {
d->clips.at(i).isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1116 d->allClipped = true;-
1117 break;
never executed: break;
0
1118 }-
1119 }
never executed: end of block
0
1120 if (!d->allClipped) {
!d->allClippedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1121 for (int i = 0; i < d->clips.size(); ++i) {
i < d->clips.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1122 *d->currentPage << QPdf::generatePath(d->clips.at(i), QTransform(), QPdf::ClipPath);-
1123 }
never executed: end of block
0
1124 }
never executed: end of block
0
1125 }
never executed: end of block
0
1126 }
never executed: end of block
0
1127-
1128 if (flags & DirtyTransform) {
flags & DirtyTransformDescription
TRUEnever evaluated
FALSEnever evaluated
0
1129 *d->currentPage << "q\n";-
1130 if (d->simplePen && !d->stroker.matrix.isIdentity())
d->simplePenDescription
TRUEnever evaluated
FALSEnever evaluated
!d->stroker.ma...x.isIdentity()Description
TRUEnever evaluated
FALSEnever evaluated
0
1131 *d->currentPage << QPdf::generateMatrix(d->stroker.matrix);
never executed: *d->currentPage << QPdf::generateMatrix(d->stroker.matrix);
0
1132 }
never executed: end of block
0
1133 if (flags & DirtyBrush)
flags & DirtyBrushDescription
TRUEnever evaluated
FALSEnever evaluated
0
1134 setBrush();
never executed: setBrush();
0
1135 if (d->simplePen && (flags & DirtyPen))
d->simplePenDescription
TRUEnever evaluated
FALSEnever evaluated
(flags & DirtyPen)Description
TRUEnever evaluated
FALSEnever evaluated
0
1136 setPen();
never executed: setPen();
0
1137}
never executed: end of block
0
1138-
1139extern QPainterPath qt_regionToPath(const QRegion &region);-
1140-
1141void QPdfEngine::updateClipPath(const QPainterPath &p, Qt::ClipOperation op)-
1142{-
1143 Q_D(QPdfEngine);-
1144 QPainterPath path = d->stroker.matrix.map(p);-
1145 //qDebug() << "updateClipPath: " << d->stroker.matrix << p.boundingRect() << path.boundingRect() << op;-
1146-
1147 if (op == Qt::NoClip) {
op == Qt::NoClipDescription
TRUEnever evaluated
FALSEnever evaluated
0
1148 d->clipEnabled = false;-
1149 d->clips.clear();-
1150 } else if (op == Qt::ReplaceClip) {
never executed: end of block
op == Qt::ReplaceClipDescription
TRUEnever evaluated
FALSEnever evaluated
0
1151 d->clips.clear();-
1152 d->clips.append(path);-
1153 } else if (op == Qt::IntersectClip) {
never executed: end of block
op == Qt::IntersectClipDescription
TRUEnever evaluated
FALSEnever evaluated
0
1154 d->clips.append(path);-
1155 } else { // UniteClip
never executed: end of block
0
1156 // ask the painter for the current clipping path. that's the easiest solution-
1157 path = painter()->clipPath();-
1158 path = d->stroker.matrix.map(path);-
1159 d->clips.clear();-
1160 d->clips.append(path);-
1161 }
never executed: end of block
0
1162}-
1163-
1164void QPdfEngine::setPen()-
1165{-
1166 Q_D(QPdfEngine);-
1167 if (d->pen.style() == Qt::NoPen)
d->pen.style() == Qt::NoPenDescription
TRUEnever evaluated
FALSEnever evaluated
0
1168 return;
never executed: return;
0
1169 QBrush b = d->pen.brush();-
1170 Q_ASSERT(b.style() == Qt::SolidPattern && b.isOpaque());-
1171-
1172 QColor rgba = b.color();-
1173 if (d->grayscale) {
d->grayscaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
1174 qreal gray = qGray(rgba.rgba())/255.;-
1175 *d->currentPage << gray << gray << gray;-
1176 } else {
never executed: end of block
0
1177 *d->currentPage << rgba.redF()-
1178 << rgba.greenF()-
1179 << rgba.blueF();-
1180 }
never executed: end of block
0
1181 *d->currentPage << "SCN\n";-
1182-
1183 *d->currentPage << d->pen.widthF() << "w ";-
1184-
1185 int pdfCapStyle = 0;-
1186 switch(d->pen.capStyle()) {-
1187 case Qt::FlatCap:
never executed: case Qt::FlatCap:
0
1188 pdfCapStyle = 0;-
1189 break;
never executed: break;
0
1190 case Qt::SquareCap:
never executed: case Qt::SquareCap:
0
1191 pdfCapStyle = 2;-
1192 break;
never executed: break;
0
1193 case Qt::RoundCap:
never executed: case Qt::RoundCap:
0
1194 pdfCapStyle = 1;-
1195 break;
never executed: break;
0
1196 default:
never executed: default:
0
1197 break;
never executed: break;
0
1198 }-
1199 *d->currentPage << pdfCapStyle << "J ";-
1200-
1201 int pdfJoinStyle = 0;-
1202 switch(d->pen.joinStyle()) {-
1203 case Qt::MiterJoin:
never executed: case Qt::MiterJoin:
0
1204 case Qt::SvgMiterJoin:
never executed: case Qt::SvgMiterJoin:
0
1205 *d->currentPage << qMax(qreal(1.0), d->pen.miterLimit()) << "M ";-
1206 pdfJoinStyle = 0;-
1207 break;
never executed: break;
0
1208 case Qt::BevelJoin:
never executed: case Qt::BevelJoin:
0
1209 pdfJoinStyle = 2;-
1210 break;
never executed: break;
0
1211 case Qt::RoundJoin:
never executed: case Qt::RoundJoin:
0
1212 pdfJoinStyle = 1;-
1213 break;
never executed: break;
0
1214 default:
never executed: default:
0
1215 break;
never executed: break;
0
1216 }-
1217 *d->currentPage << pdfJoinStyle << "j ";-
1218-
1219 *d->currentPage << QPdf::generateDashes(d->pen);-
1220}
never executed: end of block
0
1221-
1222-
1223void QPdfEngine::setBrush()-
1224{-
1225 Q_D(QPdfEngine);-
1226 Qt::BrushStyle style = d->brush.style();-
1227 if (style == Qt::NoBrush)
style == Qt::NoBrushDescription
TRUEnever evaluated
FALSEnever evaluated
0
1228 return;
never executed: return;
0
1229-
1230 bool specifyColor;-
1231 int gStateObject = 0;-
1232 int patternObject = d->addBrushPattern(d->stroker.matrix, &specifyColor, &gStateObject);-
1233 if (!patternObject && !specifyColor)
!patternObjectDescription
TRUEnever evaluated
FALSEnever evaluated
!specifyColorDescription
TRUEnever evaluated
FALSEnever evaluated
0
1234 return;
never executed: return;
0
1235-
1236 *d->currentPage << (patternObject ? "/PCSp cs " : "/CSp cs ");-
1237 if (specifyColor) {
specifyColorDescription
TRUEnever evaluated
FALSEnever evaluated
0
1238 QColor rgba = d->brush.color();-
1239 if (d->grayscale) {
d->grayscaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
1240 qreal gray = qGray(rgba.rgba())/255.;-
1241 *d->currentPage << gray << gray << gray;-
1242 } else {
never executed: end of block
0
1243 *d->currentPage << rgba.redF()-
1244 << rgba.greenF()-
1245 << rgba.blueF();-
1246 }
never executed: end of block
0
1247 }-
1248 if (patternObject)
patternObjectDescription
TRUEnever evaluated
FALSEnever evaluated
0
1249 *d->currentPage << "/Pat" << patternObject;
never executed: *d->currentPage << "/Pat" << patternObject;
0
1250 *d->currentPage << "scn\n";-
1251-
1252 if (gStateObject)
gStateObjectDescription
TRUEnever evaluated
FALSEnever evaluated
0
1253 *d->currentPage << "/GState" << gStateObject << "gs\n";
never executed: *d->currentPage << "/GState" << gStateObject << "gs\n";
0
1254 else-
1255 *d->currentPage << "/GSa gs\n";
never executed: *d->currentPage << "/GSa gs\n";
0
1256}-
1257-
1258-
1259bool QPdfEngine::newPage()-
1260{-
1261 Q_D(QPdfEngine);-
1262 if (!isActive())
!isActive()Description
TRUEnever evaluated
FALSEnever evaluated
0
1263 return false;
never executed: return false;
0
1264 d->newPage();-
1265-
1266 setupGraphicsState(DirtyBrush|DirtyPen|DirtyClipPath);-
1267 QFile *outfile = qobject_cast<QFile*> (d->outDevice);-
1268 if (outfile && outfile->error() != QFile::NoError)
outfileDescription
TRUEnever evaluated
FALSEnever evaluated
outfile->error...QFile::NoErrorDescription
TRUEnever evaluated
FALSEnever evaluated
0
1269 return false;
never executed: return false;
0
1270 return true;
never executed: return true;
0
1271}-
1272-
1273QPaintEngine::Type QPdfEngine::type() const-
1274{-
1275 return QPaintEngine::Pdf;
never executed: return QPaintEngine::Pdf;
0
1276}-
1277-
1278void QPdfEngine::setResolution(int resolution)-
1279{-
1280 Q_D(QPdfEngine);-
1281 d->resolution = resolution;-
1282}
never executed: end of block
0
1283-
1284int QPdfEngine::resolution() const-
1285{-
1286 Q_D(const QPdfEngine);-
1287 return d->resolution;
never executed: return d->resolution;
0
1288}-
1289-
1290void QPdfEngine::setPageLayout(const QPageLayout &pageLayout)-
1291{-
1292 Q_D(QPdfEngine);-
1293 d->m_pageLayout = pageLayout;-
1294}
never executed: end of block
0
1295-
1296void QPdfEngine::setPageSize(const QPageSize &pageSize)-
1297{-
1298 Q_D(QPdfEngine);-
1299 d->m_pageLayout.setPageSize(pageSize);-
1300}
never executed: end of block
0
1301-
1302void QPdfEngine::setPageOrientation(QPageLayout::Orientation orientation)-
1303{-
1304 Q_D(QPdfEngine);-
1305 d->m_pageLayout.setOrientation(orientation);-
1306}
never executed: end of block
0
1307-
1308void QPdfEngine::setPageMargins(const QMarginsF &margins, QPageLayout::Unit units)-
1309{-
1310 Q_D(QPdfEngine);-
1311 d->m_pageLayout.setUnits(units);-
1312 d->m_pageLayout.setMargins(margins);-
1313}
never executed: end of block
0
1314-
1315QPageLayout QPdfEngine::pageLayout() const-
1316{-
1317 Q_D(const QPdfEngine);-
1318 return d->m_pageLayout;
never executed: return d->m_pageLayout;
0
1319}-
1320-
1321// Metrics are in Device Pixels-
1322int QPdfEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const-
1323{-
1324 Q_D(const QPdfEngine);-
1325 int val;-
1326 switch (metricType) {-
1327 case QPaintDevice::PdmWidth:
never executed: case QPaintDevice::PdmWidth:
0
1328 val = d->m_pageLayout.paintRectPixels(d->resolution).width();-
1329 break;
never executed: break;
0
1330 case QPaintDevice::PdmHeight:
never executed: case QPaintDevice::PdmHeight:
0
1331 val = d->m_pageLayout.paintRectPixels(d->resolution).height();-
1332 break;
never executed: break;
0
1333 case QPaintDevice::PdmDpiX:
never executed: case QPaintDevice::PdmDpiX:
0
1334 case QPaintDevice::PdmDpiY:
never executed: case QPaintDevice::PdmDpiY:
0
1335 val = d->resolution;-
1336 break;
never executed: break;
0
1337 case QPaintDevice::PdmPhysicalDpiX:
never executed: case QPaintDevice::PdmPhysicalDpiX:
0
1338 case QPaintDevice::PdmPhysicalDpiY:
never executed: case QPaintDevice::PdmPhysicalDpiY:
0
1339 val = 1200;-
1340 break;
never executed: break;
0
1341 case QPaintDevice::PdmWidthMM:
never executed: case QPaintDevice::PdmWidthMM:
0
1342 val = qRound(d->m_pageLayout.paintRect(QPageLayout::Millimeter).width());-
1343 break;
never executed: break;
0
1344 case QPaintDevice::PdmHeightMM:
never executed: case QPaintDevice::PdmHeightMM:
0
1345 val = qRound(d->m_pageLayout.paintRect(QPageLayout::Millimeter).height());-
1346 break;
never executed: break;
0
1347 case QPaintDevice::PdmNumColors:
never executed: case QPaintDevice::PdmNumColors:
0
1348 val = INT_MAX;-
1349 break;
never executed: break;
0
1350 case QPaintDevice::PdmDepth:
never executed: case QPaintDevice::PdmDepth:
0
1351 val = 32;-
1352 break;
never executed: break;
0
1353 case QPaintDevice::PdmDevicePixelRatio:
never executed: case QPaintDevice::PdmDevicePixelRatio:
0
1354 val = 1;-
1355 break;
never executed: break;
0
1356 case QPaintDevice::PdmDevicePixelRatioScaled:
never executed: case QPaintDevice::PdmDevicePixelRatioScaled:
0
1357 val = 1 * QPaintDevice::devicePixelRatioFScale();-
1358 break;
never executed: break;
0
1359 default:
never executed: default:
0
1360 qWarning("QPdfWriter::metric: Invalid metric command");-
1361 return 0;
never executed: return 0;
0
1362 }-
1363 return val;
never executed: return val;
0
1364}-
1365-
1366QPdfEnginePrivate::QPdfEnginePrivate()-
1367 : clipEnabled(false), allClipped(false), hasPen(true), hasBrush(false), simplePen(false),-
1368 outDevice(0), ownsDevice(false),-
1369 embedFonts(true),-
1370 grayscale(false),-
1371 m_pageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(10, 10, 10, 10))-
1372{-
1373 resolution = 1200;-
1374 currentObject = 1;-
1375 currentPage = 0;-
1376 stroker.stream = 0;-
1377-
1378 streampos = 0;-
1379-
1380 stream = new QDataStream;-
1381}
never executed: end of block
0
1382-
1383bool QPdfEngine::begin(QPaintDevice *pdev)-
1384{-
1385 Q_D(QPdfEngine);-
1386 d->pdev = pdev;-
1387-
1388 if (!d->outDevice) {
!d->outDeviceDescription
TRUEnever evaluated
FALSEnever evaluated
0
1389 if (!d->outputFileName.isEmpty()) {
!d->outputFileName.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1390 QFile *file = new QFile(d->outputFileName);-
1391 if (!file->open(QFile::WriteOnly|QFile::Truncate)) {
!file->open(QF...ile::Truncate)Description
TRUEnever evaluated
FALSEnever evaluated
0
1392 delete file;-
1393 return false;
never executed: return false;
0
1394 }-
1395 d->outDevice = file;-
1396 } else {
never executed: end of block
0
1397 return false;
never executed: return false;
0
1398 }-
1399 d->ownsDevice = true;-
1400 }
never executed: end of block
0
1401-
1402 d->currentObject = 1;-
1403-
1404 d->currentPage = new QPdfPage;-
1405 d->stroker.stream = d->currentPage;-
1406 d->opacity = 1.0;-
1407-
1408 d->stream->setDevice(d->outDevice);-
1409-
1410 d->streampos = 0;-
1411 d->hasPen = true;-
1412 d->hasBrush = false;-
1413 d->clipEnabled = false;-
1414 d->allClipped = false;-
1415-
1416 d->xrefPositions.clear();-
1417 d->pageRoot = 0;-
1418 d->catalog = 0;-
1419 d->info = 0;-
1420 d->graphicsState = 0;-
1421 d->patternColorSpace = 0;-
1422 d->simplePen = false;-
1423-
1424 d->pages.clear();-
1425 d->imageCache.clear();-
1426 d->alphaCache.clear();-
1427-
1428 setActive(true);-
1429 d->writeHeader();-
1430 newPage();-
1431-
1432 return true;
never executed: return true;
0
1433}-
1434-
1435bool QPdfEngine::end()-
1436{-
1437 Q_D(QPdfEngine);-
1438 d->writeTail();-
1439-
1440 d->stream->unsetDevice();-
1441-
1442 qDeleteAll(d->fonts);-
1443 d->fonts.clear();-
1444 delete d->currentPage;-
1445 d->currentPage = 0;-
1446-
1447 if (d->outDevice && d->ownsDevice) {
d->outDeviceDescription
TRUEnever evaluated
FALSEnever evaluated
d->ownsDeviceDescription
TRUEnever evaluated
FALSEnever evaluated
0
1448 d->outDevice->close();-
1449 delete d->outDevice;-
1450 d->outDevice = 0;-
1451 }
never executed: end of block
0
1452-
1453 setActive(false);-
1454 return true;
never executed: return true;
0
1455}-
1456-
1457QPdfEnginePrivate::~QPdfEnginePrivate()-
1458{-
1459 qDeleteAll(fonts);-
1460 delete currentPage;-
1461 delete stream;-
1462}
never executed: end of block
0
1463-
1464void QPdfEnginePrivate::writeHeader()-
1465{-
1466 addXrefEntry(0,false);-
1467-
1468 xprintf("%%PDF-1.4\n");-
1469-
1470 writeInfo();-
1471-
1472 catalog = addXrefEntry(-1);-
1473 pageRoot = requestObject();-
1474 xprintf("<<\n"-
1475 "/Type /Catalog\n"-
1476 "/Pages %d 0 R\n"-
1477 ">>\n"-
1478 "endobj\n", pageRoot);-
1479-
1480 // graphics state-
1481 graphicsState = addXrefEntry(-1);-
1482 xprintf("<<\n"-
1483 "/Type /ExtGState\n"-
1484 "/SA true\n"-
1485 "/SM 0.02\n"-
1486 "/ca 1.0\n"-
1487 "/CA 1.0\n"-
1488 "/AIS false\n"-
1489 "/SMask /None"-
1490 ">>\n"-
1491 "endobj\n");-
1492-
1493 // color space for pattern-
1494 patternColorSpace = addXrefEntry(-1);-
1495 xprintf("[/Pattern /DeviceRGB]\n"-
1496 "endobj\n");-
1497}
never executed: end of block
0
1498-
1499void QPdfEnginePrivate::writeInfo()-
1500{-
1501 info = addXrefEntry(-1);-
1502 xprintf("<<\n/Title ");-
1503 printString(title);-
1504 xprintf("\n/Creator ");-
1505 printString(creator);-
1506 xprintf("\n/Producer ");-
1507 printString(QString::fromLatin1("Qt " QT_VERSION_STR));-
1508 QDateTime now = QDateTime::currentDateTimeUtc();-
1509 QTime t = now.time();-
1510 QDate d = now.date();-
1511 xprintf("\n/CreationDate (D:%d%02d%02d%02d%02d%02d)\n",-
1512 d.year(),-
1513 d.month(),-
1514 d.day(),-
1515 t.hour(),-
1516 t.minute(),-
1517 t.second());-
1518 xprintf(">>\n"-
1519 "endobj\n");-
1520}
never executed: end of block
0
1521-
1522void QPdfEnginePrivate::writePageRoot()-
1523{-
1524 addXrefEntry(pageRoot);-
1525-
1526 xprintf("<<\n"-
1527 "/Type /Pages\n"-
1528 "/Kids \n"-
1529 "[\n");-
1530 int size = pages.size();-
1531 for (int i = 0; i < size; ++i)
i < sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1532 xprintf("%d 0 R\n", pages[i]);
never executed: xprintf("%d 0 R\n", pages[i]);
0
1533 xprintf("]\n");-
1534-
1535 //xprintf("/Group <</S /Transparency /I true /K false>>\n");-
1536 xprintf("/Count %d\n", pages.size());-
1537-
1538 xprintf("/ProcSet [/PDF /Text /ImageB /ImageC]\n"-
1539 ">>\n"-
1540 "endobj\n");-
1541}
never executed: end of block
0
1542-
1543-
1544void QPdfEnginePrivate::embedFont(QFontSubset *font)-
1545{-
1546 //qDebug() << "embedFont" << font->object_id;-
1547 int fontObject = font->object_id;-
1548 QByteArray fontData = font->toTruetype();-
1549#ifdef FONT_DUMP-
1550 static int i = 0;-
1551 QString fileName("font%1.ttf");-
1552 fileName = fileName.arg(i++);-
1553 QFile ff(fileName);-
1554 ff.open(QFile::WriteOnly);-
1555 ff.write(fontData);-
1556 ff.close();-
1557#endif-
1558-
1559 int fontDescriptor = requestObject();-
1560 int fontstream = requestObject();-
1561 int cidfont = requestObject();-
1562 int toUnicode = requestObject();-
1563-
1564 QFontEngine::Properties properties = font->fontEngine->properties();-
1565 QByteArray postscriptName = properties.postscriptName.replace(' ', '_');-
1566-
1567 {-
1568 qreal scale = 1000/properties.emSquare.toReal();-
1569 addXrefEntry(fontDescriptor);-
1570 QByteArray descriptor;-
1571 QPdf::ByteStream s(&descriptor);-
1572 s << "<< /Type /FontDescriptor\n"-
1573 "/FontName /Q";-
1574 int tag = fontDescriptor;-
1575 for (int i = 0; i < 5; ++i) {
i < 5Description
TRUEnever evaluated
FALSEnever evaluated
0
1576 s << (char)('A' + (tag % 26));-
1577 tag /= 26;-
1578 }
never executed: end of block
0
1579 s << '+' << postscriptName << "\n"-
1580 "/Flags " << 4 << "\n"-
1581 "/FontBBox ["-
1582 << properties.boundingBox.x()*scale-
1583 << -(properties.boundingBox.y() + properties.boundingBox.height())*scale-
1584 << (properties.boundingBox.x() + properties.boundingBox.width())*scale-
1585 << -properties.boundingBox.y()*scale << "]\n"-
1586 "/ItalicAngle " << properties.italicAngle.toReal() << "\n"-
1587 "/Ascent " << properties.ascent.toReal()*scale << "\n"-
1588 "/Descent " << -properties.descent.toReal()*scale << "\n"-
1589 "/CapHeight " << properties.capHeight.toReal()*scale << "\n"-
1590 "/StemV " << properties.lineWidth.toReal()*scale << "\n"-
1591 "/FontFile2 " << fontstream << "0 R\n"-
1592 ">> endobj\n";-
1593 write(descriptor);-
1594 }-
1595 {-
1596 addXrefEntry(fontstream);-
1597 QByteArray header;-
1598 QPdf::ByteStream s(&header);-
1599-
1600 int length_object = requestObject();-
1601 s << "<<\n"-
1602 "/Length1 " << fontData.size() << "\n"-
1603 "/Length " << length_object << "0 R\n";-
1604 if (do_compress)
do_compressDescription
TRUEnever evaluated
FALSEnever evaluated
0
1605 s << "/Filter /FlateDecode\n";
never executed: s << "/Filter /FlateDecode\n";
0
1606 s << ">>\n"-
1607 "stream\n";-
1608 write(header);-
1609 int len = writeCompressed(fontData);-
1610 write("endstream\n"-
1611 "endobj\n");-
1612 addXrefEntry(length_object);-
1613 xprintf("%d\n"-
1614 "endobj\n", len);-
1615 }-
1616 {-
1617 addXrefEntry(cidfont);-
1618 QByteArray cid;-
1619 QPdf::ByteStream s(&cid);-
1620 s << "<< /Type /Font\n"-
1621 "/Subtype /CIDFontType2\n"-
1622 "/BaseFont /" << postscriptName << "\n"-
1623 "/CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >>\n"-
1624 "/FontDescriptor " << fontDescriptor << "0 R\n"-
1625 "/CIDToGIDMap /Identity\n"-
1626 << font->widthArray() <<-
1627 ">>\n"-
1628 "endobj\n";-
1629 write(cid);-
1630 }-
1631 {-
1632 addXrefEntry(toUnicode);-
1633 QByteArray touc = font->createToUnicodeMap();-
1634 xprintf("<< /Length %d >>\n"-
1635 "stream\n", touc.length());-
1636 write(touc);-
1637 write("endstream\n"-
1638 "endobj\n");-
1639 }-
1640 {-
1641 addXrefEntry(fontObject);-
1642 QByteArray font;-
1643 QPdf::ByteStream s(&font);-
1644 s << "<< /Type /Font\n"-
1645 "/Subtype /Type0\n"-
1646 "/BaseFont /" << postscriptName << "\n"-
1647 "/Encoding /Identity-H\n"-
1648 "/DescendantFonts [" << cidfont << "0 R]\n"-
1649 "/ToUnicode " << toUnicode << "0 R"-
1650 ">>\n"-
1651 "endobj\n";-
1652 write(font);-
1653 }-
1654}
never executed: end of block
0
1655-
1656-
1657void QPdfEnginePrivate::writeFonts()-
1658{-
1659 for (QHash<QFontEngine::FaceId, QFontSubset *>::iterator it = fonts.begin(); it != fonts.end(); ++it) {
it != fonts.end()Description
TRUEnever evaluated
FALSEnever evaluated
0
1660 embedFont(*it);-
1661 delete *it;-
1662 }
never executed: end of block
0
1663 fonts.clear();-
1664}
never executed: end of block
0
1665-
1666void QPdfEnginePrivate::writePage()-
1667{-
1668 if (pages.empty())
pages.empty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1669 return;
never executed: return;
0
1670-
1671 *currentPage << "Q Q\n";-
1672-
1673 uint pageStream = requestObject();-
1674 uint pageStreamLength = requestObject();-
1675 uint resources = requestObject();-
1676 uint annots = requestObject();-
1677-
1678 addXrefEntry(pages.constLast());-
1679 xprintf("<<\n"-
1680 "/Type /Page\n"-
1681 "/Parent %d 0 R\n"-
1682 "/Contents %d 0 R\n"-
1683 "/Resources %d 0 R\n"-
1684 "/Annots %d 0 R\n"-
1685 "/MediaBox [0 0 %d %d]\n"-
1686 ">>\n"-
1687 "endobj\n",-
1688 pageRoot, pageStream, resources, annots,-
1689 // make sure we use the pagesize from when we started the page, since the user may have changed it-
1690 currentPage->pageSize.width(), currentPage->pageSize.height());-
1691-
1692 addXrefEntry(resources);-
1693 xprintf("<<\n"-
1694 "/ColorSpace <<\n"-
1695 "/PCSp %d 0 R\n"-
1696 "/CSp /DeviceRGB\n"-
1697 "/CSpg /DeviceGray\n"-
1698 ">>\n"-
1699 "/ExtGState <<\n"-
1700 "/GSa %d 0 R\n",-
1701 patternColorSpace, graphicsState);-
1702-
1703 for (int i = 0; i < currentPage->graphicStates.size(); ++i)
i < currentPag...cStates.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1704 xprintf("/GState%d %d 0 R\n", currentPage->graphicStates.at(i), currentPage->graphicStates.at(i));
never executed: xprintf("/GState%d %d 0 R\n", currentPage->graphicStates.at(i), currentPage->graphicStates.at(i));
0
1705 xprintf(">>\n");-
1706-
1707 xprintf("/Pattern <<\n");-
1708 for (int i = 0; i < currentPage->patterns.size(); ++i)
i < currentPag...atterns.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1709 xprintf("/Pat%d %d 0 R\n", currentPage->patterns.at(i), currentPage->patterns.at(i));
never executed: xprintf("/Pat%d %d 0 R\n", currentPage->patterns.at(i), currentPage->patterns.at(i));
0
1710 xprintf(">>\n");-
1711-
1712 xprintf("/Font <<\n");-
1713 for (int i = 0; i < currentPage->fonts.size();++i)
i < currentPage->fonts.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1714 xprintf("/F%d %d 0 R\n", currentPage->fonts[i], currentPage->fonts[i]);
never executed: xprintf("/F%d %d 0 R\n", currentPage->fonts[i], currentPage->fonts[i]);
0
1715 xprintf(">>\n");-
1716-
1717 xprintf("/XObject <<\n");-
1718 for (int i = 0; i<currentPage->images.size(); ++i) {
i<currentPage->images.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1719 xprintf("/Im%d %d 0 R\n", currentPage->images.at(i), currentPage->images.at(i));-
1720 }
never executed: end of block
0
1721 xprintf(">>\n");-
1722-
1723 xprintf(">>\n"-
1724 "endobj\n");-
1725-
1726 addXrefEntry(annots);-
1727 xprintf("[ ");-
1728 for (int i = 0; i<currentPage->annotations.size(); ++i) {
i<currentPage-...tations.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1729 xprintf("%d 0 R ", currentPage->annotations.at(i));-
1730 }
never executed: end of block
0
1731 xprintf("]\nendobj\n");-
1732-
1733 addXrefEntry(pageStream);-
1734 xprintf("<<\n"-
1735 "/Length %d 0 R\n", pageStreamLength); // object number for stream length object-
1736 if (do_compress)
do_compressDescription
TRUEnever evaluated
FALSEnever evaluated
0
1737 xprintf("/Filter /FlateDecode\n");
never executed: xprintf("/Filter /FlateDecode\n");
0
1738-
1739 xprintf(">>\n");-
1740 xprintf("stream\n");-
1741 QIODevice *content = currentPage->stream();-
1742 int len = writeCompressed(content);-
1743 xprintf("endstream\n"-
1744 "endobj\n");-
1745-
1746 addXrefEntry(pageStreamLength);-
1747 xprintf("%d\nendobj\n",len);-
1748}
never executed: end of block
0
1749-
1750void QPdfEnginePrivate::writeTail()-
1751{-
1752 writePage();-
1753 writeFonts();-
1754 writePageRoot();-
1755 addXrefEntry(xrefPositions.size(),false);-
1756 xprintf("xref\n"-
1757 "0 %d\n"-
1758 "%010d 65535 f \n", xrefPositions.size()-1, xrefPositions[0]);-
1759-
1760 for (int i = 1; i < xrefPositions.size()-1; ++i)
i < xrefPositions.size()-1Description
TRUEnever evaluated
FALSEnever evaluated
0
1761 xprintf("%010d 00000 n \n", xrefPositions[i]);
never executed: xprintf("%010d 00000 n \n", xrefPositions[i]);
0
1762-
1763 xprintf("trailer\n"-
1764 "<<\n"-
1765 "/Size %d\n"-
1766 "/Info %d 0 R\n"-
1767 "/Root %d 0 R\n"-
1768 ">>\n"-
1769 "startxref\n%d\n"-
1770 "%%%%EOF\n",-
1771 xrefPositions.size()-1, info, catalog, xrefPositions.constLast());-
1772}
never executed: end of block
0
1773-
1774int QPdfEnginePrivate::addXrefEntry(int object, bool printostr)-
1775{-
1776 if (object < 0)
object < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1777 object = requestObject();
never executed: object = requestObject();
0
1778-
1779 if (object>=xrefPositions.size())
object>=xrefPositions.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1780 xrefPositions.resize(object+1);
never executed: xrefPositions.resize(object+1);
0
1781-
1782 xrefPositions[object] = streampos;-
1783 if (printostr)
printostrDescription
TRUEnever evaluated
FALSEnever evaluated
0
1784 xprintf("%d 0 obj\n",object);
never executed: xprintf("%d 0 obj\n",object);
0
1785-
1786 return object;
never executed: return object;
0
1787}-
1788-
1789void QPdfEnginePrivate::printString(const QString &string) {-
1790 // The 'text string' type in PDF is encoded either as PDFDocEncoding, or-
1791 // Unicode UTF-16 with a Unicode byte order mark as the first character-
1792 // (0xfeff), with the high-order byte first.-
1793 QByteArray array("(\xfe\xff");-
1794 const ushort *utf16 = string.utf16();-
1795-
1796 for (int i=0; i < string.size(); ++i) {
i < string.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1797 char part[2] = {char((*(utf16 + i)) >> 8), char((*(utf16 + i)) & 0xff)};-
1798 for(int j=0; j < 2; ++j) {
j < 2Description
TRUEnever evaluated
FALSEnever evaluated
0
1799 if (part[j] == '(' || part[j] == ')' || part[j] == '\\')
part[j] == '('Description
TRUEnever evaluated
FALSEnever evaluated
part[j] == ')'Description
TRUEnever evaluated
FALSEnever evaluated
part[j] == '\\'Description
TRUEnever evaluated
FALSEnever evaluated
0
1800 array.append('\\');
never executed: array.append('\\');
0
1801 array.append(part[j]);-
1802 }
never executed: end of block
0
1803 }
never executed: end of block
0
1804 array.append(')');-
1805 write(array);-
1806}
never executed: end of block
0
1807-
1808-
1809// For strings up to 10000 bytes only !-
1810void QPdfEnginePrivate::xprintf(const char* fmt, ...)-
1811{-
1812 if (!stream)
!streamDescription
TRUEnever evaluated
FALSEnever evaluated
0
1813 return;
never executed: return;
0
1814-
1815 const int msize = 10000;-
1816 char buf[msize];-
1817-
1818 va_list args;-
1819 va_start(args, fmt);-
1820 int bufsize = qvsnprintf(buf, msize, fmt, args);-
1821-
1822 Q_ASSERT(bufsize<msize);-
1823-
1824 va_end(args);-
1825-
1826 stream->writeRawData(buf, bufsize);-
1827 streampos += bufsize;-
1828}
never executed: end of block
0
1829-
1830int QPdfEnginePrivate::writeCompressed(QIODevice *dev)-
1831{-
1832#ifndef QT_NO_COMPRESS-
1833 if (do_compress) {
do_compressDescription
TRUEnever evaluated
FALSEnever evaluated
0
1834 int size = QPdfPage::chunkSize();-
1835 int sum = 0;-
1836 ::z_stream zStruct;-
1837 zStruct.zalloc = Z_NULL;-
1838 zStruct.zfree = Z_NULL;-
1839 zStruct.opaque = Z_NULL;-
1840 if (::deflateInit(&zStruct, Z_DEFAULT_COMPRESSION) != Z_OK) {
::deflateInit_..._stream)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1841 qWarning("QPdfStream::writeCompressed: Error in deflateInit()");-
1842 return sum;
never executed: return sum;
0
1843 }-
1844 zStruct.avail_in = 0;-
1845 QByteArray in, out;-
1846 out.resize(size);-
1847 while (!dev->atEnd() || zStruct.avail_in != 0) {
!dev->atEnd()Description
TRUEnever evaluated
FALSEnever evaluated
zStruct.avail_in != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1848 if (zStruct.avail_in == 0) {
zStruct.avail_in == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1849 in = dev->read(size);-
1850 zStruct.avail_in = in.size();-
1851 zStruct.next_in = reinterpret_cast<unsigned char*>(in.data());-
1852 if (in.size() <= 0) {
in.size() <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1853 qWarning("QPdfStream::writeCompressed: Error in read()");-
1854 ::deflateEnd(&zStruct);-
1855 return sum;
never executed: return sum;
0
1856 }-
1857 }
never executed: end of block
0
1858 zStruct.next_out = reinterpret_cast<unsigned char*>(out.data());-
1859 zStruct.avail_out = out.size();-
1860 if (::deflate(&zStruct, 0) != Z_OK) {
::deflate(&zStruct, 0) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1861 qWarning("QPdfStream::writeCompressed: Error in deflate()");-
1862 ::deflateEnd(&zStruct);-
1863 return sum;
never executed: return sum;
0
1864 }-
1865 int written = out.size() - zStruct.avail_out;-
1866 stream->writeRawData(out.constData(), written);-
1867 streampos += written;-
1868 sum += written;-
1869 }
never executed: end of block
0
1870 int ret;-
1871 do {-
1872 zStruct.next_out = reinterpret_cast<unsigned char*>(out.data());-
1873 zStruct.avail_out = out.size();-
1874 ret = ::deflate(&zStruct, Z_FINISH);-
1875 if (ret != Z_OK && ret != Z_STREAM_END) {
ret != 0Description
TRUEnever evaluated
FALSEnever evaluated
ret != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1876 qWarning("QPdfStream::writeCompressed: Error in deflate()");-
1877 ::deflateEnd(&zStruct);-
1878 return sum;
never executed: return sum;
0
1879 }-
1880 int written = out.size() - zStruct.avail_out;-
1881 stream->writeRawData(out.constData(), written);-
1882 streampos += written;-
1883 sum += written;-
1884 } while (ret == Z_OK);
never executed: end of block
ret == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1885-
1886 ::deflateEnd(&zStruct);-
1887-
1888 return sum;
never executed: return sum;
0
1889 } else-
1890#endif-
1891 {-
1892 QByteArray arr;-
1893 int sum = 0;-
1894 while (!dev->atEnd()) {
!dev->atEnd()Description
TRUEnever evaluated
FALSEnever evaluated
0
1895 arr = dev->read(QPdfPage::chunkSize());-
1896 stream->writeRawData(arr.constData(), arr.size());-
1897 streampos += arr.size();-
1898 sum += arr.size();-
1899 }
never executed: end of block
0
1900 return sum;
never executed: return sum;
0
1901 }-
1902}-
1903-
1904int QPdfEnginePrivate::writeCompressed(const char *src, int len)-
1905{-
1906#ifndef QT_NO_COMPRESS-
1907 if(do_compress) {
do_compressDescription
TRUEnever evaluated
FALSEnever evaluated
0
1908 uLongf destLen = len + len/100 + 13; // zlib requirement-
1909 Bytef* dest = new Bytef[destLen];-
1910 if (Z_OK == ::compress(dest, &destLen, (const Bytef*) src, (uLongf)len)) {
0 == ::compres..., (uLongf)len)Description
TRUEnever evaluated
FALSEnever evaluated
0
1911 stream->writeRawData((const char*)dest, destLen);-
1912 } else {
never executed: end of block
0
1913 qWarning("QPdfStream::writeCompressed: Error in compress()");-
1914 destLen = 0;-
1915 }
never executed: end of block
0
1916 delete [] dest;-
1917 len = destLen;-
1918 } else
never executed: end of block
0
1919#endif-
1920 {-
1921 stream->writeRawData(src,len);-
1922 }
never executed: end of block
0
1923 streampos += len;-
1924 return len;
never executed: return len;
0
1925}-
1926-
1927int QPdfEnginePrivate::writeImage(const QByteArray &data, int width, int height, int depth,-
1928 int maskObject, int softMaskObject, bool dct, bool isMono)-
1929{-
1930 int image = addXrefEntry(-1);-
1931 xprintf("<<\n"-
1932 "/Type /XObject\n"-
1933 "/Subtype /Image\n"-
1934 "/Width %d\n"-
1935 "/Height %d\n", width, height);-
1936-
1937 if (depth == 1) {
depth == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1938 if (!isMono) {
!isMonoDescription
TRUEnever evaluated
FALSEnever evaluated
0
1939 xprintf("/ImageMask true\n"-
1940 "/Decode [1 0]\n");-
1941 } else {
never executed: end of block
0
1942 xprintf("/BitsPerComponent 1\n"-
1943 "/ColorSpace /DeviceGray\n");-
1944 }
never executed: end of block
0
1945 } else {-
1946 xprintf("/BitsPerComponent 8\n"-
1947 "/ColorSpace %s\n", (depth == 32) ? "/DeviceRGB" : "/DeviceGray");-
1948 }
never executed: end of block
0
1949 if (maskObject > 0)
maskObject > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1950 xprintf("/Mask %d 0 R\n", maskObject);
never executed: xprintf("/Mask %d 0 R\n", maskObject);
0
1951 if (softMaskObject > 0)
softMaskObject > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1952 xprintf("/SMask %d 0 R\n", softMaskObject);
never executed: xprintf("/SMask %d 0 R\n", softMaskObject);
0
1953-
1954 int lenobj = requestObject();-
1955 xprintf("/Length %d 0 R\n", lenobj);-
1956 if (interpolateImages)
interpolateImagesDescription
TRUEnever evaluated
FALSEnever evaluated
0
1957 xprintf("/Interpolate true\n");
never executed: xprintf("/Interpolate true\n");
0
1958 int len = 0;-
1959 if (dct) {
dctDescription
TRUEnever evaluated
FALSEnever evaluated
0
1960 //qDebug("DCT");-
1961 xprintf("/Filter /DCTDecode\n>>\nstream\n");-
1962 write(data);-
1963 len = data.length();-
1964 } else {
never executed: end of block
0
1965 if (do_compress)
do_compressDescription
TRUEnever evaluated
FALSEnever evaluated
0
1966 xprintf("/Filter /FlateDecode\n>>\nstream\n");
never executed: xprintf("/Filter /FlateDecode\n>>\nstream\n");
0
1967 else-
1968 xprintf(">>\nstream\n");
never executed: xprintf(">>\nstream\n");
0
1969 len = writeCompressed(data);-
1970 }
never executed: end of block
0
1971 xprintf("endstream\n"-
1972 "endobj\n");-
1973 addXrefEntry(lenobj);-
1974 xprintf("%d\n"-
1975 "endobj\n", len);-
1976 return image;
never executed: return image;
0
1977}-
1978-
1979struct QGradientBound {-
1980 qreal start;-
1981 qreal stop;-
1982 int function;-
1983 bool reverse;-
1984};-
1985Q_DECLARE_TYPEINFO(QGradientBound, Q_PRIMITIVE_TYPE);-
1986-
1987int QPdfEnginePrivate::createShadingFunction(const QGradient *gradient, int from, int to, bool reflect, bool alpha)-
1988{-
1989 QGradientStops stops = gradient->stops();-
1990 if (stops.isEmpty()) {
stops.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1991 stops << QGradientStop(0, Qt::black);-
1992 stops << QGradientStop(1, Qt::white);-
1993 }
never executed: end of block
0
1994 if (stops.at(0).first > 0)
stops.at(0).first > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1995 stops.prepend(QGradientStop(0, stops.at(0).second));
never executed: stops.prepend(QGradientStop(0, stops.at(0).second));
0
1996 if (stops.at(stops.size() - 1).first < 1)
stops.at(stops...- 1).first < 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1997 stops.append(QGradientStop(1, stops.at(stops.size() - 1).second));
never executed: stops.append(QGradientStop(1, stops.at(stops.size() - 1).second));
0
1998-
1999 QVector<int> functions;-
2000 const int numStops = stops.size();-
2001 functions.reserve(numStops - 1);-
2002 for (int i = 0; i < numStops - 1; ++i) {
i < numStops - 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2003 int f = addXrefEntry(-1);-
2004 QByteArray data;-
2005 QPdf::ByteStream s(&data);-
2006 s << "<<\n"-
2007 "/FunctionType 2\n"-
2008 "/Domain [0 1]\n"-
2009 "/N 1\n";-
2010 if (alpha) {
alphaDescription
TRUEnever evaluated
FALSEnever evaluated
0
2011 s << "/C0 [" << stops.at(i).second.alphaF() << "]\n"-
2012 "/C1 [" << stops.at(i + 1).second.alphaF() << "]\n";-
2013 } else {
never executed: end of block
0
2014 s << "/C0 [" << stops.at(i).second.redF() << stops.at(i).second.greenF() << stops.at(i).second.blueF() << "]\n"-
2015 "/C1 [" << stops.at(i + 1).second.redF() << stops.at(i + 1).second.greenF() << stops.at(i + 1).second.blueF() << "]\n";-
2016 }
never executed: end of block
0
2017 s << ">>\n"-
2018 "endobj\n";-
2019 write(data);-
2020 functions << f;-
2021 }
never executed: end of block
0
2022-
2023 QVector<QGradientBound> gradientBounds;-
2024 gradientBounds.reserve((to - from) * (numStops - 1));-
2025-
2026 for (int step = from; step < to; ++step) {
step < toDescription
TRUEnever evaluated
FALSEnever evaluated
0
2027 if (reflect && step % 2) {
reflectDescription
TRUEnever evaluated
FALSEnever evaluated
step % 2Description
TRUEnever evaluated
FALSEnever evaluated
0
2028 for (int i = numStops - 1; i > 0; --i) {
i > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2029 QGradientBound b;-
2030 b.start = step + 1 - qBound(qreal(0.), stops.at(i).first, qreal(1.));-
2031 b.stop = step + 1 - qBound(qreal(0.), stops.at(i - 1).first, qreal(1.));-
2032 b.function = functions.at(i - 1);-
2033 b.reverse = true;-
2034 gradientBounds << b;-
2035 }
never executed: end of block
0
2036 } else {
never executed: end of block
0
2037 for (int i = 0; i < numStops - 1; ++i) {
i < numStops - 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2038 QGradientBound b;-
2039 b.start = step + qBound(qreal(0.), stops.at(i).first, qreal(1.));-
2040 b.stop = step + qBound(qreal(0.), stops.at(i + 1).first, qreal(1.));-
2041 b.function = functions.at(i);-
2042 b.reverse = false;-
2043 gradientBounds << b;-
2044 }
never executed: end of block
0
2045 }
never executed: end of block
0
2046 }-
2047-
2048 // normalize bounds to [0..1]-
2049 qreal bstart = gradientBounds.at(0).start;-
2050 qreal bend = gradientBounds.at(gradientBounds.size() - 1).stop;-
2051 qreal norm = 1./(bend - bstart);-
2052 for (int i = 0; i < gradientBounds.size(); ++i) {
i < gradientBounds.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
2053 gradientBounds[i].start = (gradientBounds[i].start - bstart)*norm;-
2054 gradientBounds[i].stop = (gradientBounds[i].stop - bstart)*norm;-
2055 }
never executed: end of block
0
2056-
2057 int function;-
2058 if (gradientBounds.size() > 1) {
gradientBounds.size() > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2059 function = addXrefEntry(-1);-
2060 QByteArray data;-
2061 QPdf::ByteStream s(&data);-
2062 s << "<<\n"-
2063 "/FunctionType 3\n"-
2064 "/Domain [0 1]\n"-
2065 "/Bounds [";-
2066 for (int i = 1; i < gradientBounds.size(); ++i)
i < gradientBounds.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
2067 s << gradientBounds.at(i).start;
never executed: s << gradientBounds.at(i).start;
0
2068 s << "]\n"-
2069 "/Encode [";-
2070 for (int i = 0; i < gradientBounds.size(); ++i)
i < gradientBounds.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
2071 s << (gradientBounds.at(i).reverse ? "1 0 " : "0 1 ");
never executed: s << (gradientBounds.at(i).reverse ? "1 0 " : "0 1 ");
0
2072 s << "]\n"-
2073 "/Functions [";-
2074 for (int i = 0; i < gradientBounds.size(); ++i)
i < gradientBounds.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
2075 s << gradientBounds.at(i).function << "0 R ";
never executed: s << gradientBounds.at(i).function << "0 R ";
0
2076 s << "]\n"-
2077 ">>\n";-
2078 write(data);-
2079 } else {
never executed: end of block
0
2080 function = functions.at(0);-
2081 }
never executed: end of block
0
2082 return function;
never executed: return function;
0
2083}-
2084-
2085int QPdfEnginePrivate::generateLinearGradientShader(const QLinearGradient *gradient, const QTransform &matrix, bool alpha)-
2086{-
2087 QPointF start = gradient->start();-
2088 QPointF stop = gradient->finalStop();-
2089 QPointF offset = stop - start;-
2090 Q_ASSERT(gradient->coordinateMode() == QGradient::LogicalMode);-
2091-
2092 int from = 0;-
2093 int to = 1;-
2094 bool reflect = false;-
2095 switch (gradient->spread()) {-
2096 case QGradient::PadSpread:
never executed: case QGradient::PadSpread:
0
2097 break;
never executed: break;
0
2098 case QGradient::ReflectSpread:
never executed: case QGradient::ReflectSpread:
0
2099 reflect = true;-
2100 // fall through-
2101 case QGradient::RepeatSpread: {
code before this statement never executed: case QGradient::RepeatSpread:
never executed: case QGradient::RepeatSpread:
0
2102 // calculate required bounds-
2103 QRectF pageRect = m_pageLayout.fullRectPixels(resolution);-
2104 QTransform inv = matrix.inverted();-
2105 QPointF page_rect[4] = { inv.map(pageRect.topLeft()),-
2106 inv.map(pageRect.topRight()),-
2107 inv.map(pageRect.bottomLeft()),-
2108 inv.map(pageRect.bottomRight()) };-
2109-
2110 qreal length = offset.x()*offset.x() + offset.y()*offset.y();-
2111-
2112 // find the max and min values in offset and orth direction that are needed to cover-
2113 // the whole page-
2114 from = INT_MAX;-
2115 to = INT_MIN;-
2116 for (int i = 0; i < 4; ++i) {
i < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
2117 qreal off = ((page_rect[i].x() - start.x()) * offset.x() + (page_rect[i].y() - start.y()) * offset.y())/length;-
2118 from = qMin(from, qFloor(off));-
2119 to = qMax(to, qCeil(off));-
2120 }
never executed: end of block
0
2121-
2122 stop = start + to * offset;-
2123 start = start + from * offset;\-
2124 break;
never executed: break;
0
2125 }-
2126 }-
2127-
2128 int function = createShadingFunction(gradient, from, to, reflect, alpha);-
2129-
2130 QByteArray shader;-
2131 QPdf::ByteStream s(&shader);-
2132 s << "<<\n"-
2133 "/ShadingType 2\n"-
2134 "/ColorSpace " << (alpha ? "/DeviceGray\n" : "/DeviceRGB\n") <<-
2135 "/AntiAlias true\n"-
2136 "/Coords [" << start.x() << start.y() << stop.x() << stop.y() << "]\n"-
2137 "/Extend [true true]\n"-
2138 "/Function " << function << "0 R\n"-
2139 ">>\n"-
2140 "endobj\n";-
2141 int shaderObject = addXrefEntry(-1);-
2142 write(shader);-
2143 return shaderObject;
never executed: return shaderObject;
0
2144}-
2145-
2146int QPdfEnginePrivate::generateRadialGradientShader(const QRadialGradient *gradient, const QTransform &matrix, bool alpha)-
2147{-
2148 QPointF p1 = gradient->center();-
2149 qreal r1 = gradient->centerRadius();-
2150 QPointF p0 = gradient->focalPoint();-
2151 qreal r0 = gradient->focalRadius();-
2152-
2153 Q_ASSERT(gradient->coordinateMode() == QGradient::LogicalMode);-
2154-
2155 int from = 0;-
2156 int to = 1;-
2157 bool reflect = false;-
2158 switch (gradient->spread()) {-
2159 case QGradient::PadSpread:
never executed: case QGradient::PadSpread:
0
2160 break;
never executed: break;
0
2161 case QGradient::ReflectSpread:
never executed: case QGradient::ReflectSpread:
0
2162 reflect = true;-
2163 // fall through-
2164 case QGradient::RepeatSpread: {
code before this statement never executed: case QGradient::RepeatSpread:
never executed: case QGradient::RepeatSpread:
0
2165 Q_ASSERT(qFuzzyIsNull(r0)); // QPainter emulates if this is not 0-
2166-
2167 QRectF pageRect = m_pageLayout.fullRectPixels(resolution);-
2168 QTransform inv = matrix.inverted();-
2169 QPointF page_rect[4] = { inv.map(pageRect.topLeft()),-
2170 inv.map(pageRect.topRight()),-
2171 inv.map(pageRect.bottomLeft()),-
2172 inv.map(pageRect.bottomRight()) };-
2173-
2174 // increase to until the whole page fits into it-
2175 bool done = false;-
2176 while (!done) {
!doneDescription
TRUEnever evaluated
FALSEnever evaluated
0
2177 QPointF center = QPointF(p0.x() + to*(p1.x() - p0.x()), p0.y() + to*(p1.y() - p0.y()));-
2178 double radius = r0 + to*(r1 - r0);-
2179 double r2 = radius*radius;-
2180 done = true;-
2181 for (int i = 0; i < 4; ++i) {
i < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
2182 QPointF off = page_rect[i] - center;-
2183 if (off.x()*off.x() + off.y()*off.y() > r2) {
off.x()*off.x(...)*off.y() > r2Description
TRUEnever evaluated
FALSEnever evaluated
0
2184 ++to;-
2185 done = false;-
2186 break;
never executed: break;
0
2187 }-
2188 }
never executed: end of block
0
2189 }
never executed: end of block
0
2190 p1 = QPointF(p0.x() + to*(p1.x() - p0.x()), p0.y() + to*(p1.y() - p0.y()));-
2191 r1 = r0 + to*(r1 - r0);-
2192 break;
never executed: break;
0
2193 }-
2194 }-
2195-
2196 int function = createShadingFunction(gradient, from, to, reflect, alpha);-
2197-
2198 QByteArray shader;-
2199 QPdf::ByteStream s(&shader);-
2200 s << "<<\n"-
2201 "/ShadingType 3\n"-
2202 "/ColorSpace " << (alpha ? "/DeviceGray\n" : "/DeviceRGB\n") <<-
2203 "/AntiAlias true\n"-
2204 "/Domain [0 1]\n"-
2205 "/Coords [" << p0.x() << p0.y() << r0 << p1.x() << p1.y() << r1 << "]\n"-
2206 "/Extend [true true]\n"-
2207 "/Function " << function << "0 R\n"-
2208 ">>\n"-
2209 "endobj\n";-
2210 int shaderObject = addXrefEntry(-1);-
2211 write(shader);-
2212 return shaderObject;
never executed: return shaderObject;
0
2213}-
2214-
2215int QPdfEnginePrivate::generateGradientShader(const QGradient *gradient, const QTransform &matrix, bool alpha)-
2216{-
2217 switch (gradient->type()) {-
2218 case QGradient::LinearGradient:
never executed: case QGradient::LinearGradient:
0
2219 return generateLinearGradientShader(static_cast<const QLinearGradient *>(gradient), matrix, alpha);
never executed: return generateLinearGradientShader(static_cast<const QLinearGradient *>(gradient), matrix, alpha);
0
2220 case QGradient::RadialGradient:
never executed: case QGradient::RadialGradient:
0
2221 return generateRadialGradientShader(static_cast<const QRadialGradient *>(gradient), matrix, alpha);
never executed: return generateRadialGradientShader(static_cast<const QRadialGradient *>(gradient), matrix, alpha);
0
2222 case QGradient::ConicalGradient:
never executed: case QGradient::ConicalGradient:
0
2223 Q_UNIMPLEMENTED(); // ### Implement me!-
2224 break;
never executed: break;
0
2225 case QGradient::NoGradient:
never executed: case QGradient::NoGradient:
0
2226 break;
never executed: break;
0
2227 }-
2228 return 0;
never executed: return 0;
0
2229}-
2230-
2231int QPdfEnginePrivate::gradientBrush(const QBrush &b, const QTransform &matrix, int *gStateObject)-
2232{-
2233 const QGradient *gradient = b.gradient();-
2234-
2235 if (!gradient || gradient->coordinateMode() != QGradient::LogicalMode)
!gradientDescription
TRUEnever evaluated
FALSEnever evaluated
gradient->coor...t::LogicalModeDescription
TRUEnever evaluated
FALSEnever evaluated
0
2236 return 0;
never executed: return 0;
0
2237-
2238 QRectF pageRect = m_pageLayout.fullRectPixels(resolution);-
2239-
2240 QTransform m = b.transform() * matrix;-
2241 int shaderObject = generateGradientShader(gradient, m);-
2242-
2243 QByteArray str;-
2244 QPdf::ByteStream s(&str);-
2245 s << "<<\n"-
2246 "/Type /Pattern\n"-
2247 "/PatternType 2\n"-
2248 "/Shading " << shaderObject << "0 R\n"-
2249 "/Matrix ["-
2250 << m.m11()-
2251 << m.m12()-
2252 << m.m21()-
2253 << m.m22()-
2254 << m.dx()-
2255 << m.dy() << "]\n";-
2256 s << ">>\n"-
2257 "endobj\n";-
2258-
2259 int patternObj = addXrefEntry(-1);-
2260 write(str);-
2261 currentPage->patterns.append(patternObj);-
2262-
2263 if (!b.isOpaque()) {
!b.isOpaque()Description
TRUEnever evaluated
FALSEnever evaluated
0
2264 bool ca = true;-
2265 QGradientStops stops = gradient->stops();-
2266 int a = stops.at(0).second.alpha();-
2267 for (int i = 1; i < stops.size(); ++i) {
i < stops.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
2268 if (stops.at(i).second.alpha() != a) {
stops.at(i).se...d.alpha() != aDescription
TRUEnever evaluated
FALSEnever evaluated
0
2269 ca = false;-
2270 break;
never executed: break;
0
2271 }-
2272 }
never executed: end of block
0
2273 if (ca) {
caDescription
TRUEnever evaluated
FALSEnever evaluated
0
2274 *gStateObject = addConstantAlphaObject(stops.at(0).second.alpha());-
2275 } else {
never executed: end of block
0
2276 int alphaShaderObject = generateGradientShader(gradient, m, true);-
2277-
2278 QByteArray content;-
2279 QPdf::ByteStream c(&content);-
2280 c << "/Shader" << alphaShaderObject << "sh\n";-
2281-
2282 QByteArray form;-
2283 QPdf::ByteStream f(&form);-
2284 f << "<<\n"-
2285 "/Type /XObject\n"-
2286 "/Subtype /Form\n"-
2287 "/BBox [0 0 " << pageRect.width() << pageRect.height() << "]\n"-
2288 "/Group <</S /Transparency >>\n"-
2289 "/Resources <<\n"-
2290 "/Shading << /Shader" << alphaShaderObject << alphaShaderObject << "0 R >>\n"-
2291 ">>\n";-
2292-
2293 f << "/Length " << content.length() << "\n"-
2294 ">>\n"-
2295 "stream\n"-
2296 << content-
2297 << "endstream\n"-
2298 "endobj\n";-
2299-
2300 int softMaskFormObject = addXrefEntry(-1);-
2301 write(form);-
2302 *gStateObject = addXrefEntry(-1);-
2303 xprintf("<< /SMask << /S /Alpha /G %d 0 R >> >>\n"-
2304 "endobj\n", softMaskFormObject);-
2305 currentPage->graphicStates.append(*gStateObject);-
2306 }
never executed: end of block
0
2307 }-
2308-
2309 return patternObj;
never executed: return patternObj;
0
2310}-
2311-
2312int QPdfEnginePrivate::addConstantAlphaObject(int brushAlpha, int penAlpha)-
2313{-
2314 if (brushAlpha == 255 && penAlpha == 255)
brushAlpha == 255Description
TRUEnever evaluated
FALSEnever evaluated
penAlpha == 255Description
TRUEnever evaluated
FALSEnever evaluated
0
2315 return 0;
never executed: return 0;
0
2316 int object = alphaCache.value(QPair<uint, uint>(brushAlpha, penAlpha), 0);-
2317 if (!object) {
!objectDescription
TRUEnever evaluated
FALSEnever evaluated
0
2318 object = addXrefEntry(-1);-
2319 QByteArray alphaDef;-
2320 QPdf::ByteStream s(&alphaDef);-
2321 s << "<<\n/ca " << (brushAlpha/qreal(255.)) << '\n';-
2322 s << "/CA " << (penAlpha/qreal(255.)) << "\n>>";-
2323 xprintf("%s\nendobj\n", alphaDef.constData());-
2324 alphaCache.insert(QPair<uint, uint>(brushAlpha, penAlpha), object);-
2325 }
never executed: end of block
0
2326 if (currentPage->graphicStates.indexOf(object) < 0)
currentPage->g...Of(object) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2327 currentPage->graphicStates.append(object);
never executed: currentPage->graphicStates.append(object);
0
2328-
2329 return object;
never executed: return object;
0
2330}-
2331-
2332-
2333int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor, int *gStateObject)-
2334{-
2335 int paintType = 2; // Uncolored tiling-
2336 int w = 8;-
2337 int h = 8;-
2338-
2339 *specifyColor = true;-
2340 *gStateObject = 0;-
2341-
2342 QTransform matrix = m;-
2343 matrix.translate(brushOrigin.x(), brushOrigin.y());-
2344 matrix = matrix * pageMatrix();-
2345 //qDebug() << brushOrigin << matrix;-
2346-
2347 Qt::BrushStyle style = brush.style();-
2348 if (style == Qt::LinearGradientPattern || style == Qt::RadialGradientPattern) {// && style <= Qt::ConicalGradientPattern) {
style == Qt::L...radientPatternDescription
TRUEnever evaluated
FALSEnever evaluated
style == Qt::R...radientPatternDescription
TRUEnever evaluated
FALSEnever evaluated
0
2349 *specifyColor = false;-
2350 return gradientBrush(brush, matrix, gStateObject);
never executed: return gradientBrush(brush, matrix, gStateObject);
0
2351 }-
2352-
2353 if ((!brush.isOpaque() && brush.style() < Qt::LinearGradientPattern) || opacity != 1.0)
!brush.isOpaque()Description
TRUEnever evaluated
FALSEnever evaluated
brush.style() ...radientPatternDescription
TRUEnever evaluated
FALSEnever evaluated
opacity != 1.0Description
TRUEnever evaluated
FALSEnever evaluated
0
2354 *gStateObject = addConstantAlphaObject(qRound(brush.color().alpha() * opacity),
never executed: *gStateObject = addConstantAlphaObject(qRound(brush.color().alpha() * opacity), qRound(pen.color().alpha() * opacity));
0
2355 qRound(pen.color().alpha() * opacity));
never executed: *gStateObject = addConstantAlphaObject(qRound(brush.color().alpha() * opacity), qRound(pen.color().alpha() * opacity));
0
2356-
2357 int imageObject = -1;-
2358 QByteArray pattern = QPdf::patternForBrush(brush);-
2359 if (pattern.isEmpty()) {
pattern.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
2360 if (brush.style() != Qt::TexturePattern)
brush.style() ...TexturePatternDescription
TRUEnever evaluated
FALSEnever evaluated
0
2361 return 0;
never executed: return 0;
0
2362 QImage image = brush.textureImage();-
2363 bool bitmap = true;-
2364 imageObject = addImage(image, &bitmap, image.cacheKey());-
2365 if (imageObject != -1) {
imageObject != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
2366 QImage::Format f = image.format();-
2367 if (f != QImage::Format_MonoLSB && f != QImage::Format_Mono) {
f != QImage::Format_MonoLSBDescription
TRUEnever evaluated
FALSEnever evaluated
f != QImage::Format_MonoDescription
TRUEnever evaluated
FALSEnever evaluated
0
2368 paintType = 1; // Colored tiling-
2369 *specifyColor = false;-
2370 }
never executed: end of block
0
2371 w = image.width();-
2372 h = image.height();-
2373 QTransform m(w, 0, 0, -h, 0, h);-
2374 QPdf::ByteStream s(&pattern);-
2375 s << QPdf::generateMatrix(m);-
2376 s << "/Im" << imageObject << " Do\n";-
2377 }
never executed: end of block
0
2378 }
never executed: end of block
0
2379-
2380 QByteArray str;-
2381 QPdf::ByteStream s(&str);-
2382 s << "<<\n"-
2383 "/Type /Pattern\n"-
2384 "/PatternType 1\n"-
2385 "/PaintType " << paintType << "\n"-
2386 "/TilingType 1\n"-
2387 "/BBox [0 0 " << w << h << "]\n"-
2388 "/XStep " << w << "\n"-
2389 "/YStep " << h << "\n"-
2390 "/Matrix ["-
2391 << matrix.m11()-
2392 << matrix.m12()-
2393 << matrix.m21()-
2394 << matrix.m22()-
2395 << matrix.dx()-
2396 << matrix.dy() << "]\n"-
2397 "/Resources \n<< "; // open resource tree-
2398 if (imageObject > 0) {
imageObject > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2399 s << "/XObject << /Im" << imageObject << ' ' << imageObject << "0 R >> ";-
2400 }
never executed: end of block
0
2401 s << ">>\n"-
2402 "/Length " << pattern.length() << "\n"-
2403 ">>\n"-
2404 "stream\n"-
2405 << pattern-
2406 << "endstream\n"-
2407 "endobj\n";-
2408-
2409 int patternObj = addXrefEntry(-1);-
2410 write(str);-
2411 currentPage->patterns.append(patternObj);-
2412 return patternObj;
never executed: return patternObj;
0
2413}-
2414-
2415static inline bool is_monochrome(const QVector<QRgb> &colorTable)-
2416{-
2417 return colorTable.size() == 2
never executed: return colorTable.size() == 2 && colorTable.at(0) == QColor(Qt::black).rgba() && colorTable.at(1) == QColor(Qt::white).rgba() ;
0
2418 && colorTable.at(0) == QColor(Qt::black).rgba()
never executed: return colorTable.size() == 2 && colorTable.at(0) == QColor(Qt::black).rgba() && colorTable.at(1) == QColor(Qt::white).rgba() ;
0
2419 && colorTable.at(1) == QColor(Qt::white).rgba()
never executed: return colorTable.size() == 2 && colorTable.at(0) == QColor(Qt::black).rgba() && colorTable.at(1) == QColor(Qt::white).rgba() ;
0
2420 ;
never executed: return colorTable.size() == 2 && colorTable.at(0) == QColor(Qt::black).rgba() && colorTable.at(1) == QColor(Qt::white).rgba() ;
0
2421}-
2422-
2423/*!-
2424 * Adds an image to the pdf and return the pdf-object id. Returns -1 if adding the image failed.-
2425 */-
2426int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_no)-
2427{-
2428 if (img.isNull())
img.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
2429 return -1;
never executed: return -1;
0
2430-
2431 int object = imageCache.value(serial_no);-
2432 if(object)
objectDescription
TRUEnever evaluated
FALSEnever evaluated
0
2433 return object;
never executed: return object;
0
2434-
2435 QImage image = img;-
2436 QImage::Format format = image.format();-
2437 if (image.depth() == 1 && *bitmap && is_monochrome(img.colorTable())) {
image.depth() == 1Description
TRUEnever evaluated
FALSEnever evaluated
*bitmapDescription
TRUEnever evaluated
FALSEnever evaluated
is_monochrome(....colorTable())Description
TRUEnever evaluated
FALSEnever evaluated
0
2438 if (format == QImage::Format_MonoLSB)
format == QIma...Format_MonoLSBDescription
TRUEnever evaluated
FALSEnever evaluated
0
2439 image = image.convertToFormat(QImage::Format_Mono);
never executed: image = image.convertToFormat(QImage::Format_Mono);
0
2440 format = QImage::Format_Mono;-
2441 } else {
never executed: end of block
0
2442 *bitmap = false;-
2443 if (format != QImage::Format_RGB32 && format != QImage::Format_ARGB32) {
format != QImage::Format_RGB32Description
TRUEnever evaluated
FALSEnever evaluated
format != QIma...:Format_ARGB32Description
TRUEnever evaluated
FALSEnever evaluated
0
2444 image = image.convertToFormat(QImage::Format_ARGB32);-
2445 format = QImage::Format_ARGB32;-
2446 }
never executed: end of block
0
2447 }
never executed: end of block
0
2448-
2449 int w = image.width();-
2450 int h = image.height();-
2451 int d = image.depth();-
2452-
2453 if (format == QImage::Format_Mono) {
format == QImage::Format_MonoDescription
TRUEnever evaluated
FALSEnever evaluated
0
2454 int bytesPerLine = (w + 7) >> 3;-
2455 QByteArray data;-
2456 data.resize(bytesPerLine * h);-
2457 char *rawdata = data.data();-
2458 for (int y = 0; y < h; ++y) {
y < hDescription
TRUEnever evaluated
FALSEnever evaluated
0
2459 memcpy(rawdata, image.constScanLine(y), bytesPerLine);-
2460 rawdata += bytesPerLine;-
2461 }
never executed: end of block
0
2462 object = writeImage(data, w, h, d, 0, 0, false, is_monochrome(img.colorTable()));-
2463 } else {
never executed: end of block
0
2464 QByteArray softMaskData;-
2465 bool dct = false;-
2466 QByteArray imageData;-
2467 bool hasAlpha = false;-
2468 bool hasMask = false;-
2469-
2470 if (QImageWriter::supportedImageFormats().contains("jpeg") && !grayscale) {
QImageWriter::...ntains("jpeg")Description
TRUEnever evaluated
FALSEnever evaluated
!grayscaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
2471 QBuffer buffer(&imageData);-
2472 QImageWriter writer(&buffer, "jpeg");-
2473 writer.setQuality(94);-
2474 writer.write(image);-
2475 dct = true;-
2476-
2477 if (format != QImage::Format_RGB32) {
format != QImage::Format_RGB32Description
TRUEnever evaluated
FALSEnever evaluated
0
2478 softMaskData.resize(w * h);-
2479 uchar *sdata = (uchar *)softMaskData.data();-
2480 for (int y = 0; y < h; ++y) {
y < hDescription
TRUEnever evaluated
FALSEnever evaluated
0
2481 const QRgb *rgb = (const QRgb *)image.constScanLine(y);-
2482 for (int x = 0; x < w; ++x) {
x < wDescription
TRUEnever evaluated
FALSEnever evaluated
0
2483 uchar alpha = qAlpha(*rgb);-
2484 *sdata++ = alpha;-
2485 hasMask |= (alpha < 255);-
2486 hasAlpha |= (alpha != 0 && alpha != 255);
alpha != 0Description
TRUEnever evaluated
FALSEnever evaluated
alpha != 255Description
TRUEnever evaluated
FALSEnever evaluated
0
2487 ++rgb;-
2488 }
never executed: end of block
0
2489 }
never executed: end of block
0
2490 }
never executed: end of block
0
2491 } else {
never executed: end of block
0
2492 imageData.resize(grayscale ? w * h : 3 * w * h);-
2493 uchar *data = (uchar *)imageData.data();-
2494 softMaskData.resize(w * h);-
2495 uchar *sdata = (uchar *)softMaskData.data();-
2496 for (int y = 0; y < h; ++y) {
y < hDescription
TRUEnever evaluated
FALSEnever evaluated
0
2497 const QRgb *rgb = (const QRgb *)image.constScanLine(y);-
2498 if (grayscale) {
grayscaleDescription
TRUEnever evaluated
FALSEnever evaluated
0
2499 for (int x = 0; x < w; ++x) {
x < wDescription
TRUEnever evaluated
FALSEnever evaluated
0
2500 *(data++) = qGray(*rgb);-
2501 uchar alpha = qAlpha(*rgb);-
2502 *sdata++ = alpha;-
2503 hasMask |= (alpha < 255);-
2504 hasAlpha |= (alpha != 0 && alpha != 255);
alpha != 0Description
TRUEnever evaluated
FALSEnever evaluated
alpha != 255Description
TRUEnever evaluated
FALSEnever evaluated
0
2505 ++rgb;-
2506 }
never executed: end of block
0
2507 } else {
never executed: end of block
0
2508 for (int x = 0; x < w; ++x) {
x < wDescription
TRUEnever evaluated
FALSEnever evaluated
0
2509 *(data++) = qRed(*rgb);-
2510 *(data++) = qGreen(*rgb);-
2511 *(data++) = qBlue(*rgb);-
2512 uchar alpha = qAlpha(*rgb);-
2513 *sdata++ = alpha;-
2514 hasMask |= (alpha < 255);-
2515 hasAlpha |= (alpha != 0 && alpha != 255);
alpha != 0Description
TRUEnever evaluated
FALSEnever evaluated
alpha != 255Description
TRUEnever evaluated
FALSEnever evaluated
0
2516 ++rgb;-
2517 }
never executed: end of block
0
2518 }
never executed: end of block
0
2519 }-
2520 if (format == QImage::Format_RGB32)
format == QImage::Format_RGB32Description
TRUEnever evaluated
FALSEnever evaluated
0
2521 hasAlpha = hasMask = false;
never executed: hasAlpha = hasMask = false;
0
2522 }
never executed: end of block
0
2523 int maskObject = 0;-
2524 int softMaskObject = 0;-
2525 if (hasAlpha) {
hasAlphaDescription
TRUEnever evaluated
FALSEnever evaluated
0
2526 softMaskObject = writeImage(softMaskData, w, h, 8, 0, 0);-
2527 } else if (hasMask) {
never executed: end of block
hasMaskDescription
TRUEnever evaluated
FALSEnever evaluated
0
2528 // dither the soft mask to 1bit and add it. This also helps PDF viewers-
2529 // without transparency support-
2530 int bytesPerLine = (w + 7) >> 3;-
2531 QByteArray mask(bytesPerLine * h, 0);-
2532 uchar *mdata = (uchar *)mask.data();-
2533 const uchar *sdata = (const uchar *)softMaskData.constData();-
2534 for (int y = 0; y < h; ++y) {
y < hDescription
TRUEnever evaluated
FALSEnever evaluated
0
2535 for (int x = 0; x < w; ++x) {
x < wDescription
TRUEnever evaluated
FALSEnever evaluated
0
2536 if (*sdata)
*sdataDescription
TRUEnever evaluated
FALSEnever evaluated
0
2537 mdata[x>>3] |= (0x80 >> (x&7));
never executed: mdata[x>>3] |= (0x80 >> (x&7));
0
2538 ++sdata;-
2539 }
never executed: end of block
0
2540 mdata += bytesPerLine;-
2541 }
never executed: end of block
0
2542 maskObject = writeImage(mask, w, h, 1, 0, 0);-
2543 }
never executed: end of block
0
2544 object = writeImage(imageData, w, h, grayscale ? 8 : 32,-
2545 maskObject, softMaskObject, dct);-
2546 }
never executed: end of block
0
2547 imageCache.insert(serial_no, object);-
2548 return object;
never executed: return object;
0
2549}-
2550-
2551void QPdfEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &ti)-
2552{-
2553 Q_Q(QPdfEngine);-
2554-
2555 if (ti.charFormat.isAnchor()) {
ti.charFormat.isAnchor()Description
TRUEnever evaluated
FALSEnever evaluated
0
2556 qreal size = ti.fontEngine->fontDef.pixelSize;-
2557 int synthesized = ti.fontEngine->synthesized();-
2558 qreal stretch = synthesized & QFontEngine::SynthesizedStretch ? ti.fontEngine->fontDef.stretch/100. : 1.;
synthesized & ...hesizedStretchDescription
TRUEnever evaluated
FALSEnever evaluated
0
2559-
2560 QTransform trans;-
2561 // Build text rendering matrix (Trm). We need it to map the text area to user-
2562 // space units on the PDF page.-
2563 trans = QTransform(size*stretch, 0, 0, size, 0, 0);-
2564 // Apply text matrix (Tm).-
2565 trans *= QTransform(1,0,0,-1,p.x(),p.y());-
2566 // Apply page displacement (Identity for first page).-
2567 trans *= stroker.matrix;-
2568 // Apply Current Transformation Matrix (CTM)-
2569 trans *= pageMatrix();-
2570 qreal x1, y1, x2, y2;-
2571 trans.map(0, 0, &x1, &y1);-
2572 trans.map(ti.width.toReal()/size, (ti.ascent.toReal()-ti.descent.toReal())/size, &x2, &y2);-
2573-
2574 uint annot = addXrefEntry(-1);-
2575 QByteArray x1s, y1s, x2s, y2s;-
2576 x1s.setNum(static_cast<double>(x1), 'f');-
2577 y1s.setNum(static_cast<double>(y1), 'f');-
2578 x2s.setNum(static_cast<double>(x2), 'f');-
2579 y2s.setNum(static_cast<double>(y2), 'f');-
2580 QByteArray rectData = x1s + ' ' + y1s + ' ' + x2s + ' ' + y2s;-
2581 xprintf("<<\n/Type /Annot\n/Subtype /Link\n/Rect [");-
2582 xprintf(rectData.constData());-
2583#ifdef Q_DEBUG_PDF_LINKS-
2584 xprintf("]\n/Border [16 16 1]\n/A <<\n");-
2585#else-
2586 xprintf("]\n/Border [0 0 0]\n/A <<\n");-
2587#endif-
2588 xprintf("/Type /Action\n/S /URI\n/URI (%s)\n",-
2589 ti.charFormat.anchorHref().toLatin1().constData());-
2590 xprintf(">>\n>>\n");-
2591 xprintf("endobj\n");-
2592-
2593 if (!currentPage->annotations.contains(annot)) {
!currentPage->...ontains(annot)Description
TRUEnever evaluated
FALSEnever evaluated
0
2594 currentPage->annotations.append(annot);-
2595 }
never executed: end of block
0
2596 }
never executed: end of block
0
2597-
2598 QFontEngine *fe = ti.fontEngine;-
2599-
2600 QFontEngine::FaceId face_id = fe->faceId();-
2601 bool noEmbed = false;-
2602 if (!embedFonts
!embedFontsDescription
TRUEnever evaluated
FALSEnever evaluated
0
2603 || face_id.filename.isEmpty()
face_id.filename.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
2604 || fe->fsType & 0x200 /* bitmap embedding only */
fe->fsType & 0x200Description
TRUEnever evaluated
FALSEnever evaluated
0
2605 || fe->fsType == 2 /* no embedding allowed */) {
fe->fsType == 2Description
TRUEnever evaluated
FALSEnever evaluated
0
2606 *currentPage << "Q\n";-
2607 q->QPaintEngine::drawTextItem(p, ti);-
2608 *currentPage << "q\n";-
2609 if (face_id.filename.isEmpty())
face_id.filename.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
2610 return;
never executed: return;
0
2611 noEmbed = true;-
2612 }
never executed: end of block
0
2613-
2614 QFontSubset *font = fonts.value(face_id, 0);-
2615 if (!font) {
!fontDescription
TRUEnever evaluated
FALSEnever evaluated
0
2616 font = new QFontSubset(fe, requestObject());-
2617 font->noEmbed = noEmbed;-
2618 }
never executed: end of block
0
2619 fonts.insert(face_id, font);-
2620-
2621 if (!currentPage->fonts.contains(font->object_id))
!currentPage->...nt->object_id)Description
TRUEnever evaluated
FALSEnever evaluated
0
2622 currentPage->fonts.append(font->object_id);
never executed: currentPage->fonts.append(font->object_id);
0
2623-
2624 qreal size = ti.fontEngine->fontDef.pixelSize;-
2625-
2626 QVarLengthArray<glyph_t> glyphs;-
2627 QVarLengthArray<QFixedPoint> positions;-
2628 QTransform m = QTransform::fromTranslate(p.x(), p.y());-
2629 ti.fontEngine->getGlyphPositions(ti.glyphs, m, ti.flags,-
2630 glyphs, positions);-
2631 if (glyphs.size() == 0)
glyphs.size() == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2632 return;
never executed: return;
0
2633 int synthesized = ti.fontEngine->synthesized();-
2634 qreal stretch = synthesized & QFontEngine::SynthesizedStretch ? ti.fontEngine->fontDef.stretch/100. : 1.;
synthesized & ...hesizedStretchDescription
TRUEnever evaluated
FALSEnever evaluated
0
2635-
2636 *currentPage << "BT\n"-
2637 << "/F" << font->object_id << size << "Tf "-
2638 << stretch << (synthesized & QFontEngine::SynthesizedItalic-
2639 ? "0 .3 -1 0 0 Tm\n"-
2640 : "0 0 -1 0 0 Tm\n");-
2641-
2642-
2643#if 0-
2644 // #### implement actual text for complex languages-
2645 const unsigned short *logClusters = ti.logClusters;-
2646 int pos = 0;-
2647 do {-
2648 int end = pos + 1;-
2649 while (end < ti.num_chars && logClusters[end] == logClusters[pos])-
2650 ++end;-
2651 *currentPage << "/Span << /ActualText <FEFF";-
2652 for (int i = pos; i < end; ++i) {-
2653 s << toHex((ushort)ti.chars[i].unicode(), buf);-
2654 }-
2655 *currentPage << "> >>\n"-
2656 "BDC\n"-
2657 "<";-
2658 int ge = end == ti.num_chars ? ti.num_glyphs : logClusters[end];-
2659 for (int gs = logClusters[pos]; gs < ge; ++gs)-
2660 *currentPage << toHex((ushort)ti.glyphs[gs].glyph, buf);-
2661 *currentPage << "> Tj\n"-
2662 "EMC\n";-
2663 pos = end;-
2664 } while (pos < ti.num_chars);-
2665#else-
2666 qreal last_x = 0.;-
2667 qreal last_y = 0.;-
2668 for (int i = 0; i < glyphs.size(); ++i) {
i < glyphs.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
2669 qreal x = positions[i].x.toReal();-
2670 qreal y = positions[i].y.toReal();-
2671 if (synthesized & QFontEngine::SynthesizedItalic)
synthesized & ...thesizedItalicDescription
TRUEnever evaluated
FALSEnever evaluated
0
2672 x += .3*y;
never executed: x += .3*y;
0
2673 x /= stretch;-
2674 char buf[5];-
2675 int g = font->addGlyph(glyphs[i]);-
2676 *currentPage << x - last_x << last_y - y << "Td <"-
2677 << QPdf::toHex((ushort)g, buf) << "> Tj\n";-
2678 last_x = x;-
2679 last_y = y;-
2680 }
never executed: end of block
0
2681 if (synthesized & QFontEngine::SynthesizedBold) {
synthesized & ...ynthesizedBoldDescription
TRUEnever evaluated
FALSEnever evaluated
0
2682 *currentPage << stretch << (synthesized & QFontEngine::SynthesizedItalic-
2683 ? "0 .3 -1 0 0 Tm\n"-
2684 : "0 0 -1 0 0 Tm\n");-
2685 *currentPage << "/Span << /ActualText <> >> BDC\n";-
2686 last_x = 0.5*fe->lineThickness().toReal();-
2687 last_y = 0.;-
2688 for (int i = 0; i < glyphs.size(); ++i) {
i < glyphs.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
2689 qreal x = positions[i].x.toReal();-
2690 qreal y = positions[i].y.toReal();-
2691 if (synthesized & QFontEngine::SynthesizedItalic)
synthesized & ...thesizedItalicDescription
TRUEnever evaluated
FALSEnever evaluated
0
2692 x += .3*y;
never executed: x += .3*y;
0
2693 x /= stretch;-
2694 char buf[5];-
2695 int g = font->addGlyph(glyphs[i]);-
2696 *currentPage << x - last_x << last_y - y << "Td <"-
2697 << QPdf::toHex((ushort)g, buf) << "> Tj\n";-
2698 last_x = x;-
2699 last_y = y;-
2700 }
never executed: end of block
0
2701 *currentPage << "EMC\n";-
2702 }
never executed: end of block
0
2703#endif-
2704-
2705 *currentPage << "ET\n";-
2706}
never executed: end of block
0
2707-
2708QTransform QPdfEnginePrivate::pageMatrix() const-
2709{-
2710 qreal scale = 72./resolution;-
2711 QTransform tmp(scale, 0.0, 0.0, -scale, 0.0, m_pageLayout.fullRectPoints().height());-
2712 if (m_pageLayout.mode() != QPageLayout::FullPageMode) {
m_pageLayout.m...::FullPageModeDescription
TRUEnever evaluated
FALSEnever evaluated
0
2713 QRect r = m_pageLayout.paintRectPixels(resolution);-
2714 tmp.translate(r.left(), r.top());-
2715 }
never executed: end of block
0
2716 return tmp;
never executed: return tmp;
0
2717}-
2718-
2719void QPdfEnginePrivate::newPage()-
2720{-
2721 if (currentPage && currentPage->pageSize.isEmpty())
currentPageDescription
TRUEnever evaluated
FALSEnever evaluated
currentPage->p...Size.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
2722 currentPage->pageSize = m_pageLayout.fullRectPoints().size();
never executed: currentPage->pageSize = m_pageLayout.fullRectPoints().size();
0
2723 writePage();-
2724-
2725 delete currentPage;-
2726 currentPage = new QPdfPage;-
2727 currentPage->pageSize = m_pageLayout.fullRectPoints().size();-
2728 stroker.stream = currentPage;-
2729 pages.append(requestObject());-
2730-
2731 *currentPage << "/GSa gs /CSp cs /CSp CS\n"-
2732 << QPdf::generateMatrix(pageMatrix())-
2733 << "q q\n";-
2734}
never executed: end of block
0
2735-
2736QT_END_NAMESPACE-
2737-
2738#endif // QT_NO_PDF-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9