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

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