Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qsvggraphics.cpp
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
4#include "qsvggraphics_p.h"
5
6#include "qsvgfont_p.h"
7
9#include <qdebug.h>
10#include <qloggingcategory.h>
11#include <qpainter.h>
13#include <qtextcursor.h>
14#include <qtextdocument.h>
15#include <private/qfixed_p.h>
16
17#include <QElapsedTimer>
18#include <QLoggingCategory>
19
20#include <math.h>
21#include <limits.h>
22
24
25Q_LOGGING_CATEGORY(lcSvgDraw, "qt.svg.draw")
26Q_LOGGING_CATEGORY(lcSvgTiming, "qt.svg.timing")
27
28#define QT_SVG_TIMING_ENTER \
29 QElapsedTimer qtSvgTimer; qtSvgTimer.start();
30
31#define QT_SVG_TIMING_EXIT(TYPE) \
32 if (Q_UNLIKELY(lcSvgTiming().isDebugEnabled())) \
33 qCDebug(lcSvgTiming) << "Drawing" << TYPE << "took" << (qtSvgTimer.nsecsElapsed() / 1000000.0f) << "ms";
34
35#define QT_SVG_DRAW_SHAPE(command) \
36 { qreal oldOpacity = p->opacity(); \
37 QBrush oldBrush = p->brush(); \
38 QPen oldPen = p->pen(); \
39 p->setPen(Qt::NoPen); \
40 p->setOpacity(oldOpacity * states.fillOpacity); \
41 command; \
42 p->setPen(oldPen); \
43 if (oldPen != Qt::NoPen && oldPen.brush() != Qt::NoBrush && oldPen.widthF() != 0) { \
44 p->setOpacity(oldOpacity * states.strokeOpacity); \
45 p->setBrush(Qt::NoBrush); \
46 command; \
47 p->setBrush(oldBrush); \
48 } \
49 p->setOpacity(oldOpacity); }
50
51#ifndef QT_SVG_MAX_LAYOUT_SIZE
52#define QT_SVG_MAX_LAYOUT_SIZE (qint64(QFIXED_MAX / 2))
53#endif
54
56{
57 qWarning("<animation> no implemented");
58}
59
61{
62 QPainterPathStroker stroker;
63 stroker.setWidth(width);
64 QPainterPath stroke = stroker.createStroke(path);
65 return p->transform().map(stroke).boundingRect();
66}
67
69 : QSvgNode(parent), m_bounds(rect)
70{
71}
72
74{
75 return p->transform().mapRect(m_bounds);
76}
77
79{
81 path.addEllipse(m_bounds);
82 qreal sw = strokeWidth(p);
83 return qFuzzyIsNull(sw) ? p->transform().map(path).boundingRect() : boundsOnStroke(p, path, sw);
84}
85
87{
91 QT_SVG_DRAW_SHAPE(p->drawEllipse(m_bounds));
93 QT_SVG_TIMING_EXIT("Ellipse")
94}
95
97 : QSvgNode(parent), m_path(path)
98{
99}
100
102{
105 if (shouldDrawNode(p, states)) {
106 if (p->pen().widthF() != 0) {
107 qreal oldOpacity = p->opacity();
108 p->setOpacity(oldOpacity * states.strokeOpacity);
109 p->drawPath(m_path);
110 p->setOpacity(oldOpacity);
111 }
112 }
114 QT_SVG_TIMING_EXIT("Arc")
115}
116
118 const QRectF &bounds)
119 : QSvgNode(parent), m_image(image),
120 m_bounds(bounds)
121{
122 if (m_bounds.width() == 0.0)
123 m_bounds.setWidth(static_cast<qreal>(m_image.width()));
124 if (m_bounds.height() == 0.0)
125 m_bounds.setHeight(static_cast<qreal>(m_image.height()));
126}
127
129{
131 if (shouldDrawNode(p, states)) {
133 p->drawImage(m_bounds, m_image);
135 }
136 QT_SVG_TIMING_EXIT("Image")
137}
138
139
141 : QSvgNode(parent), m_line(line)
142{
143}
144
145
147{
150 if (shouldDrawNode(p, states)) {
151 if (p->pen().widthF() != 0) {
152 qreal oldOpacity = p->opacity();
153 p->setOpacity(oldOpacity * states.strokeOpacity);
154 p->drawLine(m_line);
155 p->setOpacity(oldOpacity);
156 }
157 }
159 QT_SVG_TIMING_EXIT("Line")
160}
161
163 : QSvgNode(parent), m_path(qpath)
164{
165}
166
168{
171 if (shouldDrawNode(p, states)) {
172 m_path.setFillRule(states.fillRule);
173 QT_SVG_DRAW_SHAPE(p->drawPath(m_path));
174 }
176 QT_SVG_TIMING_EXIT("Path")
177}
178
180{
181 return p->transform().mapRect(m_path.controlPointRect());
182}
183
185{
186 qreal sw = strokeWidth(p);
187 return qFuzzyIsNull(sw) ? p->transform().map(m_path).boundingRect()
188 : boundsOnStroke(p, m_path, sw);
189}
190
192 : QSvgNode(parent), m_poly(poly)
193{
194}
195
197{
198 return p->transform().mapRect(m_poly.boundingRect());
199}
200
202{
203 qreal sw = strokeWidth(p);
204 if (qFuzzyIsNull(sw)) {
205 return p->transform().map(m_poly).boundingRect();
206 } else {
208 path.addPolygon(m_poly);
209 return boundsOnStroke(p, path, sw);
210 }
211}
212
214{
217 if (shouldDrawNode(p, states))
218 QT_SVG_DRAW_SHAPE(p->drawPolygon(m_poly, states.fillRule));
220 QT_SVG_TIMING_EXIT("Polygon")
221}
222
223
225 : QSvgNode(parent), m_poly(poly)
226{
227
228}
229
231{
234 if (shouldDrawNode(p, states)) {
235 qreal oldOpacity = p->opacity();
236 if (p->brush().style() != Qt::NoBrush) {
237 QPen save = p->pen();
238 p->setPen(QPen(Qt::NoPen));
239 p->setOpacity(oldOpacity * states.fillOpacity);
240 p->drawPolygon(m_poly, states.fillRule);
241 p->setPen(save);
242 }
243 if (p->pen().widthF() != 0) {
244 p->setOpacity(oldOpacity * states.strokeOpacity);
245 p->drawPolyline(m_poly);
246 }
247 p->setOpacity(oldOpacity);
248 }
250 QT_SVG_TIMING_EXIT("Polyline")
251}
252
253QSvgRect::QSvgRect(QSvgNode *node, const QRectF &rect, int rx, int ry)
254 : QSvgNode(node),
255 m_rect(rect), m_rx(rx), m_ry(ry)
256{
257}
258
260{
261 return p->transform().mapRect(m_rect);
262}
263
265{
266 qreal sw = strokeWidth(p);
267 if (qFuzzyIsNull(sw)) {
268 return p->transform().mapRect(m_rect);
269 } else {
271 path.addRect(m_rect);
272 return boundsOnStroke(p, path, sw);
273 }
274}
275
277{
280 if (shouldDrawNode(p, states)) {
281 if (m_rx || m_ry) {
282 QT_SVG_DRAW_SHAPE(p->drawRoundedRect(m_rect, m_rx, m_ry, Qt::RelativeSize));
283 } else {
284 QT_SVG_DRAW_SHAPE(p->drawRect(m_rect));
285 }
286 }
288 QT_SVG_TIMING_EXIT("Rect")
289}
290
291QSvgTspan * const QSvgText::LINEBREAK = 0;
292
295 , m_coord(coord)
296 , m_type(TEXT)
297 , m_size(0, 0)
298 , m_mode(Default)
299{
300}
301
303{
304 for (int i = 0; i < m_tspans.size(); ++i) {
305 if (m_tspans[i] != LINEBREAK)
306 delete m_tspans[i];
307 }
308}
309
311{
312 m_size = size;
313 m_type = TEXTAREA;
314}
315
317{
318 QFont font = p->font();
320
321 int charCount = 0;
322 for (int i = 0; i < m_tspans.size(); ++i)
323 charCount += m_tspans.at(i)->text().size();
324
325 QRectF approxMaximumBrect(m_coord.x(),
326 m_coord.y(),
327 charCount * fm.averageCharWidth(),
328 m_tspans.size() * fm.height());
329 return p->transform().mapRect(approxMaximumBrect);
330}
331
333{
335 if (precheck(p))
336 draw_helper(p, states, &boundingRect);
337 return p->transform().mapRect(boundingRect);
338}
339
340bool QSvgText::precheck(QPainter *p) const
341{
342 qsizetype numChars = 0;
343 qreal originalFontSize = p->font().pointSizeF();
344 qreal maxFontSize = originalFontSize;
345 for (const QSvgTspan *span : std::as_const(m_tspans)) {
346 numChars += span->text().size();
347
348 QSvgFontStyle *style = static_cast<QSvgFontStyle *>(span->styleProperty(QSvgStyleProperty::FONT));
349 if (style != nullptr && style->qfont().pointSizeF() > maxFontSize)
350 maxFontSize = style->qfont().pointSizeF();
351 }
352
353 QFont font = p->font();
354 font.setPixelSize((100.0 / originalFontSize) * maxFontSize);
356 if (m_tspans.size() * fm.height() >= QT_SVG_MAX_LAYOUT_SIZE) {
357 qCWarning(lcSvgDraw) << "Text element too high to lay out, ignoring";
358 return false;
359 }
360
361 if (numChars * fm.maxWidth() >= QT_SVG_MAX_LAYOUT_SIZE) {
362 qCWarning(lcSvgDraw) << "Text element too wide to lay out, ignoring";
363 return false;
364 }
365
366 return true;
367}
368
370{
372 if (precheck(p))
373 draw_helper(p, states);
374 QT_SVG_TIMING_EXIT("Text")
375}
376
377void QSvgText::draw_helper(QPainter *p, QSvgExtraStates &states, QRectF *boundingRect) const
378{
379 const bool isPainting = (boundingRect == nullptr);
381 if (!isPainting || shouldDrawNode(p, states)) {
382 qreal oldOpacity = p->opacity();
383 p->setOpacity(oldOpacity * states.fillOpacity);
384
385 // Force the font to have a size of 100 pixels to avoid truncation problems
386 // when the font is very small.
387 qreal scale = 100.0 / p->font().pointSizeF();
388 Qt::Alignment alignment = states.textAnchor;
389
390 QTransform oldTransform = p->worldTransform();
391 p->scale(1 / scale, 1 / scale);
392
393 qreal y = 0;
394 bool initial = true;
395 qreal px = m_coord.x() * scale;
396 qreal py = m_coord.y() * scale;
397 QSizeF scaledSize = m_size * scale;
398
399 if (m_type == TEXTAREA) {
401 px += scaledSize.width() / 2;
402 else if (alignment == Qt::AlignRight)
403 px += scaledSize.width();
404 }
405
407 if (m_size.height() != 0)
408 bounds = QRectF(0, py, 1, scaledSize.height()); // x and width are not used.
409
410 bool appendSpace = false;
411 QList<QString> paragraphs;
413 paragraphs.push_back(QString());
414
415 for (int i = 0; i < m_tspans.size(); ++i) {
416 if (m_tspans[i] == LINEBREAK) {
417 if (m_type == TEXTAREA) {
418 if (paragraphs.back().isEmpty()) {
419 QFont font = p->font();
421
423 range.start = 0;
424 range.length = 1;
425 range.format.setFont(font);
426 formatRanges.back().append(range);
427
428 paragraphs.back().append(QLatin1Char(' '));;
429 }
430 appendSpace = false;
431 paragraphs.push_back(QString());
432 formatRanges.resize(formatRanges.size() + 1);
433 }
434 } else {
435 WhitespaceMode mode = m_tspans[i]->whitespaceMode();
436 m_tspans[i]->applyStyle(p, states);
437
438 QFont font = p->font();
440
441 QString newText(m_tspans[i]->text());
442 newText.replace(QLatin1Char('\t'), QLatin1Char(' '));
443 newText.replace(QLatin1Char('\n'), QLatin1Char(' '));
444
445 bool prependSpace = !appendSpace && !m_tspans[i]->isTspan() && (mode == Default) && !paragraphs.back().isEmpty() && newText.startsWith(QLatin1Char(' '));
446 if (appendSpace || prependSpace)
447 paragraphs.back().append(QLatin1Char(' '));
448
449 bool appendSpaceNext = (!m_tspans[i]->isTspan() && (mode == Default) && newText.endsWith(QLatin1Char(' ')));
450
451 if (mode == Default) {
452 newText = newText.simplified();
453 if (newText.isEmpty())
454 appendSpaceNext = false;
455 }
456
458 range.start = paragraphs.back().size();
459 range.length = newText.size();
460 range.format.setFont(font);
461 range.format.setTextOutline(p->pen());
462 range.format.setForeground(p->brush());
463
464 if (appendSpace) {
465 Q_ASSERT(!formatRanges.back().isEmpty());
466 ++formatRanges.back().back().length;
467 } else if (prependSpace) {
468 --range.start;
469 ++range.length;
470 }
471 formatRanges.back().append(range);
472
473 appendSpace = appendSpaceNext;
474 paragraphs.back() += newText;
475
476 m_tspans[i]->revertStyle(p, states);
477 }
478 }
479
480 if (states.svgFont) {
481 // SVG fonts not fully supported...
482 QString text = paragraphs.front();
483 for (int i = 1; i < paragraphs.size(); ++i) {
484 text.append(QLatin1Char('\n'));
485 text.append(paragraphs[i]);
486 }
487 states.svgFont->draw(p, m_coord * scale, text, p->font().pointSizeF() * scale, states.textAnchor);
488 } else {
489 QRectF brect;
490 for (int i = 0; i < paragraphs.size(); ++i) {
491 QTextLayout tl(paragraphs[i]);
492 QTextOption op = tl.textOption();
494 tl.setTextOption(op);
495 tl.setFormats(formatRanges[i]);
496 tl.beginLayout();
497
498 forever {
499 QTextLine line = tl.createLine();
500 if (!line.isValid())
501 break;
502 if (m_size.width() != 0)
503 line.setLineWidth(scaledSize.width());
504 }
505 tl.endLayout();
506
507 bool endOfBoundsReached = false;
508 for (int i = 0; i < tl.lineCount(); ++i) {
509 QTextLine line = tl.lineAt(i);
510
511 qreal x = 0;
513 x -= 0.5 * line.naturalTextWidth();
514 else if (alignment == Qt::AlignRight)
515 x -= line.naturalTextWidth();
516
517 if (initial && m_type == TEXT)
518 y -= line.ascent();
519 initial = false;
520
521 line.setPosition(QPointF(x, y));
522 brect |= line.naturalTextRect();
523
524 // Check if the current line fits into the bounding rectangle.
525 if ((m_size.width() != 0 && line.naturalTextWidth() > scaledSize.width())
526 || (m_size.height() != 0 && y + line.height() > scaledSize.height())) {
527 // I need to set the bounds height to 'y-epsilon' to avoid drawing the current
528 // line. Since the font is scaled to 100 units, 1 should be a safe epsilon.
529 bounds.setHeight(y - 1);
530 endOfBoundsReached = true;
531 break;
532 }
533
534 y += 1.1 * line.height();
535 }
536 if (isPainting)
537 tl.draw(p, QPointF(px, py), QList<QTextLayout::FormatRange>(), bounds);
538
539 if (endOfBoundsReached)
540 break;
541 }
542 if (boundingRect) {
543 brect.translate(m_coord * scale);
544 if (bounds.height() > 0)
545 brect.setBottom(qMin(brect.bottom(), bounds.bottom()));
547 }
548 }
549
550 p->setWorldTransform(oldTransform, false);
551 p->setOpacity(oldOpacity);
552 }
554}
555
557{
558 m_tspans.append(new QSvgTspan(this, false));
559 m_tspans.back()->setWhitespaceMode(m_mode);
560 m_tspans.back()->addText(text);
561}
562
564 : QSvgNode(parent), m_link(node), m_start(start), m_recursing(false)
565{
566
567}
568
570{
572 if (Q_UNLIKELY(!m_link || isDescendantOf(m_link) || m_recursing))
573 return;
574
575 Q_ASSERT(states.nestedUseCount == 0 || states.nestedUseLevel > 0);
576 if (states.nestedUseLevel > 3 && states.nestedUseCount > (256 + states.nestedUseLevel * 2)) {
577 qCDebug(lcSvgDraw, "Too many nested use nodes at #%s!", qPrintable(m_linkId));
578 return;
579 }
580
582
583 if (!m_start.isNull()) {
584 p->translate(m_start);
585 }
586 if (states.nestedUseLevel > 0)
587 ++states.nestedUseCount;
588 {
589 QScopedValueRollback<int> useLevelGuard(states.nestedUseLevel, states.nestedUseLevel + 1);
590 QScopedValueRollback<bool> recursingGuard(m_recursing, true);
591 m_link->draw(p, states);
592 }
593 if (states.nestedUseLevel == 0)
594 states.nestedUseCount = 0;
595
596 if (!m_start.isNull()) {
597 p->translate(-m_start);
598 }
599
601 QT_SVG_TIMING_EXIT("Use")
602}
603
605{
607
609}
610
612{
613 return ANIMATION;
614}
615
617{
618 return ARC;
619}
620
622{
623 return CIRCLE;
624}
625
627{
628 return ELLIPSE;
629}
630
632{
633 return IMAGE;
634}
635
637{
638 return LINE;
639}
640
642{
643 return PATH;
644}
645
647{
648 return POLYGON;
649}
650
652{
653 return POLYLINE;
654}
655
657{
658 return RECT;
659}
660
662{
663 return m_type;
664}
665
667{
668 return USE;
669}
670
672{
673 return VIDEO;
674}
675
677{
679 if (Q_LIKELY(m_link && !isDescendantOf(m_link) && !m_recursing)) {
680 QScopedValueRollback<bool> guard(m_recursing, true);
681 p->translate(m_start);
682 bounds = m_link->transformedBounds(p, states);
683 p->translate(-m_start);
684 }
685 return bounds;
686}
687
689{
690 return p->transform().mapRect(m_poly.boundingRect());
691}
692
694{
695 qreal sw = strokeWidth(p);
696 if (qFuzzyIsNull(sw)) {
697 return p->transform().map(m_poly).boundingRect();
698 } else {
700 path.addPolygon(m_poly);
701 return boundsOnStroke(p, path, sw);
702 }
703}
704
706{
707 return p->transform().mapRect(m_path.controlPointRect());
708}
709
711{
712 qreal sw = strokeWidth(p);
713 return qFuzzyIsNull(sw) ? p->transform().map(m_path).boundingRect()
714 : boundsOnStroke(p, m_path, sw);
715}
716
718{
719 return p->transform().mapRect(m_bounds);
720}
721
723{
724 QPointF p1 = p->transform().map(m_line.p1());
725 QPointF p2 = p->transform().map(m_line.p2());
726 qreal minX = qMin(p1.x(), p2.x());
727 qreal minY = qMin(p1.y(), p2.y());
728 qreal maxX = qMax(p1.x(), p2.x());
729 qreal maxY = qMax(p1.y(), p2.y());
730 return QRectF(minX, minY, maxX - minX, maxY - minY);
731}
732
734{
735 qreal sw = strokeWidth(p);
736 if (qFuzzyIsNull(sw)) {
737 return fastBounds(p, s);
738 } else {
740 path.moveTo(m_line.p1());
741 path.lineTo(m_line.p2());
742 return boundsOnStroke(p, path, sw);
743 }
744}
745
\reentrant \inmodule QtGui
qreal height() const
Returns the height of the font.
qreal averageCharWidth() const
\reentrant
Definition qfont.h:20
void setPixelSize(int)
Sets the font size to pixelSize pixels, with a maxiumum size of an unsigned 16-bit integer.
Definition qfont.cpp:1034
qreal pointSizeF() const
Returns the point size of the font.
Definition qfont.cpp:1019
\inmodule QtGui
Definition qimage.h:37
int width() const
Returns the width of the image.
int height() const
Returns the height of the image.
\inmodule QtCore
Definition qline.h:182
constexpr QPointF p1() const
Returns the line's start point.
Definition qline.h:289
constexpr QPointF p2() const
Returns the line's end point.
Definition qline.h:294
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
reference back()
Definition qlist.h:686
void push_back(parameter_type t)
Definition qlist.h:672
bool endsWith(parameter_type t) const
Definition qlist.h:635
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
reference front()
Definition qlist.h:684
void append(parameter_type t)
Definition qlist.h:441
The QPainterPathStroker class is used to generate fillable outlines for a given painter path.
void setWidth(qreal width)
Sets the width of the generated outline painter path to width.
QPainterPath createStroke(const QPainterPath &path) const
Generates a new path that is a fillable area representing the outline of the given path.
\inmodule QtGui
void setFillRule(Qt::FillRule fillRule)
Sets the fill rule of the painter path to the given fillRule.
QRectF controlPointRect() const
Returns the rectangle containing all the points and control points in this path.
QRectF boundingRect() const
Returns the bounding rectangle of this painter path as a rectangle with floating point precision.
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
\inmodule QtGui
Definition qpen.h:25
\inmodule QtCore\reentrant
Definition qpoint.h:214
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:333
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:338
bool isNull() const noexcept
Returns true if both the x and y coordinates are set to 0.0 (ignoring the sign); otherwise returns fa...
Definition qpoint.h:328
The QPolygonF class provides a list of points using floating point precision.
Definition qpolygon.h:96
QRectF Q_GUI_EXPORT boundingRect() const
Returns the bounding rectangle of the polygon, or QRectF(0,0,0,0) if the polygon is empty.
Definition qpolygon.cpp:588
\inmodule QtCore\reentrant
Definition qrect.h:483
constexpr qreal bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
Definition qrect.h:499
constexpr void setBottom(qreal pos) noexcept
Sets the bottom edge of the rectangle to the given finite y coordinate.
Definition qrect.h:670
constexpr qreal height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:718
constexpr qreal width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:715
constexpr void setWidth(qreal w) noexcept
Sets the width of the rectangle to the given finite width.
Definition qrect.h:804
constexpr void translate(qreal dx, qreal dy) noexcept
Moves the rectangle dx along the x-axis and dy along the y-axis, relative to the current position.
Definition qrect.h:724
constexpr void setHeight(qreal h) noexcept
Sets the height of the rectangle to the given finite height.
Definition qrect.h:807
\inmodule QtCore
Definition qsize.h:207
constexpr qreal width() const noexcept
Returns the width.
Definition qsize.h:321
constexpr qreal height() const noexcept
Returns the height.
Definition qsize.h:324
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
QString & append(QChar c)
Definition qstring.cpp:3227
void draw(QPainter *p, QSvgExtraStates &states) override
Type type() const override
QRectF fastBounds(QPainter *p, QSvgExtraStates &states) const override
QSvgArc(QSvgNode *parent, const QPainterPath &path)
Type type() const override
void draw(QPainter *p, QSvgExtraStates &states) override
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override
Type type() const override
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override
void draw(QPainter *p, QSvgExtraStates &states) override
QRectF fastBounds(QPainter *p, QSvgExtraStates &states) const override
QSvgEllipse(QSvgNode *parent, const QRectF &rect)
Type type() const override
const QFont & qfont() const
QSvgImage(QSvgNode *parent, const QImage &image, const QRectF &bounds)
void draw(QPainter *p, QSvgExtraStates &states) override
Type type() const override
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override
QSvgLine(QSvgNode *parent, const QLineF &line)
Type type() const override
void draw(QPainter *p, QSvgExtraStates &states) override
QRectF fastBounds(QPainter *p, QSvgExtraStates &states) const override
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override
void revertStyle(QPainter *p, QSvgExtraStates &states) const
Definition qsvgnode.cpp:104
static qreal strokeWidth(QPainter *p)
Definition qsvgnode.cpp:321
virtual QRectF transformedBounds(QPainter *p, QSvgExtraStates &states) const
Definition qsvgnode.cpp:293
bool isDescendantOf(const QSvgNode *parent) const
Definition qsvgnode.cpp:34
void applyStyle(QPainter *p, QSvgExtraStates &states) const
Definition qsvgnode.cpp:99
virtual void draw(QPainter *p, QSvgExtraStates &states)=0
bool shouldDrawNode(QPainter *p, QSvgExtraStates &states) const
Definition qsvgnode.cpp:329
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override
void draw(QPainter *p, QSvgExtraStates &states) override
Type type() const override
QSvgPath(QSvgNode *parent, const QPainterPath &qpath)
QRectF fastBounds(QPainter *p, QSvgExtraStates &states) const override
QRectF fastBounds(QPainter *p, QSvgExtraStates &states) const override
Type type() const override
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override
QSvgPolygon(QSvgNode *parent, const QPolygonF &poly)
void draw(QPainter *p, QSvgExtraStates &states) override
QSvgPolyline(QSvgNode *parent, const QPolygonF &poly)
void draw(QPainter *p, QSvgExtraStates &states) override
QRectF fastBounds(QPainter *p, QSvgExtraStates &states) const override
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override
Type type() const override
Type type() const override
QRectF fastBounds(QPainter *p, QSvgExtraStates &states) const override
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override
QSvgRect(QSvgNode *paren, const QRectF &rect, int rx=0, int ry=0)
void draw(QPainter *p, QSvgExtraStates &states) override
void addText(const QString &text)
void draw(QPainter *p, QSvgExtraStates &states) override
QRectF fastBounds(QPainter *p, QSvgExtraStates &states) const override
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override
QSvgText(QSvgNode *parent, const QPointF &coord)
void setTextArea(const QSizeF &size)
Type type() const override
const QString & text() const
void setWhitespaceMode(QSvgText::WhitespaceMode mode)
void addText(const QString &text)
void draw(QPainter *p, QSvgExtraStates &states) override
QSvgUse(const QPointF &start, QSvgNode *parent, QSvgNode *link)
Type type() const override
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override
Type type() const override
void draw(QPainter *p, QSvgExtraStates &states) override
\reentrant
Definition qtextlayout.h:70
\reentrant
\reentrant
Definition qtextoption.h:18
void setWrapMode(WrapMode wrap)
Sets the option's text wrap mode to the given mode.
Definition qtextoption.h:67
@ WrapAtWordBoundaryOrAnywhere
Definition qtextoption.h:65
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
static QTransform fromScale(qreal dx, qreal dy)
Creates a matrix which corresponds to a scaling of sx horizontally and sy vertically.
QTransform & scale(qreal sx, qreal sy)
Scales the coordinate system by sx horizontally and sy vertically, and returns a reference to the mat...
QRect mapRect(const QRect &) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
QPixmap p2
QPixmap p1
[0]
QString text
rect
[4]
uint alignment
Combined button and popup list for selecting options.
@ AlignRight
Definition qnamespace.h:145
@ AlignHCenter
Definition qnamespace.h:147
@ RelativeSize
@ NoPen
@ NoBrush
Definition image.cpp:4
#define Q_UNLIKELY(x)
#define Q_LIKELY(x)
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition qfloat16.h:303
#define forever
Definition qforeach.h:78
#define qWarning
Definition qlogging.h:162
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLint GLint GLint GLint GLint x
[0]
GLenum mode
GLfloat GLfloat GLfloat GLfloat GLfloat maxY
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLfloat minY
GLsizei range
GLint GLsizei width
GLuint start
GLint y
GLfloat GLfloat GLfloat GLfloat maxX
GLuint coord
GLsizei const GLchar *const * path
GLenum GLenum GLsizei void GLsizei void void * span
GLdouble s
[6]
Definition qopenglext.h:235
GLfloat GLfloat p
[1]
GLenum GLenum GLenum GLenum GLenum scale
GLuint * states
static const QRectF boundingRect(const QPointF *points, int pointCount)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QT_BEGIN_NAMESPACE const uint Default
Definition qsplitter_p.h:25
#define qPrintable(string)
Definition qstring.h:1391
#define QT_SVG_DRAW_SHAPE(command)
#define QT_SVG_TIMING_EXIT(TYPE)
#define QT_SVG_TIMING_ENTER
#define QT_SVG_MAX_LAYOUT_SIZE
static QRectF boundsOnStroke(QPainter *p, const QPainterPath &path, qreal width)
ptrdiff_t qsizetype
Definition qtypes.h:70
double qreal
Definition qtypes.h:92
p ry()++
p rx()++
\inmodule QtCore \reentrant
Definition qchar.h:17
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent