compute method

DisplayMetrics compute()

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,
  );
}