summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias Rauter <matthias.rauter@qt.io>2023-10-19 12:49:09 +0200
committerMatthias Rauter <matthias.rauter@qt.io>2023-11-03 10:22:18 +0100
commit101982c650b6d531654eec669d237bf668a0cada (patch)
treec6dd2f6430d743a6b384edb20332d361d6cc7c0c /src
parent59962414b7d77eaea1cec5aa7fbd9e011c107fc9 (diff)
Refactor QSvgNode draw architecture
In preparation for the mask and filter tag, the draw infrastructure is changed from a C-style macro to virtual member functions. Commonalities between all nodes are encapsulated in the draw() function. The actual draw command is encapsulated in the drawCommand() function that is called by the draw function along with some common code for setting styles, masking, filtering and benchmarking. Change-Id: I19aa79be9500eff6faa6b6f12fd13d6c0fe2d0ad Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/svg/qsvggraphics.cpp263
-rw-r--r--src/svg/qsvggraphics_p.h45
-rw-r--r--src/svg/qsvghandler.cpp70
-rw-r--r--src/svg/qsvgnode.cpp98
-rw-r--r--src/svg/qsvgnode_p.h72
-rw-r--r--src/svg/qsvgstructure.cpp24
-rw-r--r--src/svg/qsvgstructure_p.h9
-rw-r--r--src/svg/qsvgtinydocument.cpp4
-rw-r--r--src/svg/qsvgtinydocument_p.h2
-rw-r--r--src/svg/qsvgvisitor.cpp80
10 files changed, 319 insertions, 348 deletions
diff --git a/src/svg/qsvggraphics.cpp b/src/svg/qsvggraphics.cpp
index 1858d8e..71c138b 100644
--- a/src/svg/qsvggraphics.cpp
+++ b/src/svg/qsvggraphics.cpp
@@ -23,38 +23,14 @@
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcSvgDraw, "qt.svg.draw")
-Q_LOGGING_CATEGORY(lcSvgTiming, "qt.svg.timing")
-
-#define QT_SVG_TIMING_ENTER \
- QElapsedTimer qtSvgTimer; qtSvgTimer.start();
-
-#define QT_SVG_TIMING_EXIT(TYPE) \
- if (Q_UNLIKELY(lcSvgTiming().isDebugEnabled())) \
- qCDebug(lcSvgTiming) << "Drawing" << TYPE << "took" << (qtSvgTimer.nsecsElapsed() / 1000000.0f) << "ms";
-
-#define QT_SVG_DRAW_SHAPE(command) \
- { qreal oldOpacity = p->opacity(); \
- QBrush oldBrush = p->brush(); \
- QPen oldPen = p->pen(); \
- p->setPen(Qt::NoPen); \
- p->setOpacity(oldOpacity * states.fillOpacity); \
- command; \
- p->setPen(oldPen); \
- if (oldPen != Qt::NoPen && oldPen.brush() != Qt::NoBrush && oldPen.widthF() != 0) { \
- p->setOpacity(oldOpacity * states.strokeOpacity); \
- p->setBrush(Qt::NoBrush); \
- command; \
- p->setBrush(oldBrush); \
- } \
- p->setOpacity(oldOpacity); }
#ifndef QT_SVG_MAX_LAYOUT_SIZE
#define QT_SVG_MAX_LAYOUT_SIZE (qint64(QFIXED_MAX / 2))
#endif
-void QSvgAnimation::draw(QPainter *, QSvgExtraStates &)
+void QSvgAnimation::drawCommand(QPainter *, QSvgExtraStates &)
{
- qWarning("<animation> no implemented");
+ qWarning("<animation> not implemented");
}
static inline QRectF boundsOnStroke(QPainter *p, const QPainterPath &path, qreal width)
@@ -83,35 +59,14 @@ QRectF QSvgEllipse::bounds(QPainter *p, QSvgExtraStates &) const
return qFuzzyIsNull(sw) ? p->transform().map(path).boundingRect() : boundsOnStroke(p, path, sw);
}
-void QSvgEllipse::draw(QPainter *p, QSvgExtraStates &states)
-{
- QT_SVG_TIMING_ENTER
- applyStyle(p, states);
- if (shouldDrawNode(p, states))
- QT_SVG_DRAW_SHAPE(p->drawEllipse(m_bounds));
- revertStyle(p, states);
- QT_SVG_TIMING_EXIT("Ellipse")
-}
-
-QSvgArc::QSvgArc(QSvgNode *parent, const QPainterPath &path)
- : QSvgNode(parent), m_path(path)
+void QSvgEllipse::drawCommand(QPainter *p, QSvgExtraStates &)
{
+ p->drawEllipse(m_bounds);
}
-void QSvgArc::draw(QPainter *p, QSvgExtraStates &states)
+bool QSvgEllipse::separateFillStroke() const
{
- QT_SVG_TIMING_ENTER
- applyStyle(p, states);
- if (shouldDrawNode(p, states)) {
- if (p->pen().widthF() != 0) {
- qreal oldOpacity = p->opacity();
- p->setOpacity(oldOpacity * states.strokeOpacity);
- p->drawPath(m_path);
- p->setOpacity(oldOpacity);
- }
- }
- revertStyle(p, states);
- QT_SVG_TIMING_EXIT("Arc")
+ return true;
}
QSvgImage::QSvgImage(QSvgNode *parent, const QImage &image,
@@ -125,55 +80,39 @@ QSvgImage::QSvgImage(QSvgNode *parent, const QImage &image,
m_bounds.setHeight(static_cast<qreal>(m_image.height()));
}
-void QSvgImage::draw(QPainter *p, QSvgExtraStates &states)
+void QSvgImage::drawCommand(QPainter *p, QSvgExtraStates &)
{
- QT_SVG_TIMING_ENTER
- if (shouldDrawNode(p, states)) {
- applyStyle(p, states);
- p->drawImage(m_bounds, m_image);
- revertStyle(p, states);
- }
- QT_SVG_TIMING_EXIT("Image")
+ p->drawImage(m_bounds, m_image);
}
-
QSvgLine::QSvgLine(QSvgNode *parent, const QLineF &line)
: QSvgNode(parent), m_line(line)
{
}
-
-void QSvgLine::draw(QPainter *p, QSvgExtraStates &states)
+void QSvgLine::drawCommand(QPainter *p, QSvgExtraStates &states)
{
- QT_SVG_TIMING_ENTER
- applyStyle(p, states);
- if (shouldDrawNode(p, states)) {
- if (p->pen().widthF() != 0) {
- qreal oldOpacity = p->opacity();
- p->setOpacity(oldOpacity * states.strokeOpacity);
- p->drawLine(m_line);
- p->setOpacity(oldOpacity);
- }
+ if (p->pen().widthF() != 0) {
+ qreal oldOpacity = p->opacity();
+ p->setOpacity(oldOpacity * states.strokeOpacity);
+ p->drawLine(m_line);
+ p->setOpacity(oldOpacity);
}
- revertStyle(p, states);
- QT_SVG_TIMING_EXIT("Line")
}
QSvgPath::QSvgPath(QSvgNode *parent, const QPainterPath &qpath)
: QSvgNode(parent), m_path(qpath)
{
}
+void QSvgPath::drawCommand(QPainter *p, QSvgExtraStates &states)
+{
+ m_path.setFillRule(states.fillRule);
+ p->drawPath(m_path);
+}
-void QSvgPath::draw(QPainter *p, QSvgExtraStates &states)
+bool QSvgPath::separateFillStroke() const
{
- QT_SVG_TIMING_ENTER
- applyStyle(p, states);
- if (shouldDrawNode(p, states)) {
- m_path.setFillRule(states.fillRule);
- QT_SVG_DRAW_SHAPE(p->drawPath(m_path));
- }
- revertStyle(p, states);
- QT_SVG_TIMING_EXIT("Path")
+ return true;
}
QRectF QSvgPath::fastBounds(QPainter *p, QSvgExtraStates &) const
@@ -210,16 +149,15 @@ QRectF QSvgPolygon::bounds(QPainter *p, QSvgExtraStates &) const
}
}
-void QSvgPolygon::draw(QPainter *p, QSvgExtraStates &states)
+void QSvgPolygon::drawCommand(QPainter *p, QSvgExtraStates &states)
{
- QT_SVG_TIMING_ENTER
- applyStyle(p, states);
- if (shouldDrawNode(p, states))
- QT_SVG_DRAW_SHAPE(p->drawPolygon(m_poly, states.fillRule));
- revertStyle(p, states);
- QT_SVG_TIMING_EXIT("Polygon")
+ p->drawPolygon(m_poly, states.fillRule);
}
+bool QSvgPolygon::separateFillStroke() const
+{
+ return true;
+}
QSvgPolyline::QSvgPolyline(QSvgNode *parent, const QPolygonF &poly)
: QSvgNode(parent), m_poly(poly)
@@ -227,27 +165,17 @@ QSvgPolyline::QSvgPolyline(QSvgNode *parent, const QPolygonF &poly)
}
-void QSvgPolyline::draw(QPainter *p, QSvgExtraStates &states)
+void QSvgPolyline::drawCommand(QPainter *p, QSvgExtraStates &states)
{
- QT_SVG_TIMING_ENTER
- applyStyle(p, states);
- if (shouldDrawNode(p, states)) {
- qreal oldOpacity = p->opacity();
- if (p->brush().style() != Qt::NoBrush) {
- QPen save = p->pen();
- p->setPen(QPen(Qt::NoPen));
- p->setOpacity(oldOpacity * states.fillOpacity);
- p->drawPolygon(m_poly, states.fillRule);
- p->setPen(save);
- }
- if (p->pen().widthF() != 0) {
- p->setOpacity(oldOpacity * states.strokeOpacity);
- p->drawPolyline(m_poly);
- }
- p->setOpacity(oldOpacity);
- }
- revertStyle(p, states);
- QT_SVG_TIMING_EXIT("Polyline")
+ if (p->brush().style() != Qt::NoBrush)
+ p->drawPolygon(m_poly, states.fillRule);
+ else
+ p->drawPolyline(m_poly);
+}
+
+bool QSvgPolyline::separateFillStroke() const
+{
+ return true;
}
QSvgRect::QSvgRect(QSvgNode *node, const QRectF &rect, qreal rx, qreal ry)
@@ -273,19 +201,17 @@ QRectF QSvgRect::bounds(QPainter *p, QSvgExtraStates &) const
}
}
-void QSvgRect::draw(QPainter *p, QSvgExtraStates &states)
+void QSvgRect::drawCommand(QPainter *p, QSvgExtraStates &)
{
- QT_SVG_TIMING_ENTER
- applyStyle(p, states);
- if (shouldDrawNode(p, states)) {
- if (m_rx || m_ry) {
- QT_SVG_DRAW_SHAPE(p->drawRoundedRect(m_rect, m_rx, m_ry, Qt::RelativeSize));
- } else {
- QT_SVG_DRAW_SHAPE(p->drawRect(m_rect));
- }
- }
- revertStyle(p, states);
- QT_SVG_TIMING_EXIT("Rect")
+ if (m_rx || m_ry)
+ p->drawRoundedRect(m_rect, m_rx, m_ry, Qt::RelativeSize);
+ else
+ p->drawRect(m_rect);
+}
+
+bool QSvgRect::separateFillStroke() const
+{
+ return true;
}
QSvgTspan * const QSvgText::LINEBREAK = 0;
@@ -293,7 +219,7 @@ QSvgTspan * const QSvgText::LINEBREAK = 0;
QSvgText::QSvgText(QSvgNode *parent, const QPointF &coord)
: QSvgNode(parent)
, m_coord(coord)
- , m_type(TEXT)
+ , m_type(Text)
, m_size(0, 0)
, m_mode(Default)
{
@@ -310,12 +236,12 @@ QSvgText::~QSvgText()
void QSvgText::setTextArea(const QSizeF &size)
{
m_size = size;
- m_type = TEXTAREA;
+ m_type = Textarea;
}
QRectF QSvgText::fastBounds(QPainter *p, QSvgExtraStates &) const
{
- QFont font = p->font();
+ QFont font = m_style.font ? m_style.font->qfont() : p->font();
QFontMetricsF fm(font);
int charCount = 0;
@@ -327,19 +253,24 @@ QRectF QSvgText::fastBounds(QPainter *p, QSvgExtraStates &) const
QRectF approxMaximumBrect(m_coord.x(),
m_coord.y(),
charCount * fm.averageCharWidth(),
- m_tspans.size() * fm.height());
+ -m_tspans.size() * fm.height());
return p->transform().mapRect(approxMaximumBrect);
}
QRectF QSvgText::bounds(QPainter *p, QSvgExtraStates &states) const
{
QRectF boundingRect;
- if (precheck(p))
+ if (shouldDrawNode(p, states))
draw_helper(p, states, &boundingRect);
return p->transform().mapRect(boundingRect);
}
-bool QSvgText::precheck(QPainter *p) const
+void QSvgText::drawCommand(QPainter *p, QSvgExtraStates &states)
+{
+ draw_helper(p, states);
+}
+
+bool QSvgText::shouldDrawNode(QPainter *p, QSvgExtraStates &) const
{
qsizetype numChars = 0;
qreal originalFontSize = p->font().pointSizeF();
@@ -371,26 +302,17 @@ bool QSvgText::precheck(QPainter *p) const
return true;
}
-void QSvgText::draw(QPainter *p, QSvgExtraStates &states)
-{
- QT_SVG_TIMING_ENTER
- if (precheck(p))
- draw_helper(p, states);
- QT_SVG_TIMING_EXIT("Text")
-}
-
void QSvgText::draw_helper(QPainter *p, QSvgExtraStates &states, QRectF *boundingRect) const
{
const bool isPainting = (boundingRect == nullptr);
- if (isPainting)
- applyStyle(p, states);
if (!isPainting || shouldDrawNode(p, states)) {
qreal oldOpacity = p->opacity();
p->setOpacity(oldOpacity * states.fillOpacity);
// Force the font to have a size of 100 pixels to avoid truncation problems
// when the font is very small.
- qreal scale = 100.0 / p->font().pointSizeF();
+ QFont font = p->font();
+ qreal scale = 100.0 / font.pointSizeF();
Qt::Alignment alignment = states.textAnchor;
QTransform oldTransform = p->worldTransform();
@@ -402,7 +324,7 @@ void QSvgText::draw_helper(QPainter *p, QSvgExtraStates &states, QRectF *boundin
qreal py = m_coord.y() * scale;
QSizeF scaledSize = m_size * scale;
- if (m_type == TEXTAREA) {
+ if (m_type == Textarea) {
if (alignment == Qt::AlignHCenter)
px += scaledSize.width() / 2;
else if (alignment == Qt::AlignRight)
@@ -420,9 +342,8 @@ void QSvgText::draw_helper(QPainter *p, QSvgExtraStates &states, QRectF *boundin
for (int i = 0; i < m_tspans.size(); ++i) {
if (m_tspans[i] == LINEBREAK) {
- if (m_type == TEXTAREA) {
+ if (m_type == Textarea) {
if (paragraphs.back().isEmpty()) {
- QFont font = p->font();
font.setPixelSize(font.pointSizeF() * scale);
QTextLayout::FormatRange range;
@@ -441,7 +362,7 @@ void QSvgText::draw_helper(QPainter *p, QSvgExtraStates &states, QRectF *boundin
WhitespaceMode mode = m_tspans[i]->whitespaceMode();
m_tspans[i]->applyStyle(p, states);
- QFont font = p->font();
+ font = p->font();
font.setPixelSize(font.pointSizeF() * scale);
QString newText(m_tspans[i]->text());
@@ -520,7 +441,7 @@ void QSvgText::draw_helper(QPainter *p, QSvgExtraStates &states, QRectF *boundin
else if (alignment == Qt::AlignRight)
x -= line.naturalTextWidth();
- if (initial && m_type == TEXT)
+ if (initial && m_type == Text)
y -= line.ascent();
initial = false;
@@ -556,8 +477,6 @@ void QSvgText::draw_helper(QPainter *p, QSvgExtraStates &states, QRectF *boundin
p->setWorldTransform(oldTransform, false);
p->setOpacity(oldOpacity);
}
- if (isPainting)
- revertStyle(p, states);
}
void QSvgText::addText(const QString &text)
@@ -573,9 +492,8 @@ QSvgUse::QSvgUse(const QPointF &start, QSvgNode *parent, QSvgNode *node)
}
-void QSvgUse::draw(QPainter *p, QSvgExtraStates &states)
+void QSvgUse::drawCommand(QPainter *p, QSvgExtraStates &states)
{
- QT_SVG_TIMING_ENTER
if (Q_UNLIKELY(!m_link || isDescendantOf(m_link) || m_recursing))
return;
@@ -585,8 +503,6 @@ void QSvgUse::draw(QPainter *p, QSvgExtraStates &states)
return;
}
- applyStyle(p, states);
-
if (!m_start.isNull()) {
p->translate(m_start);
}
@@ -603,66 +519,51 @@ void QSvgUse::draw(QPainter *p, QSvgExtraStates &states)
if (!m_start.isNull()) {
p->translate(-m_start);
}
-
- revertStyle(p, states);
- QT_SVG_TIMING_EXIT("Use")
-}
-
-void QSvgVideo::draw(QPainter *p, QSvgExtraStates &states)
-{
- applyStyle(p, states);
-
- revertStyle(p, states);
}
QSvgNode::Type QSvgAnimation::type() const
{
- return ANIMATION;
-}
-
-QSvgNode::Type QSvgArc::type() const
-{
- return ARC;
+ return Animation;
}
QSvgNode::Type QSvgCircle::type() const
{
- return CIRCLE;
+ return Circle;
}
QSvgNode::Type QSvgEllipse::type() const
{
- return ELLIPSE;
+ return Ellipse;
}
QSvgNode::Type QSvgImage::type() const
{
- return IMAGE;
+ return Image;
}
QSvgNode::Type QSvgLine::type() const
{
- return LINE;
+ return Line;
}
QSvgNode::Type QSvgPath::type() const
{
- return PATH;
+ return Path;
}
QSvgNode::Type QSvgPolygon::type() const
{
- return POLYGON;
+ return Polygon;
}
QSvgNode::Type QSvgPolyline::type() const
{
- return POLYLINE;
+ return Polyline;
}
QSvgNode::Type QSvgRect::type() const
{
- return RECT;
+ return Rect;
}
QSvgNode::Type QSvgText::type() const
@@ -672,12 +573,12 @@ QSvgNode::Type QSvgText::type() const
QSvgNode::Type QSvgUse::type() const
{
- return USE;
+ return Use;
}
QSvgNode::Type QSvgVideo::type() const
{
- return VIDEO;
+ return Video;
}
QRectF QSvgUse::bounds(QPainter *p, QSvgExtraStates &states) const
@@ -709,18 +610,6 @@ QRectF QSvgPolyline::bounds(QPainter *p, QSvgExtraStates &) const
}
}
-QRectF QSvgArc::fastBounds(QPainter *p, QSvgExtraStates &) const
-{
- return p->transform().mapRect(m_path.controlPointRect());
-}
-
-QRectF QSvgArc::bounds(QPainter *p, QSvgExtraStates &) const
-{
- qreal sw = strokeWidth(p);
- return qFuzzyIsNull(sw) ? p->transform().map(m_path).boundingRect()
- : boundsOnStroke(p, m_path, sw);
-}
-
QRectF QSvgImage::bounds(QPainter *p, QSvgExtraStates &) const
{
return p->transform().mapRect(m_bounds);
diff --git a/src/svg/qsvggraphics_p.h b/src/svg/qsvggraphics_p.h
index 42406e3..57443b2 100644
--- a/src/svg/qsvggraphics_p.h
+++ b/src/svg/qsvggraphics_p.h
@@ -31,27 +31,16 @@ class QTextCharFormat;
class Q_SVG_PRIVATE_EXPORT QSvgAnimation : public QSvgNode
{
public:
- void draw(QPainter *p, QSvgExtraStates &states) override;
+ void drawCommand(QPainter *, QSvgExtraStates &) override;
Type type() const override;
};
-class Q_SVG_PRIVATE_EXPORT QSvgArc : public QSvgNode
-{
-public:
- QSvgArc(QSvgNode *parent, const QPainterPath &path);
- void draw(QPainter *p, QSvgExtraStates &states) override;
- Type type() const override;
- QRectF fastBounds(QPainter *p, QSvgExtraStates &states) const override;
- QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
-private:
- QPainterPath m_path;
-};
-
class Q_SVG_PRIVATE_EXPORT QSvgEllipse : public QSvgNode
{
public:
QSvgEllipse(QSvgNode *parent, const QRectF &rect);
- void draw(QPainter *p, QSvgExtraStates &states) override;
+ bool separateFillStroke() const override;
+ void drawCommand(QPainter *p, QSvgExtraStates &states) override;
Type type() const override;
QRectF fastBounds(QPainter *p, QSvgExtraStates &states) const override;
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
@@ -72,7 +61,7 @@ class Q_SVG_PRIVATE_EXPORT QSvgImage : public QSvgNode
public:
QSvgImage(QSvgNode *parent, const QImage &image,
const QRectF &bounds);
- void draw(QPainter *p, QSvgExtraStates &states) override;
+ void drawCommand(QPainter *p, QSvgExtraStates &states) override;
Type type() const override;
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
@@ -87,7 +76,7 @@ class Q_SVG_PRIVATE_EXPORT QSvgLine : public QSvgNode
{
public:
QSvgLine(QSvgNode *parent, const QLineF &line);
- void draw(QPainter *p, QSvgExtraStates &states) override;
+ void drawCommand(QPainter *p, QSvgExtraStates &states) override;
Type type() const override;
QRectF fastBounds(QPainter *p, QSvgExtraStates &states) const override;
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
@@ -100,7 +89,8 @@ class Q_SVG_PRIVATE_EXPORT QSvgPath : public QSvgNode
{
public:
QSvgPath(QSvgNode *parent, const QPainterPath &qpath);
- void draw(QPainter *p, QSvgExtraStates &states) override;
+ bool separateFillStroke() const override;
+ void drawCommand(QPainter *p, QSvgExtraStates &states) override;
Type type() const override;
QRectF fastBounds(QPainter *p, QSvgExtraStates &states) const override;
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
@@ -117,7 +107,8 @@ class Q_SVG_PRIVATE_EXPORT QSvgPolygon : public QSvgNode
{
public:
QSvgPolygon(QSvgNode *parent, const QPolygonF &poly);
- void draw(QPainter *p, QSvgExtraStates &states) override;
+ bool separateFillStroke() const override;
+ void drawCommand(QPainter *p, QSvgExtraStates &states) override;
Type type() const override;
QRectF fastBounds(QPainter *p, QSvgExtraStates &states) const override;
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
@@ -132,7 +123,8 @@ class Q_SVG_PRIVATE_EXPORT QSvgPolyline : public QSvgNode
{
public:
QSvgPolyline(QSvgNode *parent, const QPolygonF &poly);
- void draw(QPainter *p, QSvgExtraStates &states) override;
+ bool separateFillStroke() const override;
+ void drawCommand(QPainter *p, QSvgExtraStates &states) override;
Type type() const override;
QRectF fastBounds(QPainter *p, QSvgExtraStates &states) const override;
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
@@ -148,7 +140,8 @@ class Q_SVG_PRIVATE_EXPORT QSvgRect : public QSvgNode
public:
QSvgRect(QSvgNode *paren, const QRectF &rect, qreal rx=0, qreal ry=0);
Type type() const override;
- void draw(QPainter *p, QSvgExtraStates &states) override;
+ bool separateFillStroke() const override;
+ void drawCommand(QPainter *p, QSvgExtraStates &states) override;
QRectF fastBounds(QPainter *p, QSvgExtraStates &states) const override;
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
QRectF rect() const { return m_rect; }
@@ -173,7 +166,8 @@ public:
~QSvgText();
void setTextArea(const QSizeF &size);
- void draw(QPainter *p, QSvgExtraStates &states) override;
+ void drawCommand(QPainter *p, QSvgExtraStates &states) override;
+ bool shouldDrawNode(QPainter *p, QSvgExtraStates &states) const override;
Type type() const override;
void addTspan(QSvgTspan *tspan) {m_tspans.append(tspan);}
@@ -189,7 +183,6 @@ public:
QSizeF size() const { return m_size; }
private:
- bool precheck(QPainter *p) const;
void draw_helper(QPainter *p, QSvgExtraStates &states, QRectF *boundingRect = nullptr) const;
static QSvgTspan * const LINEBREAK;
@@ -214,8 +207,8 @@ public:
{
}
~QSvgTspan() { };
- Type type() const override { return TSPAN; }
- void draw(QPainter *, QSvgExtraStates &) override { Q_ASSERT(!"Tspans should be drawn through QSvgText::draw()."); }
+ Type type() const override { return Tspan; }
+ void drawCommand(QPainter *, QSvgExtraStates &) override { Q_ASSERT(!"Tspans should be drawn through QSvgText::draw()."); }
void addText(const QString &text) {m_text += text;}
const QString &text() const {return m_text;}
bool isTspan() const {return m_isTspan;}
@@ -234,7 +227,7 @@ public:
QSvgUse(const QPointF &start, QSvgNode *parent, const QString &linkId)
: QSvgUse(start, parent, nullptr)
{ m_linkId = linkId; }
- void draw(QPainter *p, QSvgExtraStates &states) override;
+ void drawCommand(QPainter *p, QSvgExtraStates &states) override;
Type type() const override;
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
bool isResolved() const { return m_link != nullptr; }
@@ -252,7 +245,7 @@ private:
class QSvgVideo : public QSvgNode
{
public:
- void draw(QPainter *p, QSvgExtraStates &states) override;
+ void drawCommand(QPainter *, QSvgExtraStates &) override {};
Type type() const override;
};
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index 08f6e71..81163c4 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -455,10 +455,10 @@ public:
inline QSvgStructureNode *nodeToStructure(QSvgNode *n) const
{
if (n &&
- (n->type() == QSvgNode::DOC ||
- n->type() == QSvgNode::G ||
- n->type() == QSvgNode::DEFS ||
- n->type() == QSvgNode::SWITCH)) {
+ (n->type() == QSvgNode::Doc ||
+ n->type() == QSvgNode::Group ||
+ n->type() == QSvgNode::Defs ||
+ n->type() == QSvgNode::Switch)) {
return (QSvgStructureNode*)n;
}
return 0;
@@ -2603,7 +2603,7 @@ static QSvgStyleProperty *createFontNode(QSvgNode *parent,
qreal horizAdvX = toDouble(hax);
- while (parent && parent->type() != QSvgNode::DOC) {
+ while (parent && parent->type() != QSvgNode::Doc) {
parent = parent->parent();
}
@@ -2905,7 +2905,7 @@ static QSvgStyleProperty *createLinearGradientNode(QSvgNode *node,
ny2 = convertToNumber(y2, handler);
QSvgNode *itr = node;
- while (itr && itr->type() != QSvgNode::DOC) {
+ while (itr && itr->type() != QSvgNode::Doc) {
itr = itr->parent();
}
@@ -3285,7 +3285,7 @@ static bool parseTbreakNode(QSvgNode *parent,
const QXmlStreamAttributes &,
QSvgHandler *)
{
- if (parent->type() != QSvgNode::TEXTAREA)
+ if (parent->type() != QSvgNode::Textarea)
return false;
static_cast<QSvgText*>(parent)->addLineBreak();
return true;
@@ -3349,10 +3349,10 @@ static QSvgNode *createUseNode(QSvgNode *parent,
if (linkId.isEmpty())
linkId = attributes.value(QLatin1String("href")).toString().remove(0, 1);
switch (parent->type()) {
- case QSvgNode::DOC:
- case QSvgNode::DEFS:
- case QSvgNode::G:
- case QSvgNode::SWITCH:
+ case QSvgNode::Doc:
+ case QSvgNode::Defs:
+ case QSvgNode::Group:
+ case QSvgNode::Switch:
group = static_cast<QSvgStructureNode*>(parent);
break;
default:
@@ -3621,8 +3621,8 @@ static bool detectCycles(const QSvgNode *node, QList<const QSvgUse *> active = {
if (Q_UNLIKELY(!node))
return false;
switch (node->type()) {
- case QSvgNode::DOC:
- case QSvgNode::G:
+ case QSvgNode::Doc:
+ case QSvgNode::Group:
{
auto *g = static_cast<const QSvgStructureNode*>(node);
for (auto *r : g->renderers()) {
@@ -3631,7 +3631,7 @@ static bool detectCycles(const QSvgNode *node, QList<const QSvgUse *> active = {
}
}
break;
- case QSvgNode::USE:
+ case QSvgNode::Use:
{
if (active.contains(node))
return true;
@@ -3742,14 +3742,14 @@ bool QSvgHandler::startElement(const QString &localName,
node = method(m_doc ? m_nodes.top() : 0, attributes, this);
Q_ASSERT(node);
if (!m_doc) {
- Q_ASSERT(node->type() == QSvgNode::DOC);
+ Q_ASSERT(node->type() == QSvgNode::Doc);
m_doc = static_cast<QSvgTinyDocument*>(node);
} else {
switch (m_nodes.top()->type()) {
- case QSvgNode::DOC:
- case QSvgNode::G:
- case QSvgNode::DEFS:
- case QSvgNode::SWITCH:
+ case QSvgNode::Doc:
+ case QSvgNode::Group:
+ case QSvgNode::Defs:
+ case QSvgNode::Switch:
{
QSvgStructureNode *group =
static_cast<QSvgStructureNode*>(m_nodes.top());
@@ -3777,12 +3777,12 @@ bool QSvgHandler::startElement(const QString &localName,
node = method(m_nodes.top(), attributes, this);
if (node) {
switch (m_nodes.top()->type()) {
- case QSvgNode::DOC:
- case QSvgNode::G:
- case QSvgNode::DEFS:
- case QSvgNode::SWITCH:
+ case QSvgNode::Doc:
+ case QSvgNode::Group:
+ case QSvgNode::Defs:
+ case QSvgNode::Switch:
{
- if (node->type() == QSvgNode::TSPAN) {
+ if (node->type() == QSvgNode::Tspan) {
const QByteArray msg = QByteArrayLiteral("\'tspan\' element in wrong context.");
qCWarning(lcSvgHandler, "%s", prefixMessage(msg, xml).constData());
delete node;
@@ -3794,9 +3794,9 @@ bool QSvgHandler::startElement(const QString &localName,
group->addChild(node, someId(attributes));
}
break;
- case QSvgNode::TEXT:
- case QSvgNode::TEXTAREA:
- if (node->type() == QSvgNode::TSPAN) {
+ case QSvgNode::Text:
+ case QSvgNode::Textarea:
+ if (node->type() == QSvgNode::Tspan) {
static_cast<QSvgText *>(m_nodes.top())->addTspan(static_cast<QSvgTspan *>(node));
} else {
const QByteArray msg = QByteArrayLiteral("\'text\' or \'textArea\' element contains invalid element type.");
@@ -3819,11 +3819,11 @@ bool QSvgHandler::startElement(const QString &localName,
cssStyleLookup(node, this, m_selector);
#endif
parseStyle(node, attributes, this);
- if (node->type() == QSvgNode::TEXT || node->type() == QSvgNode::TEXTAREA) {
+ if (node->type() == QSvgNode::Text || node->type() == QSvgNode::Textarea) {
static_cast<QSvgText *>(node)->setWhitespaceMode(m_whitespaceMode.top());
- } else if (node->type() == QSvgNode::TSPAN) {
+ } else if (node->type() == QSvgNode::Tspan) {
static_cast<QSvgTspan *>(node)->setWhitespaceMode(m_whitespaceMode.top());
- } else if (node->type() == QSvgNode::USE) {
+ } else if (node->type() == QSvgNode::Use) {
auto useNode = static_cast<QSvgUse *>(node);
if (!useNode->isResolved())
m_toBeResolved.append(useNode);
@@ -3893,8 +3893,8 @@ bool QSvgHandler::endElement(const QStringView localName)
void QSvgHandler::resolveGradients(QSvgNode *node, int nestedDepth)
{
- if (!node || (node->type() != QSvgNode::DOC && node->type() != QSvgNode::G
- && node->type() != QSvgNode::DEFS && node->type() != QSvgNode::SWITCH)) {
+ if (!node || (node->type() != QSvgNode::Doc && node->type() != QSvgNode::Group
+ && node->type() != QSvgNode::Defs && node->type() != QSvgNode::Switch)) {
return;
}
@@ -3939,7 +3939,7 @@ void QSvgHandler::resolveNodes()
continue;
QSvgNode::Type t = parent->type();
- if (t != QSvgNode::DOC && t != QSvgNode::DEFS && t != QSvgNode::G && t != QSvgNode::SWITCH)
+ if (t != QSvgNode::Doc && t != QSvgNode::Defs && t != QSvgNode::Group && t != QSvgNode::Switch)
continue;
QSvgStructureNode *group = static_cast<QSvgStructureNode *>(parent);
@@ -3971,9 +3971,9 @@ bool QSvgHandler::characters(const QStringView str)
if (m_skipNodes.isEmpty() || m_skipNodes.top() == Unknown || m_nodes.isEmpty())
return true;
- if (m_nodes.top()->type() == QSvgNode::TEXT || m_nodes.top()->type() == QSvgNode::TEXTAREA) {
+ if (m_nodes.top()->type() == QSvgNode::Text || m_nodes.top()->type() == QSvgNode::Textarea) {
static_cast<QSvgText*>(m_nodes.top())->addText(str.toString());
- } else if (m_nodes.top()->type() == QSvgNode::TSPAN) {
+ } else if (m_nodes.top()->type() == QSvgNode::Tspan) {
static_cast<QSvgTspan*>(m_nodes.top())->addText(str.toString());
}
diff --git a/src/svg/qsvgnode.cpp b/src/svg/qsvgnode.cpp
index 3914ad6..7f2361a 100644
--- a/src/svg/qsvgnode.cpp
+++ b/src/svg/qsvgnode.cpp
@@ -5,20 +5,23 @@
#include "qsvgtinydocument_p.h"
#include <QLoggingCategory>
+#include<QElapsedTimer>
#include "qdebug.h"
#include "qstack.h"
#include <QtGui/private/qoutlinemapper_p.h>
-#if !defined(QT_SVG_SIZE_LIMIT)
-# define QT_SVG_SIZE_LIMIT QT_RASTER_COORD_LIMIT
-#endif
-
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcSvgDraw)
+Q_LOGGING_CATEGORY(lcSvgTiming, "qt.svg.timing")
+
+#if !defined(QT_SVG_SIZE_LIMIT)
+# define QT_SVG_SIZE_LIMIT QT_RASTER_COORD_LIMIT
+#endif
+
QSvgNode::QSvgNode(QSvgNode *parent)
: m_parent(parent),
m_visible(true),
@@ -31,6 +34,52 @@ QSvgNode::~QSvgNode()
}
+
+void QSvgNode::draw(QPainter *p, QSvgExtraStates &states)
+{
+#ifndef QT_NO_DEBUG
+ QElapsedTimer qtSvgTimer; qtSvgTimer.start();
+#endif
+
+ if (shouldDrawNode(p, states)) {
+ applyStyle(p, states);
+ if (separateFillStroke())
+ fillThenStroke(p, states);
+ else
+ drawCommand(p, states);
+ revertStyle(p, states);
+ }
+
+#ifndef QT_NO_DEBUG
+ if (Q_UNLIKELY(lcSvgTiming().isDebugEnabled()))
+ qCDebug(lcSvgTiming) << "Drawing" << typeName() << "took" << (qtSvgTimer.nsecsElapsed() / 1000000.0f) << "ms";
+#endif
+}
+
+void QSvgNode::fillThenStroke(QPainter *p, QSvgExtraStates &states)
+{
+ qreal oldOpacity = p->opacity();
+ if (p->brush().style() != Qt::NoBrush) {
+ QPen oldPen = p->pen();
+ p->setPen(Qt::NoPen);
+ p->setOpacity(oldOpacity * states.fillOpacity);
+
+ drawCommand(p, states);
+
+ p->setPen(oldPen);
+ }
+ if (p->pen() != Qt::NoPen && p->pen().brush() != Qt::NoBrush && p->pen().widthF() != 0) {
+ QBrush oldBrush = p->brush();
+ p->setOpacity(oldOpacity * states.strokeOpacity);
+ p->setBrush(Qt::NoBrush);
+
+ drawCommand(p, states);
+
+ p->setBrush(oldBrush);
+ }
+ p->setOpacity(oldOpacity);
+}
+
bool QSvgNode::isDescendantOf(const QSvgNode *parent) const
{
const QSvgNode *n = this;
@@ -220,7 +269,7 @@ QSvgTinyDocument * QSvgNode::document() const
{
QSvgTinyDocument *doc = nullptr;
QSvgNode *node = const_cast<QSvgNode*>(this);
- while (node && node->type() != QSvgNode::DOC) {
+ while (node && node->type() != QSvgNode::Doc) {
node = node->parent();
}
doc = static_cast<QSvgTinyDocument*>(node);
@@ -228,6 +277,45 @@ QSvgTinyDocument * QSvgNode::document() const
return doc;
}
+QString QSvgNode::typeName() const
+{
+ #define stringForType(type) case type: return QStringLiteral(#type);
+ switch (type()) {
+ stringForType(Doc)
+ stringForType(Group)
+ stringForType(Defs)
+ stringForType(Switch)
+ stringForType(Animation)
+ stringForType(Circle)
+ stringForType(Ellipse)
+ stringForType(Image)
+ stringForType(Line)
+ stringForType(Path)
+ stringForType(Polygon)
+ stringForType(Polyline)
+ stringForType(Rect)
+ stringForType(Text)
+ stringForType(Textarea)
+ stringForType(Tspan)
+ stringForType(Use)
+ stringForType(Video)
+ stringForType(Mask)
+ stringForType(Symbol)
+ stringForType(Marker)
+ stringForType(Pattern)
+ stringForType(Filter)
+ stringForType(FeMerge)
+ stringForType(FeMergenode)
+ stringForType(FeColormatrix)
+ stringForType(FeGaussianblur)
+ stringForType(FeOffset)
+ stringForType(FeComposite)
+ stringForType(FeFlood)
+ }
+ #undef stringForType
+ return QStringLiteral("unknown");
+}
+
void QSvgNode::setRequiredFeatures(const QStringList &lst)
{
m_requiredFeatures = lst;
diff --git a/src/svg/qsvgnode_p.h b/src/svg/qsvgnode_p.h
index 2c23b2f..27fc560 100644
--- a/src/svg/qsvgnode_p.h
+++ b/src/svg/qsvgnode_p.h
@@ -31,37 +31,36 @@ class Q_SVG_PRIVATE_EXPORT QSvgNode
public:
enum Type
{
- DOC,
- G,
- DEFS,
- SWITCH,
- ANIMATION,
- ARC,
- CIRCLE,
- ELLIPSE,
- IMAGE,
- LINE,
- PATH,
- POLYGON,
- POLYLINE,
- RECT,
- TEXT,
- TEXTAREA,
- TSPAN,
- USE,
- VIDEO,
- MASK,
- SYMBOL,
- MARKER,
- PATTERN,
- FILTER,
- FEMERGE,
- FEMERGENODE,
- FECOLORMATRIX,
- FEGAUSSIANBLUR,
- FEOFFSET,
- FECOMPOSITE,
- FEFLOOD
+ Doc,
+ Group,
+ Defs,
+ Switch,
+ Animation,
+ Circle,
+ Ellipse,
+ Image,
+ Line,
+ Path,
+ Polygon,
+ Polyline,
+ Rect,
+ Text,
+ Textarea,
+ Tspan,
+ Use,
+ Video,
+ Mask,
+ Symbol,
+ Marker,
+ Pattern,
+ Filter,
+ FeMerge,
+ FeMergenode,
+ FeColormatrix,
+ FeGaussianblur,
+ FeOffset,
+ FeComposite,
+ FeFlood
};
enum DisplayMode {
InlineMode,
@@ -83,10 +82,14 @@ public:
NoneMode,
InheritMode
};
+
public:
QSvgNode(QSvgNode *parent=0);
virtual ~QSvgNode();
- virtual void draw(QPainter *p, QSvgExtraStates &states) =0;
+ void draw(QPainter *p, QSvgExtraStates &states);
+ virtual bool separateFillStroke() const {return false;}
+ virtual void drawCommand(QPainter *p, QSvgExtraStates &states) = 0;
+ void fillThenStroke(QPainter *p, QSvgExtraStates &states);
QSvgNode *parent() const;
bool isDescendantOf(const QSvgNode *parent) const;
@@ -99,7 +102,8 @@ public:
QSvgTinyDocument *document() const;
- virtual Type type() const =0;
+ virtual Type type() const = 0;
+ QString typeName() const;
virtual QRectF fastBounds(QPainter *p, QSvgExtraStates &states) const;
virtual QRectF bounds(QPainter *p, QSvgExtraStates &states) const;
virtual QRectF transformedBounds(QPainter *p, QSvgExtraStates &states) const;
@@ -132,7 +136,7 @@ public:
QString xmlClass() const;
void setXmlClass(const QString &str);
- bool shouldDrawNode(QPainter *p, QSvgExtraStates &states) const;
+ virtual bool shouldDrawNode(QPainter *p, QSvgExtraStates &states) const;
const QSvgStyle &style() const { return m_style; }
protected:
mutable QSvgStyle m_style;
diff --git a/src/svg/qsvgstructure.cpp b/src/svg/qsvgstructure.cpp
index b4ac368..189f57d 100644
--- a/src/svg/qsvgstructure.cpp
+++ b/src/svg/qsvgstructure.cpp
@@ -26,23 +26,25 @@ QSvgStructureNode::~QSvgStructureNode()
qDeleteAll(m_renderers);
}
-void QSvgG::draw(QPainter *p, QSvgExtraStates &states)
+void QSvgG::drawCommand(QPainter *p, QSvgExtraStates &states)
{
QList<QSvgNode*>::iterator itr = m_renderers.begin();
- applyStyle(p, states);
-
while (itr != m_renderers.end()) {
QSvgNode *node = *itr;
if ((node->isVisible()) && (node->displayMode() != QSvgNode::NoneMode))
node->draw(p, states);
++itr;
}
- revertStyle(p, states);
+}
+
+bool QSvgG::shouldDrawNode(QPainter *, QSvgExtraStates &) const
+{
+ return true;
}
QSvgNode::Type QSvgG::type() const
{
- return G;
+ return Group;
}
QSvgStructureNode::QSvgStructureNode(QSvgNode *parent)
@@ -74,14 +76,14 @@ QSvgDefs::QSvgDefs(QSvgNode *parent)
{
}
-void QSvgDefs::draw(QPainter *, QSvgExtraStates &)
+bool QSvgDefs::shouldDrawNode(QPainter *, QSvgExtraStates &) const
{
- //noop
+ return false;
}
QSvgNode::Type QSvgDefs::type() const
{
- return DEFS;
+ return Defs;
}
/*
@@ -246,10 +248,9 @@ QSvgSwitch::QSvgSwitch(QSvgNode *parent)
init();
}
-void QSvgSwitch::draw(QPainter *p, QSvgExtraStates &states)
+void QSvgSwitch::drawCommand(QPainter *p, QSvgExtraStates &states)
{
QList<QSvgNode*>::iterator itr = m_renderers.begin();
- applyStyle(p, states);
while (itr != m_renderers.end()) {
QSvgNode *node = *itr;
@@ -307,12 +308,11 @@ void QSvgSwitch::draw(QPainter *p, QSvgExtraStates &states)
}
++itr;
}
- revertStyle(p, states);
}
QSvgNode::Type QSvgSwitch::type() const
{
- return SWITCH;
+ return Switch;
}
void QSvgSwitch::init()
diff --git a/src/svg/qsvgstructure_p.h b/src/svg/qsvgstructure_p.h
index f2c0c0f..5d2ed41 100644
--- a/src/svg/qsvgstructure_p.h
+++ b/src/svg/qsvgstructure_p.h
@@ -16,7 +16,6 @@
//
#include "qsvgnode_p.h"
-#include "qtsvgglobal_p.h"
#include "QtCore/qlist.h"
#include "QtCore/qhash.h"
@@ -49,7 +48,8 @@ class Q_SVG_PRIVATE_EXPORT QSvgG : public QSvgStructureNode
{
public:
QSvgG(QSvgNode *parent);
- void draw(QPainter *p, QSvgExtraStates &states) override;
+ void drawCommand(QPainter *, QSvgExtraStates &) override;
+ bool shouldDrawNode(QPainter *p, QSvgExtraStates &states) const override;
Type type() const override;
};
@@ -57,7 +57,8 @@ class Q_SVG_PRIVATE_EXPORT QSvgDefs : public QSvgStructureNode
{
public:
QSvgDefs(QSvgNode *parent);
- void draw(QPainter *p, QSvgExtraStates &states) override;
+ void drawCommand(QPainter *, QSvgExtraStates &) override {};
+ bool shouldDrawNode(QPainter *p, QSvgExtraStates &states) const override;
Type type() const override;
};
@@ -65,7 +66,7 @@ class Q_SVG_PRIVATE_EXPORT QSvgSwitch : public QSvgStructureNode
{
public:
QSvgSwitch(QSvgNode *parent);
- void draw(QPainter *p, QSvgExtraStates &states) override;
+ void drawCommand(QPainter *p, QSvgExtraStates &states) override;
Type type() const override;
private:
void init();
diff --git a/src/svg/qsvgtinydocument.cpp b/src/svg/qsvgtinydocument.cpp
index b548d19..b901fc1 100644
--- a/src/svg/qsvgtinydocument.cpp
+++ b/src/svg/qsvgtinydocument.cpp
@@ -314,7 +314,7 @@ void QSvgTinyDocument::draw(QPainter *p, const QString &id,
QSvgNode::Type QSvgTinyDocument::type() const
{
- return DOC;
+ return Doc;
}
void QSvgTinyDocument::setWidth(int len, bool percent)
@@ -398,7 +398,7 @@ void QSvgTinyDocument::draw(QPainter *p)
draw(p, QRectF());
}
-void QSvgTinyDocument::draw(QPainter *, QSvgExtraStates &)
+void QSvgTinyDocument::drawCommand(QPainter *, QSvgExtraStates &)
{
qCDebug(lcSvgHandler) << "SVG Tiny does not support nested <svg> elements: ignored.";
return;
diff --git a/src/svg/qsvgtinydocument_p.h b/src/svg/qsvgtinydocument_p.h
index 539db9c..8d5e180 100644
--- a/src/svg/qsvgtinydocument_p.h
+++ b/src/svg/qsvgtinydocument_p.h
@@ -60,7 +60,7 @@ public:
QSvg::FeatureSet featureSet() const;
- void draw(QPainter *p, QSvgExtraStates &) override; //from the QSvgNode
+ void drawCommand(QPainter *, QSvgExtraStates &) override;
void draw(QPainter *p);
void draw(QPainter *p, const QRectF &bounds);
diff --git a/src/svg/qsvgvisitor.cpp b/src/svg/qsvgvisitor.cpp
index fe3ea72..7028e16 100644
--- a/src/svg/qsvgvisitor.cpp
+++ b/src/svg/qsvgvisitor.cpp
@@ -8,19 +8,19 @@ QT_BEGIN_NAMESPACE
void QSvgVisitor::traverse(const QSvgStructureNode *node)
{
switch (node->type()) {
- case QSvgNode::SWITCH:
+ case QSvgNode::Switch:
if (!visitSwitchNodeStart(static_cast<const QSvgSwitch *>(node)))
return;
break;
- case QSvgNode::DOC:
+ case QSvgNode::Doc:
if (!visitDocumentNodeStart(static_cast<const QSvgTinyDocument *>(node)))
return;
break;
- case QSvgNode::DEFS:
+ case QSvgNode::Defs:
if (!visitDefsNodeStart(static_cast<const QSvgDefs *>(node)))
return;
break;
- case QSvgNode::G:
+ case QSvgNode::Group:
if (!visitGroupNodeStart(static_cast<const QSvgG *>(node)))
return;
break;
@@ -31,83 +31,79 @@ void QSvgVisitor::traverse(const QSvgStructureNode *node)
for (const auto *child : node->renderers()) {
switch (child->type()) {
- case QSvgNode::SWITCH:
- case QSvgNode::DOC:
- case QSvgNode::DEFS:
- case QSvgNode::G:
+ case QSvgNode::Switch:
+ case QSvgNode::Doc:
+ case QSvgNode::Defs:
+ case QSvgNode::Group:
traverse(static_cast<const QSvgStructureNode *>(child));
break;
- case QSvgNode::ANIMATION:
+ case QSvgNode::Animation:
visitAnimationNode(static_cast<const QSvgAnimation *>(child));
break;
- case QSvgNode::CIRCLE:
- case QSvgNode::ELLIPSE:
+ case QSvgNode::Circle:
+ case QSvgNode::Ellipse:
visitEllipseNode(static_cast<const QSvgEllipse *>(child));
break;
- case QSvgNode::IMAGE:
+ case QSvgNode::Image:
visitImageNode(static_cast<const QSvgImage *>(child));
break;
- case QSvgNode::LINE:
+ case QSvgNode::Line:
visitLineNode(static_cast<const QSvgLine *>(child));
break;
- case QSvgNode::PATH:
+ case QSvgNode::Path:
visitPathNode(static_cast<const QSvgPath *>(child));
break;
- case QSvgNode::POLYGON:
+ case QSvgNode::Polygon:
visitPolygonNode(static_cast<const QSvgPolygon *>(child));
break;
- case QSvgNode::POLYLINE:
+ case QSvgNode::Polyline:
visitPolylineNode(static_cast<const QSvgPolyline *>(child));
break;
- case QSvgNode::RECT:
+ case QSvgNode::Rect:
visitRectNode(static_cast<const QSvgRect *>(child));
break;
- case QSvgNode::TEXT:
- case QSvgNode::TEXTAREA:
+ case QSvgNode::Text:
+ case QSvgNode::Textarea:
visitTextNode(static_cast<const QSvgText *>(child));
break;
- case QSvgNode::TSPAN:
+ case QSvgNode::Tspan:
visitTspanNode(static_cast<const QSvgTspan *>(child));
break;
- case QSvgNode::USE:
+ case QSvgNode::Use:
visitUseNode(static_cast<const QSvgUse *>(child));
break;
- case QSvgNode::VIDEO:
+ case QSvgNode::Video:
visitVideoNode(static_cast<const QSvgVideo *>(child));
break;
// Enum values that don't have any QSvgNode classes yet:
- case QSvgNode::MASK:
- case QSvgNode::SYMBOL:
- case QSvgNode::MARKER:
- case QSvgNode::PATTERN:
- case QSvgNode::FILTER:
- case QSvgNode::FEMERGE:
- case QSvgNode::FEMERGENODE:
- case QSvgNode::FECOLORMATRIX:
- case QSvgNode::FEGAUSSIANBLUR:
- case QSvgNode::FEOFFSET:
- case QSvgNode::FECOMPOSITE:
- case QSvgNode::FEFLOOD:
+ case QSvgNode::Mask:
+ case QSvgNode::Symbol:
+ case QSvgNode::Marker:
+ case QSvgNode::Pattern:
+ case QSvgNode::Filter:
+ case QSvgNode::FeMerge:
+ case QSvgNode::FeMergenode:
+ case QSvgNode::FeColormatrix:
+ case QSvgNode::FeGaussianblur:
+ case QSvgNode::FeOffset:
+ case QSvgNode::FeComposite:
+ case QSvgNode::FeFlood:
qDebug() << "Unhandled type in switch" << child->type();
break;
-
- case QSvgNode::ARC: // Not used: to be removed
- Q_UNREACHABLE();
- break;
}
}
switch (node->type()) {
- case QSvgNode::SWITCH:
+ case QSvgNode::Switch:
visitSwitchNodeEnd(static_cast<const QSvgSwitch *>(node));
break;
- case QSvgNode::DOC:
+ case QSvgNode::Doc:
visitDocumentNodeEnd(static_cast<const QSvgTinyDocument *>(node));
break;
- case QSvgNode::DEFS:
+ case QSvgNode::Defs:
visitDefsNodeEnd(static_cast<const QSvgDefs *>(node));
break;
- case QSvgNode::G:
+ case QSvgNode::Group:
visitGroupNodeEnd(static_cast<const QSvgG *>(node));
break;
default: