cranpose-ui 0.1.164

UI primitives for Cranpose
Documentation
use super::*;

const PLATFORM_124: [(f32, f32); 10] = [
    (8.0, 9.92),
    (10.0, 12.4),
    (12.0, 14.88),
    (14.0, 17.84),
    (16.0, 19.36),
    (18.0, 20.88),
    (20.0, 22.88),
    (24.0, 25.92),
    (30.0, 30.0),
    (100.0, 100.0),
];

fn platform_124() -> FontScaleCurve {
    FontScaleCurve::from_samples(1.24, &PLATFORM_124)
}

#[test]
fn a_curve_with_no_knots_multiplies() {
    let curve = FontScaleCurve::linear(1.24);
    assert!(curve.is_linear());
    assert_eq!(curve.sp_to_dp(13.0), 13.0 * 1.24);
    assert_eq!(curve.sp_to_dp(0.4), 0.4 * 1.24);
    assert_eq!(curve.scale(), 1.24);
}

#[test]
fn the_identity_curve_leaves_a_size_alone() {
    assert!(FontScaleCurve::linear(1.0).is_identity());
    assert!(!FontScaleCurve::linear(1.24).is_identity());
    assert!(!platform_124().is_identity());
    let flat: Vec<(f32, f32)> = (1..=40).map(|sp| (sp as f32, sp as f32)).collect();
    assert!(FontScaleCurve::from_samples(1.0, &flat).is_identity());
}

#[test]
fn the_platform_curve_is_reproduced_at_every_size_the_platform_was_asked() {
    let curve = platform_124();
    for (sp, expected_px) in [
        (0.4f32, 0.992f32),
        (12.0, 29.76),
        (13.0, 32.72),
        (14.0, 35.68),
        (15.0, 37.2),
        (16.0, 38.72),
        (18.0, 41.76),
        (19.0, 43.76),
        (20.0, 45.76),
        (24.0, 51.84),
        (30.0, 60.0),
        (40.0, 80.0),
        (100.0, 200.0),
    ] {
        let px = curve.sp_to_dp(sp) * 2.0;
        assert!(
            (px - expected_px).abs() < 1.0e-3,
            "{sp}sp resolved to {px}px where the platform answered {expected_px}px",
        );
    }
}

#[test]
fn the_thirteen_sp_secondary_label_is_where_multiplying_goes_wrong() {
    let curve = platform_124();
    assert!((curve.sp_to_dp(13.0) * 2.0 - 32.72).abs() < 1.0e-3);
    assert!((FontScaleCurve::linear(1.24).sp_to_dp(13.0) * 2.0 - 32.24).abs() < 1.0e-3);
}

#[test]
fn collinear_samples_are_dropped_and_the_curve_still_answers_the_same() {
    let curve = platform_124();
    assert_eq!(curve.knot_count(), 8);
    let dense: Vec<(f32, f32)> = (1..=120)
        .map(|sp| {
            let sp = sp as f32;
            (sp, curve.sp_to_dp(sp))
        })
        .collect();
    let resampled = FontScaleCurve::from_samples(1.24, &dense);
    for step in 1..=1200 {
        let sp = step as f32 * 0.1;
        assert!(
            (resampled.sp_to_dp(sp) - curve.sp_to_dp(sp)).abs() < 1.0e-3,
            "{sp}sp: {} against {}",
            resampled.sp_to_dp(sp),
            curve.sp_to_dp(sp),
        );
    }
}

#[test]
fn samples_the_platform_could_not_have_produced_fall_back_to_multiplying() {
    for samples in [
        &[][..],
        &[(12.0, 14.88)][..],
        &[(12.0, 14.88), (12.0, 15.0)][..],
        &[(14.0, 17.84), (12.0, 14.88)][..],
        &[(12.0, f32::NAN), (14.0, 17.84)][..],
        &[(12.0, 0.0), (14.0, 17.84)][..],
    ] {
        let curve = FontScaleCurve::from_samples(1.24, samples);
        assert!(curve.is_linear(), "{samples:?} was accepted");
        assert_eq!(curve.sp_to_dp(13.0), 13.0 * 1.24);
    }
}

#[test]
fn more_bends_than_there_are_knots_falls_back_rather_than_truncating() {
    let zigzag: Vec<(f32, f32)> = (1..=40)
        .map(|sp| {
            let sp = sp as f32;
            (sp, sp * if sp as i32 % 2 == 0 { 1.5 } else { 1.2 })
        })
        .collect();
    assert!(FontScaleCurve::from_samples(1.24, &zigzag).is_linear());
}

#[test]
fn a_negative_size_keeps_its_sign() {
    let curve = platform_124();
    assert!((curve.sp_to_dp(-13.0) + curve.sp_to_dp(13.0)).abs() < 1.0e-6);
    assert!(FontScaleCurve::linear(1.24).sp_to_dp(-13.0) < 0.0);
}

#[test]
fn a_size_that_is_not_a_number_comes_back_unchanged() {
    let curve = platform_124();
    assert!(curve.sp_to_dp(f32::NAN).is_nan());
    assert_eq!(curve.sp_to_dp(f32::INFINITY), f32::INFINITY);
}

#[test]
fn curves_that_convert_differently_do_not_share_a_fingerprint() {
    let platform = platform_124();
    assert_ne!(
        platform.fingerprint(),
        FontScaleCurve::linear(1.24).fingerprint()
    );
    assert_ne!(
        FontScaleCurve::linear(1.0).fingerprint(),
        FontScaleCurve::linear(1.24).fingerprint()
    );
    assert_eq!(platform.fingerprint(), platform_124().fingerprint());
}