source: trunk/src/svg/qsvgstructure.cpp@ 428

Last change on this file since 428 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 14.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtSvg module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qsvgstructure_p.h"
43
44#ifndef QT_NO_SVG
45
46#include "qsvgnode_p.h"
47#include "qsvgstyle_p.h"
48
49#include "qpainter.h"
50#include "qlocale.h"
51#include "qdebug.h"
52
53QT_BEGIN_NAMESPACE
54
55QSvgG::QSvgG(QSvgNode *parent)
56 : QSvgStructureNode(parent)
57{
58
59}
60
61QSvgStructureNode::~QSvgStructureNode()
62{
63 qDeleteAll(m_renderers);
64}
65
66void QSvgG::draw(QPainter *p, QSvgExtraStates &states)
67{
68 QList<QSvgNode*>::iterator itr = m_renderers.begin();
69 applyStyle(p, states);
70
71 if (displayMode() != QSvgNode::NoneMode) {
72 while (itr != m_renderers.end()) {
73 QSvgNode *node = *itr;
74 if (node->isVisible())
75 node->draw(p, states);
76 ++itr;
77 }
78 }
79 revertStyle(p, states);
80}
81
82QSvgNode::Type QSvgG::type() const
83{
84 return G;
85}
86
87QSvgStructureNode::QSvgStructureNode(QSvgNode *parent)
88 :QSvgNode(parent)
89{
90
91}
92
93QSvgNode * QSvgStructureNode::scopeNode(const QString &id) const
94{
95 const QSvgStructureNode *group = this;
96 while (group && group->type() != QSvgNode::DOC) {
97 group = static_cast<QSvgStructureNode*>(group->parent());
98 }
99 if (group)
100 return group->m_scope[id];
101 return 0;
102}
103
104void QSvgStructureNode::addChild(QSvgNode *child, const QString &id, bool def)
105{
106 if (!def)
107 m_renderers.append(child);
108
109 if (child->type() == QSvgNode::DEFS) {
110 QSvgDefs *defs =
111 static_cast<QSvgDefs*>(child);
112 m_linkedScopes.append(defs);
113 }
114
115 if (id.isEmpty())
116 return; //we can't add it to scope without id
117
118 QSvgStructureNode *group = this;
119 while (group && group->type() != QSvgNode::DOC) {
120 group = static_cast<QSvgStructureNode*>(group->parent());
121 }
122 if (group)
123 group->m_scope.insert(id, child);
124}
125
126QSvgDefs::QSvgDefs(QSvgNode *parent)
127 : QSvgStructureNode(parent)
128{
129}
130
131void QSvgDefs::draw(QPainter *, QSvgExtraStates &)
132{
133 //noop
134}
135
136QSvgNode::Type QSvgDefs::type() const
137{
138 return DEFS;
139}
140
141QSvgStyleProperty * QSvgStructureNode::scopeStyle(const QString &id) const
142{
143 const QSvgStructureNode *group = this;
144 while (group) {
145 QSvgStyleProperty *prop = group->styleProperty(id);
146 if (prop)
147 return prop;
148 QList<QSvgStructureNode*>::const_iterator itr = group->m_linkedScopes.constBegin();
149 while (itr != group->m_linkedScopes.constEnd()) {
150 prop = (*itr)->styleProperty(id);
151 if (prop)
152 return prop;
153 ++itr;
154 }
155 group = static_cast<QSvgStructureNode*>(group->parent());
156 }
157 return 0;
158}
159
160
161/*
162 Below is a lookup function based on the gperf output using the following set:
163
164 http://www.w3.org/Graphics/SVG/feature/1.2/#SVG
165 http://www.w3.org/Graphics/SVG/feature/1.2/#SVG-static
166 http://www.w3.org/Graphics/SVG/feature/1.2/#CoreAttribute
167 http://www.w3.org/Graphics/SVG/feature/1.2/#Structure
168 http://www.w3.org/Graphics/SVG/feature/1.2/#ConditionalProcessing
169 http://www.w3.org/Graphics/SVG/feature/1.2/#ConditionalProcessingAttribute
170 http://www.w3.org/Graphics/SVG/feature/1.2/#Image
171 http://www.w3.org/Graphics/SVG/feature/1.2/#Prefetch
172 http://www.w3.org/Graphics/SVG/feature/1.2/#Shape
173 http://www.w3.org/Graphics/SVG/feature/1.2/#Text
174 http://www.w3.org/Graphics/SVG/feature/1.2/#PaintAttribute
175 http://www.w3.org/Graphics/SVG/feature/1.2/#OpacityAttribute
176 http://www.w3.org/Graphics/SVG/feature/1.2/#GraphicsAttribute
177 http://www.w3.org/Graphics/SVG/feature/1.2/#Gradient
178 http://www.w3.org/Graphics/SVG/feature/1.2/#SolidColor
179 http://www.w3.org/Graphics/SVG/feature/1.2/#XlinkAttribute
180 http://www.w3.org/Graphics/SVG/feature/1.2/#ExternalResourcesRequiredAttribute
181 http://www.w3.org/Graphics/SVG/feature/1.2/#Font
182 http://www.w3.org/Graphics/SVG/feature/1.2/#Hyperlinking
183 http://www.w3.org/Graphics/SVG/feature/1.2/#Extensibility
184*/
185
186// ----- begin of generated code -----
187
188/* C code produced by gperf version 3.0.2 */
189/* Command-line: gperf -c -L c svg */
190/* Computed positions: -k'45-46' */
191
192#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
193 && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
194 && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
195 && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
196 && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
197 && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
198 && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
199 && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
200 && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
201 && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
202 && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
203 && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
204 && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
205 && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
206 && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
207 && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
208 && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
209 && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
210 && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
211 && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
212 && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
213 && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
214 && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
215/* The character set is not based on ISO-646. */
216#error "gperf generated tables don't work with this execution character set. Please report a bug to <[email protected]>."
217#endif
218
219enum {
220 TOTAL_KEYWORDS = 20,
221 MIN_WORD_LENGTH = 47,
222 MAX_WORD_LENGTH = 78,
223 MIN_HASH_VALUE = 48,
224 MAX_HASH_VALUE = 88
225};
226/* maximum key range = 41, duplicates = 0 */
227
228inline static bool isSupportedSvgFeature(const QString &str)
229{
230 static const unsigned char asso_values[] = {
231 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
232 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
233 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
234 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
235 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
236 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
237 89, 89, 89, 89, 89, 89, 89, 0, 89, 5,
238 15, 5, 0, 10, 89, 89, 89, 89, 89, 0,
239 15, 89, 89, 0, 0, 89, 5, 89, 0, 89,
240 89, 89, 89, 89, 89, 89, 89, 0, 89, 89,
241 89, 0, 89, 89, 0, 89, 89, 89, 0, 5,
242 89, 0, 0, 89, 5, 89, 0, 89, 89, 89,
243 5, 0, 89, 89, 89, 89, 89, 89, 89, 89,
244 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
245 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
246 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
247 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
248 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
249 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
250 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
251 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
252 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
253 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
254 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
255 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
256 89, 89, 89, 89, 89, 89
257 };
258
259 static const char * wordlist[] = {
260 "", "", "", "", "", "", "", "", "",
261 "", "", "", "", "", "", "", "", "",
262 "", "", "", "", "", "", "", "", "",
263 "", "", "", "", "", "", "", "", "",
264 "", "", "", "", "", "", "", "", "",
265 "", "", "",
266 "http://www.w3.org/Graphics/SVG/feature/1.2/#Text",
267 "http://www.w3.org/Graphics/SVG/feature/1.2/#Shape",
268 "", "",
269 "http://www.w3.org/Graphics/SVG/feature/1.2/#SVG",
270 "http://www.w3.org/Graphics/SVG/feature/1.2/#Structure",
271 "http://www.w3.org/Graphics/SVG/feature/1.2/#SolidColor",
272 "",
273 "http://www.w3.org/Graphics/SVG/feature/1.2/#Hyperlinking",
274 "http://www.w3.org/Graphics/SVG/feature/1.2/#CoreAttribute",
275 "http://www.w3.org/Graphics/SVG/feature/1.2/#XlinkAttribute",
276 "http://www.w3.org/Graphics/SVG/feature/1.2/#SVG-static",
277 "http://www.w3.org/Graphics/SVG/feature/1.2/#OpacityAttribute",
278 "",
279 "http://www.w3.org/Graphics/SVG/feature/1.2/#Gradient",
280 "http://www.w3.org/Graphics/SVG/feature/1.2/#Font",
281 "http://www.w3.org/Graphics/SVG/feature/1.2/#Image",
282 "http://www.w3.org/Graphics/SVG/feature/1.2/#ConditionalProcessing",
283 "",
284 "http://www.w3.org/Graphics/SVG/feature/1.2/#Extensibility",
285 "", "", "",
286 "http://www.w3.org/Graphics/SVG/feature/1.2/#GraphicsAttribute",
287 "http://www.w3.org/Graphics/SVG/feature/1.2/#Prefetch",
288 "http://www.w3.org/Graphics/SVG/feature/1.2/#PaintAttribute",
289 "http://www.w3.org/Graphics/SVG/feature/1.2/#ConditionalProcessingAttribute",
290 "", "", "", "", "", "", "", "", "",
291 "", "", "", "",
292 "http://www.w3.org/Graphics/SVG/feature/1.2/#ExternalResourcesRequiredAttribute"
293 };
294
295 if (str.length() <= MAX_WORD_LENGTH && str.length() >= MIN_WORD_LENGTH) {
296 const int key = str.length()
297 + asso_values[str.at(45).unicode()]
298 + asso_values[str.at(44).unicode()];
299 if (key <= MAX_HASH_VALUE && key >= 0)
300 return str == QLatin1String(wordlist[key]);
301 }
302 return false;
303}
304
305// ----- end of generated code -----
306
307static inline bool isSupportedSvgExtension(const QString &)
308{
309 return false;
310}
311
312
313QSvgSwitch::QSvgSwitch(QSvgNode *parent)
314 : QSvgStructureNode(parent)
315{
316 init();
317}
318
319void QSvgSwitch::draw(QPainter *p, QSvgExtraStates &states)
320{
321 QList<QSvgNode*>::iterator itr = m_renderers.begin();
322 applyStyle(p, states);
323
324 if (displayMode() != QSvgNode::NoneMode) {
325 while (itr != m_renderers.end()) {
326 QSvgNode *node = *itr;
327 if (node->isVisible()) {
328 const QStringList &features = node->requiredFeatures();
329 const QStringList &extensions = node->requiredExtensions();
330 const QStringList &languages = node->requiredLanguages();
331 const QStringList &formats = node->requiredFormats();
332 const QStringList &fonts = node->requiredFonts();
333
334 bool okToRender = true;
335 if (!features.isEmpty()) {
336 QStringList::const_iterator sitr = features.constBegin();
337 for (; sitr != features.constEnd(); ++sitr) {
338 if (!isSupportedSvgFeature(*sitr)) {
339 okToRender = false;
340 break;
341 }
342 }
343 }
344
345 if (okToRender && !extensions.isEmpty()) {
346 QStringList::const_iterator sitr = extensions.constBegin();
347 for (; sitr != extensions.constEnd(); ++sitr) {
348 if (!isSupportedSvgExtension(*sitr)) {
349 okToRender = false;
350 break;
351 }
352 }
353 }
354
355 if (okToRender && !languages.isEmpty()) {
356 QStringList::const_iterator sitr = languages.constBegin();
357 okToRender = false;
358 for (; sitr != languages.constEnd(); ++sitr) {
359 if ((*sitr).startsWith(m_systemLanguagePrefix)) {
360 okToRender = true;
361 break;
362 }
363 }
364 }
365
366 if (okToRender && !formats.isEmpty()) {
367 okToRender = false;
368 }
369
370 if (okToRender && !fonts.isEmpty()) {
371 okToRender = false;
372 }
373
374 if (okToRender) {
375 node->draw(p, states);
376 break;
377 }
378 }
379 ++itr;
380 }
381 }
382 revertStyle(p, states);
383}
384
385QSvgNode::Type QSvgSwitch::type() const
386{
387 return SWITCH;
388}
389
390void QSvgSwitch::init()
391{
392 QLocale locale;
393 m_systemLanguage = locale.name().replace(QLatin1Char('_'), QLatin1Char('-'));
394 int idx = m_systemLanguage.indexOf(QLatin1Char('-'));
395 m_systemLanguagePrefix = m_systemLanguage.mid(0, idx);
396}
397
398QRectF QSvgStructureNode::bounds() const
399{
400 if (m_bounds.isEmpty()) {
401 foreach(QSvgNode *node, m_renderers) {
402 m_bounds |= node->transformedBounds(QTransform());
403 }
404 }
405
406 return m_bounds;
407}
408
409QSvgNode * QSvgStructureNode::previousSiblingNode(QSvgNode *n) const
410{
411 QSvgNode *prev = 0;
412 QList<QSvgNode*>::const_iterator itr = m_renderers.constBegin();
413 while (itr != m_renderers.constEnd()) {
414 QSvgNode *node = *itr;
415 if (node == n)
416 return prev;
417 prev = node;
418 }
419 return prev;
420}
421
422QT_END_NAMESPACE
423
424#endif // QT_NO_SVG
Note: See TracBrowser for help on using the repository browser.