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