File size: 8,015 Bytes
5cee033
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
//========================================================================
//
// QPainterOutputDev.h
//
// Copyright 2003 Glyph & Cog, LLC
//
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2005 Brad Hards <[email protected]>
// Copyright (C) 2005, 2018, 2019, 2021 Albert Astals Cid <[email protected]>
// Copyright (C) 2009, 2011 Carlos Garcia Campos <[email protected]>
// Copyright (C) 2010 Pino Toscano <[email protected]>
// Copyright (C) 2011 Andreas Hartmetz <[email protected]>
// Copyright (C) 2013 Thomas Freitag <[email protected]>
// Copyright (C) 2013 Mihai Niculescu <[email protected]>
// Copyright (C) 2017, 2018, 2020 Oliver Sander <[email protected]>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#ifndef QPAINTEROUTPUTDEV_H
#define QPAINTEROUTPUTDEV_H

#include <memory>
#include <map>
#include <stack>

#include "OutputDev.h"
#include "GfxState.h"

#include <ft2build.h>
#include FT_FREETYPE_H

#include <QtGui/QPainter>

class GfxState;
class PDFDoc;

class QRawFont;

class QPainterOutputDevType3Font;

//------------------------------------------------------------------------
// QPainterOutputDev - Qt 5 QPainter renderer
//------------------------------------------------------------------------

class QPainterOutputDev : public OutputDev
{
public:
    // Constructor.
    explicit QPainterOutputDev(QPainter *painter);

    // Destructor.
    ~QPainterOutputDev() override;

    void setHintingPreference(QFont::HintingPreference hintingPreference) { m_hintingPreference = hintingPreference; }

    //----- get info about output device

    // Does this device use upside-down coordinates?
    // (Upside-down means (0,0) is the top left corner of the page.)
    bool upsideDown() override { return true; }

    // Does this device use drawChar() or drawString()?
    bool useDrawChar() override { return true; }

    // Does this device implement shaded fills (aka gradients) natively?
    // If this returns false, these shaded fills
    // will be reduced to a series of other drawing operations.
    // type==2 is 'axial shading'
    bool useShadedFills(int type) override { return type == 2; }

    // Does this device use beginType3Char/endType3Char?  Otherwise,
    // text in Type 3 fonts will be drawn with drawChar/drawString.
    bool interpretType3Chars() override { return false; }

    //----- initialization and control

    // Set Current Transformation Matrix to a fixed matrix given in ctm[0],...,ctm[5]
    void setDefaultCTM(const double *ctm) override;

    // Start a page.
    void startPage(int pageNum, GfxState *state, XRef *xref) override;

    // End a page.
    void endPage() override;

    //----- save/restore graphics state
    void saveState(GfxState *state) override;
    void restoreState(GfxState *state) override;

    //----- update graphics state
    void updateAll(GfxState *state) override;
    void updateCTM(GfxState *state, double m11, double m12, double m21, double m22, double m31, double m32) override;
    void updateLineDash(GfxState *state) override;
    void updateFlatness(GfxState *state) override;
    void updateLineJoin(GfxState *state) override;
    void updateLineCap(GfxState *state) override;
    void updateMiterLimit(GfxState *state) override;
    void updateLineWidth(GfxState *state) override;
    void updateFillColor(GfxState *state) override;
    void updateStrokeColor(GfxState *state) override;
    void updateBlendMode(GfxState *state) override;
    void updateFillOpacity(GfxState *state) override;
    void updateStrokeOpacity(GfxState *state) override;

    //----- update text state
    void updateFont(GfxState *state) override;

    //----- path painting
    void stroke(GfxState *state) override;
    void fill(GfxState *state) override;
    void eoFill(GfxState *state) override;
    bool axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax) override;

    //----- path clipping
    void clip(GfxState *state) override;
    void eoClip(GfxState *state) override;
    void clipToStrokePath(GfxState *state) override;

    //----- text drawing
    //   virtual void drawString(GfxState *state, GooString *s);
    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;
    void endTextObject(GfxState *state) override;

    //----- image drawing
    void drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, bool invert, bool interpolate, bool inlineImg) override;
    void drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, const int *maskColors, bool inlineImg) override;

    void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, bool interpolate, Stream *maskStr, int maskWidth, int maskHeight, GfxImageColorMap *maskColorMap,
                             bool maskInterpolate) override;

    //----- Type 3 font operators
    void type3D0(GfxState *state, double wx, double wy) override;
    void type3D1(GfxState *state, double wx, double wy, double llx, double lly, double urx, double ury) override;

    //----- transparency groups and soft masks
    void beginTransparencyGroup(GfxState *state, const double *bbox, GfxColorSpace *blendingColorSpace, bool isolated, bool knockout, bool forSoftMask) override;
    void endTransparencyGroup(GfxState *state) override;
    void paintTransparencyGroup(GfxState *state, const double *bbox) override;

    //----- special access

    // Called to indicate that a new PDF document has been loaded.
    void startDoc(PDFDoc *doc);

    bool isReverseVideo() { return false; }

private:
    // The stack of QPainters is used to implement transparency groups.  When such a group
    // is opened, annew Painter that paints onto a QPicture is pushed onto the stack.
    // It is popped again when the transparency group ends.
    std::stack<QPainter *> m_painter;

    // This is the corresponding stack of QPicture objects
    std::stack<QPicture *> m_qpictures;

    // endTransparencyGroup removes a QPicture from the stack, but stores
    // it here for later use in paintTransparencyGroup.
    QPicture *m_lastTransparencyGroupPicture;

    QFont::HintingPreference m_hintingPreference;

    QPen m_currentPen;
    // The various stacks are used to implement the 'saveState' and 'restoreState' methods
    std::stack<QPen> m_currentPenStack;

    QBrush m_currentBrush;
    std::stack<QBrush> m_currentBrushStack;

    bool m_needFontUpdate; // set when the font needs to be updated
    PDFDoc *m_doc;
    XRef *xref; // xref table for current document

    // The current font in use
    QRawFont *m_rawFont;
    std::stack<QRawFont *> m_rawFontStack;

    QPainterOutputDevType3Font *m_currentType3Font;
    std::stack<QPainterOutputDevType3Font *> m_type3FontStack;

    // Cache all fonts by their Ref and font size
    using QPainterFontID = std::pair<Ref, double>;
    std::map<QPainterFontID, std::unique_ptr<QRawFont>> m_rawFontCache;
    std::map<QPainterFontID, std::unique_ptr<QPainterOutputDevType3Font>> m_type3FontCache;
    std::map<Ref, const int *> m_codeToGIDCache;

    // The table that maps character codes to glyph indexes
    const int *m_codeToGID;
    std::stack<const int *> m_codeToGIDStack;

    FT_Library m_ftLibrary;
    // as of FT 2.1.8, CID fonts are indexed by CID instead of GID
    bool m_useCIDs;
};

#endif