apcaContrastOfApcaY function
Implementation
double apcaContrastOfApcaY(double textApcaY, double backgroundApcaY) {
const inputClampMin = 0.0;
const inputClampMax = 1.1;
final smallest = math.min(textApcaY, backgroundApcaY);
final largest = math.max(textApcaY, backgroundApcaY);
assert(smallest >= inputClampMin);
assert(largest <= inputClampMax);
var sapc = 0.0; // For raw SAPC value
var outputContrast = 0.0;
// Rational for ignore; crucial property of algorithm, present in original
// implementation, and signals the code was ported correctly.
// ignore: unused_local_variable
var polarity = _ApcaPolarity.blackOnWhite;
// Soft clamps Y for either color if it is near black.
textApcaY = _fixupForBlackThreshold(textApcaY);
backgroundApcaY = _fixupForBlackThreshold(backgroundApcaY);
// Return 0 Early for extremely low ∆Y
if ((backgroundApcaY - textApcaY).abs() < deltaYMin) {
return 0.0;
}
// APCA/SAPC CONTRAST - LOW CLIP (W3 LICENSE)
if (backgroundApcaY > textApcaY) {
// For normal polarity, black text on white (BoW)
// Calculate the SAPC contrast value and scale
sapc =
(math.pow(backgroundApcaY, normBg) - math.pow(textApcaY, normText)) *
scaleBoW;
// Low Contrast smooth rollout to prevent polarity reversal and also a
// low-clip for very low contrasts
outputContrast = (sapc < loClip) ? 0.0 : sapc - loBoWOffset;
} else {
// background < text
polarity = _ApcaPolarity.whiteOnBlack;
sapc =
(math.pow(backgroundApcaY, revBg) - math.pow(textApcaY, revText)) *
scaleWoB;
outputContrast = (sapc > (-1.0 * loClip)) ? 0.0 : sapc + loWoBOffset;
}
// return Lc (lightness contrast) as a signed numeric value
//
// Note: Original implementation could conditionally return a string based
// on the value of a `places` argument.
return outputContrast * 100.0;
}