setMaxWidth method

void setMaxWidth(
  1. ChantContext ctxt,
  2. double maxWidth, [
  3. double firstLineMaxWidth = -1
])

Implementation

void setMaxWidth(
  ChantContext ctxt,
  double maxWidth, [
  double firstLineMaxWidth = -1,
]) {
  if (spans.any((s) => s.newLine > 0)) {
    recalculateMetrics(ctxt);
  }
  if (bounds.width > maxWidth) {
    final percentage = maxWidth / bounds.width;
    if (this is Lyric && percentage >= 0.85) {
      resize = percentage;
    } else {
      if (firstLineMaxWidth < 0) firstLineMaxWidth = maxWidth;
      this.firstLineMaxWidth = firstLineMaxWidth;
      RegExpMatch? lastMatch;
      final regex = RegExp(r'\s+|$', multiLine: true);
      double max = firstLineMaxWidth;
      for (final match in regex.allMatches(text)) {
        if (lastMatch == null || match.start > lastMatch.start) {
          var width = measureSubstring(ctxt, match.start);
          if (width > max && lastMatch != null) {
            var spanIndex = 0, length = 0;
            while (length < lastMatch.start && spanIndex < spans.length) {
              var span = spans[spanIndex++];
              length += span.text.length + span.newLine;
            }
            if (length > lastMatch.start || spanIndex >= spans.length) {
              var span = spans[--spanIndex];
              length -= span.text.length;
            }
            var splitSpan = spans[spanIndex];
            var textLeft = splitSpan.text.substring(
              0,
              lastMatch.start - length,
            );

            rightAligned =
                max == firstLineMaxWidth && firstLineMaxWidth != maxWidth;
            final newSpans = [
              TextSpan(
                textLeft,
                splitSpan.propertyArray,
                splitSpan.activeTags,
              ),
            ];
            if (lastMatch.start + lastMatch[0]!.length - length <
                splitSpan.text.length) {
              final textRight = splitSpan.text.substring(
                lastMatch.start + lastMatch[0]!.length - length,
              );
              newSpans.add(
                TextSpan(
                  textRight,
                  splitSpan.propertyArray,
                  splitSpan.activeTags,
                  0,
                  {'newLine': 1},
                ),
              );
            } else if (spans.length > spanIndex + 1) {
              spans[spanIndex + 1].newLine = 1;
            }
            spans.replaceRange(spanIndex, spanIndex + 1, newSpans);
            needsLayout = true;
            max = maxWidth;
            if (match.start == text.length ||
                measureSubstring(ctxt) <= maxWidth) {
              break;
            }
            width = 0;
          }
          lastMatch = match;
        }
      }
    }
    recalculateMetrics(ctxt, false);
  }
}