//! Text shaping + glyph atlas — piece 3 of the Stage-8 in-game UI system.
//!
//! Three sub-modules cooperate:
//!
//! - [`font`] wraps `ab_glyph::FontVec` behind an engine-owned [`Font`] /
//!   [`FontStore`] surface so consumers never see the font crate directly.
//!   Adds descriptor-based lookup keyed by the piece-2
//!   [`FontRef`](super::visual::FontRef), so a theme's `font: Some(...)`
//!   resolves to a [`FontId`] the shaper can use.
//! - [`atlas`] packs rasterized glyphs into one R8 alpha texture via a
//!   shelf packer and caches them by [`GlyphKey`]. The atlas **is** the
//!   cache — the chosen library never re-rasterizes a glyph that's already
//!   been packed, which is why this stage's choice between ab_glyph and
//!   fontdue is a one-time-startup decision, not a per-frame one.
//! - [`shape`] turns a sequence of [`TextRun`]s into positioned
//!   [`ShapedGlyph`]s with line wrapping, alignment, multi-font runs, and
//!   DPI scaling. Pure CPU; never touches the atlas. The renderer
//!   (piece 4) walks the [`ShapedText`] output and queries the atlas per
//!   glyph to emit textured quads.
//!
//! # End-to-end shape → atlas
//!
//! ```no_run
//! use oxide_engine::ui::text::{
//!     shape, FontStore, GlyphAtlas, ShapeParams, ShapedText, TextStyle,
//! };
//! # use oxide_engine::ui::text::Font;
//! # fn load_font() -> Font { todo!() }
//!
//! let mut fonts = FontStore::new();
//! let id = fonts.insert(load_font());
//! let style = TextStyle { font: id, size_px: 16.0 };
//! let shaped: ShapedText = shape("Hello world", style, &ShapeParams::default(), &fonts);
//!
//! let mut atlas = GlyphAtlas::new(1024, 1024);
//! for line in &shaped.lines {
//!     for glyph in &line.glyphs {
//!         // get_or_rasterize returns None for glyphs with no outline (e.g.
//!         // the space character). Real renderers skip emitting a quad.
//!         if let Some(entry) = atlas.get_or_rasterize(glyph.key, &fonts) {
//!             let _quad_top_left = glyph.position + entry.bearing;
//!             let _quad_size = entry.size_px;
//!         }
//!     }
//! }
//! ```

pub mod atlas;
pub mod font;
pub mod shape;

pub use atlas::{AtlasEntry, GlyphAtlas, GlyphKey};
pub use font::{
    common_system_font_paths, Font, FontError, FontId, FontLoader, FontStore, GlyphId,
    RasterizedGlyph,
};
pub use shape::{
    shape, shape_runs, ShapeParams, ShapedGlyph, ShapedLine, ShapedText, TextAlign, TextRun,
    TextStyle,
};
