Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsvgstyle_p.h
Go to the documentation of this file.
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// Qt-Security score:significant reason:default
4
5
6#ifndef QSVGSTYLE_P_H
7#define QSVGSTYLE_P_H
8
9//
10// W A R N I N G
11// -------------
12//
13// This file is not part of the Qt API. It exists purely as an
14// implementation detail. This header file may change from version to
15// version without notice, or even be removed.
16//
17// We mean it.
18//
19
20#include "QtCore/qstack.h"
21#include "QtGui/qpainter.h"
22#include "QtGui/qpainterpath.h"
23#include "QtGui/qpen.h"
24#include "QtGui/qbrush.h"
25#include "QtGui/qtransform.h"
26#include "QtGui/qfont.h"
27#include <qdebug.h>
28#include "qtsvgglobal_p.h"
29#include <QtSvg/private/qsvgpaintserver_p.h>
30
32
33class QPainter;
34class QSvgNode;
35class QSvgFont;
36class QSvgDocument;
37
38template <class T> class QSvgRefCounter
39{
40public:
41 QSvgRefCounter() { t = nullptr; }
43 {
44 t = _t;
45 if (t)
46 t->ref();
47 }
49 {
50 t = other.t;
51 if (t)
52 t->ref();
53 }
55 {
56 if(_t)
57 _t->ref();
58 if (t)
59 t->deref();
60 t = _t;
61 return *this;
62 }
64 {
65 if(other.t)
66 other.t->ref();
67 if (t)
68 t->deref();
69 t = other.t;
70 return *this;
71 }
73 {
74 if (t)
75 t->deref();
76 }
77
78 inline T *operator->() const { return t; }
79 inline operator T*() const { return t; }
80
81 inline bool isDefault() const { return !t || t->isDefault(); }
82
83private:
84 T *t;
85};
86
87class Q_SVG_EXPORT QSvgRefCounted
88{
89 Q_DISABLE_COPY_MOVE(QSvgRefCounted)
90public:
91 QSvgRefCounted() { _ref = 0; }
92 virtual ~QSvgRefCounted();
93
94 void ref() {
95 ++_ref;
96// qDebug() << this << ": adding ref, now " << _ref;
97 }
98 void deref() {
99// qDebug() << this << ": removing ref, now " << _ref;
100 if(!--_ref) {
101// qDebug(" deleting");
102 delete this;
103 }
104 }
105private:
106 int _ref;
107};
108
109struct Q_SVG_EXPORT QSvgExtraStates
110{
111 QSvgExtraStates();
112
115 QSvgFont *svgFont;
122 bool trustedSource = false;
123 quint8 remainingNestedNodes = QtSvg::renderingMaxNestedNodes;
124 bool vectorEffect; // true if pen is cosmetic
125 qint8 imageRendering; // QSvgQualityStyle::ImageRendering
126 bool inUse = false; // true if currently in QSvgUseNode
127};
128
129class Q_SVG_EXPORT QSvgStyleProperty : public QSvgRefCounted
130{
131public:
132 enum Type
133 {
134 QUALITY,
135 FILL,
136 VIEWPORT_FILL,
137 FONT,
138 STROKE,
139 TRANSFORM,
140 OPACITY,
141 COMP_OP,
142 OFFSET,
143 };
144public:
145 virtual ~QSvgStyleProperty();
146
147 virtual void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) = 0;
148 virtual void revert(QPainter *p, QSvgExtraStates &states) =0;
149 virtual Type type() const=0;
150 bool isDefault() const { return false; } // [not virtual since called from templated class]
151};
152
153class Q_SVG_EXPORT QSvgQualityStyle : public QSvgStyleProperty
154{
155public:
156 enum ImageRendering: qint8 {
157 ImageRenderingAuto = 0,
158 ImageRenderingOptimizeSpeed = 1,
159 ImageRenderingOptimizeQuality = 2,
160 };
161
162 QSvgQualityStyle(int color);
163 ~QSvgQualityStyle() override;
164
165 void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
166 void revert(QPainter *p, QSvgExtraStates &states) override;
167 Type type() const override;
168
169 void setImageRendering(ImageRendering);
170private:
171 // color-render ing v v 'auto' | 'optimizeSpeed' |
172 // 'optimizeQuality' | 'inherit'
173 //int m_colorRendering;
174
175 // shape-rendering v v 'auto' | 'optimizeSpeed' | 'crispEdges' |
176 // 'geometricPrecision' | 'inherit'
177 //QSvgShapeRendering m_shapeRendering;
178
179
180 // text-rendering v v 'auto' | 'optimizeSpeed' | 'optimizeLegibility'
181 // | 'geometricPrecision' | 'inherit'
182 //QSvgTextRendering m_textRendering;
183
184
185 // vector-effect v x 'default' | 'non-scaling-stroke' | 'inherit'
186 //QSvgVectorEffect m_vectorEffect;
187
188 // image-rendering v v 'auto' | 'optimizeSpeed' | 'optimizeQuality' |
189 // 'inherit'
190 qint32 m_imageRendering: 4;
191 qint32 m_oldImageRendering: 4;
192 quint32 m_imageRenderingSet: 1;
193};
194
195
196
197class Q_SVG_EXPORT QSvgOpacityStyle : public QSvgStyleProperty
198{
199public:
200 QSvgOpacityStyle(qreal opacity);
201 ~QSvgOpacityStyle() override;
202
203 void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
204 void revert(QPainter *p, QSvgExtraStates &states) override;
205 Type type() const override;
206 qreal opacity() const { return m_opacity; }
207 bool isDefault() const { return qFuzzyCompare(m_opacity, qreal(1.0)); }
208
209private:
210 qreal m_opacity;
211 qreal m_oldOpacity;
212};
213
214class Q_SVG_EXPORT QSvgFillStyle : public QSvgStyleProperty
215{
216public:
217 QSvgFillStyle();
218 ~QSvgFillStyle() override;
219
220 void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
221 void revert(QPainter *p, QSvgExtraStates &states) override;
222 Type type() const override;
223
224 void setFillRule(Qt::FillRule f);
225 void setFillOpacity(qreal opacity);
226 void setPaintServer(QSvgPaintServerSharedPtr paintServer);
227 void setBrush(QBrush brush);
228
229 const QBrush & qbrush() const
230 {
231 return m_fill;
232 }
233
234 qreal fillOpacity() const
235 {
236 return m_fillOpacity;
237 }
238
239 Qt::FillRule fillRule() const
240 {
241 return m_fillRule;
242 }
243
244 QSvgPaintServer *paintServer() const
245 {
246 return m_paintServer.get();
247 }
248
249 void setPaintStyleId(const QString &Id)
250 {
251 m_paintStyleId = Id;
252 }
253
254 QString paintStyleId() const
255 {
256 return m_paintStyleId;
257 }
258
259private:
260 // fill v v 'inherit' | <Paint.datatype>
261 // fill-opacity v v 'inherit' | <OpacityValue.datatype>
262 QBrush m_fill;
263 QBrush m_oldFill;
264 QSvgPaintServerSharedPtr m_paintServer;
265
266 Qt::FillRule m_fillRule{Qt::WindingFill};
267 Qt::FillRule m_oldFillRule{Qt::WindingFill};
268 qreal m_fillOpacity{1.0};
269 qreal m_oldFillOpacity{0.};
270
271 QString m_paintStyleId;
272
273 uint m_fillRuleSet : 1;
274 uint m_fillOpacitySet : 1;
275 uint m_fillSet : 1;
276};
277
278class Q_SVG_EXPORT QSvgViewportFillStyle : public QSvgStyleProperty
279{
280public:
281 QSvgViewportFillStyle(const QBrush &brush);
282 ~QSvgViewportFillStyle() override;
283
284 void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
285 void revert(QPainter *p, QSvgExtraStates &states) override;
286 Type type() const override;
287
288 const QBrush & qbrush() const
289 {
290 return m_viewportFill;
291 }
292private:
293 // viewport-fill v x 'inherit' | <Paint.datatype>
294 // viewport-fill-opacity v x 'inherit' | <OpacityValue.datatype>
295 QBrush m_viewportFill;
296
297 QBrush m_oldFill;
298};
299
300class Q_SVG_EXPORT QSvgFontStyle : public QSvgStyleProperty
301{
302public:
303 static const int LIGHTER = -1;
304 static const int BOLDER = 1;
305
306 QSvgFontStyle(QSvgFont *font, QSvgDocument *doc);
307 QSvgFontStyle();
308 ~QSvgFontStyle() override;
309
310 void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
311 void revert(QPainter *p, QSvgExtraStates &states) override;
312 Type type() const override;
313
314 void setSize(qreal size)
315 {
316 // Store the _pixel_ size in the font. Since QFont::setPixelSize() only takes an int, call
317 // QFont::SetPointSize() instead. Set proper font size just before rendering.
318 m_qfont.setPointSizeF(size);
319 m_sizeSet = 1;
320 }
321
322 void setTextAnchor(Qt::Alignment anchor)
323 {
324 m_textAnchor = anchor;
325 m_textAnchorSet = 1;
326 }
327
328 void setFamily(const QString &family)
329 {
330 m_qfont.setFamilies({family});
331 m_familySet = 1;
332 }
333
334 void setStyle(QFont::Style fontStyle) {
335 m_qfont.setStyle(fontStyle);
336 m_styleSet = 1;
337 }
338
339 void setVariant(QFont::Capitalization fontVariant)
340 {
341 m_qfont.setCapitalization(fontVariant);
342 m_variantSet = 1;
343 }
344
345 void setWeight(int weight)
346 {
347 m_weight = weight;
348 m_weightSet = 1;
349 }
350
351 QSvgFont * svgFont() const
352 {
353 return m_svgFont;
354 }
355
356 const QFont &qfont() const
357 {
358 return m_qfont;
359 }
360
361 QSvgDocument *doc() const {return m_doc;}
362
363private:
364 QSvgFont *m_svgFont;
365 QSvgDocument *m_doc;
366 QFont m_qfont;
367
368 int m_weight = 0;
369 Qt::Alignment m_textAnchor;
370
371 QSvgFont *m_oldSvgFont = nullptr;
372 QFont m_oldQFont;
373 Qt::Alignment m_oldTextAnchor;
374 int m_oldWeight = 0;
375
376 uint m_familySet : 1;
377 uint m_sizeSet : 1;
378 uint m_styleSet : 1;
379 uint m_variantSet : 1;
380 uint m_weightSet : 1;
381 uint m_textAnchorSet : 1;
382};
383
384class Q_SVG_EXPORT QSvgStrokeStyle : public QSvgStyleProperty
385{
386public:
387 QSvgStrokeStyle();
388 ~QSvgStrokeStyle() override;
389
390 void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
391 void revert(QPainter *p, QSvgExtraStates &states) override;
392 Type type() const override;
393
394 void setStroke(QBrush brush)
395 {
396 m_stroke.setBrush(brush);
397 m_paintServer.reset();
398 m_strokeSet = 1;
399 }
400
401 void setPaintServer(QSvgPaintServerSharedPtr paintServer)
402 {
403 m_paintServer = paintServer;
404 m_strokeSet = 1;
405 }
406
407 void setDashArray(const QList<qreal> &dashes);
408
409 void setDashArrayNone()
410 {
411 m_stroke.setStyle(Qt::SolidLine);
412 m_strokeDashArraySet = 1;
413 }
414
415 void setDashOffset(qreal offset)
416 {
417 m_strokeDashOffset = offset;
418 m_strokeDashOffsetSet = 1;
419 }
420
421 void setLineCap(Qt::PenCapStyle cap)
422 {
423 m_stroke.setCapStyle(cap);
424 m_strokeLineCapSet = 1;
425 }
426
427 void setLineJoin(Qt::PenJoinStyle join)
428 {
429 m_stroke.setJoinStyle(join);
430 m_strokeLineJoinSet = 1;
431 }
432
433 void setMiterLimit(qreal limit)
434 {
435 m_stroke.setMiterLimit(limit);
436 m_strokeMiterLimitSet = 1;
437 }
438
439 void setOpacity(qreal opacity)
440 {
441 m_strokeOpacity = opacity;
442 m_strokeOpacitySet = 1;
443 }
444
445 void setWidth(qreal width)
446 {
447 m_stroke.setWidthF(width);
448 m_strokeWidthSet = 1;
449 Q_ASSERT(!m_strokeDashArraySet); // set width before dash array.
450 }
451
452 qreal width()
453 {
454 return m_stroke.widthF();
455 }
456
457 void setVectorEffect(bool nonScalingStroke)
458 {
459 m_vectorEffect = nonScalingStroke;
460 m_vectorEffectSet = 1;
461 }
462
463 QSvgPaintServer *paintServer() const
464 {
465 return m_paintServer.get();
466 }
467
468 void setPaintStyleId(const QString &Id)
469 {
470 m_paintStyleId = Id;
471 }
472
473 QString paintStyleId() const
474 {
475 return m_paintStyleId;
476 }
477
478 QPen stroke() const
479 {
480 return m_stroke;
481 }
482
483private:
484 // stroke v v 'inherit' | <Paint.datatype>
485 // stroke-dasharray v v 'inherit' | <StrokeDashArrayValue.datatype>
486 // stroke-dashoffset v v 'inherit' | <StrokeDashOffsetValue.datatype>
487 // stroke-linecap v v 'butt' | 'round' | 'square' | 'inherit'
488 // stroke-linejoin v v 'miter' | 'round' | 'bevel' | 'inherit'
489 // stroke-miterlimit v v 'inherit' | <StrokeMiterLimitValue.datatype>
490 // stroke-opacity v v 'inherit' | <OpacityValue.datatype>
491 // stroke-width v v 'inherit' | <StrokeWidthValue.datatype>
492 QPen m_stroke;
493 QPen m_oldStroke;
494 qreal m_strokeOpacity{1.0};
495 qreal m_oldStrokeOpacity{0.};
496 qreal m_strokeDashOffset{0.};
497 qreal m_oldStrokeDashOffset{0.};
498
499 QSvgPaintServerSharedPtr m_paintServer;
500 QString m_paintStyleId;
501 uint m_vectorEffect : 1;
502 uint m_oldVectorEffect : 1;
503
504 uint m_strokeSet : 1;
505 uint m_strokeDashArraySet : 1;
506 uint m_strokeDashOffsetSet : 1;
507 uint m_strokeLineCapSet : 1;
508 uint m_strokeLineJoinSet : 1;
509 uint m_strokeMiterLimitSet : 1;
510 uint m_strokeOpacitySet : 1;
511 uint m_strokeWidthSet : 1;
512 uint m_vectorEffectSet : 1;
513};
514
515class Q_SVG_EXPORT QSvgTransformStyle : public QSvgStyleProperty
516{
517public:
518 QSvgTransformStyle(const QTransform &transform);
519 ~QSvgTransformStyle() override;
520
521 void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
522 void revert(QPainter *p, QSvgExtraStates &states) override;
523 Type type() const override;
524
525 const QTransform & qtransform() const
526 {
527 return m_transform;
528 }
529 bool isDefault() const { return m_transform.isIdentity(); }
530private:
531 //7.6 The transform attribute
532 QTransform m_transform;
533 QStack<QTransform> m_oldWorldTransform;
534};
535
536class Q_SVG_EXPORT QSvgCompOpStyle : public QSvgStyleProperty
537{
538public:
539 QSvgCompOpStyle(QPainter::CompositionMode mode);
540 ~QSvgCompOpStyle() override;
541
542 void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
543 void revert(QPainter *p, QSvgExtraStates &states) override;
544 Type type() const override;
545
546 const QPainter::CompositionMode & compOp() const
547 {
548 return m_mode;
549 }
550private:
551 //comp-op attribute
552 QPainter::CompositionMode m_mode;
553
554 QPainter::CompositionMode m_oldMode{QPainter::CompositionMode_SourceOver};
555};
556
557class Q_SVG_EXPORT QSvgOffsetStyle : public QSvgStyleProperty
558{
559public:
560 QSvgOffsetStyle() = default;
561 ~QSvgOffsetStyle() override;
562
563 void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states) override;
564 void revert(QPainter *p, QSvgExtraStates &states) override;
565 Type type() const override;
566
567 void setPath(const QPainterPath &path)
568 {
569 m_path = path;
570 }
571
572 const QPainterPath &path() const
573 {
574 return m_path;
575 }
576
577 void setRotateAngle(qreal angle)
578 {
579 m_rotateAngle = angle;
580 }
581
582 qreal rotateAngle() const
583 {
584 return m_rotateAngle;
585 }
586
587 void setRotateType(QtSvg::OffsetRotateType type)
588 {
589 m_rotateType = type;
590 }
591
592 QtSvg::OffsetRotateType rotateType() const
593 {
594 return m_rotateType;
595 }
596
597 void setDistance(qreal distance)
598 {
599 m_distance = distance;
600 }
601
602 qreal distance() const
603 {
604 return m_distance;
605 }
606
607private:
608 QPainterPath m_path;
609 qreal m_distance{0.};
610 qreal m_rotateAngle{0.};
611 QtSvg::OffsetRotateType m_rotateType{QtSvg::OffsetRotateType::Auto};
612};
613
614class Q_SVG_EXPORT QSvgStaticStyle
615{
616public:
617 QSvgStaticStyle();
618 ~QSvgStaticStyle();
619
620 void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states);
621 void revert(QPainter *p, QSvgExtraStates &states);
622 QSvgRefCounter<QSvgQualityStyle> quality;
623 QSvgRefCounter<QSvgFillStyle> fill;
624 QSvgRefCounter<QSvgViewportFillStyle> viewportFill;
625 QSvgRefCounter<QSvgFontStyle> font;
626 QSvgRefCounter<QSvgStrokeStyle> stroke;
627 QSvgRefCounter<QSvgTransformStyle> transform;
628 QSvgRefCounter<QSvgOpacityStyle> opacity;
629 QSvgRefCounter<QSvgCompOpStyle> compop;
630 QSvgRefCounter<QSvgOffsetStyle> offset;
631};
632
633class QSvgAbstractAnimation;
634
648
649class Q_SVG_EXPORT QSvgAnimatedStyle
650{
651public:
652 QSvgAnimatedStyle();
653 ~QSvgAnimatedStyle();
654
655 void apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states);
656 void revert(QPainter *p, QSvgExtraStates &states);
657
658private:
659 void savePaintingState(const QPainter *p, const QSvgNode *node, QSvgExtraStates &states);
660 void fetchStyleState(const QSvgAbstractAnimation *animation, QSvgStyleState &currentStyle);
661 void applyStyle(QPainter *p, QSvgExtraStates &states, const QSvgStyleState &currentStyle);
662
663private:
664 QTransform m_worldTransform;
665 QTransform m_transformToNode;
666 QSvgStyleState m_static;
667};
668
669/********************************************************/
670// NOT implemented:
671
672// color v v 'inherit' | <Color.datatype>
673//QColor m_color;
674
675// display v x 'inline' | 'block' | 'list-item'
676// | 'run-in' | 'compact' | 'marker' |
677// 'table' | 'inline-table' |
678// 'table-row-group' | 'table-header-group' |
679// 'table-footer-group' | 'table-row' |
680// 'table-column-group' | 'table-column' |
681// 'table-cell' | 'table-caption' |
682// 'none' | 'inherit'
683//QSvgDisplayStyle m_display;
684
685// display-align v v 'auto' | 'before' | 'center' | 'after' | 'inherit'
686//QSvgDisplayAlign m_displayAlign;
687
688// line-increment v v 'auto' | 'inherit' | <Number.datatype>
689//int m_lineIncrement;
690
691// text-anchor v v 'start' | 'middle' | 'end' | 'inherit'
692//QSvgTextAnchor m_textAnchor;
693
694// visibility v v 'visible' | 'hidden' | 'inherit'
695//QSvgVisibility m_visibility;
696
697/******************************************************/
698// the following do not make sense for us
699
700// pointer-events v v 'visiblePainted' | 'visibleFill' | 'visibleStroke' |
701// 'visible' | 'painted' | 'fill' | 'stroke' | 'all' |
702// 'none' | 'inherit'
703//QSvgPointEvents m_pointerEvents;
704
705// audio-level v x 'inherit' | <Number.datatype>
706
707QT_END_NAMESPACE
708
709#endif // QSVGSTYLE_P_H
friend class QPainter
T * operator->() const
Definition qsvgstyle_p.h:78
operator T*() const
Definition qsvgstyle_p.h:79
QSvgRefCounter(T *_t)
Definition qsvgstyle_p.h:42
bool isDefault() const
Definition qsvgstyle_p.h:81
QSvgRefCounter(const QSvgRefCounter &other)
Definition qsvgstyle_p.h:48
QSvgRefCounter & operator=(const QSvgRefCounter &other)
Definition qsvgstyle_p.h:63
QSvgRefCounter & operator=(T *_t)
Definition qsvgstyle_p.h:54
Combined button and popup list for selecting options.
QSvgFont * svgFont
Qt::Alignment textAnchor
Qt::FillRule fillRule
quint8 remainingNestedNodes
QTransform transform
QtSvg::OffsetRotateType offsetRotateType
std::optional< QPainterPath > offsetPath