tawasuyu

tawasuyu/llimphi

Sovereign retained-mode GPU UI framework in Rust (wgpu+vello+taffy+parley), Elm loop, 40+ widgets.

Rust 614Markdown 274TOML 149RON 310606 Sutichaykuna

⎇ main llimphi-text/tests/mono_ancho_fijo.rs Rust · 74 siq'ikuna · 3.0 KB Ñawpa willay Pi imata llamkarqan ch'uya

chore: refresco desde el monorepo — vello 0.9 / wgpu 29, 120 miembros d251eb32b · Sergio ·

1//! La familia monoespaciada embebida tiene que dar **ancho fijo de verdad**.
2//!
3//! Es un test de regresión con evidencia numérica: si el registro de
4//! Liberation Mono falla (o alguien le cambia el nombre de familia), parley
5//! resuelve la proporcional y las tablas de la consola se tuercen sin que
6//! nada compile mal. Acá se ve en números.
7
8// Este test mide anchos, que NO necesitan vello — pero construye `TextBlock`
9// con `peniko::Color`, que antes llegaba vía vello. Se toma del reexport del
10// propio crate, que existe en los dos perfiles (W2).
11use llimphi_text::peniko::Color;
12use llimphi_text::{Typesetter, TextBlock, MONOSPACE};
13
14fn ancho(ts: &mut Typesetter, texto: &str, familia: Option<&str>) -> f32 {
15    let mut b = TextBlock::simple(texto, 12.0, Color::WHITE, (0.0, 0.0));
16    b.font_family = familia.map(str::to_string);
17    llimphi_text::measure(ts, &b).width
18}
19
20#[test]
21fn mono_da_el_mismo_ancho_para_anchas_y_angostas() {
22    let mut ts = Typesetter::new();
23    let m = ancho(&mut ts, "MMMMMMMMMM", Some(MONOSPACE));
24    let i = ancho(&mut ts, "iiiiiiiiii", Some(MONOSPACE));
25    println!("mono  M×10={m:.2}  i×10={i:.2}");
26    assert!(
27        (m - i).abs() < 0.5,
28        "la familia mono no da ancho fijo: M×10={m:.2} vs i×10={i:.2}"
29    );
30}
31
32#[test]
33fn la_proporcional_si_difiere_el_test_anterior_no_es_trivial() {
34    let mut ts = Typesetter::new();
35    let m = ancho(&mut ts, "MMMMMMMMMM", None);
36    let i = ancho(&mut ts, "iiiiiiiiii", None);
37    println!("sans  M×10={m:.2}  i×10={i:.2}");
38    assert!((m - i).abs() > 2.0, "la sans mide igual: el test de mono no prueba nada");
39}
40
41/// El agujero real: `layout_runs` (texto con color por tramos) no recibía
42/// familia, así que shapeaba con la sans aunque la vista pidiera `.mono()`.
43/// Nada compilaba mal — la consola simplemente salía torcida.
44#[test]
45fn el_camino_multicolor_respeta_la_familia_mono() {
46    use llimphi_text::Alignment;
47    let mut ts = Typesetter::new();
48    let tramos = |t: &str| -> Vec<(usize, usize, Color)> { vec![(0, t.len(), Color::WHITE)] };
49    let mut medir = |t: &str| {
50        ts.layout_runs(t, 12.0, Color::WHITE, &tramos(t), Alignment::Start, 1.2, 400.0, false, false, Some(MONOSPACE))
51            .width()
52    };
53    let m = medir("MMMMMMMMMM");
54    let i = medir("iiiiiiiiii");
55    println!("runs  M×10={m:.2}  i×10={i:.2}");
56    assert!(
57        (m - i).abs() < 0.5,
58        "el texto con tramos de color perdió el ancho fijo: M×10={m:.2} vs i×10={i:.2}"
59    );
60}
61
62#[test]
63fn los_caracteres_de_caja_no_se_caen_a_otra_fuente() {
64    // Si Liberation Mono no tiene el glifo, parley busca en el fallback y ese
65    // no es mono: la tabla se tuerce justo donde más se nota.
66    let mut ts = Typesetter::new();
67    let ascii = ancho(&mut ts, "++++++++++", Some(MONOSPACE));
68    let caja = ancho(&mut ts, "┌┬┐├┼┤└┴┘─", Some(MONOSPACE));
69    println!("mono  +×10={ascii:.2}  caja×10={caja:.2}");
70    assert!(
71        (ascii - caja).abs() < 0.5,
72        "los caracteres de caja no salen en la mono: +×10={ascii:.2} vs caja×10={caja:.2}"
73    );
74}