40 lines
1.6 KiB
Dart
40 lines
1.6 KiB
Dart
|
|
// lib/editor/layout/viewport_fit.dart
|
||
|
|
//
|
||
|
|
// Pure fit/centering math for the viewport's initial transform + the reader
|
||
|
|
// "fit width / fit page" actions (F3). Today this lives as untested ad-hoc
|
||
|
|
// arithmetic in pen_editor_screen._centerPage; extracting it here makes it
|
||
|
|
// testable and shared by the new viewport widget.
|
||
|
|
//
|
||
|
|
// Content coordinates are scale-1 logical px; the returned scale + offset place
|
||
|
|
// content inside the viewport. No widgets beyond dart:ui Size/Offset.
|
||
|
|
|
||
|
|
import 'dart:ui' show Offset, Size;
|
||
|
|
|
||
|
|
/// Scale so content width fills the viewport width (fit-to-width, the
|
||
|
|
/// continuous-single default). 0 for non-positive content width.
|
||
|
|
double fitWidthScale(Size content, double viewportWidth) {
|
||
|
|
if (content.width <= 0) return 0;
|
||
|
|
return viewportWidth / content.width;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Scale so the whole content fits inside the viewport (letterboxed) —
|
||
|
|
/// min(widthFit, heightFit). 0 for non-positive content extents.
|
||
|
|
double fitPageScale(Size content, Size viewport) {
|
||
|
|
if (content.width <= 0 || content.height <= 0) return 0;
|
||
|
|
final w = viewport.width / content.width;
|
||
|
|
final h = viewport.height / content.height;
|
||
|
|
return w < h ? w : h;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Top-left translation that centers [content] scaled by [scale] within
|
||
|
|
/// [viewport]. When the scaled content is larger than the viewport on an axis
|
||
|
|
/// the offset is negative (content overflows equally on both sides).
|
||
|
|
Offset centerOffset(Size content, Size viewport, double scale) {
|
||
|
|
final scaledW = content.width * scale;
|
||
|
|
final scaledH = content.height * scale;
|
||
|
|
return Offset(
|
||
|
|
(viewport.width - scaledW) / 2.0,
|
||
|
|
(viewport.height - scaledH) / 2.0,
|
||
|
|
);
|
||
|
|
}
|