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
qsgopenvghelpers.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 "qsgopenvghelpers.h"
5#include <cmath>
6
8
9namespace QSGOpenVGHelpers {
10
12{
13 int count = path.elementCount();
14
15 VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD,
16 VG_PATH_DATATYPE_F,
17 1.0f, // scale
18 0.0f, // bias
19 count + 1, // segmentCapacityHint
20 count * 2, // coordCapacityHint
21 VG_PATH_CAPABILITY_ALL);
22
23 if (count == 0)
24 return vgpath;
25
26 QVector<VGfloat> coords;
27 QVector<VGubyte> segments;
28
29 int curvePos = 0;
30 QPointF temp;
31
32 // Keep track of the start and end of each sub-path. QPainterPath
33 // does not have an "implicit close" flag like QVectorPath does.
34 // We therefore have to detect closed paths by looking for a LineTo
35 // element that connects back to the initial MoveTo element.
36 qreal startx = 0.0;
37 qreal starty = 0.0;
38 qreal endx = 0.0;
39 qreal endy = 0.0;
40 bool haveStart = false;
41 bool haveEnd = false;
42
43 for (int i = 0; i < count; ++i) {
44 const QPainterPath::Element element = path.elementAt(i);
45 switch (element.type) {
46
48 {
49 if (haveStart && haveEnd && startx == endx && starty == endy) {
50 // Implicitly close the previous sub-path.
51 segments.append(VG_CLOSE_PATH);
52 }
53 temp = QPointF(element.x, element.y);
54 startx = temp.x();
55 starty = temp.y();
56 coords.append(startx);
57 coords.append(starty);
58 haveStart = true;
59 haveEnd = false;
60 segments.append(VG_MOVE_TO_ABS);
61 }
62 break;
63
65 {
66 temp = QPointF(element.x, element.y);
67 endx = temp.x();
68 endy = temp.y();
69 coords.append(endx);
70 coords.append(endy);
71 haveEnd = true;
72 segments.append(VG_LINE_TO_ABS);
73 }
74 break;
75
77 {
78 temp = QPointF(element.x, element.y);
79 coords.append(temp.x());
80 coords.append(temp.y());
81 haveEnd = false;
82 curvePos = 2;
83 }
84 break;
85
87 {
88 temp = QPointF(element.x, element.y);
89 coords.append(temp.x());
90 coords.append(temp.y());
91 haveEnd = false;
92 curvePos += 2;
93 if (curvePos == 6) {
94 curvePos = 0;
95 segments.append(VG_CUBIC_TO_ABS);
96 }
97 }
98 break;
99
100 }
101 }
102
103 if (haveStart && haveEnd && startx == endx && starty == endy) {
104 // Implicitly close the last sub-path.
105 segments.append(VG_CLOSE_PATH);
106 }
107
108 vgAppendPathData(vgpath, segments.count(),
109 segments.constData(), coords.constData());
110
111 return vgpath;
112}
113
114
115void qDrawTiled(VGImage image, const QSize imageSize, const QRectF &targetRect, const QPointF offset, float scaleX, float scaleY) {
116
117 //Check for valid image size and targetRect
118 if (imageSize.width() <= 0 || imageSize.height() <= 0)
119 return;
120 if (targetRect.width() <= 0 || targetRect.height() <= 0)
121 return;
122
123 // This logic is mostly from the Qt Raster PaintEngine's qt_draw_tile
124 qreal drawH;
125 qreal drawW;
126 qreal xPos;
127 qreal xOff;
128 qreal yPos = targetRect.y();
129 qreal yOff;
130
131 if (offset.y() < 0)
132 yOff = imageSize.height() - qRound(-offset.y()) % imageSize.height();
133 else
134 yOff = qRound(offset.y()) % imageSize.height();
135
136
137 // Save the current image transform matrix
138 vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
139 QVector<float> originalMatrix(9);
140 vgGetMatrix(originalMatrix.data());
141
142 while (!qFuzzyCompare(yPos, targetRect.y() + targetRect.height()) &&
143 yPos < targetRect.y() + targetRect.height()) {
144 drawH = imageSize.height() - yOff; // Cropping first row
145 if (yPos + drawH * scaleY > targetRect.y() + targetRect.height()) { // Cropping last row
146 // Check that values aren't equal
147 if (!qFuzzyCompare((float)(yPos + drawH * scaleY), (float)(targetRect.y() + targetRect.height())))
148 drawH = targetRect.y() + targetRect.height() - yPos;
149 }
150 xPos = targetRect.x();
151 if (offset.x() < 0)
152 xOff = imageSize.width() - qRound(-offset.x()) % imageSize.width();
153 else
154 xOff = qRound(offset.x()) % imageSize.width();
155
156 while (!qFuzzyCompare(xPos, targetRect.x() + targetRect.width()) &&
157 xPos < targetRect.x() + targetRect.width()) {
158 drawW = imageSize.width() - xOff; // Cropping first column
159 if (xPos + drawW * scaleX > targetRect.x() + targetRect.width()) {
160 // Check that values aren't equal
161 if (!qFuzzyCompare((float)(xPos + drawW * scaleX), (float)(targetRect.x() + targetRect.width())))
162 drawW = targetRect.x() + targetRect.width() - xPos;
163 }
164 if (round(drawW) > 0 && round(drawH) > 0) { // Can't source image less than 1 width or height
165 //Draw here
166 VGImage childRectImage = vgChildImage(image, xOff, yOff, round(drawW), round(drawH));
167 vgTranslate(xPos, yPos);
168 vgScale(scaleX, scaleY);
169 vgDrawImage(childRectImage);
170 vgDestroyImage(childRectImage);
171 vgLoadMatrix(originalMatrix.constData());
172 }
173 if ( drawW > 0)
174 xPos += drawW * scaleX;
175 xOff = 0;
176 }
177 if ( drawH > 0)
178 yPos += drawH * scaleY;
179 yOff = 0;
180
181 }
182}
183
184void qDrawBorderImage(VGImage image, const QSizeF &textureSize, const QRectF &targetRect, const QRectF &innerTargetRect, const QRectF &subSourceRect)
185{
186 // Create normalized margins
187 QMarginsF margins(qMax(innerTargetRect.left() - targetRect.left(), qreal(0.0)),
188 qMax(innerTargetRect.top() - targetRect.top(), qreal(0.0)),
189 qMax(targetRect.right() - innerTargetRect.right(), qreal(0.0)),
190 qMax(targetRect.bottom() - innerTargetRect.bottom(), qreal(0.0)));
191
192 QRectF sourceRect(0, 0, textureSize.width(), textureSize.height());
193
194 // Create all the subRects
195 QRectF topLeftSourceRect(sourceRect.topLeft(), QSizeF(margins.left(), margins.top()));
196 QRectF topRightSourceRect(sourceRect.width() - margins.right(), sourceRect.top(), margins.right(), margins.top());
197 QRectF bottomLeftSourceRect(sourceRect.left(), sourceRect.height() - margins.bottom(), margins.left(), margins.bottom());
198 QRectF bottomRightSourceRect(sourceRect.width() - margins.right(), sourceRect.height() - margins.bottom(), margins.right(), margins.bottom());
199
200 QRectF topSourceRect(margins.left(), 0.0, sourceRect.width() - (margins.right() + margins.left()), margins.top());
201 QRectF topTargetRect(margins.left(), 0.0, innerTargetRect.width(), margins.top());
202 QRectF bottomSourceRect(margins.left(), sourceRect.height() - margins.bottom(), sourceRect.width() - (margins.right() + margins.left()), margins.bottom());
203 QRectF bottomTargetRect(margins.left(), targetRect.height() - margins.bottom(), innerTargetRect.width(), margins.bottom());
204 QRectF leftSourceRect(0.0, margins.top(), margins.left(), sourceRect.height() - (margins.bottom() + margins.top()));
205 QRectF leftTargetRect(0.0, margins.top(), margins.left(), innerTargetRect.height());
206 QRectF rightSourceRect(sourceRect.width() - margins.right(), margins.top(), margins.right(), sourceRect.height() - (margins.bottom() + margins.top()));
207 QRectF rightTargetRect(targetRect.width() - margins.right(), margins.top(), margins.right(), innerTargetRect.height());
208
209 QRectF centerSourceRect(margins.left(), margins.top(), sourceRect.width() - (margins.right() + margins.left()), sourceRect.height() - (margins.top() + margins.bottom()));
210
211 // Draw the 9 different sections
212 // (1) Top Left (unscaled)
214 topLeftSourceRect,
215 targetRect.topLeft());
216
217 // (3) Top Right (unscaled)
219 topRightSourceRect,
220 QPointF(targetRect.width() - margins.right(), 0.0));
221
222 // (7) Bottom Left (unscaled)
224 bottomLeftSourceRect,
225 QPointF(targetRect.left(), targetRect.height() - margins.bottom()));
226
227 // (9) Bottom Right (unscaled)
229 bottomRightSourceRect,
230 QPointF(targetRect.width() - margins.right(), targetRect.height() - margins.bottom()));
231
232 double scaledWidth = 1.0;
233 double scaledHeight = 1.0;
234
235 // (2) Top (scaled via horizontalTileRule)
236 VGImage topImage = vgChildImage(image, topSourceRect.x(), topSourceRect.y(), topSourceRect.width(), topSourceRect.height());
237 scaledWidth = (topTargetRect.width() / subSourceRect.width()) / topSourceRect.width();
238
239 QSGOpenVGHelpers::qDrawTiled(topImage, topSourceRect.size().toSize(), topTargetRect, QPoint(0.0, 0.0), scaledWidth, 1);
240
241 vgDestroyImage(topImage);
242
243 // (8) Bottom (scaled via horizontalTileRule)
244 VGImage bottomImage = vgChildImage(image, bottomSourceRect.x(), bottomSourceRect.y(), bottomSourceRect.width(), bottomSourceRect.height());
245 scaledWidth = (bottomTargetRect.width() / subSourceRect.width()) / bottomSourceRect.width();
246
247 QSGOpenVGHelpers::qDrawTiled(bottomImage, bottomSourceRect.size().toSize(), bottomTargetRect, QPoint(0.0, 0.0), scaledWidth, 1);
248
249 vgDestroyImage(bottomImage);
250
251 // (4) Left (scaled via verticalTileRule)
252 VGImage leftImage = vgChildImage(image, leftSourceRect.x(), leftSourceRect.y(), leftSourceRect.width(), leftSourceRect.height());
253 scaledHeight = (leftTargetRect.height() / subSourceRect.height()) / leftSourceRect.height();
254 QSGOpenVGHelpers::qDrawTiled(leftImage, leftSourceRect.size().toSize(), leftTargetRect, QPointF(0.0, 0.0), 1, scaledHeight);
255
256 vgDestroyImage(leftImage);
257
258 // (6) Right (scaled via verticalTileRule)
259 VGImage rightImage = vgChildImage(image, rightSourceRect.x(), rightSourceRect.y(), rightSourceRect.width(), rightSourceRect.height());
260 scaledHeight = (rightTargetRect.height() / subSourceRect.height()) / rightSourceRect.height();
261
262 QSGOpenVGHelpers::qDrawTiled(rightImage, rightSourceRect.size().toSize(), rightTargetRect, QPointF(0, 0), 1, scaledHeight);
263
264 vgDestroyImage(rightImage);
265
266 // (5) Center (saled via verticalTileRule and horizontalTileRule)
267 VGImage centerImage = vgChildImage(image, centerSourceRect.x(), centerSourceRect.y(), centerSourceRect.width(), centerSourceRect.height());
268
269 scaledWidth = (innerTargetRect.width() / subSourceRect.width()) / centerSourceRect.width();
270 scaledHeight = (innerTargetRect.height() / subSourceRect.height()) / centerSourceRect.height();
271
272 QSGOpenVGHelpers::qDrawTiled(centerImage, centerSourceRect.size().toSize(), innerTargetRect, QPointF(0, 0), scaledWidth, scaledHeight);
273
274 vgDestroyImage(centerImage);
275}
276
277void qDrawSubImage(VGImage image, const QRectF &sourceRect, const QPointF &destOffset)
278{
279 // Check for valid source size
280 if (sourceRect.width() <= 0 || sourceRect.height() <= 0)
281 return;
282
283 // Save the current image transform matrix
284 vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
285 QVector<float> originalMatrix(9);
286 vgGetMatrix(originalMatrix.data());
287
288 // Get the child Image
289 VGImage childRectImage = vgChildImage(image, sourceRect.x(), sourceRect.y(), sourceRect.width(), sourceRect.height());
290 vgTranslate(destOffset.x(), destOffset.y());
291 vgDrawImage(childRectImage);
292 vgDestroyImage(childRectImage);
293
294 // Pop Matrix
295 vgLoadMatrix(originalMatrix.constData());
296}
297
298const QVector<VGfloat> qColorToVGColor(const QColor &color, float opacity)
299{
300 QVector<VGfloat> vgColor(4);
301 float r, g, b, a;
302 color.getRgbF(&r, &g, &b, &a);
303 vgColor[0] = r;
304 vgColor[1] = g;
305 vgColor[2] = b;
306 vgColor[3] = a * opacity;
307 return vgColor;
308}
309
311{
312 VGImageFormat vgFormat;
313
314 switch (format) {
317 vgFormat = VG_BW_1;
318 break;
320 vgFormat = VG_sXRGB_8888;
321 break;
323 vgFormat = VG_sARGB_8888;
324 break;
326 vgFormat = VG_sARGB_8888_PRE;
327 break;
329 vgFormat = VG_sRGB_565;
330 break;
332 vgFormat = VG_sRGBX_8888;
333 break;
335 vgFormat = VG_sRGBA_8888;
336 break;
338 vgFormat = VG_sRGBA_8888_PRE;
339 break;
341 vgFormat = VG_A_8;
342 break;
344 vgFormat = VG_sL_8;
345 break;
346 default:
347 //Invalid
348 vgFormat = (VGImageFormat)-1;
349 break;
350 }
351
352 return vgFormat;
353}
354
356{
357 QImage::Format qImageFormat;
358
359 switch (format) {
360 case VG_BW_1:
361 qImageFormat = QImage::Format_Mono;
362 break;
363 case VG_sXRGB_8888:
364 qImageFormat = QImage::Format_RGB32;
365 break;
366 case VG_sARGB_8888:
367 qImageFormat = QImage::Format_ARGB32;
368 break;
369 case VG_sARGB_8888_PRE:
371 break;
372 case VG_sRGB_565:
373 qImageFormat = QImage::Format_RGB16;
374 break;
375 case VG_sRGBX_8888:
376 qImageFormat = QImage::Format_RGBX8888;
377 break;
378 case VG_sRGBA_8888:
379 qImageFormat = QImage::Format_RGBA8888;
380 break;
381 case VG_sRGBA_8888_PRE:
383 break;
384 case VG_A_8:
385 qImageFormat = QImage::Format_Alpha8;
386 break;
387 case VG_sL_8:
388 qImageFormat = QImage::Format_Grayscale8;
389 break;
390 default:
391 qImageFormat = QImage::Format_ARGB32;
392 break;
393 }
394
395 return qImageFormat;
396}
397
398} // end namespace QSGOpenVGHelpers
399
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
Format
The following image formats are available in Qt.
Definition qimage.h:41
@ Format_Alpha8
Definition qimage.h:65
@ Format_RGBA8888
Definition qimage.h:59
@ Format_RGB32
Definition qimage.h:46
@ Format_MonoLSB
Definition qimage.h:44
@ Format_RGBA8888_Premultiplied
Definition qimage.h:60
@ Format_Mono
Definition qimage.h:43
@ Format_ARGB32_Premultiplied
Definition qimage.h:48
@ Format_RGB16
Definition qimage.h:49
@ Format_ARGB32
Definition qimage.h:47
@ Format_RGBX8888
Definition qimage.h:58
@ Format_Grayscale8
Definition qimage.h:66
\inmodule QtCore
Definition qmargins.h:270
constexpr qreal right() const noexcept
Returns the right margin.
Definition qmargins.h:383
constexpr qreal left() const noexcept
Returns the left margin.
Definition qmargins.h:377
constexpr qreal top() const noexcept
Returns the top margin.
Definition qmargins.h:380
constexpr qreal bottom() const noexcept
Returns the bottom margin.
Definition qmargins.h:386
\inmodule QtGui
\inmodule QtGui
\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
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:484
constexpr qreal y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:672
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 qreal x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:669
constexpr qreal left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:497
constexpr QPointF topLeft() const noexcept
Returns the position of the rectangle's top-left corner.
Definition qrect.h:511
constexpr qreal top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:498
\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
\inmodule QtCore
Definition qsize.h:25
void qDrawBorderImage(VGImage image, const QSizeF &textureSize, const QRectF &targetRect, const QRectF &innerTargetRect, const QRectF &subSourceRect)
void qDrawTiled(VGImage image, const QSize imageSize, const QRectF &targetRect, const QPointF offset, float scaleX, float scaleY)
QImage::Format qVGImageFormatToQImageFormat(VGImageFormat format)
VGImageFormat qImageFormatToVGImageFormat(QImage::Format format)
const QVector< VGfloat > qColorToVGColor(const QColor &color, float opacity)
VGPath qPainterPathToVGPath(const QPainterPath &path)
void qDrawSubImage(VGImage image, const QRectF &sourceRect, const QPointF &destOffset)
Combined button and popup list for selecting options.
Definition image.cpp:4
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:333
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:327
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLboolean r
[2]
GLsizei const GLubyte GLsizei GLenum const void * coords
GLenum GLenum GLsizei count
GLuint color
[2]
GLenum GLuint GLintptr offset
GLboolean GLboolean g
GLint GLsizei GLsizei GLenum format
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei imageSize
GLsizei const GLchar *const * path
GLuint segments
double qreal
Definition qtypes.h:187