ferroui-pretext-layout 0.4.0

Platform-neutral wrap metrics and obstacle-aware column flow for prepared text
Documentation
  • Coverage
  • 22.58%
    7 out of 31 items documented0 out of 0 items with examples
  • Size
  • Source code size: 61.6 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 471.1 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 7s Average build duration of successful builds.
  • all releases: 7s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • wieslawsoltes/FerroUI
    190 14 19
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • wieslawsoltes

FerroUI Pretext Layout

Platform-neutral sizing and obstacle-aware flow for prepared text. Preparation and text measurement come from ferroui-pretext; this crate adds no renderer, native backend, thread, clock or file dependency.

APIs

API Purpose
PreparedTextMetrics::measure_max_line_width Measure genuinely unwrapped text, honoring preserved hard breaks.
PreparedTextMetrics::collect_wrap_metrics Measure count, height and widest painted line without materializing strings.
PreparedTextMetrics::find_tight_wrap_metrics Find the smallest integral width without increasing the original line count.
ObstacleLayoutHelper::carve_text_line_slots Subtract overlapping intervals from an available horizontal line slot.
ObstacleLayoutHelper::circle_interval_for_band Compute circle exclusion over an entire text band.
ObstacleLayoutHelper::ellipse_interval_for_band Compute ellipse exclusion with independent radii and padding.
ObstacleLayoutHelper::get_rect_intervals_for_band Select rectangle exclusions intersecting a text band.
ObstacleLayoutHelper::pick_slot Select the widest slot, with an explicit tie direction.
ColumnFlowLayout::layout_into_columns Flow text through ordered rectangular columns around rectangles and circles.

Coordinates and widths use the configured measurer's units. Circle x and y are its center. Band boundaries are half open: tangent obstacles do not block a row. Column flow uses one widest slot on each row; remaining text beyond the last column is not materialized.

use std::rc::Rc;
use ferroui_pretext::{DelegateTextMeasurerFactory, PrepareOptions, PretextLayout};
use ferroui_pretext_layout::{ColumnFlowLayout, RectObstacle};

# fn main() -> Result<(), Box<dyn std::error::Error>> {
// Use the native FerroUI adapter in a real application. This deterministic
// measurer keeps the example independent of installed fonts.
let engine = PretextLayout::new(Rc::new(DelegateTextMeasurerFactory::new(
    |text: &str, _: &str| text.chars().count() as f64 * 8.0,
)));
let prepared = engine.prepare_with_segments(
    "Prepare once and flow across multiple columns.",
    "16px Inter",
    PrepareOptions::default(),
)?;
let columns = [
    RectObstacle { x: 0.0, y: 0.0, width: 160.0, height: 40.0 },
    RectObstacle { x: 180.0, y: 0.0, width: 160.0, height: 40.0 },
];
let lines = ColumnFlowLayout::layout_into_columns(
    &prepared, &columns, &[], &[], 20.0, 20.0,
)?;
for line in lines {
    println!("{} at ({}, {})", line.text, line.x, line.y);
}
# Ok(())
# }

Source mapping and deliberate corrections

All four source files from Pretext.Layout are mapped one to one:

Source Rust
LayoutPrimitives.cs layout_primitives.rs
PreparedTextMetrics.cs prepared_text_metrics.rs
ObstacleLayoutHelper.cs obstacle_layout_helper.rs
ColumnFlowLayout.cs column_flow_layout.rs

The source's IsExternalInit.cs polyfill is unnecessary in Rust. C# optional parameters are explicit Rust arguments. Plain data records have public fields and derived value equality; stateless classes retain associated functions.

This port corrects the following observed source defects:

  • No-fitting-slot selection returns None. The source's value-type FirstOrDefault() produced (0, 0) and consumed text in blocked rows.
  • Circle exclusion in column flow uses the entire row band, rather than its midpoint, so glyph rectangles do not overlap a circle near a row edge.
  • Maximum line width uses infinity rather than a magic 100_000 width.
  • Empty slot selection returns None rather than indexing an absent element.
  • Column flow rejects nonpositive/nonfinite line heights, invalid geometry and coordinates that cannot advance to another finite row. Tight-wrap search rejects invalid widths and bounds the search to exactly representable f64 integers. Both return LayoutError instead of looping indefinitely.
  • Columns with no possible slot (zero width, narrower than the minimum slot, too short, or completely covered by one rectangle) are skipped immediately, avoiding a row-by-row scan for tiny positive line heights.
  • Geometry helpers ignore degenerate/nonfinite blocked intervals, return no intersection for invalid shapes, and reject invalid base slots and padding.

See docs/porting/pretext.md in the repository for the complete port report. The upstream MIT notice is included in NOTICE.md.