fix: blobs now allow to be drawn in device pixels to stay sharp
C++ / fmt (pull_request) Failing after 5s
C++ / build (pull_request) Failing after 10s
C++ / clang-tidy (pull_request) Failing after 10s
JS/TS / fmt (pull_request) Successful in 9s
JS/TS / lint (pull_request) Successful in 25s
Python / static (pull_request) Successful in 34s
Rust / build (pull_request) Successful in 51s
Python / verify (pull_request) Failing after 1m25s
Rust / fmt (pull_request) Successful in 39s
Rust / clippy (pull_request) Successful in 59s

This commit is contained in:
2026-10-30 01:52:33 +01:00
parent 78a9577209
commit c5608dc9b9
30 changed files with 794 additions and 435 deletions
+8 -14
View File
@@ -11,28 +11,24 @@
BlobInvertedRect::BlobInvertedRect(QQuickItem* parent) : BlobShape(parent) {}
static void setFrameIndices(quint16* idx) {
// Top strip: 0-1-4, 1-5-4
idx[0] = 0;
idx[1] = 1;
idx[2] = 4;
idx[3] = 1;
idx[4] = 5;
idx[5] = 4;
// Right strip: 1-2-5, 2-6-5
idx[6] = 1;
idx[7] = 2;
idx[8] = 5;
idx[9] = 2;
idx[10] = 6;
idx[11] = 5;
// Bottom strip: 2-3-6, 3-7-6
idx[12] = 2;
idx[13] = 3;
idx[14] = 6;
idx[15] = 3;
idx[16] = 7;
idx[17] = 6;
// Left strip: 3-0-7, 0-4-7
idx[18] = 3;
idx[19] = 0;
idx[20] = 7;
@@ -50,17 +46,20 @@ QSGNode* BlobInvertedRect::updatePaintNode(
const float pad = static_cast<float>(m_group->smoothing());
// Compute inner hole boundary in local coords
// Inset past the inner border edge by 2x smoothing to cover the blend zone
const float inset = pad * 2.0f;
const float holeLeft = static_cast<float>(m_borderLeft) + inset;
const float holeTop = static_cast<float>(m_borderTop) + inset;
const float holeRight = static_cast<float>(width() - m_borderRight) - inset;
const float holeBot = static_cast<float>(height() - m_borderBottom) - inset;
// If the hole is too small or invalid, fall back to full quad
if (holeLeft >= holeRight || holeTop >= holeBot)
if (holeLeft >= holeRight || holeTop >= holeBot) {
auto* oldGeoNode = static_cast<QSGGeometryNode*>(oldNode);
if (oldNode && oldGeoNode->geometry()->vertexCount() != 4) {
delete oldNode;
oldNode = nullptr;
}
return BlobShape::updatePaintNode(oldNode, nullptr);
}
auto* node = static_cast<QSGGeometryNode*>(oldNode);
@@ -87,7 +86,6 @@ QSGNode* BlobInvertedRect::updatePaintNode(
node->setFlag(QSGNode::OwnsMaterial);
}
// Outer bounds (local coords)
const float x0 = static_cast<float>(m_localPaddedRect.x());
const float y0 = static_cast<float>(m_localPaddedRect.y());
const float x1 = x0 + static_cast<float>(m_localPaddedRect.width());
@@ -95,15 +93,12 @@ QSGNode* BlobInvertedRect::updatePaintNode(
const float w = x1 - x0;
const float h = y1 - y0;
// Update vertex positions and texture coordinates
auto* v = node->geometry()->vertexDataAsTexturedPoint2D();
// Outer corners
v[0].set(x0, y0, 0.0f, 0.0f);
v[1].set(x1, y0, 1.0f, 0.0f);
v[2].set(x1, y1, 1.0f, 1.0f);
v[3].set(x0, y1, 0.0f, 1.0f);
// Inner corners (hole)
v[4].set(holeLeft, holeTop, (holeLeft - x0) / w, (holeTop - y0) / h);
v[5].set(holeRight, holeTop, (holeRight - x0) / w, (holeTop - y0) / h);
v[6].set(holeRight, holeBot, (holeRight - x0) / w, (holeBot - y0) / h);
@@ -111,7 +106,6 @@ QSGNode* BlobInvertedRect::updatePaintNode(
node->markDirty(QSGNode::DirtyGeometry);
// Update material uniforms
auto* material = static_cast<BlobMaterial*>(node->material());
material->m_paddedX = m_cachedPaddedX;
material->m_paddedY = m_cachedPaddedY;
@@ -218,7 +212,7 @@ void BlobInvertedRect::outerCornerRadii(float out[4]) const {
const auto base = std::min(static_cast<float>(m_outerRadius), maxR);
out[0] = std::min(
m_outerTopRightRadius >= 0 ? static_cast<float>(m_outerTopRightRadius)
: base,
: base,
maxR);
out[1] = std::min(
m_outerBottomRightRadius >= 0