compute method
Implementation
DisplayMetrics compute() {
final ppm = pxPerMm;
final vdist = viewingDistanceMm ?? usage?.viewingDistanceMm;
final tanPip = math.tan(logicalPixelVisualAngleDegrees * math.pi / 180.0);
final double visualScale;
final bool usedFallback;
if (ppm != null && vdist != null && vdist.isFinite && vdist > 0) {
// vdist * (0.5 + 180 / vdist), without division by a small distance.
visualScale =
ppm *
tanPip *
(0.5 * vdist + _adaptationDistanceMm) *
userScaleFactor;
usedFallback = false;
} else {
visualScale =
logicalPixelVisualAngleDegrees /
_fallbackPixelVisualAngleDegrees *
userScaleFactor;
usedFallback = true;
}
double? touchScale;
final touchTargets = touch;
if (touchTargets != null && ppm != null) {
touchScale = ppm * touchTargets.minPhysicalMm / touchTargets.minLogicalPx;
}
var raw = visualScale;
if (touchScale != null && touchScale > raw) {
raw = touchScale;
}
double scale;
final nearestInt = raw.roundToDouble();
if (nearestInt >= 1.0 &&
(raw - nearestInt).abs() / nearestInt <= integerSnapTolerance &&
(touchScale == null || nearestInt >= touchScale)) {
scale = nearestInt;
} else {
// Quantize to 8 mantissa bits so scale * any integer up to +/-65793
// stays exact in float32, killing seam/round-off bugs in layout.
scale = _quantize(raw, (m) => m.roundToDouble());
if (touchScale != null && scale < touchScale) {
// Rounding dipped below the physical touch floor; take the next
// quantization step up instead.
scale = _quantize(raw, (m) => m.ceilToDouble());
}
}
return DisplayMetrics(
scale: scale,
logicalWidth: widthPx / scale,
logicalHeight: heightPx / scale,
pxPerMm: ppm,
viewingDistanceMm: vdist,
visualScale: visualScale,
touchScale: touchScale,
usedFallback: usedFallback,
);
}