pub struct Typesetter { /* private fields */ }Expand description
The main entry point for text typesetting.
Owns the font registry, glyph atlas, layout cache, and render state. The typical usage pattern is:
- Create with
Typesetter::new - Register fonts with
register_font - Set default font with
set_default_font - Set viewport with
set_viewport - Lay out content with
layout_fullorlayout_blocks - Set cursor state with
set_cursor - Render with
renderto get aRenderFrame - On edits, use
relayout_blockfor incremental updates
§Thread safety
Typesetter is !Send + !Sync because its internal fontdb, atlas allocator,
and swash scale context are not thread-safe. It lives on the adapter’s render
thread alongside the framework’s drawing calls.
Implementations§
Source§impl Typesetter
impl Typesetter
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new typesetter with no fonts loaded.
Call register_font and set_default_font
before laying out any content.
Sourcepub fn register_font(&mut self, data: &[u8]) -> FontFaceId
pub fn register_font(&mut self, data: &[u8]) -> FontFaceId
Register a font face from raw TTF/OTF/WOFF bytes.
Parses the font’s name table to extract family, weight, and style,
then indexes it for CSS-spec font matching via fontdb.
Returns the first face ID (font collections like .ttc may contain multiple faces).
§Panics
Panics if the font data contains no parseable faces.
Sourcepub fn register_font_as(
&mut self,
data: &[u8],
family: &str,
weight: u16,
italic: bool,
) -> FontFaceId
pub fn register_font_as( &mut self, data: &[u8], family: &str, weight: u16, italic: bool, ) -> FontFaceId
Register a font with explicit metadata, overriding the font’s name table.
Use when the font’s internal metadata is unreliable or when aliasing a font to a different family name.
§Panics
Panics if the font data contains no parseable faces.
Sourcepub fn set_default_font(&mut self, face: FontFaceId, size_px: f32)
pub fn set_default_font(&mut self, face: FontFaceId, size_px: f32)
Set which font face to use as the document default.
This is the fallback font when a fragment’s TextFormat doesn’t specify
a family or the specified family isn’t found.
Sourcepub fn set_generic_family(&mut self, generic: &str, family: &str)
pub fn set_generic_family(&mut self, generic: &str, family: &str)
Map a generic family name to a registered font family.
Common mappings: "serif" → "Noto Serif", "monospace" → "Fira Code".
When text-document specifies font_family: "monospace", the typesetter
resolves it through this mapping before querying fontdb.
Sourcepub fn font_family_name(&self, face_id: FontFaceId) -> Option<String>
pub fn font_family_name(&self, face_id: FontFaceId) -> Option<String>
Look up the family name of a registered font by its face ID.
Sourcepub fn font_registry(&self) -> &FontRegistry
pub fn font_registry(&self) -> &FontRegistry
Access the font registry for advanced queries (glyph coverage, fallback, etc.).
Sourcepub fn set_viewport(&mut self, width: f32, height: f32)
pub fn set_viewport(&mut self, width: f32, height: f32)
Set the viewport dimensions (visible area in pixels).
The viewport controls:
- Culling: only blocks within the viewport are rendered.
- Selection highlight: multi-line selections extend to viewport width.
- Layout width (in
ContentWidthMode::Auto): text wraps at viewport width.
Call this when the window or container resizes.
Sourcepub fn set_content_width(&mut self, width: f32)
pub fn set_content_width(&mut self, width: f32)
Set a fixed content width, independent of viewport.
Text wraps at this width regardless of how wide the viewport is.
Use for page-like (WYSIWYG) layout or documents with explicit width.
Pass f32::INFINITY for no-wrap mode.
Sourcepub fn set_content_width_auto(&mut self)
pub fn set_content_width_auto(&mut self)
Set content width to follow viewport width (default).
Text reflows when the viewport is resized. This is the standard behavior for editors 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).
Sourcepub fn set_scroll_offset(&mut self, offset: f32)
pub fn set_scroll_offset(&mut self, offset: f32)
Set the vertical scroll offset in pixels from the top of the document.
Affects which blocks are visible (culling) and the screen-space
y coordinates in the rendered RenderFrame.
Sourcepub fn content_height(&self) -> f32
pub fn content_height(&self) -> f32
Total content height after layout, in pixels.
Use for scrollbar range: scrollbar.max = content_height - viewport_height.
Sourcepub fn max_content_width(&self) -> f32
pub fn max_content_width(&self) -> f32
Maximum content width across all laid-out lines, in pixels.
Use for horizontal scrollbar range when text wrapping is disabled. Returns 0.0 if no blocks have been laid out.
Sourcepub fn set_zoom(&mut self, zoom: f32)
pub fn set_zoom(&mut self, zoom: f32)
Set the display zoom level.
Zoom is a pure display transform: layout stays at base size, and all screen-space output (glyph quads, decorations, caret rects) is scaled by the zoom factor. Hit-test input coordinates are inversely scaled.
This is PDF-viewer-style zoom (no text reflow). 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 set_scale_factor(&mut self, scale_factor: f32)
pub fn set_scale_factor(&mut self, scale_factor: f32)
Set the device pixel ratio for HiDPI rasterization.
Layout stays in logical pixels, but glyphs are shaped and rasterized
at size_px * scale_factor so text is sharp on HiDPI displays.
This is orthogonal to set_zoom, which is a pure
display transform applied after rendering.
Changing this value invalidates cached layout and cached glyphs:
the flow layout is cleared, the glyph cache is emptied, and the
atlas is reset. After calling this, re-run layout_blocks /
layout_full and then render().
Clamped to 0.25..=8.0. Default is 1.0.
Sourcepub fn scale_factor(&self) -> f32
pub fn scale_factor(&self) -> f32
The current scale factor (device pixel ratio). Default is 1.0.
Sourcepub fn layout_full(&mut self, flow: &FlowSnapshot)
pub fn layout_full(&mut self, flow: &FlowSnapshot)
Full layout from a text-document FlowSnapshot.
Converts all snapshot elements (blocks, tables, frames) to internal
layout params and lays out the entire document flow. Call this on
DocumentReset events or initial document load.
For incremental updates after small edits, prefer relayout_block.
Sourcepub fn layout_blocks(&mut self, block_params: Vec<BlockLayoutParams>)
pub fn layout_blocks(&mut self, block_params: Vec<BlockLayoutParams>)
Lay out a list of blocks from scratch (framework-agnostic API).
Replaces all existing layout state with the given blocks.
This is the non-text-document equivalent of layout_full.
the caller converts snapshot types to BlockLayoutParams.
Sourcepub fn add_frame(&mut self, params: &FrameLayoutParams)
pub fn add_frame(&mut self, params: &FrameLayoutParams)
Add a frame to the current flow layout.
The frame is placed after all previously laid-out content.
Frame position (inline, float, absolute) is determined by
FrameLayoutParams::position.
Sourcepub fn add_table(&mut self, params: &TableLayoutParams)
pub fn add_table(&mut self, params: &TableLayoutParams)
Add a table to the current flow layout.
The table is placed after all previously laid-out content.
Sourcepub fn relayout_block(&mut self, params: &BlockLayoutParams)
pub fn relayout_block(&mut self, params: &BlockLayoutParams)
Relayout a single block after its content or formatting changed.
Re-shapes and re-wraps the block, then shifts subsequent blocks
if the height changed. Much cheaper than layout_full
for single-block edits (typing, formatting changes).
If the block is inside a table cell (BlockSnapshot::table_cell is Some),
the table row height is re-measured and content below the table shifts.
Sourcepub fn render(&mut self) -> &RenderFrame
pub fn render(&mut self) -> &RenderFrame
Render the visible viewport and return everything needed to draw.
Performs viewport culling (only processes blocks within the scroll window), rasterizes any new glyphs into the atlas, and produces glyph quads, image placeholders, and decoration rectangles.
The returned reference borrows the Typesetter. The adapter should iterate
the frame for drawing, then drop the reference before calling any
layout/scroll methods on the next frame.
On each call, stale glyphs (unused for ~120 frames) are evicted from the atlas to reclaim space.
Sourcepub fn render_block_only(&mut self, block_id: usize) -> &RenderFrame
pub fn render_block_only(&mut self, 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(). Use after relayout_block() when only one
block’s text changed.
If the block’s height changed (causing subsequent blocks to shift),
this falls back to a full render() since cached glyph positions
for other blocks would be stale.
Sourcepub fn render_cursor_only(&mut self) -> &RenderFrame
pub fn render_cursor_only(&mut self) -> &RenderFrame
Lightweight render that only updates cursor/selection decorations.
Reuses the existing glyph quads and images from the last full render().
Use this when only the cursor blinked or selection changed, not the text.
If the scroll offset changed since the last full render, falls back to
a full render so that glyph positions are updated.
Sourcepub fn atlas_snapshot(
&mut self,
advance_generation: bool,
) -> (bool, u32, u32, &[u8], bool)
pub fn atlas_snapshot( &mut self, advance_generation: bool, ) -> (bool, u32, u32, &[u8], bool)
Read the glyph atlas state without triggering the full document render pipeline. Advances the cache generation and runs eviction (to reclaim atlas space), but does NOT re-render document content.
Returns (dirty, width, height, pixels, glyphs_evicted).
When glyphs_evicted is true, callers that cache glyph output
(e.g. paint caches) must invalidate — evicted atlas space may be
reused by future glyph allocations.
Sourcepub fn layout_single_line(
&mut self,
text: &str,
format: &TextFormat,
max_width: Option<f32>,
) -> SingleLineResult
pub fn layout_single_line( &mut self, text: &str, format: &TextFormat, max_width: Option<f32>, ) -> SingleLineResult
Lay out a single line of text and return GPU-ready glyph quads.
This is the fast path for simple labels, tooltips, overlays, and other single-line text that does not need the full document layout pipeline.
What it does:
- Resolves the font from
format(family, weight, italic, size). - Shapes the text with rustybuzz (including glyph fallback).
- Rasterizes glyphs into the atlas (same path as the full pipeline).
- If
max_widthis provided and the text exceeds it, truncates with an ellipsis character.
What it skips:
- Line breaking (there is only one line).
- Bidi analysis (assumes a single direction run).
- Flow layout, margins, indents, block stacking.
Glyph quads are positioned with the top-left at (0, 0).
Sourcepub fn layout_paragraph(
&mut self,
text: &str,
format: &TextFormat,
max_width: f32,
max_lines: Option<usize>,
) -> ParagraphResult
pub fn layout_paragraph( &mut self, text: &str, format: &TextFormat, max_width: f32, max_lines: Option<usize>, ) -> ParagraphResult
Lay out a multi-line paragraph by wrapping text at max_width.
This is the multi-line counterpart to layout_single_line. It shapes
the input text, breaks it into lines 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 — any
remaining lines are silently dropped. (A future extension may insert a
trailing ellipsis on the last emitted line; this is currently plain
truncation.)
The caller is responsible for offsetting the returned glyph quads by the paragraph’s screen position.
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 accounted for internally.
Returns None if the flow has no content.
Sourcepub fn caret_rect(&self, position: usize) -> [f32; 4]
pub fn caret_rect(&self, position: usize) -> [f32; 4]
Get the screen-space caret rectangle at a document position.
Returns [x, y, width, height] in screen pixels. Use this to report
the caret position to the platform IME system for composition window
placement. For drawing the caret, use the crate::DecorationKind::Cursor
entry in crate::RenderFrame::decorations instead.
Sourcepub fn set_cursor(&mut self, cursor: &CursorDisplay)
pub fn set_cursor(&mut self, cursor: &CursorDisplay)
Update the cursor display state for a single cursor.
The adapter reads position and anchor from text-document’s
TextCursor, toggles visible on a blink timer, and passes
the result here. The typesetter includes cursor and selection
decorations in the next render call.
Sourcepub fn set_cursors(&mut self, cursors: &[CursorDisplay])
pub fn set_cursors(&mut self, cursors: &[CursorDisplay])
Update multiple cursors (multi-cursor editing support).
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], 0.0-1.0).
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 cursor caret color ([r, g, b, a], 0.0-1.0).
Default: [0.0, 0.0, 0.0, 1.0] (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], 0.0-1.0).
This color is used for glyphs and decorations (underline, strikeout, overline)
when no per-fragment foreground_color is set.
Default: [0.0, 0.0, 0.0, 1.0] (black).
Sourcepub fn block_visual_info(&self, block_id: usize) -> Option<BlockVisualInfo>
pub fn block_visual_info(&self, block_id: usize) -> Option<BlockVisualInfo>
Get the visual position and height of a laid-out block.
Returns None if the 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
Check whether a block belongs to a table cell.
Returns true if block_id is found in any table cell layout,
false if it is a top-level or frame block (or unknown).
Sourcepub fn scroll_to_position(&mut self, position: usize) -> f32
pub fn scroll_to_position(&mut self, position: usize) -> f32
Scroll so that the given document position is visible, placing it roughly 1/3 from the top of the viewport.
Returns the new scroll 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 cursor movement (arrow keys, click, typing) to keep
the caret in view. Returns Some(new_offset) if scrolling occurred,
or None if the caret was already visible.