extractFromInlineSpan static method
- InlineSpan span,
- TextScaler textScaler
Helper function for extracting WidgetSpans in preorder, from the given InlineSpan as a list of widgets.
The textScaler
is the scaling strategy for scaling the content.
This function is used by EditableText and RichText so calling it directly is rarely necessary.
Implementation
static List<Widget> extractFromInlineSpan(InlineSpan span, TextScaler textScaler) {
final List<Widget> widgets = <Widget>[];
// _kEngineDefaultFontSize is the default font size to use when none of the
// ancestor spans specifies one.
final List<double> fontSizeStack = <double>[kDefaultFontSize];
int index = 0;
// This assumes an InlineSpan tree's logical order is equivalent to preorder.
bool visitSubtree(InlineSpan span) {
final double? fontSizeToPush = switch (span.style?.fontSize) {
final double size when size != fontSizeStack.last => size,
_ => null,
};
if (fontSizeToPush != null) {
fontSizeStack.add(fontSizeToPush);
}
if (span is WidgetSpan) {
final double fontSize = fontSizeStack.last;
final double textScaleFactor = fontSize == 0 ? 0 : textScaler.scale(fontSize) / fontSize;
widgets.add(
_WidgetSpanParentData(
span: span,
child: Semantics(
tagForChildren: PlaceholderSpanIndexSemanticsTag(index++),
child: _AutoScaleInlineWidget(span: span, textScaleFactor: textScaleFactor, child: span.child),
),
),
);
}
assert(
span is WidgetSpan || span is! PlaceholderSpan,
'$span is a PlaceholderSpan but not a WidgetSpan subclass. This is currently not supported.',
);
span.visitDirectChildren(visitSubtree);
if (fontSizeToPush != null) {
final double poppedFontSize = fontSizeStack.removeLast();
assert(fontSizeStack.isNotEmpty);
assert(poppedFontSize == fontSizeToPush);
}
return true;
}
visitSubtree(span);
return widgets;
}