separateFromDigit function

KeyColors? separateFromDigit(
  1. KeyColors k,
  2. int digitFace,
  3. GuardrailLimits lim, {
  4. int? avoid,
  5. double avoidDeltaE = 0,
  6. int rounds = 6,
})

Moves k's face lightness away from digitFace in 0.06 steps (up to rounds) until it is distinct from it (and, if avoid is given, ΔE ≥ avoidDeltaE from that face too), re-solving the label each step.

Implementation

KeyColors? separateFromDigit(
  KeyColors k,
  int digitFace,
  GuardrailLimits lim, {
  int? avoid,
  double avoidDeltaE = 0,
  int rounds = 6,
}) {
  bool ok(int face) =>
      _distinct(face, digitFace, lim) &&
      (avoid == null || minCvdDeltaE(face, avoid) >= avoidDeltaE);
  if (ok(k.face)) return k;
  if (((k.face >>> 24) & 0xFF) != 255) return null;
  final face = argbToOklch(k.face);
  final digitL = argbToOklab(digitFace).$1;
  final policy = lim.labelPolicy;
  // Try moving away from the digit face first, then the other way past it.
  for (final up in [face.l >= digitL, face.l < digitL]) {
    var l = face.l;
    for (var i = 0; i < rounds; i++) {
      l = clamp01(l + (up ? 0.06 : -0.06));
      final f = oklchToArgb(l, face.c, face.h);
      if (!ok(f)) continue;
      final fixed = repairKeyLabel(k.copyWith(face: f), policy, [f]);
      if (fixed != null && ok(fixed.face)) return fixed;
    }
  }
  return null;
}