185 const QRectF &innerTargetRect,
187 const QRectF &innerSourceRect,
188 const QRectF &subSourceRect,
190 bool mirrorHorizontally,
191 bool mirrorVertically,
194 int floorLeft =
qFloor(subSourceRect.left());
195 int ceilRight =
qCeil(subSourceRect.right());
196 int floorTop =
qFloor(subSourceRect.top());
197 int ceilBottom =
qCeil(subSourceRect.bottom());
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())
213 if (innerTargetRect.bottom() != targetRect.bottom())
216 QVarLengthArray<X, 32> xData(2 * hCells);
217 QVarLengthArray<Y, 32> yData(2 * vCells);
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();
251 Q_ASSERT(xs == xData.data() + xData.size());
252 if (mirrorHorizontally) {
253 float leftPlusRight = targetRect.left() + targetRect.right();
254 int count = xData.size();
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();
273 float b = innerTargetRect.height() / subSourceRect.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();
285 if (innerTargetRect.bottom() != targetRect.bottom()) {
286 ys[0].y = innerTargetRect.bottom();
287 ys[0].ty = innerSourceRect.bottom();
288 ys[1].y = targetRect.bottom();
289 ys[1].ty = sourceRect.
bottom();
292 Q_ASSERT(ys == yData.data() + yData.size());
293 if (mirrorVertically) {
294 float topPlusBottom = targetRect.top() + targetRect.bottom();
295 int count = yData.size();
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;
350 float delta = float(
qAbs(targetRect.width()) <
qAbs(targetRect.height())
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)
The QSGDynamicTexture class serves as a baseclass for dynamically changing textures,...
virtual QSize textureSize() const =0
Returns the size of the texture in pixels.