1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
40 ****************************************************************************/
49 // This file is not part of the Qt API. It exists purely as an
50 // implementation detail. This header file may change from version to
51 // version without notice, or even be removed.
55 #include "QtGui/qmatrix.h"
56 #include "QtCore/qstring.h"
57 #include "QtCore/qvector.h"
58 #include "private/qstroker_p.h"
59 #include "private/qpaintengine_p.h"
60 #include "private/qfontengine_p.h"
61 #include "private/qfontsubset_p.h"
63 // #define USE_NATIVE_GRADIENTS
67 const char *qt_real_to_string(qreal val, char *buf);
68 const char *qt_int_to_string(int val, char *buf);
75 // fileBacking means that ByteStream will buffer the contents on disk
76 // if the size exceeds a certain threshold. In this case, if a byte
77 // array was passed in, its contents may no longer correspond to the
78 // ByteStream contents.
79 explicit ByteStream(bool fileBacking = false);
80 explicit ByteStream(QByteArray *ba, bool fileBacking = false);
82 ByteStream &operator <<(char chr);
83 ByteStream &operator <<(const char *str);
84 ByteStream &operator <<(const QByteArray &str);
85 ByteStream &operator <<(const ByteStream &src);
86 ByteStream &operator <<(qreal val);
87 ByteStream &operator <<(int val);
88 ByteStream &operator <<(const QPointF &p);
89 // Note that the stream may be invalidated by calls that insert data.
93 static inline int maxMemorySize() { return 100000000; }
94 static inline int chunkSize() { return 10000000; }
97 void constructor_helper(QIODevice *dev);
98 void constructor_helper(QByteArray *ba);
101 void prepareBuffer();
106 bool fileBackingEnabled;
107 bool fileBackingActive;
117 QByteArray generatePath(const QPainterPath &path, const QTransform &matrix, PathFlags flags);
118 QByteArray generateMatrix(const QTransform &matrix);
119 QByteArray generateDashes(const QPen &pen);
120 QByteArray patternForBrush(const QBrush &b);
121 #ifdef USE_NATIVE_GRADIENTS
122 QByteArray generateLinearGradientShader(const QLinearGradient *lg, const QPointF *page_rect, bool alpha = false);
127 void setPen(const QPen &pen);
128 void strokePath(const QPainterPath &path);
134 QStroker basicStroker;
135 QDashStroker dashStroker;
136 QStrokerOps *stroker;
139 QByteArray ascii85Encode(const QByteArray &input);
141 const char *toHex(ushort u, char *buffer);
142 const char *toHex(uchar u, char *buffer);
147 class QPdfPage : public QPdf::ByteStream
152 QVector<uint> images;
153 QVector<uint> graphicStates;
154 QVector<uint> patterns;
156 QVector<uint> annotations;
158 void streamImage(int w, int h, int object);
165 class QPdfEnginePrivate;
167 class Q_GUI_EXPORT QPdfEngine : public QPaintEngine
169 Q_DECLARE_PRIVATE(QPdfEngine)
170 friend class QPdfWriter;
173 QPdfEngine(QPdfEnginePrivate &d);
176 void setOutputFilename(const QString &filename);
177 inline void setResolution(int resolution);
179 // reimplementations QPaintEngine
180 bool begin(QPaintDevice *pdev);
183 void drawPoints(const QPointF *points, int pointCount);
184 void drawLines(const QLineF *lines, int lineCount);
185 void drawRects(const QRectF *rects, int rectCount);
186 void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
187 void drawPath (const QPainterPath & path);
189 void drawTextItem(const QPointF &p, const QTextItem &textItem);
191 void drawPixmap (const QRectF & rectangle, const QPixmap & pixmap, const QRectF & sr);
192 void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
193 Qt::ImageConversionFlags flags = Qt::AutoColor);
194 void drawTiledPixmap (const QRectF & rectangle, const QPixmap & pixmap, const QPointF & point);
196 void updateState(const QPaintEngineState &state);
198 int metric(QPaintDevice::PaintDeviceMetric metricType) const;
200 // end reimplementations QPaintEngine
207 void setupGraphicsState(QPaintEngine::DirtyFlags flags);
210 void updateClipPath(const QPainterPath & path, Qt::ClipOperation op);
213 class Q_GUI_EXPORT QPdfEnginePrivate : public QPaintEnginePrivate
215 Q_DECLARE_PUBLIC(QPdfEngine)
218 ~QPdfEnginePrivate();
220 inline uint requestObject() { return currentObject++; }
222 QRect paperRect() const;
223 QRect pageRect() const;
226 QRect r = paperRect();
227 return qRound(r.width()*72./resolution);
230 QRect r = paperRect();
231 return qRound(r.height()*72./resolution);
237 int addImage(const QImage &image, bool *bitmap, qint64 serial_no);
238 int addConstantAlphaObject(int brushAlpha, int penAlpha = 255);
239 int addBrushPattern(const QTransform &matrix, bool *specifyColor, int *gStateObject);
241 void drawTextItem(const QPointF &p, const QTextItemInt &ti);
243 QTransform pageMatrix() const;
250 QPdfPage* currentPage;
251 QPdf::Stroker stroker;
256 QList<QPainterPath> clips;
264 QHash<QFontEngine::FaceId, QFontSubset *> fonts;
268 // the device the output is in the end streamed to.
269 QIODevice *outDevice;
273 QString outputFileName;
282 // in postscript points
284 qreal leftMargin, topMargin, rightMargin, bottomMargin;
287 #ifdef USE_NATIVE_GRADIENTS
288 int gradientBrush(const QBrush &b, const QMatrix &matrix, int *gStateObject);
292 void writePageRoot();
294 void embedFont(QFontSubset *font);
296 QVector<int> xrefPositions;
300 int writeImage(const QByteArray &data, int width, int height, int depth,
301 int maskObject, int softMaskObject, bool dct = false);
304 int addXrefEntry(int object, bool printostr = true);
305 void printString(const QString &string);
306 void xprintf(const char* fmt, ...);
307 inline void write(const QByteArray &data) {
308 stream->writeRawData(data.constData(), data.size());
309 streampos += data.size();
312 int writeCompressed(const char *src, int len);
313 inline int writeCompressed(const QByteArray &data) { return writeCompressed(data.constData(), data.length()); }
314 int writeCompressed(QIODevice *dev);
316 // various PDF objects
317 int pageRoot, catalog, info, graphicsState, patternColorSpace;
319 QHash<qint64, uint> imageCache;
320 QHash<QPair<uint, uint>, uint > alphaCache;
323 void QPdfEngine::setResolution(int resolution)
326 d->resolution = resolution;