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
+40 -15
View File
@@ -8,6 +8,10 @@
#include <algorithm>
#include <cmath>
namespace {
constexpr int kMaxRects = 16;
} // namespace
static float deformPadding(const QMatrix4x4& dm, float hw, float hh) {
const float dm00 = dm(0, 0), dm01 = dm(0, 1);
const float dm10 = dm(1, 0), dm11 = dm(1, 1);
@@ -45,6 +49,7 @@ BlobShape::BlobShape(QQuickItem* parent) : QQuickItem(parent) {
void BlobShape::setGroup(BlobGroup* g) {
if (m_group == g) return;
if (m_group && isComponentComplete()) unregisterFromGroup();
if (m_group) resetDeformMatrix();
m_group = g;
if (m_group && isComponentComplete()) registerWithGroup();
emit groupChanged();
@@ -87,6 +92,8 @@ void BlobShape::geometryChange(
std::abs(m_pendingDh) > syncThreshold) {
m_pendingDx = 0;
m_pendingDy = 0;
m_pendingDw = 0;
m_pendingDh = 0;
m_group->markShapeDirty(this);
}
}
@@ -105,6 +112,12 @@ void BlobShape::updateCenteredDeformMatrix() {
}
}
void BlobShape::resetDeformMatrix() {
m_deformMatrix = QMatrix4x4();
emit rawDeformMatrixChanged();
updateCenteredDeformMatrix();
}
void BlobShape::cornerRadii(float out[4]) const {
const auto maxR = static_cast<float>(std::min(width(), height())) * 0.5f;
const auto r = std::min(static_cast<float>(m_radius), maxR);
@@ -187,6 +200,12 @@ void BlobShape::updatePolish() {
}
if (include) {
if (other == this && m_cachedRects.size() >= kMaxRects) {
m_cachedRects.removeLast();
rectShapes.removeLast();
}
if (m_cachedRects.size() >= kMaxRects) continue;
if (other == this)
m_cachedMyIndex = static_cast<int>(m_cachedRects.size());
@@ -240,8 +259,7 @@ void BlobShape::updatePolish() {
m_cachedInvertedRadius = 0;
memset(m_cachedInvertedOuter, 0, sizeof(m_cachedInvertedOuter));
memset(m_cachedInvertedInner, 0, sizeof(m_cachedInvertedInner));
memset(
m_cachedInvertedOuterRadii, 0, sizeof(m_cachedInvertedOuterRadii));
memset(m_cachedInvertedOuterRadii, 0, sizeof(m_cachedInvertedOuterRadii));
auto* inv = m_group->invertedRect();
if (inv) {
@@ -308,10 +326,11 @@ void BlobShape::updatePolish() {
BlobShape* const si = rectShapes[i];
float fTr = 1.0f, fBr = 1.0f, fBl = 1.0f, fTl = 1.0f;
const float cTrX = ri.cx + ri.hw, cTrY = ri.cy - ri.hh;
const float cBrX = ri.cx + ri.hw, cBrY = ri.cy + ri.hh;
const float cBlX = ri.cx - ri.hw, cBlY = ri.cy + ri.hh;
const float cTlX = ri.cx - ri.hw, cTlY = ri.cy - ri.hh;
const float dcx = ri.cx + ri.offsetX, dcy = ri.cy + ri.offsetY;
const float cTrX = dcx + ri.hw, cTrY = dcy - ri.hh;
const float cBrX = dcx + ri.hw, cBrY = dcy + ri.hh;
const float cBlX = dcx - ri.hw, cBlY = dcy + ri.hh;
const float cTlX = dcx - ri.hw, cTlY = dcy - ri.hh;
for (qsizetype j = 0; cornerFill && j < rectCount; ++j) {
if (j == i) continue;
@@ -319,10 +338,12 @@ void BlobShape::updatePolish() {
BlobShape* const sj = rectShapes[j];
if (si->isCornerExcluded(sj) || sj->isCornerExcluded(si)) continue;
const auto& rj = m_cachedRects[j];
const float sdTr = cpuSdBox(cTrX, cTrY, rj.cx, rj.cy, rj.hw, rj.hh);
const float sdBr = cpuSdBox(cBrX, cBrY, rj.cx, rj.cy, rj.hw, rj.hh);
const float sdBl = cpuSdBox(cBlX, cBlY, rj.cx, rj.cy, rj.hw, rj.hh);
const float sdTl = cpuSdBox(cTlX, cTlY, rj.cx, rj.cy, rj.hw, rj.hh);
const float jcx = rj.cx + rj.offsetX;
const float jcy = rj.cy + rj.offsetY;
const float sdTr = cpuSdBox(cTrX, cTrY, jcx, jcy, rj.hw, rj.hh);
const float sdBr = cpuSdBox(cBrX, cBrY, jcx, jcy, rj.hw, rj.hh);
const float sdBl = cpuSdBox(cBlX, cBlY, jcx, jcy, rj.hw, rj.hh);
const float sdTl = cpuSdBox(cTlX, cTlY, jcx, jcy, rj.hw, rj.hh);
fTr = std::min(fTr, cornerFillFactor(sdTr, smoothFactor));
fBr = std::min(fBr, cornerFillFactor(sdBr, smoothFactor));
fBl = std::min(fBl, cornerFillFactor(sdBl, smoothFactor));
@@ -360,10 +381,14 @@ void BlobShape::updatePolish() {
-cpuSdBox(cTlX, cTlY, icx, icy, ihw, ihh)));
}
ri.radius[0] = std::max(ri.radius[0] * fTr, minR);
ri.radius[1] = std::max(ri.radius[1] * fBr, minR);
ri.radius[2] = std::max(ri.radius[2] * fBl, minR);
ri.radius[3] = std::max(ri.radius[3] * fTl, minR);
ri.radius[0] = ri.radius[0] > 0.0f ? std::max(ri.radius[0] * fTr, minR)
: 0.0f;
ri.radius[1] = ri.radius[1] > 0.0f ? std::max(ri.radius[1] * fBr, minR)
: 0.0f;
ri.radius[2] = ri.radius[2] > 0.0f ? std::max(ri.radius[2] * fBl, minR)
: 0.0f;
ri.radius[3] = ri.radius[3] > 0.0f ? std::max(ri.radius[3] * fTl, minR)
: 0.0f;
}
}
@@ -428,7 +453,7 @@ QSGNode* BlobShape::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) {
sizeof(m_cachedInvertedOuterRadii));
const int count =
static_cast<int>(qMin(m_cachedRects.size(), qsizetype(16)));
static_cast<int>(qMin(m_cachedRects.size(), qsizetype(kMaxRects)));
material->m_rectCount = count;
for (int i = 0; i < count; ++i)
material->m_rects[i] = m_cachedRects[i];