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
qquickqmlgenerator.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 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
5#include "qquicknodeinfo_p.h"
6#include "utils_p.h"
7
8#include <private/qsgcurveprocessor_p.h>
9#include <private/qquickshape_p.h>
10#include <private/qquadpath_p.h>
11#include <private/qquickitem_p.h>
12#include <private/qquickimagebase_p_p.h>
13
14#include <QtCore/qloggingcategory.h>
15#include <QtCore/qdir.h>
16
18
19QQuickQmlGenerator::QQuickQmlGenerator(const QString fileName, QQuickVectorImageGenerator::GeneratorFlags flags, const QString &outFileName)
21 , outputFileName(outFileName)
22{
23 m_result.open(QIODevice::ReadWrite);
24}
25
27{
28 if (m_generationSucceeded && !outputFileName.isEmpty()) {
29 QFileInfo fileInfo(outputFileName);
30 QDir dir(fileInfo.absolutePath());
31 if (!dir.exists() && !dir.mkpath(QStringLiteral("."))) {
32 qCWarning(lcQuickVectorImage) << "Failed to create path" << dir.absolutePath();
33 } else {
34 stream().flush(); // Add a final newline and flush the stream to m_result
35 QFile outFile(outputFileName);
36 outFile.open(QIODevice::WriteOnly);
37 outFile.write(m_result.data());
38 outFile.close();
39 }
40 }
41
42 if (lcQuickVectorImage().isDebugEnabled())
43 qCDebug(lcQuickVectorImage).noquote() << m_result.data().left(300);
44}
45
47{
48 m_shapeTypeName = name.toLatin1();
49}
50
52{
53 return QString::fromLatin1(m_shapeTypeName);
54}
55
57{
58 m_commentString = commentString;
59}
60
62{
63 return m_commentString;
64}
65
67{
68 m_indentLevel++;
69 if (!info.nodeId.isEmpty())
70 stream() << "objectName: \"" << info.nodeId << "\"";
71 if (!info.isDefaultTransform) {
72 auto sx = info.transform.m11();
73 auto sy = info.transform.m22();
74 auto x = info.transform.m31();
75 auto y = info.transform.m32();
76 if (info.transform.type() == QTransform::TxTranslate) {
77 stream() << "transform: Translate { " << "x: " << x << "; y: " << y << " }";
78 } else if (info.transform.type() == QTransform::TxScale && !x && !y) {
79 stream() << "transform: Scale { xScale: " << sx << "; yScale: " << sy << " }";
80 } else {
81 stream() << "transform: Matrix4x4 { matrix: ";
82 generateTransform(info.transform);
83 stream(SameLine) << " }";
84 }
85 }
86 if (!info.isDefaultOpacity) {
87 stream() << "opacity: " << info.opacity;
88 }
89 m_indentLevel--;
90}
91
93{
95
96 return false;
97}
98
100{
101 if (!isNodeVisible(info))
102 return;
103
104 const QFileInfo outputFileInfo(outputFileName);
105 const QDir outputDir(outputFileInfo.absolutePath());
106
107 QString filePath;
108
109 if (!m_retainFilePaths || info.externalFileReference.isEmpty()) {
110 filePath = m_assetFileDirectory;
111 if (filePath.isEmpty())
112 filePath = outputDir.absolutePath();
113
114 if (!filePath.isEmpty() && !filePath.endsWith(u'/'))
115 filePath += u'/';
116
117 QDir fileDir(filePath);
118 if (!fileDir.exists()) {
119 if (!fileDir.mkpath(QStringLiteral(".")))
120 qCWarning(lcQuickVectorImage) << "Failed to create image resource directory:" << filePath;
121 }
122
123 filePath += QStringLiteral("%1%2.png").arg(m_assetFilePrefix.isEmpty()
124 ? QStringLiteral("svg_asset_")
125 : m_assetFilePrefix)
126 .arg(info.image.cacheKey());
127
128 if (!info.image.save(filePath))
129 qCWarning(lcQuickVectorImage) << "Unabled to save image resource" << filePath;
130 qCDebug(lcQuickVectorImage) << "Saving copy of IMAGE" << filePath;
131 } else {
132 filePath = info.externalFileReference;
133 }
134
135 const QFileInfo assetFileInfo(filePath);
136
137 // TODO: this requires proper asset management.
138 stream() << "Image {";
139 m_indentLevel++;
140
142 stream() << "x: " << info.rect.x();
143 stream() << "y: " << info.rect.y();
144 stream() << "width: " << info.rect.width();
145 stream() << "height: " << info.rect.height();
146 stream() << "source: \"" << outputDir.relativeFilePath(assetFileInfo.absoluteFilePath()) <<"\"";
147
148 m_indentLevel--;
149
150 stream() << "}";
151}
152
154{
155 if (!isNodeVisible(info))
156 return;
157
158 if (m_inShapeItem) {
159 if (!info.isDefaultTransform)
160 qWarning() << "Skipped transform for node" << info.nodeId << "type" << info.typeName << "(this is not supposed to happen)";
162 } else {
163 m_inShapeItem = true;
164 stream() << shapeName() << " {";
165
166 // Check ??
168
169 m_indentLevel++;
171 stream() << "preferredRendererType: Shape.CurveRenderer";
173 //qCDebug(lcQuickVectorGraphics) << *node->qpath();
174 m_indentLevel--;
175 stream() << "}";
176 m_inShapeItem = false;
177 }
178}
179
180void QQuickQmlGenerator::generateGradient(const QGradient *grad, const QRectF &boundingRect)
181{
182 if (grad->type() == QGradient::LinearGradient) {
183 auto *linGrad = static_cast<const QLinearGradient *>(grad);
184 stream() << "fillGradient: LinearGradient {";
185 m_indentLevel++;
186
187 QRectF gradRect(linGrad->start(), linGrad->finalStop());
188 QRectF logRect = linGrad->coordinateMode() == QGradient::LogicalMode ? gradRect : QQuickVectorImageGenerator::Utils::mapToQtLogicalMode(gradRect, boundingRect);
189
190 stream() << "x1: " << logRect.left();
191 stream() << "y1: " << logRect.top();
192 stream() << "x2: " << logRect.right();
193 stream() << "y2: " << logRect.bottom();
194 for (auto &stop : linGrad->stops())
195 stream() << "GradientStop { position: " << stop.first << "; color: \"" << stop.second.name(QColor::HexArgb) << "\" }";
196 m_indentLevel--;
197 stream() << "}";
198 } else if (grad->type() == QGradient::RadialGradient) {
199 auto *radGrad = static_cast<const QRadialGradient*>(grad);
200 stream() << "fillGradient: RadialGradient {";
201 m_indentLevel++;
202
203 stream() << "centerX: " << radGrad->center().x();
204 stream() << "centerY: " << radGrad->center().y();
205 stream() << "centerRadius: " << radGrad->radius();
206 stream() << "focalX:" << radGrad->focalPoint().x();
207 stream() << "focalY:" << radGrad->focalPoint().y();
208 for (auto &stop : radGrad->stops())
209 stream() << "GradientStop { position: " << stop.first << "; color: \"" << stop.second.name(QColor::HexArgb) << "\" }";
210 m_indentLevel--;
211 stream() << "}";
212 }
213}
214
215void QQuickQmlGenerator::generateTransform(const QTransform &xf)
216{
217 if (xf.isAffine()) {
218 stream(SameLine) << "PlanarTransform.fromAffineMatrix("
219 << xf.m11() << ", " << xf.m12() << ", "
220 << xf.m21() << ", " << xf.m22() << ", "
221 << xf.dx() << ", " << xf.dy() << ")";
222 } else {
223 QMatrix4x4 m(xf);
224 stream(SameLine) << "Qt.matrix4x4(";
225 m_indentLevel += 3;
226 const auto *data = m.data();
227 for (int i = 0; i < 4; i++) {
228 stream() << data[i] << ", " << data[i+4] << ", " << data[i+8] << ", " << data[i+12];
229 if (i < 3)
230 stream(SameLine) << ", ";
231 }
232 stream(SameLine) << ")";
233 m_indentLevel -= 3;
234 }
235}
236
238{
239 Q_UNUSED(pathSelector)
240 Q_ASSERT(painterPath || quadPath);
241
242 const bool noPen = info.strokeStyle.color == QColorConstants::Transparent;
243 if (pathSelector == QQuickVectorImageGenerator::StrokePath && noPen)
244 return;
245
246 const bool noFill = info.grad.type() == QGradient::NoGradient && info.fillColor == QColorConstants::Transparent;
247
248 if (pathSelector == QQuickVectorImageGenerator::FillPath && noFill)
249 return;
250
251 auto fillRule = QQuickShapePath::FillRule(painterPath ? painterPath->fillRule() : quadPath->fillRule());
252 stream() << "ShapePath {";
253 m_indentLevel++;
254 if (!info.nodeId.isEmpty()) {
255 switch (pathSelector) {
257 stream() << "objectName: \"svg_fill_path:" << info.nodeId << "\"";
258 break;
260 stream() << "objectName: \"svg_stroke_path:" << info.nodeId << "\"";
261 break;
263 stream() << "objectName: \"svg_path:" << info.nodeId << "\"";
264 break;
265 }
266 }
267
268 if (noPen || !(pathSelector & QQuickVectorImageGenerator::StrokePath)) {
269 stream() << "strokeColor: \"transparent\"";
270 } else {
271 stream() << "strokeColor: \"" << info.strokeStyle.color.name(QColor::HexArgb) << "\"";
272 stream() << "strokeWidth: " << info.strokeStyle.width;
273 stream() << "capStyle: " << QQuickVectorImageGenerator::Utils::strokeCapStyleString(info.strokeStyle.lineCapStyle);
274 stream() << "joinStyle: " << QQuickVectorImageGenerator::Utils::strokeJoinStyleString(info.strokeStyle.lineJoinStyle);
275 stream() << "miterLimit: " << info.strokeStyle.miterLimit;
276 if (info.strokeStyle.dashArray.length() != 0) {
277 stream() << "strokeStyle: " << "ShapePath.DashLine";
278 stream() << "dashPattern: " << QQuickVectorImageGenerator::Utils::listString(info.strokeStyle.dashArray);
279 stream() << "dashOffset: " << info.strokeStyle.dashOffset;
280 }
281 }
282
283 if (!(pathSelector & QQuickVectorImageGenerator::FillPath)) {
284 stream() << "fillColor: \"transparent\"";
285 } else if (info.grad.type() != QGradient::NoGradient) {
286 generateGradient(&info.grad, boundingRect);
287 } else {
288 stream() << "fillColor: \"" << info.fillColor.name(QColor::HexArgb) << "\"";
289 }
290
291 if (!info.fillTransform.isIdentity()) {
292 const QTransform &xf = info.fillTransform;
293 stream() << "fillTransform: ";
294 if (info.fillTransform.type() == QTransform::TxTranslate)
295 stream(SameLine) << "PlanarTransform.fromTranslate(" << xf.dx() << ", " << xf.dy() << ")";
296 else if (info.fillTransform.type() == QTransform::TxScale && !xf.dx() && !xf.dy())
297 stream(SameLine) << "PlanarTransform.fromScale(" << xf.m11() << ", " << xf.m22() << ")";
298 else
299 generateTransform(xf);
300 }
301
302 if (fillRule == QQuickShapePath::WindingFill)
303 stream() << "fillRule: ShapePath.WindingFill";
304 else
305 stream() << "fillRule: ShapePath.OddEvenFill";
306
307 QString hintStr;
308 if (quadPath)
310 if (!hintStr.isEmpty())
311 stream() << hintStr;
312
313
315 stream() << "PathSvg { path: \"" << svgPathString << "\" }";
316
317 m_indentLevel--;
318 stream() << "}";
319}
320
322{
323 if (!isNodeVisible(info))
324 return;
325
326 stream() << "// Missing Implementation for SVG Node: " << info.typeName;
327 stream() << "// Adding an empty Item and skipping";
328 stream() << "Item {";
330 stream() << "}";
331}
332
334{
335 if (!isNodeVisible(info))
336 return;
337
338 static int counter = 0;
339 stream() << "Item {";
341 m_indentLevel++;
342
343 if (!info.isTextArea)
344 stream() << "Item { id: textAlignItem_" << counter << "; x: " << info.position.x() << "; y: " << info.position.y() << "}";
345
346 stream() << "Text {";
347
348 m_indentLevel++;
349
350 if (info.isTextArea) {
351 stream() << "x: " << info.position.x();
352 stream() << "y: " << info.position.y();
353 if (info.size.width() > 0)
354 stream() << "width: " << info.size.width();
355 if (info.size.height() > 0)
356 stream() << "height: " << info.size.height();
357 stream() << "wrapMode: Text.Wrap"; // ### WordWrap? verify with SVG standard
358 stream() << "clip: true"; //### Not exactly correct: should clip on the text level, not the pixel level
359 } else {
360 QString hAlign = QStringLiteral("left");
361 stream() << "anchors.baseline: textAlignItem_" << counter << ".top";
362 switch (info.alignment) {
363 case Qt::AlignHCenter:
364 hAlign = QStringLiteral("horizontalCenter");
365 break;
366 case Qt::AlignRight:
367 hAlign = QStringLiteral("right");
368 break;
369 default:
370 qCDebug(lcQuickVectorImage) << "Unexpected text alignment" << info.alignment;
372 case Qt::AlignLeft:
373 break;
374 }
375 stream() << "anchors." << hAlign << ": textAlignItem_" << counter << ".left";
376 }
377 counter++;
378
379 stream() << "color: \"" << info.fillColor.name(QColor::HexArgb) << "\"";
380 stream() << "textFormat:" << (info.needsRichText ? "Text.RichText" : "Text.StyledText");
381
382 QString s = info.text;
383 s.replace(QLatin1Char('"'), QLatin1String("\\\""));
384 stream() << "text: \"" << s << "\"";
385 stream() << "font.family: \"" << info.font.family() << "\"";
386 if (info.font.pixelSize() > 0)
387 stream() << "font.pixelSize:" << info.font.pixelSize();
388 else if (info.font.pointSize() > 0)
389 stream() << "font.pixelSize:" << info.font.pointSizeF();
390 if (info.font.underline())
391 stream() << "font.underline: true";
392 if (info.font.weight() != QFont::Normal)
393 stream() << "font.weight: " << int(info.font.weight());
394 if (info.font.italic())
395 stream() << "font.italic: true";
396
397 if (info.strokeColor != QColorConstants::Transparent) {
398 stream() << "styleColor: \"" << info.strokeColor.name(QColor::HexArgb) << "\"";
399 stream() << "style: Text.Outline";
400 }
401
402 m_indentLevel--;
403 stream() << "}";
404
405 m_indentLevel--;
406 stream() << "}";
407}
408
410{
411 if (!isNodeVisible(info))
412 return;
413
414 if (info.stage == StructureNodeStage::Start) {
415 stream() << "Item {";
417 m_indentLevel++;
418 stream() << "x: " << info.startPos.x();
419 stream() << "y: " << info.startPos.y();
420 } else {
421 m_indentLevel--;
422 stream() << "}";
423 }
424}
425
427{
428 if (!isNodeVisible(info))
429 return false;
430
431 if (info.stage == StructureNodeStage::Start) {
432 if (!info.forceSeparatePaths && info.isPathContainer) {
433 stream() << shapeName() <<" {";
434 m_indentLevel++;
436 stream() << "preferredRendererType: Shape.CurveRenderer";
437 m_indentLevel--;
438
439 m_inShapeItem = true;
440 } else {
441 stream() << "Item {";
442 }
443
444 if (!info.viewBox.isEmpty()) {
445 m_indentLevel++;
446 stream() << "transform: [";
447 m_indentLevel++;
448 bool translate = !qFuzzyIsNull(info.viewBox.x()) || !qFuzzyIsNull(info.viewBox.y());
449 if (translate)
450 stream() << "Translate { x: " << -info.viewBox.x() << "; y: " << -info.viewBox.y() << " },";
451 stream() << "Scale { xScale: width / " << info.viewBox.width() << "; yScale: height / " << info.viewBox.height() << " }";
452 m_indentLevel--;
453 stream() << "]";
454 m_indentLevel--;
455 }
456
458 m_indentLevel++;
459 } else {
460 m_indentLevel--;
461 stream() << "}";
462 m_inShapeItem = false;
463 }
464
465 return true;
466}
467
469{
470 m_indentLevel = 0;
471 const QStringList comments = m_commentString.split(u'\n');
472
473 if (!isNodeVisible(info)) {
474 if (comments.isEmpty()) {
475 stream() << "// Generated from SVG";
476 } else {
477 for (const auto &comment : comments)
478 stream() << "// " << comment;
479 }
480
481 stream() << "import QtQuick";
482 stream() << "import QtQuick.Shapes" << Qt::endl;
483 stream() << "Item {";
484 m_indentLevel++;
485
486 double w = info.size.width();
487 double h = info.size.height();
488 if (w > 0)
489 stream() << "implicitWidth: " << w;
490 if (h > 0)
491 stream() << "implicitHeight: " << h;
492
493 m_indentLevel--;
494 stream() << "}";
495
496 return false;
497 }
498
499 if (info.stage == StructureNodeStage::Start) {
500 if (comments.isEmpty())
501 stream() << "// Generated from SVG";
502 else
503 for (const auto &comment : comments)
504 stream() << "// " << comment;
505
506 stream() << "import QtQuick";
507 stream() << "import QtQuick.Shapes" << Qt::endl;
508 stream() << "Item {";
509 m_indentLevel++;
510
511 double w = info.size.width();
512 double h = info.size.height();
513 if (w > 0)
514 stream() << "implicitWidth: " << w;
515 if (h > 0)
516 stream() << "implicitHeight: " << h;
517
518 if (!info.viewBox.isEmpty()) {
519 stream() << "transform: [";
520 m_indentLevel++;
521 bool translate = !qFuzzyIsNull(info.viewBox.x()) || !qFuzzyIsNull(info.viewBox.y());
522 if (translate)
523 stream() << "Translate { x: " << -info.viewBox.x() << "; y: " << -info.viewBox.y() << " },";
524 stream() << "Scale { xScale: width / " << info.viewBox.width() << "; yScale: height / " << info.viewBox.height() << " }";
525 m_indentLevel--;
526 stream() << "]";;
527 }
528
530 } else {
531 stream() << "}";
532 m_inShapeItem = false;
533 }
534
535 return true;
536}
537
538QStringView QQuickQmlGenerator::indent()
539{
540 static QString indentString;
541 int indentWidth = m_indentLevel * 4;
542 if (indentWidth > indentString.size())
543 indentString.fill(QLatin1Char(' '), indentWidth * 2);
544 return QStringView(indentString).first(indentWidth);
545}
546
547QTextStream &QQuickQmlGenerator::stream(int flags)
548{
549 if (m_stream.device() == nullptr)
550 m_stream.setDevice(&m_result);
551 else if (!(flags & StreamFlags::SameLine))
552 m_stream << Qt::endl << indent();
553 return m_stream;
554}
555
556const char *QQuickQmlGenerator::shapeName() const
557{
558 return m_shapeTypeName.isEmpty() ? "Shape" : m_shapeTypeName.constData();
559}
560
bool open(OpenMode openMode) override
\reimp
Definition qbuffer.cpp:295
const QByteArray & data() const
Returns the data contained in the buffer.
Definition qbuffer.cpp:245
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:124
QByteArray left(qsizetype n) const &
Definition qbytearray.h:169
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:107
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
@ HexArgb
Definition qcolor.h:36
\inmodule QtCore
Definition qdir.h:20
QString absolutePath() const
Returns the absolute path of the file system entry this QFileInfo refers to, excluding the entry's na...
\inmodule QtCore
Definition qfile.h:93
@ Normal
Definition qfont.h:68
\inmodule QtGui
Definition qbrush.h:135
@ LogicalMode
Definition qbrush.h:154
Type type() const
Returns the type of gradient.
Definition qbrush.h:344
@ LinearGradient
Definition qbrush.h:139
@ NoGradient
Definition qbrush.h:142
@ RadialGradient
Definition qbrush.h:140
\inmodule QtGui
Definition qbrush.h:394
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition qmatrix4x4.h:25
\inmodule QtGui
Qt::FillRule fillRule() const
Returns the painter path's currently set fill rule.
void optimizePaths(const PathNodeInfo &info)
QQuickVectorImageGenerator::GeneratorFlags m_flags
bool isNodeVisible(const NodeInfo &info)
void outputShapePath(const PathNodeInfo &info, const QPainterPath *path, const QQuadPath *quadPath, QQuickVectorImageGenerator::PathSelector pathSelector, const QRectF &boundingRect) override
bool generateRootNode(const StructureNodeInfo &info) override
void setCommentString(const QString commentString)
void generateNode(const NodeInfo &info) override
void generateImageNode(const ImageNodeInfo &info) override
void generateNodeBase(const NodeInfo &info) override
QString shapeTypeName() const
void setShapeTypeName(const QString &name)
QString commentString() const
bool generateStructureNode(const StructureNodeInfo &info) override
void generateUseNode(const UseNodeInfo &info) override
QQuickQmlGenerator(const QString fileName, QQuickVectorImageGenerator::GeneratorFlags flags, const QString &outFileName)
void generatePath(const PathNodeInfo &info) override
bool generateDefsNode(const NodeInfo &info) override
void generateTextNode(const TextNodeInfo &info) override
\inmodule QtGui
Definition qbrush.h:412
\inmodule QtCore\reentrant
Definition qrect.h:484
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:78
constexpr QStringView first(qsizetype n) const noexcept
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString & fill(QChar c, qsizetype size=-1)
Sets every character in the string to character ch.
Definition qstring.cpp:6369
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5881
QStringList split(const QString &sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Splits the string into substrings wherever sep occurs, and returns the list of those strings.
Definition qstring.cpp:8229
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition qstring.cpp:5516
\inmodule QtCore
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
constexpr QColor Transparent
Definition qcolor.h:310
QString strokeJoinStyleString(Qt::PenJoinStyle strokeJoinStyle)
Definition utils_p.h:217
QString strokeCapStyleString(Qt::PenCapStyle strokeCapStyle)
Definition utils_p.h:196
QRectF mapToQtLogicalMode(const QRectF &objModeRect, const QRectF &boundingRect)
Definition utils_p.h:120
QString listString(QList< T > list)
Definition utils_p.h:240
QString pathHintString(const QQuadPath &qp)
Definition utils_p.h:84
QString toSvgString(const QPainterPath &path)
Definition utils_p.h:145
Combined button and popup list for selecting options.
@ AlignRight
Definition qnamespace.h:146
@ AlignHCenter
Definition qnamespace.h:148
@ AlignLeft
Definition qnamespace.h:144
QTextStream & endl(QTextStream &stream)
Writes '\n' to the stream and flushes the stream.
#define Q_FALLTHROUGH()
EGLStreamKHR stream
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition qfloat16.h:349
#define qWarning
Definition qlogging.h:167
#define qCWarning(category,...)
#define qCDebug(category,...)
GLint GLint GLint GLint GLint x
[0]
const GLfloat * m
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLbitfield flags
GLuint name
GLint first
GLint y
GLfloat GLfloat GLfloat GLfloat h
GLuint counter
GLdouble s
[6]
Definition qopenglext.h:235
static const QRectF boundingRect(const QPointF *points, int pointCount)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
SSL_CTX int void * arg
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QStringLiteral(str)
#define Q_UNUSED(x)
static bool translate(xcb_connection_t *connection, xcb_window_t child, xcb_window_t parent, int *x, int *y)
QString dir
[11]
QHostInfo info
[0]
\inmodule QtCore \reentrant
Definition qchar.h:18