refresh: stack al día (vello 0.7 / wgpu 27 / parley 0.6) + motor 3D voxel

Re-sincroniza las fuentes desde el monorepo (estaba en vello 0.5/wgpu 24 y con la
estructura vieja de eventloop) y suma el 3D:

- bump del workspace a vello 0.7 / wgpu 27 / parley 0.6, + accesskit 0.24 /
  accesskit_winit 0.33 / vello_hybrid 0.0.9.
- nuevos crates: llimphi-3d (voxels ray-march + mallas en un depth compartido,
  montable dentro de un View 2D vía set_viewport+scissor) y llimphi-voxel
  (world-gen, personajes, director de escenas) + shared/foreign-vox (puente .vox).
- README: sección "Not just 2D — a 3D voxel engine" + GIF (docs/llimphi_voxel.gif).
- excluido modules/allichay (arrastra deps fuera del alcance del front-door).
- cargo check --workspace: verde.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sergio
2026-06-18 14:40:00 +00:00
parent e74800d9da
commit ccab39f140
202 changed files with 44034 additions and 1811 deletions
+111
View File
@@ -57,6 +57,53 @@ fn parrafo_largo_reserva_varias_lineas() {
assert!(rect.w <= 200.0 + 1.0, "no debería exceder el ancho del bloque");
}
#[test]
fn no_wrap_mide_una_sola_linea_fase_7_1253() {
use llimphi_layout::taffy::AvailableSpace;
// Mismo texto largo, mismo ancho disponible (angosto): con `no_wrap` se
// mide en una sola línea (ancho completo, ignora el available); sin él,
// envuelve (más alto, ancho acotado al disponible).
let texto = "una linea larga que normalmente envuelve en varios renglones \
cuando el ancho disponible es angosto de verdad";
let mk = |no_wrap: bool| llimphi_compositor::TextMeasure {
content: texto.to_string(),
size_px: 16.0,
alignment: llimphi_text::Alignment::Start,
italic: false,
font_family: None,
line_height: 1.2,
weight: 400.0,
max_lines: None,
ellipsis: false,
underline: false,
strikethrough: false,
spans: None,
letter_spacing: 0.0,
word_spacing: 0.0,
no_wrap,
overflow_wrap: false,
};
let mut ts = llimphi_text::Typesetter::new();
let known = TSize { width: None, height: None };
let avail = TSize {
width: AvailableSpace::Definite(160.0),
height: AvailableSpace::MaxContent,
};
let env = measure_text_node(&mut ts, &mk(false), known, avail);
let nw = measure_text_node(&mut ts, &mk(true), known, avail);
// Envuelto: ancho acotado al disponible y alto de varias líneas.
assert!(env.width <= 160.0 + 1.0, "wrap acota el ancho: {}", env.width);
assert!(env.height > 40.0, "wrap reserva varias líneas: {}", env.height);
// no_wrap: una sola línea → mucho más ancho que el disponible y bajo.
assert!(nw.width > 160.0, "no_wrap mide ancho completo: {}", nw.width);
assert!(
nw.height < env.height,
"no_wrap es una línea (más bajo que el envuelto): nw={} env={}",
nw.height,
env.height
);
}
#[test]
fn line_height_mayor_reserva_mas_alto() {
let texto = "una línea de texto que envuelve en dos o tres renglones según \
@@ -70,6 +117,16 @@ fn line_height_mayor_reserva_mas_alto() {
italic: false,
font_family: None,
line_height: lh,
weight: 400.0,
max_lines: None,
ellipsis: false,
underline: false,
strikethrough: false,
spans: None,
letter_spacing: 0.0,
word_spacing: 0.0,
no_wrap: false,
overflow_wrap: false,
};
let known = TSize { width: Some(180.0_f32), height: None };
let avail = TSize {
@@ -85,3 +142,57 @@ fn line_height_mayor_reserva_mas_alto() {
"line-height: 2 debería reservar bastante más alto que 1.0 (got {compacto} vs {comodo})"
);
}
#[test]
fn overflow_wrap_parte_la_palabra_larga_fase_7_1254() {
use llimphi_layout::taffy::AvailableSpace;
// Una sola palabra sin espacios, más ancha que la caja angosta. Sin
// `overflow-wrap` parley la deja desbordar (mide más ancho que la caja);
// con `overflow-wrap` la parte para que entre (ancho acotado, varias líneas
// ⇒ más alto). Es el regresor directo de la Fase 7.1254.
let palabrota = "supercalifragilisticoexpialidosoineluctableantidisestablishmentariano";
let mk = |overflow_wrap: bool| llimphi_compositor::TextMeasure {
content: palabrota.to_string(),
size_px: 16.0,
alignment: llimphi_text::Alignment::Start,
italic: false,
font_family: None,
line_height: 1.2,
weight: 400.0,
max_lines: None,
ellipsis: false,
underline: false,
strikethrough: false,
spans: None,
letter_spacing: 0.0,
word_spacing: 0.0,
no_wrap: false,
overflow_wrap,
};
let mut ts = llimphi_text::Typesetter::new();
let known = TSize { width: None, height: None };
let avail = TSize {
width: AvailableSpace::Definite(80.0),
height: AvailableSpace::MaxContent,
};
let normal = measure_text_node(&mut ts, &mk(false), known, avail);
let roto = measure_text_node(&mut ts, &mk(true), known, avail);
// Sin overflow-wrap: la palabra desborda → ancho mayor que la caja.
assert!(
normal.width > 80.0,
"sin overflow-wrap la palabra desborda: {}",
normal.width
);
// Con overflow-wrap: se parte → ancho acotado a la caja y más alto.
assert!(
roto.width <= 80.0 + 1.0,
"overflow-wrap acota el ancho a la caja: {}",
roto.width
);
assert!(
roto.height > normal.height,
"overflow-wrap parte en varias líneas (más alto): roto={} normal={}",
roto.height,
normal.height
);
}