extractFromInlineSpan static method

List<Widget> extractFromInlineSpan(
  1. InlineSpan span,
  2. 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;
}