setEmojiTextStyle method

List<InlineSpan> setEmojiTextStyle(
  1. String text, {
  2. required TextStyle emojiStyle,
  3. TextStyle? parentStyle,
})

Produce a list of spans to adjust style for emoji characters. Spans enclosing emojis will have parentStyle combined with emojiStyle. Other spans will not have an explicit style (this method does not set parentStyle to the whole text.

Implementation

List<InlineSpan> setEmojiTextStyle(
  String text, {
  required TextStyle emojiStyle,
  TextStyle? parentStyle,
}) {
  final composedEmojiStyle = (parentStyle ?? const TextStyle())
      .merge(DefaultEmojiTextStyle)
      .merge(emojiStyle);

  final spans = <TextSpan>[];
  final matches = getEmojiRegex().allMatches(text).toList();
  var cursor = 0;
  for (final match in matches) {
    if (cursor != match.start) {
      // Non emoji text + following emoji
      spans
        ..add(TextSpan(
            text: text.substring(cursor, match.start), style: parentStyle))
        ..add(TextSpan(
          text: text.substring(match.start, match.end),
          style: composedEmojiStyle,
        ));
    } else {
      if (spans.isEmpty) {
        // Create new span if no previous emoji TextSpan exists
        spans.add(TextSpan(
          text: text.substring(match.start, match.end),
          style: composedEmojiStyle,
        ));
      } else {
        // Update last span if current text is still emoji
        final lastIndex = spans.length - 1;
        final lastText = spans[lastIndex].text ?? '';
        final currentText = text.substring(match.start, match.end);
        spans[lastIndex] = TextSpan(
          text: '$lastText$currentText',
          style: composedEmojiStyle,
        );
      }
    }
    // Update cursor
    cursor = match.end;
  }
  // Add remaining text
  if (cursor != text.length) {
    spans.add(TextSpan(
        text: text.substring(cursor, text.length), style: parentStyle));
  }
  return spans;
}