pub(crate) struct LayoutState {
pub(crate) pages: Vec<Page>,
pub(crate) current_page: Page,
pub(crate) cursor_y: f32,
pub(crate) page_has_content: bool,
pub(crate) diagnostics: Vec<Diagnostic>,
pub(crate) page: PageStyle,
pub(crate) text: TextStyle,
pub(crate) image_handles: Vec<ImageHandle>,
pub(crate) current_left_pt: f32,
pub(crate) pending_marker: Option<PendingMarker>,
pub(crate) pending_labels: Vec<String>,
pub(crate) label_pages: BTreeMap<String, u32>,
}Expand description
Mutable cursor + accumulator threaded through the layout.
Fields§
§pages: Vec<Page>§current_page: PageIn-progress page being filled.
cursor_y: f32Y position of the next baseline, measured from page top.
page_has_content: boolWhether current_page has had any block emitted yet (controls
space_before skipping).
diagnostics: Vec<Diagnostic>§page: PageStyle§text: TextStyle§image_handles: Vec<ImageHandle>Image dedup table: resolved path → handle. Two #image(...)
directives that reference the same on-disk file share one
ImageHandle (and therefore one XObject in the emitted PDF).
current_left_pt: f32Left edge of the current text column. Equals page.margin_pt
at the top level; list layout pushes this rightward so item
text hangs into the gutter under its marker.
pending_marker: Option<PendingMarker>Marker run to emit at the start of the next flushed line. Used
by list items to draw • / 1. in the gutter to the left of
current_left_pt on the first line of each item. Cleared by
flush_line once the marker is committed to a page.
pending_labels: Vec<String>Labels of blocks dispatched but not yet committed to a page. Bound
to the page their first content lands on (issue #72): see
LayoutState::bind_pending_labels.
label_pages: BTreeMap<String, u32>Built result of label → 1-based start page. Emitted into the
PageGraph by LayoutState::finish.
Implementations§
Source§impl LayoutState
impl LayoutState
Sourcepub(crate) fn layout_image(&mut self, node_id: NodeId, image: &Node)
pub(crate) fn layout_image(&mut self, node_id: NodeId, image: &Node)
Lay out a top-level Image node as a block. The image is
horizontally centred within the column and capped at the column
width; declared width/height override natural 72-DPI size.
Sourcepub(crate) fn layout_figure(&mut self, document: &Document, figure: &Node)
pub(crate) fn layout_figure(&mut self, document: &Document, figure: &Node)
Lay out a Figure block and keep image + caption together when
the remaining space allows.
fn measure_paragraph_height( &mut self, document: &Document, paragraph: &Node, ) -> f32
fn intrinsic_image_size(&self, image: &Node) -> Option<(f32, f32)>
fn intern_image(&mut self, image: &Node) -> Option<ImageHandle>
Source§impl LayoutState
impl LayoutState
Sourcepub(crate) fn layout_list(&mut self, document: &Document, list_node: &Node)
pub(crate) fn layout_list(&mut self, document: &Document, list_node: &Node)
Lay out a [NodeKind::List] and its [NodeKind::ListItem]
children with hanging indent.
Source§impl LayoutState
impl LayoutState
pub(crate) fn new(page: PageStyle, text: TextStyle) -> Self
Sourcepub(crate) fn queue_label(&mut self, node: &Node)
pub(crate) fn queue_label(&mut self, node: &Node)
Queue a block’s label attribute (if present) for binding to the
page its first content commits to (issue #72).
Sourcepub(crate) fn discard_unbound_labels(&mut self)
pub(crate) fn discard_unbound_labels(&mut self)
Drop labels still queued after a block finished laying out. The block
(or its label) committed no content, so the label has no page; clearing
it keeps a labelled no-content block out of label_pages instead of
letting its label leak onto the next block that does emit content. Only
the just-dispatched block’s label can be queued here, since
queue_label runs once per top-level block.
Sourcepub(crate) fn bind_pending_labels(&mut self)
pub(crate) fn bind_pending_labels(&mut self)
Bind every queued label to the current page. Called at each
first-content-commit site after its page-break check, so a label
maps to where its target actually lands. First placement wins
(or_insert), matching the resolver’s first-occurrence label rule.
pub(crate) fn column_width_pt(&self) -> f32
pub(crate) fn finish(self) -> LayoutResult
pub(crate) fn layout_heading(&mut self, document: &Document, section: &Node)
pub(crate) fn layout_paragraph(&mut self, document: &Document, paragraph: &Node)
pub(crate) fn layout_raw_block(&mut self, raw: &Node)
Sourcepub(crate) fn collect_words(
&mut self,
document: &Document,
parent: &Node,
default_font: Font,
size: f32,
) -> Vec<WordItem>
pub(crate) fn collect_words( &mut self, document: &Document, parent: &Node, default_font: Font, size: f32, ) -> Vec<WordItem>
Walk parent’s inline children and produce a flat list of
WordItems. Inline whitespace inside text runs collapses to
a single split point (split_ascii_whitespace handles
\n/\r/\t uniformly and intentionally preserves U+00A0
NBSP: non-ASCII whitespace stays inside the word so the
breaker never splits at NBSP). Each word is shaped once here;
the resulting glyphs and width flow through to TextRun
without re-shaping during line breaking. NodeKind::HardBreak
children are emitted as WordItem::HardBreak sentinels.
Sourcepub(crate) fn flow_words(&mut self, items: &[WordItem], leading: f32)
pub(crate) fn flow_words(&mut self, items: &[WordItem], leading: f32)
Greedy line-break items and emit text runs onto the page,
paginating as we go. leading is the line-height multiplier
applied per line. WordItem::HardBreak forces a line flush
at its position (and produces a blank line when two hard
breaks are adjacent or one lands mid-paragraph with no words
behind it).
Sourcepub(crate) fn flush_line(&mut self, line: &[Word], leading: f32)
pub(crate) fn flush_line(&mut self, line: &[Word], leading: f32)
Emit one line worth of words at cursor_y, advancing past it.
Computes the line’s typographic metrics from line itself so
the caller doesn’t have to track them in parallel.
Sourcepub(crate) fn flush_oversize_word(&mut self, word: &Word, leading: f32)
pub(crate) fn flush_oversize_word(&mut self, word: &Word, leading: f32)
Emit a word that’s wider than the column by chopping it on already-shaped cluster boundaries. The word was shaped when it was collected, so this avoids re-running rustybuzz for every growing prefix of a degenerate long word.
pub(crate) fn flush_oversize_chunk( &mut self, text: String, width_pt: f32, subruns: Vec<WordSubRun>, source: &Word, leading: f32, )
pub(crate) fn start_new_page(&mut self)
Auto Trait Implementations§
impl Freeze for LayoutState
impl RefUnwindSafe for LayoutState
impl Send for LayoutState
impl Sync for LayoutState
impl Unpin for LayoutState
impl UnsafeUnpin for LayoutState
impl UnwindSafe for LayoutState
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<U, T> ToOwnedObj<U> for Twhere
U: FromObjRef<T>,
impl<U, T> ToOwnedObj<U> for Twhere
U: FromObjRef<T>,
§fn to_owned_obj(&self, data: FontData<'_>) -> U
fn to_owned_obj(&self, data: FontData<'_>) -> U
T, using the provided data to resolve any offsets.