setMaxWidth method
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);
}
}