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