1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QPDF_P_H
5#define QPDF_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtGui/private/qtguiglobal_p.h>
19
20#ifndef QT_NO_PDF
21
22#include "QtCore/qlist.h"
23#include "QtCore/qstring.h"
24#include "private/qfontengine_p.h"
25#include "private/qfontsubset_p.h"
26#include "private/qpaintengine_p.h"
27#include "private/qstroker_p.h"
28#include "qpagelayout.h"
29
30QT_BEGIN_NAMESPACE
31
32const char *qt_real_to_string(qreal val, char *buf);
33const char *qt_int_to_string(int val, char *buf);
34
35namespace QPdf {
36
37 class ByteStream
38 {
39 public:
40 // fileBacking means that ByteStream will buffer the contents on disk
41 // if the size exceeds a certain threshold. In this case, if a byte
42 // array was passed in, its contents may no longer correspond to the
43 // ByteStream contents.
44 explicit ByteStream(bool fileBacking = false);
45 explicit ByteStream(QByteArray *ba, bool fileBacking = false);
46 ~ByteStream();
47 ByteStream &operator <<(char chr);
48 ByteStream &operator <<(const char *str);
49 ByteStream &operator <<(const QByteArray &str);
50 ByteStream &operator <<(const ByteStream &src);
51 ByteStream &operator <<(qreal val);
52 ByteStream &operator <<(int val);
53 ByteStream &operator <<(uint val) { return (*this << int(val)); }
54 ByteStream &operator <<(qint64 val) { return (*this << int(val)); }
55 ByteStream &operator <<(const QPointF &p);
56 // Note that the stream may be invalidated by calls that insert data.
57 QIODevice *stream();
58 void clear();
59
60 static inline int maxMemorySize() { return 100000000; }
61 static inline int chunkSize() { return 10000000; }
62
63 protected:
64 void constructor_helper(QIODevice *dev);
65 void constructor_helper(QByteArray *ba);
66
67 private:
68 void prepareBuffer();
69
70 private:
71 QIODevice *dev;
72 QByteArray ba;
73 bool fileBackingEnabled;
74 bool fileBackingActive;
75 bool handleDirty;
76 };
77
78 enum PathFlags {
79 ClipPath,
80 FillPath,
81 StrokePath,
82 FillAndStrokePath
83 };
84 QByteArray generatePath(const QPainterPath &path, const QTransform &matrix, PathFlags flags);
85 QByteArray generateMatrix(const QTransform &matrix);
86 QByteArray generateDashes(const QPen &pen);
87 QByteArray patternForBrush(const QBrush &b);
88
89 struct Stroker {
90 Stroker();
91 void setPen(const QPen &pen, QPainter::RenderHints hints);
92 void strokePath(const QPainterPath &path);
93 ByteStream *stream;
94 bool first;
95 QTransform matrix;
96 bool cosmeticPen;
97 private:
98 QStroker basicStroker;
99 QDashStroker dashStroker;
100 QStrokerOps *stroker;
101 };
102
103 QByteArray ascii85Encode(const QByteArray &input);
104
105 const char *toHex(ushort u, char *buffer);
106 const char *toHex(uchar u, char *buffer);
107
108}
109
110
111class QPdfPage : public QPdf::ByteStream
112{
113public:
114 QPdfPage();
115
116 QList<uint> images;
117 QList<uint> graphicStates;
118 QList<uint> patterns;
119 QList<uint> fonts;
120 QList<uint> annotations;
121
122 void streamImage(int w, int h, uint object);
123
124 QSize pageSize;
125private:
126};
127
128class QPdfWriter;
129class QPdfEnginePrivate;
130
131class Q_GUI_EXPORT QPdfEngine : public QPaintEngine
132{
133 Q_DECLARE_PRIVATE(QPdfEngine)
134 friend class QPdfWriter;
135public:
136 // keep in sync with QPagedPaintDevice::PdfVersion and QPdfEnginePrivate::writeHeader()::mapping!
137 enum PdfVersion
138 {
139 Version_1_4,
140 Version_A1b,
141 Version_1_6
142 };
143
144 QPdfEngine();
145 QPdfEngine(QPdfEnginePrivate &d);
146 ~QPdfEngine() {}
147
148 void setOutputFilename(const QString &filename);
149
150 void setResolution(int resolution);
151 int resolution() const;
152
153 void setPdfVersion(PdfVersion version);
154
155 void setDocumentXmpMetadata(const QByteArray &xmpMetadata);
156 QByteArray documentXmpMetadata() const;
157
158 void addFileAttachment(const QString &fileName, const QByteArray &data, const QString &mimeType);
159
160 // reimplementations QPaintEngine
161 bool begin(QPaintDevice *pdev) override;
162 bool end() override;
163
164 void drawPoints(const QPointF *points, int pointCount) override;
165 void drawLines(const QLineF *lines, int lineCount) override;
166 void drawRects(const QRectF *rects, int rectCount) override;
167 void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) override;
168 void drawPath (const QPainterPath & path) override;
169
170 void drawTextItem(const QPointF &p, const QTextItem &textItem) override;
171
172 void drawPixmap (const QRectF & rectangle, const QPixmap & pixmap, const QRectF & sr) override;
173 void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
174 Qt::ImageConversionFlags flags = Qt::AutoColor) override;
175 void drawTiledPixmap (const QRectF & rectangle, const QPixmap & pixmap, const QPointF & point) override;
176
177 void drawHyperlink(const QRectF &r, const QUrl &url);
178
179 void updateState(const QPaintEngineState &state) override;
180
181 int metric(QPaintDevice::PaintDeviceMetric metricType) const;
182 Type type() const override;
183 // end reimplementations QPaintEngine
184
185 // Printer stuff...
186 bool newPage();
187
188 // Page layout stuff
189 void setPageLayout(const QPageLayout &pageLayout);
190 void setPageSize(const QPageSize &pageSize);
191 void setPageOrientation(QPageLayout::Orientation orientation);
192 void setPageMargins(const QMarginsF &margins, QPageLayout::Unit units = QPageLayout::Point);
193
194 QPageLayout pageLayout() const;
195
196 void setPen();
197 void setBrush();
198 void setupGraphicsState(QPaintEngine::DirtyFlags flags);
199
200private:
201 void updateClipPath(const QPainterPath & path, Qt::ClipOperation op);
202};
203
204class Q_GUI_EXPORT QPdfEnginePrivate : public QPaintEnginePrivate
205{
206 Q_DECLARE_PUBLIC(QPdfEngine)
207public:
208 QPdfEnginePrivate();
209 ~QPdfEnginePrivate();
210
211 inline uint requestObject() { return currentObject++; }
212
213 void writeHeader();
214 void writeTail();
215
216 int addImage(const QImage &image, bool *bitmap, bool lossless, qint64 serial_no);
217 int addConstantAlphaObject(int brushAlpha, int penAlpha = 255);
218 int addBrushPattern(const QTransform &matrix, bool *specifyColor, int *gStateObject);
219
220 void drawTextItem(const QPointF &p, const QTextItemInt &ti);
221
222 QTransform pageMatrix() const;
223
224 void newPage();
225
226 int currentObject;
227
228 QPdfPage* currentPage;
229 QPdf::Stroker stroker;
230
231 QPointF brushOrigin;
232 QBrush brush;
233 QPen pen;
234 QList<QPainterPath> clips;
235 bool clipEnabled;
236 bool allClipped;
237 bool hasPen;
238 bool hasBrush;
239 bool simplePen;
240 bool needsTransform;
241 qreal opacity;
242 QPdfEngine::PdfVersion pdfVersion;
243
244 QHash<QFontEngine::FaceId, QFontSubset *> fonts;
245
246 QPaintDevice *pdev;
247
248 // the device the output is in the end streamed to.
249 QIODevice *outDevice;
250 bool ownsDevice;
251
252 // printer options
253 QString outputFileName;
254 QString title;
255 QString creator;
256 bool embedFonts;
257 int resolution;
258 bool grayscale;
259
260 // Page layout: size, orientation and margins
261 QPageLayout m_pageLayout;
262
263private:
264 int gradientBrush(const QBrush &b, const QTransform &matrix, int *gStateObject);
265 int generateGradientShader(const QGradient *gradient, const QTransform &matrix, bool alpha = false);
266 int generateLinearGradientShader(const QLinearGradient *lg, const QTransform &matrix, bool alpha);
267 int generateRadialGradientShader(const QRadialGradient *gradient, const QTransform &matrix, bool alpha);
268 int createShadingFunction(const QGradient *gradient, int from, int to, bool reflect, bool alpha);
269
270 void writeInfo();
271 int writeXmpDcumentMetaData();
272 int writeOutputIntent();
273 void writePageRoot();
274 void writeDestsRoot();
275 void writeAttachmentRoot();
276 void writeNamesRoot();
277 void writeFonts();
278 void embedFont(QFontSubset *font);
279 qreal calcUserUnit() const;
280
281 QList<int> xrefPositions;
282 QDataStream* stream;
283 int streampos;
284
285 int writeImage(const QByteArray &data, int width, int height, int depth,
286 int maskObject, int softMaskObject, bool dct = false, bool isMono = false);
287 void writePage();
288
289 int addXrefEntry(int object, bool printostr = true);
290 void printString(QStringView string);
291 void xprintf(const char* fmt, ...);
292 inline void write(const QByteArray &data) {
293 stream->writeRawData(data.constData(), len: data.size());
294 streampos += data.size();
295 }
296
297 int writeCompressed(const char *src, int len);
298 inline int writeCompressed(const QByteArray &data) { return writeCompressed(src: data.constData(), len: data.size()); }
299 int writeCompressed(QIODevice *dev);
300
301 struct AttachmentInfo
302 {
303 AttachmentInfo (const QString &fileName, const QByteArray &data, const QString &mimeType)
304 : fileName(fileName), data(data), mimeType(mimeType) {}
305 QString fileName;
306 QByteArray data;
307 QString mimeType;
308 };
309
310 struct DestInfo
311 {
312 QString anchor;
313 uint pageObj;
314 QPointF coords;
315 };
316
317 // various PDF objects
318 int pageRoot, namesRoot, destsRoot, attachmentsRoot, catalog, info;
319 int graphicsState, patternColorSpace;
320 QList<uint> pages;
321 QHash<qint64, uint> imageCache;
322 QHash<QPair<uint, uint>, uint > alphaCache;
323 QList<DestInfo> destCache;
324 QList<AttachmentInfo> fileCache;
325 QByteArray xmpDocumentMetadata;
326};
327
328QT_END_NAMESPACE
329
330#endif // QT_NO_PDF
331
332#endif // QPDF_P_H
333
334

source code of qtbase/src/gui/painting/qpdf_p.h