Styled text, ready for layout.
The typography engine works on rich text rather than plain strings, because line breaking has to know the width of every word, and width depends on the font and size of the run it belongs to.
Most callers want from_plain/2:
RichText.from_plain("Hello world", font: "Times-Roman", size: 11)Use from_runs/1 when a paragraph mixes styles — a bold lead-in followed by
regular body text is one paragraph, not two, and must break across lines as
a unit:
RichText.from_runs([
%RichText.Run{text: "Warning: ", font: "Helvetica-Bold", size: 11},
%RichText.Run{text: "this operation cannot be undone.", font: "Helvetica", size: 11}
])Internally the runs are tokenised into words, spaces and breaks, which is
what the line breaker consumes. from_tokens/1 accepts that form directly
and exists so text spilling from one page can continue on the next without
losing its styling.
Summary
Functions
Build rich text from a single plain string.
Build rich text from a list of styled runs.
Recompute every token width against a measurement context.
The font names whose widths are still estimates, because no context supplied so far could resolve them.
Types
@type t() :: %Tincture.Typography.RichText{ runs: [Tincture.Typography.RichText.Run.t()], tokens: [token()] }
@type token() :: Tincture.Typography.RichText.Word.t() | Tincture.Typography.RichText.Space.t() | Tincture.Typography.RichText.Break.t()
Functions
Build rich text from a single plain string.
Options
:font— font name. Defaults to"Helvetica".:size— point size. Defaults to12.:style— an arbitrary style tag carried through to the tokens.:context— aTincture.Font.Context.t/0used to measure. Needed only to measure an embedded font up front, since embedded metrics live on the document rather than being globally resolvable. The document-aware entry points —Tincture.text_paragraph/6,Tincture.Layout.Box.flow_text/7— re-measure against their own document anyway, so this is usually unnecessary.
Examples
RichText.from_plain("Hello world", font: "Times-Roman", size: 11)
# Measuring an embedded font outside a layout call.
context = Tincture.Font.Context.from_pdf(pdf)
RichText.from_plain("Hello", font: "Body", size: 11, context: context)
@spec from_runs( [Tincture.Typography.RichText.Run.t()], keyword() ) :: t()
Build rich text from a list of styled runs.
Accepts a :context option, as from_plain/2 does.
@spec remeasure(t(), Tincture.Font.Context.t()) :: t()
Recompute every token width against a measurement context.
Token widths are baked in when the rich text is built, so text built without
a context has measured its embedded fonts wrongly — or failed to measure them
at all. The document-aware layout functions call this for you; it exists
publicly for code that lays out text through Tincture.Typography directly.
rich
|> RichText.remeasure(Tincture.Font.Context.from_pdf(pdf))
|> Tincture.Typography.layout_paragraph(450, align: :justified)Structure is preserved exactly — only widths change — so this is safe to apply to text that has already been through a layout pass.
The font names whose widths are still estimates, because no context supplied so far could resolve them.
Empty for text that is ready to lay out.