separateGlassEquals function
Keeps the = glass apart from the operators over any two background
samples (the generic equalsVsOperator rule compares every pair) and
from the digit tint over the same sample (glassOperatorTint): when
it is too close, its tint moves 0.06 at a time in lightness — away
from the operator's first, then the other way — at an alpha of at
least 230 (a denser jewel varies less across the mesh), re-solving the
label each step. Null when no step works.
Implementation
KeyColors? separateGlassEquals(
KeyColors eq,
KeyColors op,
KeyColors digit,
GuardrailLimits lim,
List<int> bgs,
) {
final opLabs = [for (final s in faceSamples(op.face, bgs)) cvdLabs(s)];
bool ok(KeyColors e) {
if (glassTintDistance(e.face, digit.face, bgs) < lim.cvdDeltaE) {
return false;
}
for (final s in faceSamples(e.face, bgs)) {
final labs = cvdLabs(s);
for (final o in opLabs) {
if (minCvdDeltaELabs(labs, o) < lim.equalsVsOperatorDeltaE) {
return false;
}
}
}
return true;
}
if (ok(eq)) return eq;
final tint = argbToOklch(eq.face | 0xFF000000);
final alpha = (eq.face >>> 24) & 0xFF;
final label = argbToOklch(eq.label);
final opL = argbToOklch(op.face | 0xFF000000).l;
for (final up in [tint.l >= opL, tint.l < opL]) {
var l = tint.l;
for (var i = 0; i < 6; i++) {
l = clamp01(l + (up ? 0.06 : -0.06));
final k = solveGlassKey(
tint: (l: l, c: tint.c, h: tint.h),
alpha: alpha < 230 ? 230 : alpha,
label: l < 0.62
? (l: 0.98, c: label.c, h: label.h)
: (l: 0.18, c: label.c, h: label.h),
bgs: bgs,
target: lim.labelRatio,
edge: eq.edge,
);
if (k != null && ok(k)) return k;
}
}
return null;
}