pub struct DocumentFlow { /* private fields */ }Expand description
Per-widget document flow state.
See the module docs for the shape of the split and for
lifecycle examples. Every layout/render method here takes a
TextFontService reference so flows can share one atlas across
an entire window.
Implementations§
Source§impl DocumentFlow
impl DocumentFlow
Sourcepub fn new() -> Self
pub fn new() -> Self
Create an empty flow with no content.
After construction the caller typically calls
set_viewport and one of the
layout_* methods before the first render.
Sourcepub fn set_viewport(&mut self, width: f32, height: f32)
pub fn set_viewport(&mut self, width: f32, height: f32)
Set the visible area dimensions in logical pixels.
The viewport controls:
- Culling: only blocks within the viewport are rendered.
- Selection highlight: multi-line selection extends to the viewport width.
- Layout width (in
ContentWidthMode::Auto): text wraps atviewport_width / zoom.
Call this when the widget’s container resizes. A resize by
itself does not relayout — re-run layout_full /
layout_blocks if the wrap width changed.
Sourcepub fn viewport_width(&self) -> f32
pub fn viewport_width(&self) -> f32
Current viewport width in logical pixels.
Sourcepub fn viewport_height(&self) -> f32
pub fn viewport_height(&self) -> f32
Current viewport height in logical pixels.
Sourcepub fn set_content_width(&mut self, width: f32)
pub fn set_content_width(&mut self, width: f32)
Pin content width at a fixed value, independent of viewport.
Text wraps at this width regardless of how wide the viewport
is. Use for page-like (WYSIWYG) layout or documents with an
explicit column width. Pass f32::INFINITY for no-wrap mode.
Sourcepub fn set_content_width_auto(&mut self)
pub fn set_content_width_auto(&mut self)
Reflow content width to follow the viewport (the default).
Text re-wraps on every viewport resize. Standard editor and web-style layout.
Sourcepub fn layout_width(&self) -> f32
pub fn layout_width(&self) -> f32
The effective width used for text layout (line wrapping, table columns, etc.).
In ContentWidthMode::Auto, equals viewport_width / zoom
so that text reflows to fit the zoomed viewport. In
ContentWidthMode::Fixed, equals the set value (zoom only
magnifies the rendered output).
Sourcepub fn content_width_mode(&self) -> ContentWidthMode
pub fn content_width_mode(&self) -> ContentWidthMode
The currently configured content-width mode.
Sourcepub fn set_scroll_offset(&mut self, offset: f32)
pub fn set_scroll_offset(&mut self, offset: f32)
Set the vertical scroll offset in logical pixels from the
top of the document. Affects culling and screen-space y
coordinates in the rendered frame.
Sourcepub fn scroll_offset(&self) -> f32
pub fn scroll_offset(&self) -> f32
Current vertical scroll offset.
Sourcepub fn content_height(&self) -> f32
pub fn content_height(&self) -> f32
Total content height after layout, in logical pixels.
Sourcepub fn max_content_width(&self) -> f32
pub fn max_content_width(&self) -> f32
Maximum content width across all laid-out lines, in logical pixels. Used for horizontal scrollbar range when wrapping is disabled.
Sourcepub fn set_zoom(&mut self, zoom: f32)
pub fn set_zoom(&mut self, zoom: f32)
Set the display zoom level (PDF-style, no reflow).
Zoom is a pure display transform: layout stays at base size and all screen-space output (glyph quads, decorations, caret rects) is scaled by this factor. Hit-test inputs are inversely scaled.
For browser-style zoom that reflows text, combine with
set_content_width(viewport_width / zoom).
Clamped to 0.1..=10.0. Default is 1.0.
Sourcepub fn has_layout(&self) -> bool
pub fn has_layout(&self) -> bool
Whether any layout_* method has run on this flow at least
once. Callers that need to distinguish “never laid out”
from “laid out against a stale scale factor” read this
alongside layout_dirty_for_scale.
Sourcepub fn layout_dirty_for_scale(&self, service: &TextFontService) -> bool
pub fn layout_dirty_for_scale(&self, service: &TextFontService) -> bool
Returns true when the backing TextFontService has had
its HiDPI scale factor changed since this flow was last laid
out, meaning stored shaped advances and cached ppem values
are stale.
Call after every service.set_scale_factor(...) to decide
whether to re-run layout_full / layout_blocks before the
next render. Returns false for flows that have never been
laid out at all (nothing to invalidate).
Sourcepub fn layout_full(&mut self, service: &TextFontService, flow: &FlowSnapshot)
pub fn layout_full(&mut self, service: &TextFontService, flow: &FlowSnapshot)
Full layout from a text-document FlowSnapshot.
Clears any existing flow state and lays out every element
(blocks, tables, frames) from the snapshot in flow order.
Call on document load or DocumentReset. For single-block
edits prefer relayout_block.
Sourcepub fn layout_blocks(
&mut self,
service: &TextFontService,
block_params: Vec<BlockLayoutParams>,
)
pub fn layout_blocks( &mut self, service: &TextFontService, block_params: Vec<BlockLayoutParams>, )
Lay out a list of blocks from scratch.
Framework-agnostic entry point — the caller assembles
BlockLayoutParams directly without going through
text-document. Replaces any existing flow state.
Sourcepub fn add_frame(
&mut self,
service: &TextFontService,
params: &FrameLayoutParams,
)
pub fn add_frame( &mut self, service: &TextFontService, params: &FrameLayoutParams, )
Append a frame to the current flow. The frame’s position
(inline, float, absolute) is carried in params.
Sourcepub fn add_table(
&mut self,
service: &TextFontService,
params: &TableLayoutParams,
)
pub fn add_table( &mut self, service: &TextFontService, params: &TableLayoutParams, )
Append a table to the current flow.
Sourcepub fn relayout_block(
&mut self,
service: &TextFontService,
params: &BlockLayoutParams,
) -> Result<(), RelayoutError>
pub fn relayout_block( &mut self, service: &TextFontService, params: &BlockLayoutParams, ) -> Result<(), RelayoutError>
Relayout a single block after its content or formatting changed.
Re-shapes and re-wraps just that block, then shifts subsequent items if the height changed. Much cheaper than a full layout for single-block edits (typing, format toggles). If the block lives inside a table cell, the row height is re-measured and content below the table shifts.
§Invariants
This is an incremental operation and only makes sense when
a valid layout is already installed on this flow, laid out
against the same HiDPI scale factor the service currently
reports. Violations produce a RelayoutError:
RelayoutError::NoLayoutif nolayout_*method has run on this flow yet — there is nothing to update.RelayoutError::ScaleDirtyif the service’s scale factor has changed since the last layout — reshaping a single block would leave neighbors at the old ppem and produce an inconsistent flow. The caller must re-runlayout_full/layout_blocksfirst.
Both conditions are detected structurally from
has_layout and
layout_dirty_for_scale,
so callers that already guard those don’t need to handle
the error.
Sourcepub fn render(&mut self, service: &mut TextFontService) -> &RenderFrame
pub fn render(&mut self, service: &mut TextFontService) -> &RenderFrame
Render the visible viewport and return the produced frame.
Performs viewport culling, rasterizes any glyphs missing
from the atlas into it, and emits glyph quads, image quads,
and decoration rectangles. The returned reference borrows
both self and service; drop it before the next mutation.
On every call, stale glyphs (unused for ~120 frames) are evicted from the atlas to reclaim slot space.
Sourcepub fn render_block_only(
&mut self,
service: &mut TextFontService,
block_id: usize,
) -> &RenderFrame
pub fn render_block_only( &mut self, service: &mut TextFontService, block_id: usize, ) -> &RenderFrame
Incremental render that only re-renders one block’s glyphs.
Reuses cached glyph / decoration data for all other blocks
from the last full render(). Call after
relayout_block when only one block’s
text changed.
Falls back to a full render if the block’s
height changed (subsequent glyph positions would be stale),
if scroll offset or zoom changed since the last full render,
or if the block lives inside a table / frame (those are
cached with a different key).
Sourcepub fn render_cursor_only(
&mut self,
service: &mut TextFontService,
) -> &RenderFrame
pub fn render_cursor_only( &mut self, service: &mut TextFontService, ) -> &RenderFrame
Lightweight render that only updates cursor/selection decorations.
Reuses the existing glyph quads and images from the last
full render(). Use when only the cursor blinked or the
selection changed. Falls back to a full render
if the scroll offset or zoom changed in the meantime.
Sourcepub fn layout_single_line(
&mut self,
service: &mut TextFontService,
text: &str,
format: &TextFormat,
max_width: Option<f32>,
) -> SingleLineResult
pub fn layout_single_line( &mut self, service: &mut TextFontService, text: &str, format: &TextFormat, max_width: Option<f32>, ) -> SingleLineResult
Lay out a single line of text and return GPU-ready glyph quads. Fast path for labels, tooltips, overlays — anything that doesn’t need the full document pipeline.
If max_width is set and the shaped text exceeds it, the
output is truncated with an ellipsis character. Glyph quads
are positioned with the top-left at (0, 0).
Sourcepub fn layout_paragraph(
&mut self,
service: &mut TextFontService,
text: &str,
format: &TextFormat,
max_width: f32,
max_lines: Option<usize>,
) -> ParagraphResult
pub fn layout_paragraph( &mut self, service: &mut TextFontService, text: &str, format: &TextFormat, max_width: f32, max_lines: Option<usize>, ) -> ParagraphResult
Lay out a multi-line paragraph by wrapping text at max_width.
Multi-line counterpart to
layout_single_line. Shapes the
input, breaks it at Unicode line-break opportunities
(greedy, left-aligned), and rasterizes each line’s glyphs
into paragraph-local coordinates starting at (0, 0).
If max_lines is Some(n), at most n lines are emitted
and any remainder is silently dropped.
Sourcepub fn layout_single_line_markup(
&mut self,
service: &mut TextFontService,
markup: &InlineMarkup,
format: &TextFormat,
max_width: Option<f32>,
) -> SingleLineResult
pub fn layout_single_line_markup( &mut self, service: &mut TextFontService, markup: &InlineMarkup, format: &TextFormat, max_width: Option<f32>, ) -> SingleLineResult
Single-line layout with inline markup. See
layout_single_line for the plain
variant. Accepts parsed [label](url), *italic*, and
**bold** spans and annotates the output with per-span
bounding rectangles for hit-testing.
Sourcepub fn layout_paragraph_markup(
&mut self,
service: &mut TextFontService,
markup: &InlineMarkup,
format: &TextFormat,
max_width: f32,
max_lines: Option<usize>,
) -> ParagraphResult
pub fn layout_paragraph_markup( &mut self, service: &mut TextFontService, markup: &InlineMarkup, format: &TextFormat, max_width: f32, max_lines: Option<usize>, ) -> ParagraphResult
Paragraph layout with inline markup. Multi-line counterpart
to layout_single_line_markup.
Emits a LaidOutSpan for every link segment so the caller
can hit-test against wrapped links.
Sourcepub fn hit_test(&self, x: f32, y: f32) -> Option<HitTestResult>
pub fn hit_test(&self, x: f32, y: f32) -> Option<HitTestResult>
Map a screen-space point to a document position. Coordinates
are relative to the widget’s top-left corner; the scroll
offset is applied internally. Returns None when the flow
has no content.
Sourcepub fn character_geometry(
&self,
block_id: usize,
char_start: usize,
char_end: usize,
) -> Vec<CharacterGeometry>
pub fn character_geometry( &self, block_id: usize, char_start: usize, char_end: usize, ) -> Vec<CharacterGeometry>
Per-character advance geometry within a laid-out block.
Used by accessibility layers that need to expose character
positions to screen readers (AccessKit’s character_positions
/ character_widths on Role::TextRun). char_start and
char_end are block-relative character offsets. Returns one
entry per character in the range, with position measured
in run-local coordinates (the first character sits at 0).
Sourcepub fn caret_rect(&self, position: usize) -> [f32; 4]
pub fn caret_rect(&self, position: usize) -> [f32; 4]
Screen-space caret rectangle at a document position, as
[x, y, width, height]. Feed this to the platform IME for
composition window placement. For drawing the caret itself,
use the DecorationKind::Cursor entry in
RenderFrame::decorations instead.
Sourcepub fn set_cursor(&mut self, cursor: &CursorDisplay)
pub fn set_cursor(&mut self, cursor: &CursorDisplay)
Replace the cursor display with a single cursor.
Sourcepub fn set_cursors(&mut self, cursors: &[CursorDisplay])
pub fn set_cursors(&mut self, cursors: &[CursorDisplay])
Replace the cursor display with multiple cursors (multi-caret editing). Each cursor independently generates a caret and optional selection highlight.
Sourcepub fn set_selection_color(&mut self, color: [f32; 4])
pub fn set_selection_color(&mut self, color: [f32; 4])
Set the selection highlight color [r, g, b, a] in 0..=1
space. Default: [0.26, 0.52, 0.96, 0.3] (translucent blue).
Sourcepub fn set_cursor_color(&mut self, color: [f32; 4])
pub fn set_cursor_color(&mut self, color: [f32; 4])
Set the caret color [r, g, b, a]. Default: black.
Sourcepub fn set_text_color(&mut self, color: [f32; 4])
pub fn set_text_color(&mut self, color: [f32; 4])
Set the default text color [r, g, b, a], used when a
fragment has no explicit foreground_color. Default: black.
Sourcepub fn text_color(&self) -> [f32; 4]
pub fn text_color(&self) -> [f32; 4]
Current default text color.
Sourcepub fn block_visual_info(&self, block_id: usize) -> Option<BlockVisualInfo>
pub fn block_visual_info(&self, block_id: usize) -> Option<BlockVisualInfo>
Visual position and height of a laid-out block. Returns
None if block_id is not in the current layout.
Sourcepub fn is_block_in_table(&self, block_id: usize) -> bool
pub fn is_block_in_table(&self, block_id: usize) -> bool
Whether a block lives inside any table cell.
Sourcepub fn scroll_to_position(&mut self, position: usize) -> f32
pub fn scroll_to_position(&mut self, position: usize) -> f32
Scroll so that position is visible, placing it roughly one
third from the top of the viewport. Returns the new offset.
Sourcepub fn ensure_caret_visible(&mut self) -> Option<f32>
pub fn ensure_caret_visible(&mut self) -> Option<f32>
Scroll the minimum amount needed to make the current caret
visible. Call after arrow-key / click / typing. Returns
Some(new_offset) if the scroll moved, None otherwise.