6#include <QtCore/qvarlengtharray.h>
7#include <QtCore/qmath.h>
33 : m_innerSourceRect(0, 0, 1, 1)
34 , m_subSourceRect(0, 0, 1, 1)
35 , m_antialiasing(
false)
36 , m_mirrorHorizontally(
false)
37 , m_mirrorVertically(
false)
38 , m_dirtyGeometry(
false)
39 , m_geometry(
QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
44#ifdef QSG_RUNTIME_DESCRIPTION
128 bool doDirty =
false;
131 doDirty =
t->updateTexture();
154 struct X {
float x, tx; };
155 struct Y {
float y,
ty; };
158static inline void appendQuad(
int indexType,
void **indexData,
159 int topLeft,
int topRight,
160 int bottomLeft,
int bottomRight)
185 const QRectF &innerTargetRect,
187 const QRectF &innerSourceRect,
188 const QRectF &subSourceRect,
190 bool mirrorHorizontally,
191 bool mirrorVertically,
196 int floorTop =
qFloor(subSourceRect.
top());
198 int hTiles = ceilRight - floorLeft;
199 int vTiles = ceilBottom - floorTop;
203 if (innerTargetRect.
width() == 0)
205 if (innerTargetRect.
left() != targetRect.
left())
207 if (innerTargetRect.
right() != targetRect.
right())
209 if (innerTargetRect.
height() == 0)
211 if (innerTargetRect.
top() != targetRect.
top())
218 X *xs = xData.
data();
219 Y *ys = yData.
data();
221 if (innerTargetRect.
left() != targetRect.
left()) {
222 xs[0].x = targetRect.
left();
223 xs[0].tx = sourceRect.
left();
224 xs[1].x = innerTargetRect.
left();
225 xs[1].tx = innerSourceRect.
left();
228 if (innerTargetRect.
width() != 0 && hTiles > 0) {
229 xs[0].x = innerTargetRect.
left();
230 xs[0].tx = innerSourceRect.
x() + (subSourceRect.
left() - floorLeft) * innerSourceRect.
width();
232 float b = innerTargetRect.
width() / subSourceRect.
width();
233 float a = innerTargetRect.
x() - subSourceRect.
x() *
b;
234 for (
int i = floorLeft + 1;
i <= ceilRight - 1; ++
i) {
235 xs[0].x = xs[1].x =
a +
b *
i;
236 xs[0].tx = innerSourceRect.
right();
237 xs[1].tx = innerSourceRect.
left();
240 xs[0].x = innerTargetRect.
right();
241 xs[0].tx = innerSourceRect.
x() + (subSourceRect.
right() - ceilRight + 1) * innerSourceRect.
width();
244 if (innerTargetRect.
right() != targetRect.
right()) {
245 xs[0].x = innerTargetRect.
right();
246 xs[0].tx = innerSourceRect.
right();
247 xs[1].x = targetRect.
right();
248 xs[1].tx = sourceRect.
right();
252 if (mirrorHorizontally) {
253 float leftPlusRight = targetRect.
left() + targetRect.
right();
256 for (
int i = 0;
i < (
count >> 1); ++
i)
259 xs[
i].
x = leftPlusRight - xs[
i].
x;
262 if (innerTargetRect.
top() != targetRect.
top()) {
263 ys[0].y = targetRect.
top();
264 ys[0].ty = sourceRect.
top();
265 ys[1].y = innerTargetRect.
top();
266 ys[1].ty = innerSourceRect.
top();
269 if (innerTargetRect.
height() != 0 && vTiles > 0) {
270 ys[0].y = innerTargetRect.
top();
271 ys[0].ty = innerSourceRect.
y() + (subSourceRect.
top() - floorTop) * innerSourceRect.
height();
274 float a = innerTargetRect.
y() - subSourceRect.
y() *
b;
275 for (
int i = floorTop + 1;
i <= ceilBottom - 1; ++
i) {
276 ys[0].y = ys[1].y =
a +
b *
i;
277 ys[0].ty = innerSourceRect.
bottom();
278 ys[1].ty = innerSourceRect.
top();
281 ys[0].y = innerTargetRect.
bottom();
282 ys[0].ty = innerSourceRect.
y() + (subSourceRect.
bottom() - ceilBottom + 1) * innerSourceRect.
height();
286 ys[0].y = innerTargetRect.
bottom();
287 ys[0].ty = innerSourceRect.
bottom();
288 ys[1].y = targetRect.
bottom();
289 ys[1].ty = sourceRect.
bottom();
293 if (mirrorVertically) {
294 float topPlusBottom = targetRect.
top() + targetRect.
bottom();
297 for (
int i = 0;
i < (
count >> 1); ++
i)
300 ys[
i].
y = topPlusBottom - ys[
i].
y;
306 if (hCells * vCells * 4 > 0x7fff)
312 hCells * vCells * 4 + (hCells + vCells - 1) * 4,
313 hCells * vCells * 6 + (hCells + vCells) * 12,
317 hCells * vCells * 6 + (hCells + vCells) * 12);
323 auto *vertices =
reinterpret_cast<SmoothImageVertex *
>(
g->vertexData());
324 memset(vertices, 0,
g->vertexCount() *
g->sizeOfVertex());
325 void *indexData =
g->indexData();
330 float leftDx = xData.
at(1).x - xData.
at(0).x;
331 float rightDx = xData.
at(xData.
size() - 1).x - xData.
at(xData.
size() - 2).x;
332 float topDy = yData.
at(1).y - yData.
at(0).y;
333 float bottomDy = yData.
at(yData.
size() - 1).y - yData.
at(yData.
size() - 2).y;
335 float leftDu = xData.
at(1).tx - xData.
at(0).tx;
336 float rightDu = xData.
at(xData.
size() - 1).tx - xData.
at(xData.
size() - 2).tx;
337 float topDv = yData.
at(1).ty - yData.
at(0).ty;
338 float bottomDv = yData.
at(yData.
size() - 1).ty - yData.
at(yData.
size() - 2).ty;
341 leftDx = rightDx *= 0.5f;
342 leftDu = rightDu *= 0.5f;
345 topDy = bottomDy *= 0.5f;
346 topDv = bottomDv *= 0.5f;
351 ? targetRect.
width() : targetRect.
height()) * 0.5f;
355 for (
int j = 0;
j < vCells; ++
j, ys += 2) {
358 bool isBottom =
j == vCells - 1;
359 for (
int i = 0;
i < hCells; ++
i, xs += 2) {
360 bool isLeft =
i == 0;
361 bool isRight =
i == hCells - 1;
363 SmoothImageVertex *
v = vertices +
index;
366 for (
int k = (isTop || isLeft ? 2 : 1); k--; ++
v, ++
index) {
373 int topRight =
index;
374 for (
int k = (isTop || isRight ? 2 : 1); k--; ++
v, ++
index) {
381 int bottomLeft =
index;
382 for (
int k = (isBottom || isLeft ? 2 : 1); k--; ++
v, ++
index) {
389 int bottomRight =
index;
390 for (
int k = (isBottom || isRight ? 2 : 1); k--; ++
v, ++
index) {
397 appendQuad(
g->indexType(), &indexData, topLeft, topRight, bottomLeft, bottomRight);
400 vertices[topLeft].dy = vertices[topRight].dy = topDy;
401 vertices[topLeft].dv = vertices[topRight].dv = topDv;
402 vertices[topLeft + 1].dy = vertices[topRight + 1].dy = -delta;
403 appendQuad(
g->indexType(), &indexData, topLeft + 1, topRight + 1, topLeft, topRight);
407 vertices[bottomLeft].dy = vertices[bottomRight].dy = -bottomDy;
408 vertices[bottomLeft].dv = vertices[bottomRight].dv = -bottomDv;
409 vertices[bottomLeft + 1].dy = vertices[bottomRight + 1].dy = delta;
410 appendQuad(
g->indexType(), &indexData, bottomLeft, bottomRight, bottomLeft + 1, bottomRight + 1);
414 vertices[topLeft].dx = vertices[bottomLeft].dx = leftDx;
415 vertices[topLeft].du = vertices[bottomLeft].du = leftDu;
416 vertices[topLeft + 1].dx = vertices[bottomLeft + 1].dx = -delta;
417 appendQuad(
g->indexType(), &indexData, topLeft + 1, topLeft, bottomLeft + 1, bottomLeft);
421 vertices[topRight].dx = vertices[bottomRight].dx = -rightDx;
422 vertices[topRight].du = vertices[bottomRight].du = -rightDu;
423 vertices[topRight + 1].dx = vertices[bottomRight + 1].dx = delta;
424 appendQuad(
g->indexType(), &indexData, topRight, topRight + 1, bottomRight, bottomRight + 1);
433 hCells * vCells * 4, hCells * vCells * 6,
441 for (
int j = 0;
j < vCells; ++
j, ys += 2) {
443 for (
int i = 0;
i < hCells; ++
i, xs += 2) {
444 vertices[0].
x = vertices[2].
x = xs[0].x;
445 vertices[0].
tx = vertices[2].
tx = xs[0].tx;
446 vertices[1].
x = vertices[3].
x = xs[1].x;
447 vertices[1].
tx = vertices[3].
tx = xs[1].tx;
449 vertices[0].
y = vertices[1].
y = ys[0].y;
450 vertices[0].
ty = vertices[1].
ty = ys[0].ty;
451 vertices[2].
y = vertices[3].
y = ys[1].y;
452 vertices[2].
ty = vertices[3].
ty = ys[1].ty;
458 for (
int i = 0;
i < 4 * vCells * hCells;
i += 4)
472 memset(
g->vertexData(), 0,
g->sizeOfVertex() * 4);
474 QRectF sourceRect =
t->normalizedTextureSubRect();
487 int hTiles = ceilRight - floorLeft;
488 int vTiles = ceilBottom - floorTop;
490 bool hasTiles = hTiles > 1 || vTiles > 1;
491 bool fullTexture = innerSourceRect ==
QRectF(0, 0, 1, 1);
498 if (!hasMargins && (!hasTiles || (fullTexture &&
supportsWrap(
t->textureSize())))) {
529 auto *vertices =
reinterpret_cast<SmoothImageVertex *
>(
g->vertexData());
534 for (
int d = -1;
d <= 1;
d += 2) {
535 for (
int j = 0;
j < 2; ++
j) {
536 for (
int i = 0;
i < 2; ++
i, ++vertices) {
539 vertices->u = sr.
x() +
i * sr.
width();
540 vertices->v = sr.
y() +
j * sr.
height();
541 vertices->dx = (
i == 0 ? delta : -delta) *
d;
542 vertices->dy = (
j == 0 ? delta : -delta) *
d;
543 vertices->du = (
d < 0 ? 0 : vertices->dx * sx);
544 vertices->dv = (
d < 0 ? 0 : vertices->dy * sy);
548 Q_ASSERT(vertices -
g->vertexCount() ==
g->vertexData());
550 0, 4, 1, 5, 3, 7, 2, 6, 0, 4,
\inmodule QtCore\reentrant
constexpr bool isEmpty() const noexcept
Returns true if the rectangle is empty, otherwise returns false.
constexpr qreal bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
constexpr void setBottom(qreal pos) noexcept
Sets the bottom edge of the rectangle to the given finite y coordinate.
constexpr void setRight(qreal pos) noexcept
Sets the right edge of the rectangle to the given finite x coordinate.
constexpr void setLeft(qreal pos) noexcept
Sets the left edge of the rectangle to the given finite x coordinate.
constexpr qreal y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr qreal height() const noexcept
Returns the height of the rectangle.
constexpr qreal width() const noexcept
Returns the width of the rectangle.
constexpr qreal x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr void setTop(qreal pos) noexcept
Sets the top edge of the rectangle to the given finite y coordinate.
constexpr qreal left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr qreal top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr qreal right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
const QSGGeometry * geometry() const
Returns this node's geometry.
void setGeometry(QSGGeometry *geometry)
Sets the geometry of this node to geometry.
virtual bool supportsWrap(const QSize &size) const =0
void setTexture(QSGTexture *texture) override
void setInnerSourceRect(const QRectF &rect) override
void setMirror(bool mirrorHorizontally, bool mirrorVertically) override
void setInnerTargetRect(const QRectF &rect) override
virtual void setMaterialTexture(QSGTexture *texture)=0
void setAntialiasing(bool antialiasing) override
virtual void updateMaterialAntialiasing()=0
void setTargetRect(const QRectF &rect) override
QSGDynamicTexture * m_dynamicTexture
QRectF m_dynamicTextureSubRect
uint m_mirrorHorizontally
QSize m_dynamicTextureSize
void setSubSourceRect(const QRectF &rect) override
virtual QSGTexture * materialTexture() const =0
QSGBasicInternalImageNode()
virtual bool updateMaterialBlending()=0
void preprocess() override
Override this function to do processing on the node before it is rendered.
The QSGDynamicTexture class serves as a baseclass for dynamically changing textures,...
The QSGGeometry class provides low-level storage for graphics primitives in the \l{Qt Quick Scene Gra...
void setDrawingMode(unsigned int mode)
Sets the mode to be used for drawing this geometry.
TexturedPoint2D * vertexDataAsTexturedPoint2D()
Convenience function to access the vertex data as a mutable array of QSGGeometry::TexturedPoint2D.
static const AttributeSet & defaultAttributes_TexturedPoint2D()
Convenience function which returns attributes to be used for textured 2D drawing.
static void updateTexturedRectGeometry(QSGGeometry *g, const QRectF &rect, const QRectF &sourceRect)
Updates the geometry g with the coordinates in rect and texture coordinates from textureRect.
void * indexData()
Returns a pointer to the raw index data of this geometry object.
int indexType() const
Returns the primitive type used for indices in this geometry object.
void allocate(int vertexCount, int indexCount=0)
Resizes the vertex and index data of this geometry object to fit vertexCount vertices and indexCount ...
Type
Specifies the component type in the vertex data.
void markDirty(DirtyState bits)
Notifies all connected renderers that the node has dirty bits.
void setFlag(Flag, bool=true)
Sets the flag f on this node if enabled is true; otherwise clears the flag.
virtual QSize textureSize() const =0
Returns the size of the texture in pixels.
constexpr size_type size() const noexcept
const T & at(qsizetype idx) const
Combined button and popup list for selecting options.
const QSGGeometry::AttributeSet & smoothImageAttributeSet()
static struct AttrInfo attrs[]
constexpr T qAbs(const T &t)
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLsizei GLenum const void * indices
static void appendQuad(int indexType, void **indexData, int topLeft, int topRight, int bottomLeft, int bottomRight)
void qsgnode_set_description(QSGNode *node, const QString &description)
QLatin1StringView QLatin1String
The QSGGeometry::AttributeSet describes how the vertices in a QSGGeometry are built up.
The QSGGeometry::Attribute describes a single vertex attribute in a QSGGeometry.
static Attribute createWithAttributeType(int pos, int tupleSize, int primitiveType, AttributeType attributeType)
Creates a new QSGGeometry::Attribute for attribute register pos with tupleSize.
The QSGGeometry::TexturedPoint2D struct is a convenience struct for accessing 2D Points with texture ...