aura-gui 0.3.5

UI nativa acelerada por GPU para escritorio, Android e iOS, en un solo crate: estilo tipo Tailwind, componentes, sombras, animaciones y agentes de IA. Reposo a cero. Licencia AGPL-3.0 o comercial.
//! Sonda visual temporal: compara texto a 1× y 2× con la misma escena.
use aura_ui::core::{Bounds, Point, Size, px};
use aura_ui::gpu::cpu::CpuRenderer;
use aura_ui::gpu::text::TextPlacement;
use aura_ui::gpu::{Quad, Scene, TextStyle, TextSystem, TextTraits};
use aura_ui::view::theme::Theme;

const SAMPLES: [(&str, f32, u16); 5] = [
    ("Conversaciones — Buscar conversaciones", 13.0, 400),
    ("Conversaciones — Buscar conversaciones", 13.0, 500),
    ("Conversaciones — Buscar conversaciones", 14.0, 400),
    ("La UI en Windows se ve más fina: 0123456789 ñandú", 14.0, 400),
    ("fn find_rc_exe() -> Option<PathBuf> {", 14.0, 400),
];

fn render(scale: f32, path: &str) {
    let (w, h) = (640.0, 260.0);
    let (fw, fh) = ((w * scale) as u32, (h * scale) as u32);
    let theme = Theme::light();
    let mut scene = Scene::default();
    let clip = Bounds::new(Point::new(px(0.0), px(0.0)), Size::new(px(w), px(h)));
    scene.insert_quad(Quad::new(clip, clip, theme.canvas));
    let mut renderer = CpuRenderer::new(None, fw, fh);
    let mut text = TextSystem::new();
    let mut y = 24.0;
    for (label, size, weight) in SAMPLES {
        let style = TextStyle {
            font_size: size,
            line_height: 24.0,
            monospace: label.starts_with("fn "),
            family: None,
            max_width: None,
            traits: TextTraits { weight, ..Default::default() },
        };
        let shaped = text.shape(label, &style);
        let placement = TextPlacement { origin: Point::new(px(20.0), px(y)), color: theme.text, clip, scale };
        text.paint(&shaped, &placement, &mut renderer.glyph_target(), &mut scene);
        y += 42.0;
    }
    let frame = renderer.capture(&scene, scale, theme.canvas);
    let mut encoder = png::Encoder::new(std::fs::File::create(path).unwrap(), frame.width, frame.height);
    encoder.set_color(png::ColorType::Rgba);
    encoder.set_depth(png::BitDepth::Eight);
    encoder.write_header().unwrap().write_image_data(&frame.rgba).unwrap();
}

fn main() {
    render(1.0, "target/text_probe_1x.png");
    render(2.0, "target/text_probe_2x.png");
}