1 | //======================================================================== |
2 | // |
3 | // QPainterOutputDev.h |
4 | // |
5 | // Copyright 2003 Glyph & Cog, LLC |
6 | // |
7 | //======================================================================== |
8 | |
9 | //======================================================================== |
10 | // |
11 | // Modified under the Poppler project - http://poppler.freedesktop.org |
12 | // |
13 | // All changes made under the Poppler project to this file are licensed |
14 | // under GPL version 2 or later |
15 | // |
16 | // Copyright (C) 2005 Brad Hards <bradh@frogmouth.net> |
17 | // Copyright (C) 2005, 2018, 2019, 2021 Albert Astals Cid <aacid@kde.org> |
18 | // Copyright (C) 2009, 2011 Carlos Garcia Campos <carlosgc@gnome.org> |
19 | // Copyright (C) 2010 Pino Toscano <pino@kde.org> |
20 | // Copyright (C) 2011 Andreas Hartmetz <ahartmetz@gmail.com> |
21 | // Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de> |
22 | // Copyright (C) 2013 Mihai Niculescu <q.quark@gmail.com> |
23 | // Copyright (C) 2017, 2018, 2020 Oliver Sander <oliver.sander@tu-dresden.de> |
24 | // |
25 | // To see a description of the changes please see the Changelog file that |
26 | // came with your tarball or type make ChangeLog if you are building from git |
27 | // |
28 | //======================================================================== |
29 | |
30 | #ifndef QPAINTEROUTPUTDEV_H |
31 | #define QPAINTEROUTPUTDEV_H |
32 | |
33 | #include <memory> |
34 | #include <map> |
35 | #include <stack> |
36 | |
37 | #include "OutputDev.h" |
38 | #include "GfxState.h" |
39 | |
40 | #include <ft2build.h> |
41 | #include FT_FREETYPE_H |
42 | |
43 | #include <QtGui/QPainter> |
44 | |
45 | class GfxState; |
46 | class PDFDoc; |
47 | |
48 | class QRawFont; |
49 | |
50 | class QPainterOutputDevType3Font; |
51 | |
52 | //------------------------------------------------------------------------ |
53 | // QPainterOutputDev - QPainter renderer |
54 | //------------------------------------------------------------------------ |
55 | |
56 | class QPainterOutputDev : public OutputDev |
57 | { |
58 | public: |
59 | // Constructor. |
60 | explicit QPainterOutputDev(QPainter *painter); |
61 | |
62 | // Destructor. |
63 | ~QPainterOutputDev() override; |
64 | |
65 | void setHintingPreference(QFont::HintingPreference hintingPreference) { m_hintingPreference = hintingPreference; } |
66 | |
67 | //----- get info about output device |
68 | |
69 | // Does this device use upside-down coordinates? |
70 | // (Upside-down means (0,0) is the top left corner of the page.) |
71 | bool upsideDown() override { return true; } |
72 | |
73 | // Does this device use drawChar() or drawString()? |
74 | bool useDrawChar() override { return true; } |
75 | |
76 | // Does this device implement shaded fills (aka gradients) natively? |
77 | // If this returns false, these shaded fills |
78 | // will be reduced to a series of other drawing operations. |
79 | // type==2 is 'axial shading' |
80 | bool useShadedFills(int type) override { return type == 2; } |
81 | |
82 | // Does this device use beginType3Char/endType3Char? Otherwise, |
83 | // text in Type 3 fonts will be drawn with drawChar/drawString. |
84 | bool interpretType3Chars() override { return false; } |
85 | |
86 | //----- initialization and control |
87 | |
88 | // Set Current Transformation Matrix to a fixed matrix given in ctm[0],...,ctm[5] |
89 | void setDefaultCTM(const double *ctm) override; |
90 | |
91 | // Start a page. |
92 | void startPage(int pageNum, GfxState *state, XRef *xref) override; |
93 | |
94 | // End a page. |
95 | void endPage() override; |
96 | |
97 | //----- save/restore graphics state |
98 | void saveState(GfxState *state) override; |
99 | void restoreState(GfxState *state) override; |
100 | |
101 | //----- update graphics state |
102 | void updateAll(GfxState *state) override; |
103 | void updateCTM(GfxState *state, double m11, double m12, double m21, double m22, double m31, double m32) override; |
104 | void updateLineDash(GfxState *state) override; |
105 | void updateFlatness(GfxState *state) override; |
106 | void updateLineJoin(GfxState *state) override; |
107 | void updateLineCap(GfxState *state) override; |
108 | void updateMiterLimit(GfxState *state) override; |
109 | void updateLineWidth(GfxState *state) override; |
110 | void updateFillColor(GfxState *state) override; |
111 | void updateStrokeColor(GfxState *state) override; |
112 | void updateBlendMode(GfxState *state) override; |
113 | void updateFillOpacity(GfxState *state) override; |
114 | void updateStrokeOpacity(GfxState *state) override; |
115 | |
116 | //----- update text state |
117 | void updateFont(GfxState *state) override; |
118 | |
119 | //----- path painting |
120 | void stroke(GfxState *state) override; |
121 | void fill(GfxState *state) override; |
122 | void eoFill(GfxState *state) override; |
123 | bool axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax) override; |
124 | |
125 | //----- path clipping |
126 | void clip(GfxState *state) override; |
127 | void eoClip(GfxState *state) override; |
128 | void clipToStrokePath(GfxState *state) override; |
129 | |
130 | //----- text drawing |
131 | // virtual void drawString(GfxState *state, GooString *s); |
132 | void drawChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, int nBytes, const Unicode *u, int uLen) override; |
133 | void endTextObject(GfxState *state) override; |
134 | |
135 | //----- image drawing |
136 | void drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, bool invert, bool interpolate, bool inlineImg) override; |
137 | void drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, const int *maskColors, bool inlineImg) override; |
138 | |
139 | void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, Stream *maskStr, int maskWidth, int maskHeight, GfxImageColorMap *maskColorMap, |
140 | bool maskInterpolate) override; |
141 | |
142 | //----- Type 3 font operators |
143 | void type3D0(GfxState *state, double wx, double wy) override; |
144 | void type3D1(GfxState *state, double wx, double wy, double llx, double lly, double urx, double ury) override; |
145 | |
146 | //----- transparency groups and soft masks |
147 | void beginTransparencyGroup(GfxState *state, const double *bbox, GfxColorSpace *blendingColorSpace, bool isolated, bool knockout, bool forSoftMask) override; |
148 | void endTransparencyGroup(GfxState *state) override; |
149 | void paintTransparencyGroup(GfxState *state, const double *bbox) override; |
150 | |
151 | //----- special access |
152 | |
153 | // Called to indicate that a new PDF document has been loaded. |
154 | void startDoc(PDFDoc *doc); |
155 | |
156 | bool isReverseVideo() { return false; } |
157 | |
158 | private: |
159 | // The stack of QPainters is used to implement transparency groups. When such a group |
160 | // is opened, annew Painter that paints onto a QPicture is pushed onto the stack. |
161 | // It is popped again when the transparency group ends. |
162 | std::stack<QPainter *> m_painter; |
163 | |
164 | // This is the corresponding stack of QPicture objects |
165 | std::stack<QPicture *> m_qpictures; |
166 | |
167 | // endTransparencyGroup removes a QPicture from the stack, but stores |
168 | // it here for later use in paintTransparencyGroup. |
169 | QPicture *m_lastTransparencyGroupPicture; |
170 | |
171 | QFont::HintingPreference m_hintingPreference; |
172 | |
173 | QPen m_currentPen; |
174 | // The various stacks are used to implement the 'saveState' and 'restoreState' methods |
175 | std::stack<QPen> m_currentPenStack; |
176 | |
177 | QBrush m_currentBrush; |
178 | std::stack<QBrush> m_currentBrushStack; |
179 | |
180 | bool m_needFontUpdate; // set when the font needs to be updated |
181 | PDFDoc *m_doc; |
182 | XRef *xref; // xref table for current document |
183 | |
184 | // The current font in use |
185 | QRawFont *m_rawFont; |
186 | std::stack<QRawFont *> m_rawFontStack; |
187 | |
188 | QPainterOutputDevType3Font *m_currentType3Font; |
189 | std::stack<QPainterOutputDevType3Font *> m_type3FontStack; |
190 | |
191 | // Cache all fonts by their Ref and font size |
192 | using QPainterFontID = std::pair<Ref, double>; |
193 | std::map<QPainterFontID, std::unique_ptr<QRawFont>> m_rawFontCache; |
194 | std::map<QPainterFontID, std::unique_ptr<QPainterOutputDevType3Font>> m_type3FontCache; |
195 | std::map<Ref, const int *> m_codeToGIDCache; |
196 | |
197 | // The table that maps character codes to glyph indexes |
198 | const int *m_codeToGID; |
199 | std::stack<const int *> m_codeToGIDStack; |
200 | |
201 | FT_Library m_ftLibrary; |
202 | // as of FT 2.1.8, CID fonts are indexed by CID instead of GID |
203 | bool m_useCIDs; |
204 | }; |
205 | |
206 | #endif |
207 | |