const HIMETRIC_PER_INCH: i64 = 2540;
const PIXELS_PER_INCH: i64 = 96;
pub fn pixels_to_himetric(pixels: i32) -> i32 {
scale(pixels as i64, HIMETRIC_PER_INCH, PIXELS_PER_INCH)
}
pub fn himetric_to_pixels(himetric: i32) -> i32 {
scale(himetric as i64, PIXELS_PER_INCH, HIMETRIC_PER_INCH)
}
fn scale(value: i64, numerator: i64, denominator: i64) -> i32 {
let half = denominator / 2;
let scaled = if value >= 0 {
(value * numerator + half) / denominator
} else {
(value * numerator - half) / denominator
};
scaled.clamp(i32::MIN as i64, i32::MAX as i64) as i32
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn himetric_round_trips_at_the_sizes_a_control_uses() {
for pixels in [1, 2, 96, 100, 200, 640, 1080, 1920] {
assert_eq!(
himetric_to_pixels(pixels_to_himetric(pixels)),
pixels,
"{pixels} px did not survive the round trip"
);
}
}
#[test]
fn one_inch_is_exact_in_both_directions() {
assert_eq!(pixels_to_himetric(96), 2540);
assert_eq!(himetric_to_pixels(2540), 96);
assert_eq!(pixels_to_himetric(192), 5080);
}
#[test]
fn an_absurd_extent_saturates_rather_than_overflowing() {
assert_eq!(pixels_to_himetric(i32::MAX), i32::MAX);
assert_eq!(pixels_to_himetric(i32::MIN), i32::MIN);
assert_eq!(himetric_to_pixels(i32::MAX), 81_164_736);
}
}