alonso.torres 991a93aa98 ✨ Render Japanese text layouts in WASM
Lay out horizontal and vertical Japanese text with kinsoku, ruby,
emphasis, warichu, tate-chu-yoko and proportional font features.
Carry the layout through glyph paths, SVG export and text selection.

Update the Rust and ClojureScript binary formats together, including
the editor bridge and headless exporter. Resolve CJK fallback fonts
and add renderer tests and font fixtures.
2026-11-12 00:47:09 +01:00

56 lines
2.2 KiB
Rust

// Vertical (tategaki) text layout: columns flow top->bottom and advance
// right->left. Skia's skparagraph has no vertical writing mode, so this
// module owns the whole vertical pipeline:
//
// segment spans by glyph orientation (`orientation`) -> shape each segment
// with SkShaper, OpenType `vert`/`vrt2` for upright runs (`shaping`) ->
// derive cells: one per upright glyph cluster, one per rotated run, one per
// composite (`cells`) -> JLREQ spacing and kinsoku-aware column breaks
// (`flow`) -> place columns and annotations (`layout`, `annotations`) ->
// paint / outline export (`paint`) and position data / hit-testing
// (`positions`) from the cells.
//
// Offsets: cells use UTF-16 offsets in transformed layout text. Position
// data maps those ranges back to the original span text before it crosses
// the WASM boundary; the WORD JOINER OffsetMap applies only to
// skparagraph-driven horizontal breaks.
//
// Layouts are computed on demand, as the horizontal path rebuilds its
// skparagraph objects per paint; only per-typeface font tables are cached.
//
// Text-align aligns each column's glyphs along the vertical (inline) axis:
// Left/Start->top, Center->middle, Right/End->bottom of the wrap budget.
// Justify stretches every column but the last to fill the wrap budget.
//
// Letter-spacing adds advance along the column once per upright cluster
// and once per glyph inside a rotated run, matching the horizontal
// `letter-spacing` that Skia applies to each glyph advance.
//
// Not supported yet: PDF/vector emoji overlays and inner shadows.
mod annotations;
mod cells;
mod flow;
mod font_tables;
mod layout;
mod orientation;
mod paint;
mod positions;
mod shaping;
#[cfg(test)]
pub(crate) mod test_support;
pub use layout::{block_axis_offset, layout_for_rect, VerticalLayout};
pub(crate) use orientation::{is_emoji_char, is_upright_char};
pub use paint::{
paint_drop_shadow, paint_grid, paint_layout, paint_stroke, paint_text_vertical,
paint_text_vertical_with, vertical_text_paths, GlyphOutput,
};
pub use positions::{
caret_from_point, caret_rect, intersects, position_data, range_rects, DIRECTION_EMPHASIS_MARK,
};
pub(crate) use shaping::{
shape_segment_with_fallbacks, single_glyph_blob, span_font_families, ShapedRun,
};