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 QSVGSTYLE_P_H |
5 | #define QSVGSTYLE_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/qstack.h" |
19 | #include "QtGui/qpainter.h" |
20 | #include "QtGui/qpen.h" |
21 | #include "QtGui/qbrush.h" |
22 | #include "QtGui/qtransform.h" |
23 | #include "QtGui/qcolor.h" |
24 | #include "QtGui/qfont.h" |
25 | #include <qdebug.h> |
26 | #include "qtsvgglobal_p.h" |
27 | |
28 | QT_BEGIN_NAMESPACE |
29 | |
30 | class QPainter; |
31 | class QSvgNode; |
32 | class QSvgFont; |
33 | class QSvgTinyDocument; |
34 | class QSvgPattern; |
35 | |
36 | template <class T> class QSvgRefCounter |
37 | { |
38 | public: |
39 | QSvgRefCounter() { t = nullptr; } |
40 | QSvgRefCounter(T *_t) |
41 | { |
42 | t = _t; |
43 | if (t) |
44 | t->ref(); |
45 | } |
46 | QSvgRefCounter(const QSvgRefCounter &other) |
47 | { |
48 | t = other.t; |
49 | if (t) |
50 | t->ref(); |
51 | } |
52 | QSvgRefCounter &operator =(T *_t) |
53 | { |
54 | if(_t) |
55 | _t->ref(); |
56 | if (t) |
57 | t->deref(); |
58 | t = _t; |
59 | return *this; |
60 | } |
61 | QSvgRefCounter &operator =(const QSvgRefCounter &other) |
62 | { |
63 | if(other.t) |
64 | other.t->ref(); |
65 | if (t) |
66 | t->deref(); |
67 | t = other.t; |
68 | return *this; |
69 | } |
70 | ~QSvgRefCounter() |
71 | { |
72 | if (t) |
73 | t->deref(); |
74 | } |
75 | |
76 | inline T *operator->() const { return t; } |
77 | inline operator T*() const { return t; } |
78 | |
79 | inline bool isDefault() const { return !t || t->isDefault(); } |
80 | |
81 | private: |
82 | T *t; |
83 | }; |
84 | |
85 | class Q_SVG_EXPORT QSvgRefCounted |
86 | { |
87 | public: |
88 | QSvgRefCounted() { _ref = 0; } |
89 | virtual ~QSvgRefCounted() {} |
90 | void ref() { |
91 | ++_ref; |
92 | // qDebug() << this << ": adding ref, now " << _ref; |
93 | } |
94 | void deref() { |
95 | // qDebug() << this << ": removing ref, now " << _ref; |
96 | if(!--_ref) { |
97 | // qDebug(" deleting"); |
98 | delete this; |
99 | } |
100 | } |
101 | private: |
102 | int _ref; |
103 | }; |
104 | |
105 | struct Q_SVG_EXPORT QSvgExtraStates |
106 | { |
107 | QSvgExtraStates(); |
108 | |
109 | qreal fillOpacity; |
110 | qreal strokeOpacity; |
111 | QSvgFont *svgFont; |
112 | Qt::Alignment textAnchor; |
113 | int fontWeight; |
114 | Qt::FillRule fillRule; |
115 | qreal strokeDashOffset; |
116 | int nestedUseLevel = 0; |
117 | int nestedUseCount = 0; |
118 | bool vectorEffect; // true if pen is cosmetic |
119 | qint8 imageRendering; // QSvgQualityStyle::ImageRendering |
120 | bool inUse = false; // true if currently in QSvgUseNode |
121 | }; |
122 | |
123 | class Q_SVG_EXPORT QSvgStyleProperty : public QSvgRefCounted |
124 | { |
125 | public: |
126 | enum Type |
127 | { |
128 | QUALITY, |
129 | FILL, |
130 | VIEWPORT_FILL, |
131 | FONT, |
132 | STROKE, |
133 | SOLID_COLOR, |
134 | GRADIENT, |
135 | PATTERN, |
136 | TRANSFORM, |
137 | ANIMATE_TRANSFORM, |
138 | ANIMATE_COLOR, |
139 | OPACITY, |
140 | COMP_OP |
141 | }; |
142 | public: |
143 | virtual ~QSvgStyleProperty(); |
144 | virtual void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) = 0; |
145 | virtual void revert(QPainter *p, QSvgExtraStates &states) =0; |
146 | virtual Type type() const=0; |
147 | bool isDefault() const { return false; } // [not virtual since called from templated class] |
148 | }; |
149 | |
150 | class Q_SVG_EXPORT QSvgPaintStyleProperty : public QSvgStyleProperty |
151 | { |
152 | public: |
153 | virtual QBrush brush(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) = 0; |
154 | void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override; |
155 | void revert(QPainter *p, QSvgExtraStates &states) override; |
156 | }; |
157 | |
158 | class Q_SVG_EXPORT QSvgQualityStyle : public QSvgStyleProperty |
159 | { |
160 | public: |
161 | enum ImageRendering: qint8 { |
162 | ImageRenderingAuto = 0, |
163 | ImageRenderingOptimizeSpeed = 1, |
164 | ImageRenderingOptimizeQuality = 2, |
165 | }; |
166 | |
167 | QSvgQualityStyle(int color); |
168 | void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override; |
169 | void revert(QPainter *p, QSvgExtraStates &states) override; |
170 | Type type() const override; |
171 | |
172 | void setImageRendering(ImageRendering); |
173 | private: |
174 | // color-render ing v v 'auto' | 'optimizeSpeed' | |
175 | // 'optimizeQuality' | 'inherit' |
176 | //int m_colorRendering; |
177 | |
178 | // shape-rendering v v 'auto' | 'optimizeSpeed' | 'crispEdges' | |
179 | // 'geometricPrecision' | 'inherit' |
180 | //QSvgShapeRendering m_shapeRendering; |
181 | |
182 | |
183 | // text-rendering v v 'auto' | 'optimizeSpeed' | 'optimizeLegibility' |
184 | // | 'geometricPrecision' | 'inherit' |
185 | //QSvgTextRendering m_textRendering; |
186 | |
187 | |
188 | // vector-effect v x 'default' | 'non-scaling-stroke' | 'inherit' |
189 | //QSvgVectorEffect m_vectorEffect; |
190 | |
191 | // image-rendering v v 'auto' | 'optimizeSpeed' | 'optimizeQuality' | |
192 | // 'inherit' |
193 | qint32 m_imageRendering: 4; |
194 | qint32 m_oldImageRendering: 4; |
195 | quint32 m_imageRenderingSet: 1; |
196 | }; |
197 | |
198 | |
199 | |
200 | class Q_SVG_EXPORT QSvgOpacityStyle : public QSvgStyleProperty |
201 | { |
202 | public: |
203 | QSvgOpacityStyle(qreal opacity); |
204 | void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override; |
205 | void revert(QPainter *p, QSvgExtraStates &states) override; |
206 | Type type() const override; |
207 | qreal opacity() const { return m_opacity; } |
208 | bool isDefault() const { return qFuzzyCompare(p1: m_opacity, p2: qreal(1.0)); } |
209 | |
210 | private: |
211 | qreal m_opacity; |
212 | qreal m_oldOpacity; |
213 | }; |
214 | |
215 | class Q_SVG_EXPORT QSvgFillStyle : public QSvgStyleProperty |
216 | { |
217 | public: |
218 | QSvgFillStyle(); |
219 | void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override; |
220 | void revert(QPainter *p, QSvgExtraStates &states) override; |
221 | Type type() const override; |
222 | |
223 | void setFillRule(Qt::FillRule f); |
224 | void setFillOpacity(qreal opacity); |
225 | void setFillStyle(QSvgPaintStyleProperty* style); |
226 | void setBrush(QBrush brush); |
227 | |
228 | const QBrush & qbrush() const |
229 | { |
230 | return m_fill; |
231 | } |
232 | |
233 | qreal fillOpacity() const |
234 | { |
235 | return m_fillOpacity; |
236 | } |
237 | |
238 | Qt::FillRule fillRule() const |
239 | { |
240 | return m_fillRule; |
241 | } |
242 | |
243 | QSvgPaintStyleProperty* style() const |
244 | { |
245 | return m_style; |
246 | } |
247 | |
248 | void setPaintStyleId(const QString &Id) |
249 | { |
250 | m_paintStyleId = Id; |
251 | } |
252 | |
253 | QString paintStyleId() const |
254 | { |
255 | return m_paintStyleId; |
256 | } |
257 | |
258 | void setPaintStyleResolved(bool resolved) |
259 | { |
260 | m_paintStyleResolved = resolved; |
261 | } |
262 | |
263 | bool isPaintStyleResolved() const |
264 | { |
265 | return m_paintStyleResolved; |
266 | } |
267 | |
268 | private: |
269 | // fill v v 'inherit' | <Paint.datatype> |
270 | // fill-opacity v v 'inherit' | <OpacityValue.datatype> |
271 | QBrush m_fill; |
272 | QBrush m_oldFill; |
273 | QSvgPaintStyleProperty *m_style; |
274 | |
275 | Qt::FillRule m_fillRule; |
276 | Qt::FillRule m_oldFillRule; |
277 | qreal m_fillOpacity; |
278 | qreal m_oldFillOpacity; |
279 | |
280 | QString m_paintStyleId; |
281 | uint m_paintStyleResolved : 1; |
282 | |
283 | uint m_fillRuleSet : 1; |
284 | uint m_fillOpacitySet : 1; |
285 | uint m_fillSet : 1; |
286 | }; |
287 | |
288 | class Q_SVG_EXPORT QSvgViewportFillStyle : public QSvgStyleProperty |
289 | { |
290 | public: |
291 | QSvgViewportFillStyle(const QBrush &brush); |
292 | void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override; |
293 | void revert(QPainter *p, QSvgExtraStates &states) override; |
294 | Type type() const override; |
295 | |
296 | const QBrush & qbrush() const |
297 | { |
298 | return m_viewportFill; |
299 | } |
300 | private: |
301 | // viewport-fill v x 'inherit' | <Paint.datatype> |
302 | // viewport-fill-opacity v x 'inherit' | <OpacityValue.datatype> |
303 | QBrush m_viewportFill; |
304 | |
305 | QBrush m_oldFill; |
306 | }; |
307 | |
308 | class Q_SVG_EXPORT QSvgFontStyle : public QSvgStyleProperty |
309 | { |
310 | public: |
311 | static const int LIGHTER = -1; |
312 | static const int BOLDER = 1; |
313 | |
314 | QSvgFontStyle(QSvgFont *font, QSvgTinyDocument *doc); |
315 | QSvgFontStyle(); |
316 | void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override; |
317 | void revert(QPainter *p, QSvgExtraStates &states) override; |
318 | Type type() const override; |
319 | |
320 | void setSize(qreal size) |
321 | { |
322 | // Store the _pixel_ size in the font. Since QFont::setPixelSize() only takes an int, call |
323 | // QFont::SetPointSize() instead. Set proper font size just before rendering. |
324 | m_qfont.setPointSizeF(size); |
325 | m_sizeSet = 1; |
326 | } |
327 | |
328 | void setTextAnchor(Qt::Alignment anchor) |
329 | { |
330 | m_textAnchor = anchor; |
331 | m_textAnchorSet = 1; |
332 | } |
333 | |
334 | void setFamily(const QString &family) |
335 | { |
336 | m_qfont.setFamilies({family}); |
337 | m_familySet = 1; |
338 | } |
339 | |
340 | void setStyle(QFont::Style fontStyle) { |
341 | m_qfont.setStyle(fontStyle); |
342 | m_styleSet = 1; |
343 | } |
344 | |
345 | void setVariant(QFont::Capitalization fontVariant) |
346 | { |
347 | m_qfont.setCapitalization(fontVariant); |
348 | m_variantSet = 1; |
349 | } |
350 | |
351 | void setWeight(int weight) |
352 | { |
353 | m_weight = weight; |
354 | m_weightSet = 1; |
355 | } |
356 | |
357 | QSvgFont * svgFont() const |
358 | { |
359 | return m_svgFont; |
360 | } |
361 | |
362 | const QFont &qfont() const |
363 | { |
364 | return m_qfont; |
365 | } |
366 | |
367 | QSvgTinyDocument *doc() const {return m_doc;} |
368 | |
369 | private: |
370 | QSvgFont *m_svgFont; |
371 | QSvgTinyDocument *m_doc; |
372 | QFont m_qfont; |
373 | |
374 | int m_weight; |
375 | Qt::Alignment m_textAnchor; |
376 | |
377 | QSvgFont *m_oldSvgFont; |
378 | QFont m_oldQFont; |
379 | Qt::Alignment m_oldTextAnchor; |
380 | int m_oldWeight; |
381 | |
382 | uint m_familySet : 1; |
383 | uint m_sizeSet : 1; |
384 | uint m_styleSet : 1; |
385 | uint m_variantSet : 1; |
386 | uint m_weightSet : 1; |
387 | uint m_textAnchorSet : 1; |
388 | }; |
389 | |
390 | class Q_SVG_EXPORT QSvgStrokeStyle : public QSvgStyleProperty |
391 | { |
392 | public: |
393 | QSvgStrokeStyle(); |
394 | void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override; |
395 | void revert(QPainter *p, QSvgExtraStates &states) override; |
396 | Type type() const override; |
397 | |
398 | void setStroke(QBrush brush) |
399 | { |
400 | m_stroke.setBrush(brush); |
401 | m_style = nullptr; |
402 | m_strokeSet = 1; |
403 | } |
404 | |
405 | void setStyle(QSvgPaintStyleProperty *style) |
406 | { |
407 | m_style = style; |
408 | m_strokeSet = 1; |
409 | } |
410 | |
411 | void setDashArray(const QList<qreal> &dashes); |
412 | |
413 | void setDashArrayNone() |
414 | { |
415 | m_stroke.setStyle(Qt::SolidLine); |
416 | m_strokeDashArraySet = 1; |
417 | } |
418 | |
419 | void setDashOffset(qreal offset) |
420 | { |
421 | m_strokeDashOffset = offset; |
422 | m_strokeDashOffsetSet = 1; |
423 | } |
424 | |
425 | void setLineCap(Qt::PenCapStyle cap) |
426 | { |
427 | m_stroke.setCapStyle(cap); |
428 | m_strokeLineCapSet = 1; |
429 | } |
430 | |
431 | void setLineJoin(Qt::PenJoinStyle join) |
432 | { |
433 | m_stroke.setJoinStyle(join); |
434 | m_strokeLineJoinSet = 1; |
435 | } |
436 | |
437 | void setMiterLimit(qreal limit) |
438 | { |
439 | m_stroke.setMiterLimit(limit); |
440 | m_strokeMiterLimitSet = 1; |
441 | } |
442 | |
443 | void setOpacity(qreal opacity) |
444 | { |
445 | m_strokeOpacity = opacity; |
446 | m_strokeOpacitySet = 1; |
447 | } |
448 | |
449 | void setWidth(qreal width) |
450 | { |
451 | m_stroke.setWidthF(width); |
452 | m_strokeWidthSet = 1; |
453 | Q_ASSERT(!m_strokeDashArraySet); // set width before dash array. |
454 | } |
455 | |
456 | qreal width() |
457 | { |
458 | return m_stroke.widthF(); |
459 | } |
460 | |
461 | void setVectorEffect(bool nonScalingStroke) |
462 | { |
463 | m_vectorEffect = nonScalingStroke; |
464 | m_vectorEffectSet = 1; |
465 | } |
466 | |
467 | QSvgPaintStyleProperty* style() const |
468 | { |
469 | return m_style; |
470 | } |
471 | |
472 | void setPaintStyleId(const QString &Id) |
473 | { |
474 | m_paintStyleId = Id; |
475 | } |
476 | |
477 | QString paintStyleId() const |
478 | { |
479 | return m_paintStyleId; |
480 | } |
481 | |
482 | void setPaintStyleResolved(bool resolved) |
483 | { |
484 | m_paintStyleResolved = resolved; |
485 | } |
486 | |
487 | bool isPaintStyleResolved() const |
488 | { |
489 | return m_paintStyleResolved; |
490 | } |
491 | |
492 | QPen stroke() const |
493 | { |
494 | return m_stroke; |
495 | } |
496 | |
497 | private: |
498 | // stroke v v 'inherit' | <Paint.datatype> |
499 | // stroke-dasharray v v 'inherit' | <StrokeDashArrayValue.datatype> |
500 | // stroke-dashoffset v v 'inherit' | <StrokeDashOffsetValue.datatype> |
501 | // stroke-linecap v v 'butt' | 'round' | 'square' | 'inherit' |
502 | // stroke-linejoin v v 'miter' | 'round' | 'bevel' | 'inherit' |
503 | // stroke-miterlimit v v 'inherit' | <StrokeMiterLimitValue.datatype> |
504 | // stroke-opacity v v 'inherit' | <OpacityValue.datatype> |
505 | // stroke-width v v 'inherit' | <StrokeWidthValue.datatype> |
506 | QPen m_stroke; |
507 | QPen m_oldStroke; |
508 | qreal m_strokeOpacity; |
509 | qreal m_oldStrokeOpacity; |
510 | qreal m_strokeDashOffset; |
511 | qreal m_oldStrokeDashOffset; |
512 | |
513 | QSvgPaintStyleProperty *m_style; |
514 | QString m_paintStyleId; |
515 | uint m_paintStyleResolved : 1; |
516 | uint m_vectorEffect : 1; |
517 | uint m_oldVectorEffect : 1; |
518 | |
519 | uint m_strokeSet : 1; |
520 | uint m_strokeDashArraySet : 1; |
521 | uint m_strokeDashOffsetSet : 1; |
522 | uint m_strokeLineCapSet : 1; |
523 | uint m_strokeLineJoinSet : 1; |
524 | uint m_strokeMiterLimitSet : 1; |
525 | uint m_strokeOpacitySet : 1; |
526 | uint m_strokeWidthSet : 1; |
527 | uint m_vectorEffectSet : 1; |
528 | }; |
529 | |
530 | class Q_SVG_EXPORT QSvgSolidColorStyle : public QSvgPaintStyleProperty |
531 | { |
532 | public: |
533 | QSvgSolidColorStyle(const QColor &color); |
534 | Type type() const override; |
535 | |
536 | const QColor & qcolor() const |
537 | { |
538 | return m_solidColor; |
539 | } |
540 | |
541 | QBrush brush(QPainter *, const QSvgNode *, QSvgExtraStates &) override |
542 | { |
543 | return m_solidColor; |
544 | } |
545 | |
546 | private: |
547 | // solid-color v x 'inherit' | <SVGColor.datatype> |
548 | // solid-opacity v x 'inherit' | <OpacityValue.datatype> |
549 | QColor m_solidColor; |
550 | |
551 | QBrush m_oldFill; |
552 | QPen m_oldStroke; |
553 | }; |
554 | |
555 | class Q_SVG_EXPORT QSvgGradientStyle : public QSvgPaintStyleProperty |
556 | { |
557 | public: |
558 | QSvgGradientStyle(QGradient *grad); |
559 | ~QSvgGradientStyle() { delete m_gradient; } |
560 | Type type() const override; |
561 | |
562 | void setStopLink(const QString &link, QSvgTinyDocument *doc); |
563 | QString stopLink() const { return m_link; } |
564 | void resolveStops(); |
565 | void resolveStops_helper(QStringList *visited); |
566 | |
567 | void setTransform(const QTransform &transform); |
568 | QTransform qtransform() const |
569 | { |
570 | return m_transform; |
571 | } |
572 | |
573 | QGradient *qgradient() const |
574 | { |
575 | return m_gradient; |
576 | } |
577 | |
578 | bool gradientStopsSet() const |
579 | { |
580 | return m_gradientStopsSet; |
581 | } |
582 | |
583 | void setGradientStopsSet(bool set) |
584 | { |
585 | m_gradientStopsSet = set; |
586 | } |
587 | |
588 | QBrush brush(QPainter *, const QSvgNode *, QSvgExtraStates &) override; |
589 | private: |
590 | QGradient *m_gradient; |
591 | QTransform m_transform; |
592 | |
593 | QSvgTinyDocument *m_doc; |
594 | QString m_link; |
595 | bool m_gradientStopsSet; |
596 | }; |
597 | |
598 | class Q_SVG_EXPORT QSvgPatternStyle : public QSvgPaintStyleProperty |
599 | { |
600 | public: |
601 | QSvgPatternStyle(QSvgPattern *pattern); |
602 | ~QSvgPatternStyle() = default; |
603 | Type type() const override; |
604 | |
605 | QBrush brush(QPainter *, const QSvgNode *, QSvgExtraStates &) override; |
606 | QSvgPattern *patternNode() { return m_pattern; } |
607 | private: |
608 | QSvgPattern *m_pattern; |
609 | QImage m_patternImage; |
610 | QRectF m_parentBound; |
611 | }; |
612 | |
613 | |
614 | class Q_SVG_EXPORT QSvgTransformStyle : public QSvgStyleProperty |
615 | { |
616 | public: |
617 | QSvgTransformStyle(const QTransform &transform); |
618 | void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override; |
619 | void revert(QPainter *p, QSvgExtraStates &states) override; |
620 | Type type() const override; |
621 | |
622 | const QTransform & qtransform() const |
623 | { |
624 | return m_transform; |
625 | } |
626 | bool isDefault() const { return m_transform.isIdentity(); } |
627 | private: |
628 | //7.6 The transform attribute |
629 | QTransform m_transform; |
630 | QStack<QTransform> m_oldWorldTransform; |
631 | }; |
632 | |
633 | class Q_SVG_EXPORT QSvgAnimate : public QSvgStyleProperty |
634 | { |
635 | public: |
636 | QSvgAnimate(); |
637 | void setRepeatCount(qreal repeatCount); |
638 | void setRunningTime(int startMs, int durMs, int endMs, int by = 0); |
639 | |
640 | protected: |
641 | qreal lerp(qreal a, qreal b, qreal t) const; |
642 | qreal currentIterTimeFraction(qreal elapsedTime); |
643 | |
644 | protected: |
645 | qreal m_from; |
646 | qreal m_totalRunningTime; |
647 | qreal m_end; |
648 | qreal m_repeatCount; |
649 | bool m_finished; |
650 | }; |
651 | |
652 | class Q_SVG_EXPORT QSvgAnimateTransform : public QSvgAnimate |
653 | { |
654 | public: |
655 | enum TransformType |
656 | { |
657 | Empty, |
658 | Translate, |
659 | Scale, |
660 | Rotate, |
661 | SkewX, |
662 | SkewY |
663 | }; |
664 | enum Additive |
665 | { |
666 | Sum, |
667 | Replace |
668 | }; |
669 | public: |
670 | QSvgAnimateTransform(); |
671 | void setArgs(TransformType type, Additive additive, const QList<qreal> &args); |
672 | void setFreeze(bool freeze); |
673 | void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override; |
674 | void revert(QPainter *p, QSvgExtraStates &states) override; |
675 | Type type() const override; |
676 | QSvgAnimateTransform::Additive additiveType() const |
677 | { |
678 | return m_additive; |
679 | } |
680 | |
681 | bool animActive(qreal totalTimeElapsed) |
682 | { |
683 | if (totalTimeElapsed < m_from) |
684 | return false; |
685 | if (m_freeze || m_repeatCount < 0) // fill="freeze" or repeat="indefinite" |
686 | return true; |
687 | if (m_totalRunningTime == 0) |
688 | return false; |
689 | qreal animationFrame = (totalTimeElapsed - m_from) / m_totalRunningTime; |
690 | if (animationFrame > m_repeatCount) |
691 | return false; |
692 | return true; |
693 | } |
694 | |
695 | bool transformApplied() const |
696 | { |
697 | return m_transformApplied; |
698 | } |
699 | |
700 | // Call this instead of revert if you know that revert is unnecessary. |
701 | void clearTransformApplied() |
702 | { |
703 | m_transformApplied = false; |
704 | } |
705 | |
706 | protected: |
707 | void resolveMatrix(const QSvgNode *node); |
708 | private: |
709 | TransformType m_type; |
710 | Additive m_additive; |
711 | QList<qreal> m_args; |
712 | int m_count; |
713 | QTransform m_transform; |
714 | QTransform m_oldWorldTransform; |
715 | bool m_freeze; |
716 | bool m_transformApplied; |
717 | }; |
718 | |
719 | |
720 | class Q_SVG_EXPORT QSvgAnimateColor : public QSvgAnimate |
721 | { |
722 | public: |
723 | QSvgAnimateColor(); |
724 | void setArgs(bool fill, const QList<QColor> &colors); |
725 | void setFreeze(bool freeze); |
726 | void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override; |
727 | void revert(QPainter *p, QSvgExtraStates &states) override; |
728 | Type type() const override; |
729 | private: |
730 | QList<QColor> m_colors; |
731 | QBrush m_oldBrush; |
732 | QPen m_oldPen; |
733 | bool m_fill; |
734 | bool m_freeze; |
735 | }; |
736 | |
737 | |
738 | class Q_SVG_EXPORT QSvgCompOpStyle : public QSvgStyleProperty |
739 | { |
740 | public: |
741 | QSvgCompOpStyle(QPainter::CompositionMode mode); |
742 | void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override; |
743 | void revert(QPainter *p, QSvgExtraStates &states) override; |
744 | Type type() const override; |
745 | |
746 | const QPainter::CompositionMode & compOp() const |
747 | { |
748 | return m_mode; |
749 | } |
750 | private: |
751 | //comp-op attribute |
752 | QPainter::CompositionMode m_mode; |
753 | |
754 | QPainter::CompositionMode m_oldMode; |
755 | }; |
756 | |
757 | |
758 | class Q_SVG_EXPORT QSvgStyle |
759 | { |
760 | public: |
761 | QSvgStyle() |
762 | : quality(0), |
763 | fill(0), |
764 | viewportFill(0), |
765 | font(0), |
766 | stroke(0), |
767 | solidColor(0), |
768 | gradient(0), |
769 | pattern(0), |
770 | transform(0), |
771 | opacity(0), |
772 | compop(0) |
773 | {} |
774 | ~QSvgStyle(); |
775 | |
776 | void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states); |
777 | void revert(QPainter *p, QSvgExtraStates &states); |
778 | QSvgRefCounter<QSvgQualityStyle> quality; |
779 | QSvgRefCounter<QSvgFillStyle> fill; |
780 | QSvgRefCounter<QSvgViewportFillStyle> viewportFill; |
781 | QSvgRefCounter<QSvgFontStyle> font; |
782 | QSvgRefCounter<QSvgStrokeStyle> stroke; |
783 | QSvgRefCounter<QSvgSolidColorStyle> solidColor; |
784 | QSvgRefCounter<QSvgGradientStyle> gradient; |
785 | QSvgRefCounter<QSvgPatternStyle> pattern; |
786 | QSvgRefCounter<QSvgTransformStyle> transform; |
787 | QList<QSvgRefCounter<QSvgAnimateColor> > animateColors; |
788 | QList<QSvgRefCounter<QSvgAnimateTransform> > animateTransforms; |
789 | QSvgRefCounter<QSvgOpacityStyle> opacity; |
790 | QSvgRefCounter<QSvgCompOpStyle> compop; |
791 | }; |
792 | |
793 | /********************************************************/ |
794 | // NOT implemented: |
795 | |
796 | // color v v 'inherit' | <Color.datatype> |
797 | //QColor m_color; |
798 | |
799 | // display v x 'inline' | 'block' | 'list-item' |
800 | // | 'run-in' | 'compact' | 'marker' | |
801 | // 'table' | 'inline-table' | |
802 | // 'table-row-group' | 'table-header-group' | |
803 | // 'table-footer-group' | 'table-row' | |
804 | // 'table-column-group' | 'table-column' | |
805 | // 'table-cell' | 'table-caption' | |
806 | // 'none' | 'inherit' |
807 | //QSvgDisplayStyle m_display; |
808 | |
809 | // display-align v v 'auto' | 'before' | 'center' | 'after' | 'inherit' |
810 | //QSvgDisplayAlign m_displayAlign; |
811 | |
812 | // line-increment v v 'auto' | 'inherit' | <Number.datatype> |
813 | //int m_lineIncrement; |
814 | |
815 | // text-anchor v v 'start' | 'middle' | 'end' | 'inherit' |
816 | //QSvgTextAnchor m_textAnchor; |
817 | |
818 | // visibility v v 'visible' | 'hidden' | 'inherit' |
819 | //QSvgVisibility m_visibility; |
820 | |
821 | /******************************************************/ |
822 | // the following do not make sense for us |
823 | |
824 | // pointer-events v v 'visiblePainted' | 'visibleFill' | 'visibleStroke' | |
825 | // 'visible' | 'painted' | 'fill' | 'stroke' | 'all' | |
826 | // 'none' | 'inherit' |
827 | //QSvgPointEvents m_pointerEvents; |
828 | |
829 | // audio-level v x 'inherit' | <Number.datatype> |
830 | |
831 | QT_END_NAMESPACE |
832 | |
833 | #endif // QSVGSTYLE_P_H |
834 |
Definitions
- QSvgRefCounter
- QSvgRefCounter
- QSvgRefCounter
- QSvgRefCounter
- operator =
- operator =
- ~QSvgRefCounter
- operator->
- operator T*
- isDefault
- QSvgRefCounted
- QSvgRefCounted
- ~QSvgRefCounted
- ref
- deref
- QSvgExtraStates
- QSvgStyleProperty
- Type
- isDefault
- QSvgPaintStyleProperty
- QSvgQualityStyle
- ImageRendering
- QSvgOpacityStyle
- opacity
- isDefault
- QSvgFillStyle
- qbrush
- fillOpacity
- fillRule
- style
- setPaintStyleId
- paintStyleId
- setPaintStyleResolved
- isPaintStyleResolved
- QSvgViewportFillStyle
- qbrush
- QSvgFontStyle
- setSize
- setTextAnchor
- setFamily
- setStyle
- setVariant
- setWeight
- svgFont
- qfont
- doc
- QSvgStrokeStyle
- setStroke
- setStyle
- setDashArrayNone
- setDashOffset
- setLineCap
- setLineJoin
- setMiterLimit
- setOpacity
- setWidth
- width
- setVectorEffect
- style
- setPaintStyleId
- paintStyleId
- setPaintStyleResolved
- isPaintStyleResolved
- stroke
- QSvgSolidColorStyle
- qcolor
- brush
- QSvgGradientStyle
- ~QSvgGradientStyle
- stopLink
- qtransform
- qgradient
- gradientStopsSet
- setGradientStopsSet
- QSvgPatternStyle
- ~QSvgPatternStyle
- patternNode
- QSvgTransformStyle
- qtransform
- isDefault
- QSvgAnimate
- QSvgAnimateTransform
- TransformType
- Additive
- additiveType
- animActive
- transformApplied
- clearTransformApplied
- QSvgAnimateColor
- QSvgCompOpStyle
- compOp
- QSvgStyle
Learn Advanced QML with KDAB
Find out more