Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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#include "qsvgstructure_p.h"
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")
26
27#ifndef QT_SVG_MAX_LAYOUT_SIZE
28#define QT_SVG_MAX_LAYOUT_SIZE (qint64(QFIXED_MAX / 2))
29#endif
30
32{
33 qWarning("<animation> not implemented");
34}
35
37{
38 QPainterPathStroker stroker;
39 stroker.setWidth(width);
40 QPainterPath stroke = stroker.createStroke(path);
41 return p->transform().map(stroke).boundingRect();
42}
43
45 : QSvgNode(parent), m_bounds(rect)
46{
47}
48
50{
51 return p->transform().mapRect(m_bounds);
52}
53
55{
57 path.addEllipse(m_bounds);
58 qreal sw = strokeWidth(p);
59 return qFuzzyIsNull(sw) ? p->transform().map(path).boundingRect() : boundsOnStroke(p, path, sw);
60}
61
63{
64 p->drawEllipse(m_bounds);
65}
66
68{
69 return true;
70}
71
73 const QImage &image,
74 const QString &filename,
75 const QRectF &bounds)
76 : QSvgNode(parent)
77 , m_filename(filename)
78 , m_image(image)
79 , m_bounds(bounds)
80{
81 if (m_bounds.width() == 0.0)
82 m_bounds.setWidth(static_cast<qreal>(m_image.width()));
83 if (m_bounds.height() == 0.0)
84 m_bounds.setHeight(static_cast<qreal>(m_image.height()));
85}
86
88{
89 p->drawImage(m_bounds, m_image);
90}
91
93 : QSvgNode(parent), m_line(line)
94{
95}
96
98{
99 if (p->pen().widthF() != 0) {
100 qreal oldOpacity = p->opacity();
101 p->setOpacity(oldOpacity * states.strokeOpacity);
102 p->drawLine(m_line);
103 p->setOpacity(oldOpacity);
104 }
106}
107
109 : QSvgNode(parent), m_path(qpath)
110{
111}
112
114{
115 m_path.setFillRule(states.fillRule);
116 p->drawPath(m_path);
118}
119
121{
122 return true;
123}
124
126{
127 return p->transform().mapRect(m_path.controlPointRect());
128}
129
131{
132 qreal sw = strokeWidth(p);
133 return qFuzzyIsNull(sw) ? p->transform().map(m_path).boundingRect()
134 : boundsOnStroke(p, m_path, sw);
135}
136
138 : QSvgNode(parent), m_poly(poly)
139{
140}
141
143{
144 return p->transform().mapRect(m_poly.boundingRect());
145}
146
148{
149 qreal sw = strokeWidth(p);
150 if (qFuzzyIsNull(sw)) {
151 return p->transform().map(m_poly).boundingRect();
152 } else {
154 path.addPolygon(m_poly);
155 return boundsOnStroke(p, path, sw);
156 }
157}
158
160{
161 p->drawPolygon(m_poly, states.fillRule);
163}
164
166{
167 return true;
168}
169
171 : QSvgNode(parent), m_poly(poly)
172{
173
174}
175
177{
178 if (p->brush().style() != Qt::NoBrush) {
179 p->drawPolygon(m_poly, states.fillRule);
180 } else {
181 p->drawPolyline(m_poly);
183 }
184}
185
187{
188 return true;
189}
190
192 : QSvgNode(node),
193 m_rect(rect), m_rx(rx), m_ry(ry)
194{
195}
196
198{
199 return p->transform().mapRect(m_rect);
200}
201
203{
204 qreal sw = strokeWidth(p);
205 if (qFuzzyIsNull(sw)) {
206 return p->transform().mapRect(m_rect);
207 } else {
209 path.addRect(m_rect);
210 return boundsOnStroke(p, path, sw);
211 }
212}
213
215{
216 if (m_rx || m_ry)
217 p->drawRoundedRect(m_rect, m_rx, m_ry, Qt::RelativeSize);
218 else
219 p->drawRect(m_rect);
220}
221
223{
224 return true;
225}
226
227QSvgTspan * const QSvgText::LINEBREAK = 0;
228
230 : QSvgNode(parent)
231 , m_coord(coord)
232 , m_type(Text)
233 , m_size(0, 0)
234 , m_mode(Default)
235{
236}
237
239{
240 for (int i = 0; i < m_tspans.size(); ++i) {
241 if (m_tspans[i] != LINEBREAK)
242 delete m_tspans[i];
243 }
244}
245
247{
248 m_size = size;
249 m_type = Textarea;
250}
251
253{
254 QFont font = m_style.font ? m_style.font->qfont() : p->font();
256
257 int charCount = 0;
258 for (int i = 0; i < m_tspans.size(); ++i) {
259 if (m_tspans.at(i) != LINEBREAK)
260 charCount += m_tspans.at(i)->text().size();
261 }
262
263 QRectF approxMaximumBrect(m_coord.x(),
264 m_coord.y(),
265 charCount * fm.averageCharWidth(),
266 -m_tspans.size() * fm.height());
267 return p->transform().mapRect(approxMaximumBrect);
268}
269
271{
273 if (shouldDrawNode(p, states))
274 draw_helper(p, states, &boundingRect);
275 return p->transform().mapRect(boundingRect);
276}
277
279{
280 draw_helper(p, states);
281}
282
284{
285 qsizetype numChars = 0;
286 qreal originalFontSize = p->font().pointSizeF();
287 qreal maxFontSize = originalFontSize;
288 for (const QSvgTspan *span : std::as_const(m_tspans)) {
289 if (span == LINEBREAK)
290 continue;
291
292 numChars += span->text().size();
293
294 QSvgFontStyle *style = static_cast<QSvgFontStyle *>(span->styleProperty(QSvgStyleProperty::FONT));
295 if (style != nullptr && style->qfont().pointSizeF() > maxFontSize)
296 maxFontSize = style->qfont().pointSizeF();
297 }
298
299 QFont font = p->font();
300 font.setPixelSize((100.0 / originalFontSize) * maxFontSize);
302 if (m_tspans.size() * fm.height() >= QT_SVG_MAX_LAYOUT_SIZE) {
303 qCWarning(lcSvgDraw) << "Text element too high to lay out, ignoring";
304 return false;
305 }
306
307 if (numChars * fm.maxWidth() >= QT_SVG_MAX_LAYOUT_SIZE) {
308 qCWarning(lcSvgDraw) << "Text element too wide to lay out, ignoring";
309 return false;
310 }
311
312 return true;
313}
314
315void QSvgText::draw_helper(QPainter *p, QSvgExtraStates &states, QRectF *boundingRect) const
316{
317 const bool isPainting = (boundingRect == nullptr);
318 if (!isPainting || shouldDrawNode(p, states)) {
319 qreal oldOpacity = p->opacity();
320 p->setOpacity(oldOpacity * states.fillOpacity);
321
322 // Force the font to have a size of 100 pixels to avoid truncation problems
323 // when the font is very small.
324 QFont font = p->font();
325 qreal scale = 100.0 / font.pointSizeF();
326 Qt::Alignment alignment = states.textAnchor;
327
328 QTransform oldTransform = p->worldTransform();
329 p->scale(1 / scale, 1 / scale);
330
331 qreal y = 0;
332 bool initial = true;
333 qreal px = m_coord.x() * scale;
334 qreal py = m_coord.y() * scale;
335 QSizeF scaledSize = m_size * scale;
336
337 if (m_type == Textarea) {
339 px += scaledSize.width() / 2;
340 else if (alignment == Qt::AlignRight)
341 px += scaledSize.width();
342 }
343
345 if (m_size.height() != 0)
346 bounds = QRectF(0, py, 1, scaledSize.height()); // x and width are not used.
347
348 bool appendSpace = false;
349 QList<QString> paragraphs;
350 QList<QList<QTextLayout::FormatRange> > formatRanges(1);
351 paragraphs.push_back(QString());
352
353 for (int i = 0; i < m_tspans.size(); ++i) {
354 if (m_tspans[i] == LINEBREAK) {
355 if (m_type == Textarea) {
356 if (paragraphs.back().isEmpty()) {
358
360 range.start = 0;
361 range.length = 1;
362 range.format.setFont(font);
363 formatRanges.back().append(range);
364
365 paragraphs.back().append(QLatin1Char(' '));;
366 }
367 appendSpace = false;
368 paragraphs.push_back(QString());
369 formatRanges.resize(formatRanges.size() + 1);
370 }
371 } else {
372 WhitespaceMode mode = m_tspans[i]->whitespaceMode();
373 m_tspans[i]->applyStyle(p, states);
374
375 font = p->font();
377
378 QString newText(m_tspans[i]->text());
379 newText.replace(QLatin1Char('\t'), QLatin1Char(' '));
380 newText.replace(QLatin1Char('\n'), QLatin1Char(' '));
381
382 bool prependSpace = !appendSpace && !m_tspans[i]->isTspan() && (mode == Default) && !paragraphs.back().isEmpty() && newText.startsWith(QLatin1Char(' '));
383 if (appendSpace || prependSpace)
384 paragraphs.back().append(QLatin1Char(' '));
385
386 bool appendSpaceNext = (!m_tspans[i]->isTspan() && (mode == Default) && newText.endsWith(QLatin1Char(' ')));
387
388 if (mode == Default) {
389 newText = newText.simplified();
390 if (newText.isEmpty())
391 appendSpaceNext = false;
392 }
393
395 range.start = paragraphs.back().size();
396 range.length = newText.size();
397 range.format.setFont(font);
398 range.format.setTextOutline(p->pen());
399 range.format.setForeground(p->brush());
400
401 if (appendSpace) {
402 Q_ASSERT(!formatRanges.back().isEmpty());
403 ++formatRanges.back().back().length;
404 } else if (prependSpace) {
405 --range.start;
406 ++range.length;
407 }
408 formatRanges.back().append(range);
409
410 appendSpace = appendSpaceNext;
411 paragraphs.back() += newText;
412
413 m_tspans[i]->revertStyle(p, states);
414 }
415 }
416
417 if (states.svgFont) {
418 // SVG fonts not fully supported...
419 QString text = paragraphs.front();
420 for (int i = 1; i < paragraphs.size(); ++i) {
421 text.append(QLatin1Char('\n'));
422 text.append(paragraphs[i]);
423 }
424 states.svgFont->draw(p, m_coord * scale, text, p->font().pointSizeF() * scale, states.textAnchor);
425 } else {
426 QRectF brect;
427 for (int i = 0; i < paragraphs.size(); ++i) {
428 QTextLayout tl(paragraphs[i]);
429 QTextOption op = tl.textOption();
431 tl.setTextOption(op);
432 tl.setFormats(formatRanges[i]);
433 tl.beginLayout();
434
435 forever {
436 QTextLine line = tl.createLine();
437 if (!line.isValid())
438 break;
439 if (m_size.width() != 0)
440 line.setLineWidth(scaledSize.width());
441 }
442 tl.endLayout();
443
444 bool endOfBoundsReached = false;
445 for (int i = 0; i < tl.lineCount(); ++i) {
446 QTextLine line = tl.lineAt(i);
447
448 qreal x = 0;
450 x -= 0.5 * line.naturalTextWidth();
451 else if (alignment == Qt::AlignRight)
452 x -= line.naturalTextWidth();
453
454 if (initial && m_type == Text)
455 y -= line.ascent();
456 initial = false;
457
458 line.setPosition(QPointF(x, y));
459 brect |= line.naturalTextRect();
460
461 // Check if the current line fits into the bounding rectangle.
462 if ((m_size.width() != 0 && line.naturalTextWidth() > scaledSize.width())
463 || (m_size.height() != 0 && y + line.height() > scaledSize.height())) {
464 // I need to set the bounds height to 'y-epsilon' to avoid drawing the current
465 // line. Since the font is scaled to 100 units, 1 should be a safe epsilon.
466 bounds.setHeight(y - 1);
467 endOfBoundsReached = true;
468 break;
469 }
470
471 y += 1.1 * line.height();
472 }
473 if (isPainting)
474 tl.draw(p, QPointF(px, py), QList<QTextLayout::FormatRange>(), bounds);
475
476 if (endOfBoundsReached)
477 break;
478 }
479 if (boundingRect) {
480 brect.translate(m_coord * scale);
481 if (bounds.height() > 0)
482 brect.setBottom(qMin(brect.bottom(), bounds.bottom()));
483 *boundingRect = QTransform::fromScale(1 / scale, 1 / scale).mapRect(brect);
484 }
485 }
486
487 p->setWorldTransform(oldTransform, false);
488 p->setOpacity(oldOpacity);
489 }
490}
491
493{
494 m_tspans.append(new QSvgTspan(this, false));
495 m_tspans.back()->setWhitespaceMode(m_mode);
496 m_tspans.back()->addText(text);
497}
498
500 : QSvgNode(parent), m_link(node), m_start(start), m_recursing(false)
501{
502
503}
504
506{
507 if (Q_UNLIKELY(!m_link || isDescendantOf(m_link) || m_recursing))
508 return;
509
510 Q_ASSERT(states.nestedUseCount == 0 || states.nestedUseLevel > 0);
511 if (states.nestedUseLevel > 3 && states.nestedUseCount > (256 + states.nestedUseLevel * 2)) {
512 qCDebug(lcSvgDraw, "Too many nested use nodes at #%s!", qPrintable(m_linkId));
513 return;
514 }
515
516 QScopedValueRollback<bool> inUseGuard(states.inUse, true);
517
518 if (!m_start.isNull()) {
519 p->translate(m_start);
520 }
521 if (states.nestedUseLevel > 0)
522 ++states.nestedUseCount;
523 {
524 QScopedValueRollback<int> useLevelGuard(states.nestedUseLevel, states.nestedUseLevel + 1);
525 QScopedValueRollback<bool> recursingGuard(m_recursing, true);
526 m_link->draw(p, states);
527 }
528 if (states.nestedUseLevel == 0)
529 states.nestedUseCount = 0;
530
531 if (!m_start.isNull()) {
532 p->translate(-m_start);
533 }
534}
535
537{
538 return Animation;
539}
540
542{
543 return Circle;
544}
545
547{
548 return Ellipse;
549}
550
552{
553 return Image;
554}
555
557{
558 return Line;
559}
560
562{
563 return Path;
564}
565
567{
568 return Polygon;
569}
570
572{
573 return Polyline;
574}
575
577{
578 return Rect;
579}
580
582{
583 return m_type;
584}
585
587{
588 return Use;
589}
590
592{
593 return Video;
594}
595
597{
599 if (Q_LIKELY(m_link && !isDescendantOf(m_link) && !m_recursing)) {
600 QScopedValueRollback<bool> guard(m_recursing, true);
601 p->translate(m_start);
602 bounds = m_link->transformedBounds(p, states);
603 p->translate(-m_start);
604 }
605 return bounds;
606}
607
609{
610 return p->transform().mapRect(m_poly.boundingRect());
611}
612
614{
615 qreal sw = strokeWidth(p);
616 if (qFuzzyIsNull(sw)) {
617 return p->transform().map(m_poly).boundingRect();
618 } else {
620 path.addPolygon(m_poly);
621 return boundsOnStroke(p, path, sw);
622 }
623}
624
626{
627 return p->transform().mapRect(m_bounds);
628}
629
631{
632 QPointF p1 = p->transform().map(m_line.p1());
633 QPointF p2 = p->transform().map(m_line.p2());
634 qreal minX = qMin(p1.x(), p2.x());
635 qreal minY = qMin(p1.y(), p2.y());
636 qreal maxX = qMax(p1.x(), p2.x());
637 qreal maxY = qMax(p1.y(), p2.y());
638 return QRectF(minX, minY, maxX - minX, maxY - minY);
639}
640
642{
643 qreal sw = strokeWidth(p);
644 if (qFuzzyIsNull(sw)) {
645 return fastBounds(p, s);
646 } else {
648 path.moveTo(m_line.p1());
649 path.lineTo(m_line.p2());
650 return boundsOnStroke(p, path, sw);
651 }
652}
653
\reentrant \inmodule QtGui
\reentrant
Definition qfont.h:22
void setPixelSize(int)
Sets the font size to pixelSize pixels, with a maxiumum size of an unsigned 16-bit integer.
Definition qfont.cpp:1049
qreal pointSizeF() const
Returns the point size of the font.
Definition qfont.cpp:1034
\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\compares equality \compareswith equality QLine \endcompareswith
Definition qline.h:192
constexpr QPointF p1() const
Returns the line's start point.
Definition qline.h:317
constexpr QPointF p2() const
Returns the line's end point.
Definition qline.h:322
qsizetype size() const noexcept
Definition qlist.h:397
reference back()
Definition qlist.h:689
bool endsWith(parameter_type t) const
Definition qlist.h:652
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
void append(parameter_type t)
Definition qlist.h:458
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 QtCore\reentrant
Definition qpoint.h:217
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:343
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:348
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:338
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:583
\inmodule QtCore\reentrant
Definition qrect.h:484
constexpr qreal bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
Definition qrect.h:500
constexpr void setBottom(qreal pos) noexcept
Sets the bottom edge of the rectangle to the given finite y coordinate.
Definition qrect.h:684
constexpr qreal height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:732
constexpr qreal width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:729
constexpr void setWidth(qreal w) noexcept
Sets the width of the rectangle to the given finite width.
Definition qrect.h:818
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:738
constexpr void setHeight(qreal h) noexcept
Sets the height of the rectangle to the given finite height.
Definition qrect.h:821
\inmodule QtCore
Definition qsize.h:208
constexpr qreal width() const noexcept
Returns the width.
Definition qsize.h:332
constexpr qreal height() const noexcept
Returns the height.
Definition qsize.h:335
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
QChar front() const
Definition qstring.h:230
QString & append(QChar c)
Definition qstring.cpp:3252
Type type() const override
void drawCommand(QPainter *, QSvgExtraStates &) override
Type type() const override
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override
QRectF fastBounds(QPainter *p, QSvgExtraStates &states) const override
bool separateFillStroke() const override
QSvgEllipse(QSvgNode *parent, const QRectF &rect)
void drawCommand(QPainter *p, QSvgExtraStates &states) override
Type type() const override
const QFont & qfont() const
Type type() const override
void drawCommand(QPainter *p, QSvgExtraStates &states) override
QSvgImage(QSvgNode *parent, const QImage &image, const QString &filename, const QRectF &bounds)
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override
QSvgLine(QSvgNode *parent, const QLineF &line)
Type type() 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
static void drawMarkersForNode(QSvgNode *node, QPainter *p, QSvgExtraStates &states)
static qreal strokeWidth(QPainter *p)
Definition qsvgnode.cpp:604
virtual QRectF transformedBounds(QPainter *p, QSvgExtraStates &states) const
Definition qsvgnode.cpp:484
bool isDescendantOf(const QSvgNode *parent) const
Definition qsvgnode.cpp:161
QSvgStyle m_style
Definition qsvgnode_p.h:171
void draw(QPainter *p, QSvgExtraStates &states)
Definition qsvgnode.cpp:38
const QSvgStyle & style() const
Definition qsvgnode_p.h:169
bool separateFillStroke() const override
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override
void drawCommand(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
bool separateFillStroke() const override
void drawCommand(QPainter *p, QSvgExtraStates &states) override
QSvgPolygon(QSvgNode *parent, const QPolygonF &poly)
QSvgPolyline(QSvgNode *parent, const QPolygonF &poly)
void drawCommand(QPainter *p, QSvgExtraStates &states) override
QRectF fastBounds(QPainter *p, QSvgExtraStates &states) const override
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override
bool separateFillStroke() 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
bool separateFillStroke() const override
void drawCommand(QPainter *p, QSvgExtraStates &states) override
QSvgRect(QSvgNode *paren, const QRectF &rect, qreal rx=0, qreal ry=0)
QSvgRefCounter< QSvgFontStyle > font
bool shouldDrawNode(QPainter *p, QSvgExtraStates &states) const override
void addText(const QString &text)
QSizeF size() const
void drawCommand(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 drawCommand(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
\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...
QPixmap p2
QPixmap p1
[0]
QString text
rect
[4]
uint alignment
Combined button and popup list for selecting options.
@ AlignRight
Definition qnamespace.h:146
@ AlignHCenter
Definition qnamespace.h:148
@ RelativeSize
@ NoBrush
Definition image.cpp:4
#define Q_UNLIKELY(x)
#define Q_LIKELY(x)
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition qfloat16.h:349
#define forever
Definition qforeach.h:78
#define qWarning
Definition qlogging.h:166
#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
GLdouble s
[6]
Definition qopenglext.h:235
GLuint coord
GLsizei const GLchar *const * path
GLenum GLenum GLsizei void GLsizei void void * span
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:27
#define qPrintable(string)
Definition qstring.h:1531
#define QT_SVG_MAX_LAYOUT_SIZE
static QRectF boundsOnStroke(QPainter *p, const QPainterPath &path, qreal width)
ptrdiff_t qsizetype
Definition qtypes.h:165
double qreal
Definition qtypes.h:187
p ry()++
p rx()++
\inmodule QtCore \reentrant
Definition qchar.h:18