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 QSVGHANDLER_P_H |
5 | #define QSVGHANDLER_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 "QtCore/qxmlstream.h" |
19 | #include "QtCore/qhash.h" |
20 | #include "QtCore/qstack.h" |
21 | #include <QtCore/QLoggingCategory> |
22 | #include "qsvgstyle_p.h" |
23 | #if QT_CONFIG(cssparser) |
24 | #include "private/qcssparser_p.h" |
25 | #endif |
26 | #include "qsvggraphics_p.h" |
27 | #include "qtsvgglobal_p.h" |
28 | |
29 | QT_BEGIN_NAMESPACE |
30 | |
31 | class QSvgNode; |
32 | class QSvgTinyDocument; |
33 | class QSvgHandler; |
34 | class QColor; |
35 | class QSvgStyleSelector; |
36 | |
37 | #ifndef QT_NO_CSSPARSER |
38 | |
39 | struct QSvgCssAttribute |
40 | { |
41 | QString name; |
42 | QString value; |
43 | }; |
44 | |
45 | #endif |
46 | |
47 | class Q_SVG_PRIVATE_EXPORT QSvgHandler |
48 | { |
49 | public: |
50 | enum LengthType { |
51 | LT_PERCENT, |
52 | LT_PX, |
53 | LT_PC, |
54 | LT_PT, |
55 | LT_MM, |
56 | LT_CM, |
57 | LT_IN, |
58 | LT_OTHER |
59 | }; |
60 | |
61 | public: |
62 | QSvgHandler(QIODevice *device); |
63 | QSvgHandler(const QByteArray &data); |
64 | QSvgHandler(QXmlStreamReader *const data); |
65 | ~QSvgHandler(); |
66 | |
67 | QIODevice *device() const; |
68 | QSvgTinyDocument *document() const; |
69 | |
70 | inline bool ok() const { |
71 | return document() != 0 && !xml->hasError(); |
72 | } |
73 | |
74 | inline QString errorString() const { return xml->errorString(); } |
75 | inline int lineNumber() const { return xml->lineNumber(); } |
76 | |
77 | void setDefaultCoordinateSystem(LengthType type); |
78 | LengthType defaultCoordinateSystem() const; |
79 | |
80 | void pushColor(const QColor &color); |
81 | void pushColorCopy(); |
82 | void popColor(); |
83 | QColor currentColor() const; |
84 | |
85 | #ifndef QT_NO_CSSPARSER |
86 | void setInStyle(bool b); |
87 | bool inStyle() const; |
88 | |
89 | QSvgStyleSelector *selector() const; |
90 | #endif |
91 | |
92 | void setAnimPeriod(int start, int end); |
93 | int animationDuration() const; |
94 | |
95 | #ifndef QT_NO_CSSPARSER |
96 | void parseCSStoXMLAttrs(const QString &css, QList<QSvgCssAttribute> *attributes); |
97 | #endif |
98 | |
99 | inline QPen defaultPen() const |
100 | { return m_defaultPen; } |
101 | |
102 | public: |
103 | bool startElement(const QString &localName, const QXmlStreamAttributes &attributes); |
104 | bool endElement(QStringView localName); |
105 | bool characters(QStringView str); |
106 | bool processingInstruction(const QString &target, const QString &data); |
107 | |
108 | private: |
109 | void init(); |
110 | |
111 | QSvgTinyDocument *m_doc; |
112 | QStack<QSvgNode *> m_nodes; |
113 | // TODO: This is only needed during parsing, so it unnecessarily takes up space after that. |
114 | // Temporary container for <use> nodes which haven't been resolved yet. |
115 | QList<QSvgUse *> m_toBeResolved; |
116 | |
117 | enum CurrentNode |
118 | { |
119 | Unknown, |
120 | Graphics, |
121 | Style |
122 | }; |
123 | QStack<CurrentNode> m_skipNodes; |
124 | |
125 | /*! |
126 | Follows the depths of elements. The top is current xml:space |
127 | value that applies for a given element. |
128 | */ |
129 | QStack<QSvgText::WhitespaceMode> m_whitespaceMode; |
130 | |
131 | QSvgRefCounter<QSvgStyleProperty> m_style; |
132 | |
133 | LengthType m_defaultCoords; |
134 | |
135 | QStack<QColor> m_colorStack; |
136 | QStack<int> m_colorTagCount; |
137 | |
138 | int m_animEnd; |
139 | |
140 | QXmlStreamReader *const xml; |
141 | #ifndef QT_NO_CSSPARSER |
142 | bool m_inStyle; |
143 | QSvgStyleSelector *m_selector; |
144 | QCss::Parser m_cssParser; |
145 | #endif |
146 | void parse(); |
147 | void resolveGradients(QSvgNode *node, int nestedDepth = 0); |
148 | void resolveNodes(); |
149 | |
150 | QPen m_defaultPen; |
151 | /** |
152 | * Whether we own the variable xml, and hence whether |
153 | * we need to delete it. |
154 | */ |
155 | const bool m_ownsReader; |
156 | }; |
157 | |
158 | Q_DECLARE_LOGGING_CATEGORY(lcSvgHandler) |
159 | |
160 | QT_END_NAMESPACE |
161 | |
162 | #endif // QSVGHANDLER_P_H |
163 | |