Internally, the em-square has fixed dimensions (e.g., 1,000 units per side). Externally, the em-square is scaled to the font size (e.g., 12 pixels per side). This establishes a correspondence between internal/logical units and external/physical units (e.g.,
0.012pixels per unit).
1.5would cause fonts to appear 50% larger). This effect is achieved my multiply the font size by the scale factor.
FontWeightcharacterize the glyphs used during rendering (specifying slant and glyph thickness, respectively).
FontFeatureencodes a feature tag, a four-character tag associated with an integer value that customizes font-specific features (i.e. these can be anything from enabling slashed zeros to selecting random glyph variants).
TextAligndescribes the horizontal alignment of text. “Left”, “right”, and “center” describe the text’s alignment with respect to its container. “Start” and “end” do the same, but in a directionality-aware manner. “Justify” stretches wrapped text such that it fills the available width.
TextBaselineidentifies the horizontal lines used to vertically align glyphs (alphabetic or ideographic).
TextDecorationis a linear decoration (underline, overline, or a strikethrough) that can be applied to text; overlapping decorations merge intelligently.
TextDecorationStylealters how decorations are rendered: using a solid, double, dotted, dashed, or wavy line.
TextStyledescribes the size, position, and rendering of text in a way that can be transformed for use by the engine. This description includes colors, spacing, the desired font family, the text decoration, and so on.
TextPositionrepresents an insertion point in rendered and unrendered text (i.e., a position between letters). This is encoded as an offset indicating the index of the letter immediately after the position, even if that index exceeds string bounds. An affinity is used to disambiguate the following cases where an offset becomes ambiguous after rendereding:
e.x., offset 3 can be “abc|
ABC” or “
TextAffinityresolves ambiguity when an offset can correspond to multiple positions after rendering (e.g., because a renderer might insert line breaks or flip portions due to directionality).
TextAffinity.upstreamselects the option closer to the start of the string (e.g., the end of the line before a break, “abc|
TextAffinity.downstreamselects the option closer to the end (e.g., the start of the line after a break, “
TextBoxidentifies a rectangular region containing text relative to the parent’s top left corner. Provides direction-aware accessors (i.e.,
TextWidthBasisenumerates approaches for measuring the width of a paragraph. Longest line selects the minimum space needed to contain the longest line (e.g., a chat bubble). Parent selects the width of the container for multi-line text or the actual width for a single line of text (e.g., a paragraph of text).
RenderComparisondescribes the renderable difference between two inline spans. Spans may have differences that will affect their layout (and painting), their painting, their metadata, etc.
ParagraphStyledescribes how lines are laid out by
ParagraphBuilder. Among other things, this class allows a maximum number of lines to be set as well as the text’s directionality and ellipses behavior; crucially, it allows the paragraph’s strut to be configured.
ParagraphConstraintsdescribe the input to
Paragraphlayout. Its only value is “width,” which specifies a maximum width for the paragraph. This maximum is enforced in two ways: (1) if possible, a soft line break (i.e., located between words) is inserted before the maximum is reached. Otherwise, (2) a hard line break (i.e., located within words) is inserted, instead.
TextAlign); any ellipses is ignored for the purposes of alignment. Ellipses length is considered when determining line breaks [?].
StrutStyledefines a “strut” which dictates a line of text’s minimum height. Glyphs assume the larger of their own dimensions and the strut’s dimensions (with ascent and descent considered separately). Conceptually, paragraph’s prepend a zero-width strut character to each line. The strut can be forced, causing line height to be determined solely by the strut.
PlaceholderAlignmentexpresses the vertical alignment of a placeholder relative to the font. Placeholders can have their top, bottom, or baseline aligned to the parent baseline. Placeholders may also be positioned relative to the font’s ascenders, descenders, or median.
PlaceholderDimensionsdescribe the size and alignment of a placeholder. If a baseline-relative alignment is used, the type of baseline must be specified (e.g., alphabetic or ideographic). An optional baseline offset indicates the distance from the top of the box to its logical baseline (e.g., this is used to align inline widgets via
InlineSpanrepresents an immutable span of content within a paragraph. A span is associated with a text style which is inherited by child spans. Spans are added to a
InlineSpan.build(this is handled automatically by
TextPainter); any accessibility text scaling is specified at this point. An ancestor span may be queried to locate the descendent span containing a
InlineSpanto represent an immutable span of styled text. The provided
TextStyleis inherited by all children, which may override all or some styles. Text spans contain text as well as any number of inline span children. Children form a text span tree that is traversed in order. Each node is also associated with a string of text (styled using the span’s
TextStyle) which effectively precedes any children.
TextSpansare interactive and have an associated gesture recognizer that is managed externally (e.g., by
InlineSpanto represent a reserved region within a paragraph.
PlaceholderSpanto embed a
Widgetwithin a paragraph. Widgets are constrained to the maximum width of the paragraph. The widget is laid out and painted by
TextPaintersimply leaves space within the paragraph.
ParagraphBuildertracks the number of placeholders added so far; this number is used when building to identify the
PlaceholderDimensionscorresponding to this span. These dimensions are typically computed by
RenderParagraph, which lays out all widget spans before building the paragraph so that the necessary amount of space is reserved.
Paragraph.layoutmust be invoked to compute these metrics. Paragraph supports efficient resizing and painting (via
Canvas.addParagraph) and must be built by
ParagraphBuilder. Each glyph is assigned an integer offset computed before rendering (thus there is no affinity issue). Note that
Paragraphis a thin wrapper around engine code.
TextPositionassociated with a 2D offset, and word boundaries given an integer offset.
Paragraphscan provide bounding boxes for a range within the pre-rendered text. Boxes are derived from runs of text, each of which may have a distinct style and therefore height. Thus, boxes can be sized in a variety of ways (via
BoxWidthStyle). Boxes can tightly enclose only the rendered glyphs (the default), expand to include different portions of the line height, be sized to the maximum height in a given line, etc.
ParagraphBuilderassembles a single
Paragraphfrom a sequence of text and placeholders using the provided
TextStylesare pushed and popped, allowing styles to be inherited and overridden, and placeholders boxes (e.g., for embedded widgets) are reserved and tracked. The
Paragraphitself is built by the engine.
TextOverflowdescribes how visual overflow is handled when rendering text via
RenderParagraph. Options include clipping, fading, adding ellipses, or tolerating overflow.
TextPainterperforms the actual work of building a
InlineSpantree and painting it to the canvas; the caller must explicitly request layout and painting. The painter incorporates the various text rendering
APIsto provide a convenient interface for rendering text. If the container’s width changes, layout and painting must be repeated.
TextPaintersupports a variety of queries; it can provide bounding boxes for a
TextSelection, the height and offset of the glyph at a given
TextPosition, neighboring editable offsets, and can convert a 2D offset into a
RichTextwhich obtains the ambient text style via
MultiChildRenderObjectWidgetthat configures a single
RenderParagraphwith a provided
InlineSpan. Its children are obtained by traversing this span to locate
WidgetSpaninstances. Any render objects produced by the associated widgets will be attached to the
RenderParagraph; this is how the
RenderParagraphis able to layout and paint widgets into the paragraphs’ placeholders.
TextParentDatais the parent data associated with the inline widgets contained in a paragraph of text. It extends
ContainerBoxParentDatato track the text scale applied to the child.
RenderParagraphdisplays a paragraph of text, optionally containing inline widgets. It delegates to (and augments) an underlying
TextPainterwhich builds, lays out, and paints the actual paragraph. Any operations that depend on text layout generally recompute layout blindly; this is acceptable since
TextPainterignores redundant calls.
TextPainterto the render tree, adding the ability to render widgets (i.e.,
WidgetSpaninstances) within the text. Any such widgets are parented to the
RenderParagraph; a list of all descendent placeholders (
RenderParagraph._placeholderSpans) is also cached. The
RenderParagraphproxies the various inputs to the text rendering system, invalidating painting and layout as values change (
RenderComparisonallows this to be done efficiently).
TextOverfloweffect is applied (by clipping, configuring an overflow shader, etc).
PlaceholderDimensionsis assembled using the resulting layout. If the associated
InlineSpanis aligned to the baseline, the offset to the child’s baseline is computed (via
RenderBox.getDistanceToBaseline); this ensures that the child’s baseline is coincident with the text’s baseline. Finally, the dimensions are bound to the
ParagraphConstraints(i.e., height is ignored). If wrapping or truncation is enabled, the maximum width is retained; otherwise, the width is considered infinite. These constraints are provided to
TextPainter.layout, which builds and lays out the underlying
Paragraph(via the engine).
TextPainter.inlinePlaceholderBoxes, which exposes an ordered list of
TextPainteris stateful, and certain operations (e.g., computing intrinsic dimensions) destroy this state, the text must be relaid out before painting.
TextOverflowsetting requires a shader, the canvas is configured accordingly.
TextPainterpaints the text (via
Canvas.drawParagraph). Empty spaces will appear in the text wherever placeholders were included.
InlineSpansubclasses can be associated with a gesture recognizer (
InlineSpan.recognizer). This instance’s lifecycle, however, must be maintained by client code (i.e., the
RenderParagraph). Additionally, events must be propagated to each
InlineSpansince spans do not support bubbling themselves.
RenderObject.handleEventto attach new pointers (i.e.,
PointerDownEvent) directly to the span that was tapped.
TextPosition, then finally locating the span that contains this position (via
RenderParagraphis also responsible for hit testing any render objects included via inline widgets. These are hit tested using a similar approach as
RenderBoxthat additionally takes into account any text scaling.
RenderParagraphis always included in the hit test result.
Paragraph.layoutis required to obtain the intrinsic dimensions from the engine).
RenderBoxprotocol. The input dimension (e.g., height) is provided to obtain the opposite intrinsic dimension (e.g., minimum intrinsic width); this value is used to obtain the remaining intrinsic dimension (e.g., minimum intrinsic height). These values are then wrapped in a
PlaceholderDimensioninstance which is aligned appropriately (via
TextPainter.setPlaceHolderDimensions). This ensures that the resulting intrinsics accurately reflect any inline widgets. After layout, intrinsics can be read from the
Paragraphdirectly. Note that this is destructive in that it wipes out earlier dimensions associated with the
Flutterdoes not have a default text direction (
TextDirection). Throughout the lower levels of the framework, directionality must be specified. At the widget level, an ambient directionality is introduced by the
Directionalitywidget. Other widgets use the ambient directionality when interacting with lower level aspects of the framework.
EdgeInsetsDirectional). The former exposes top, left, right, and bottom properties; the latter exposes top, start, end, and bottom properties.
ICUto split text into lines.
HarfBuzzto retrieve glyphs from a font.