Dispose Paragraph objects (#110627)
This commit is contained in:
parent
783e7b0122
commit
eaff1562a9
@ -36,6 +36,7 @@ class _MyScrollContainerState extends State<_MyScrollContainer> {
|
|||||||
static const Duration stepDuration = Duration(milliseconds: 500);
|
static const Duration stepDuration = Duration(milliseconds: 500);
|
||||||
|
|
||||||
late PageController pageController;
|
late PageController pageController;
|
||||||
|
final _CustomPainter _painter = _CustomPainter('aa');
|
||||||
int pageNumber = 0;
|
int pageNumber = 0;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -57,6 +58,7 @@ class _MyScrollContainerState extends State<_MyScrollContainer> {
|
|||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
pageController.dispose();
|
pageController.dispose();
|
||||||
|
_painter._textPainter.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +68,7 @@ class _MyScrollContainerState extends State<_MyScrollContainer> {
|
|||||||
controller: pageController,
|
controller: pageController,
|
||||||
itemBuilder: (BuildContext context, int position) {
|
itemBuilder: (BuildContext context, int position) {
|
||||||
return CustomPaint(
|
return CustomPaint(
|
||||||
painter: _CustomPainter('aa'),
|
painter: _painter,
|
||||||
size: const Size(300, 500),
|
size: const Size(300, 500),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -182,6 +182,7 @@ class BoardPainter extends CustomPainter {
|
|||||||
);
|
);
|
||||||
final Vertices vertices = board!.getVerticesForBoardPoint(boardPoint, color);
|
final Vertices vertices = board!.getVerticesForBoardPoint(boardPoint, color);
|
||||||
canvas.drawVertices(vertices, BlendMode.color, Paint());
|
canvas.drawVertices(vertices, BlendMode.color, Paint());
|
||||||
|
vertices.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
board!.forEach(drawBoardPoint);
|
board!.forEach(drawBoardPoint);
|
||||||
|
@ -482,8 +482,11 @@ class CupertinoDatePicker extends StatefulWidget {
|
|||||||
// because there's no other way to get the information we want without
|
// because there's no other way to get the information we want without
|
||||||
// laying out the text.
|
// laying out the text.
|
||||||
painter.layout();
|
painter.layout();
|
||||||
|
try {
|
||||||
return painter.maxIntrinsicWidth;
|
return painter.maxIntrinsicWidth;
|
||||||
|
} finally {
|
||||||
|
painter.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1663,6 +1666,7 @@ class _CupertinoTimerPickerState extends State<CupertinoTimerPicker> {
|
|||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
PaintingBinding.instance.systemFonts.removeListener(_handleSystemFontsChange);
|
PaintingBinding.instance.systemFonts.removeListener(_handleSystemFontsChange);
|
||||||
|
textPainter.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1090,6 +1090,13 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix
|
|||||||
super.detach();
|
super.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_startLabelPainter.dispose();
|
||||||
|
_endLabelPainter.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
double _getValueFromVisualPosition(double visualPosition) {
|
double _getValueFromVisualPosition(double visualPosition) {
|
||||||
switch (textDirection) {
|
switch (textDirection) {
|
||||||
case TextDirection.rtl:
|
case TextDirection.rtl:
|
||||||
|
@ -1342,6 +1342,12 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
|
|||||||
super.detach();
|
super.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_labelPainter.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
double _getValueFromVisualPosition(double visualPosition) {
|
double _getValueFromVisualPosition(double visualPosition) {
|
||||||
switch (textDirection) {
|
switch (textDirection) {
|
||||||
case TextDirection.rtl:
|
case TextDirection.rtl:
|
||||||
|
@ -860,6 +860,17 @@ class _DialPainter extends CustomPainter {
|
|||||||
|
|
||||||
static const double _labelPadding = 28.0;
|
static const double _labelPadding = 28.0;
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
|
for (final _TappableLabel label in primaryLabels) {
|
||||||
|
label.painter.dispose();
|
||||||
|
}
|
||||||
|
for (final _TappableLabel label in secondaryLabels) {
|
||||||
|
label.painter.dispose();
|
||||||
|
}
|
||||||
|
primaryLabels.clear();
|
||||||
|
secondaryLabels.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void paint(Canvas canvas, Size size) {
|
void paint(Canvas canvas, Size size) {
|
||||||
final double radius = size.shortestSide / 2.0;
|
final double radius = size.shortestSide / 2.0;
|
||||||
@ -966,6 +977,7 @@ class _DialState extends State<_Dial> with SingleTickerProviderStateMixin {
|
|||||||
late ThemeData themeData;
|
late ThemeData themeData;
|
||||||
late MaterialLocalizations localizations;
|
late MaterialLocalizations localizations;
|
||||||
late MediaQueryData media;
|
late MediaQueryData media;
|
||||||
|
_DialPainter? painter;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didChangeDependencies() {
|
void didChangeDependencies() {
|
||||||
@ -989,6 +1001,7 @@ class _DialState extends State<_Dial> with SingleTickerProviderStateMixin {
|
|||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_thetaController.dispose();
|
_thetaController.dispose();
|
||||||
|
painter?.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1280,6 +1293,18 @@ class _DialState extends State<_Dial> with SingleTickerProviderStateMixin {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
painter?.dispose();
|
||||||
|
painter = _DialPainter(
|
||||||
|
selectedValue: selectedDialValue,
|
||||||
|
primaryLabels: primaryLabels,
|
||||||
|
secondaryLabels: secondaryLabels,
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
accentColor: accentColor,
|
||||||
|
dotColor: theme.colorScheme.surface,
|
||||||
|
theta: _theta.value,
|
||||||
|
textDirection: Directionality.of(context),
|
||||||
|
);
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
excludeFromSemantics: true,
|
excludeFromSemantics: true,
|
||||||
onPanStart: _handlePanStart,
|
onPanStart: _handlePanStart,
|
||||||
@ -1288,16 +1313,7 @@ class _DialState extends State<_Dial> with SingleTickerProviderStateMixin {
|
|||||||
onTapUp: _handleTapUp,
|
onTapUp: _handleTapUp,
|
||||||
child: CustomPaint(
|
child: CustomPaint(
|
||||||
key: const ValueKey<String>('time-picker-dial'),
|
key: const ValueKey<String>('time-picker-dial'),
|
||||||
painter: _DialPainter(
|
painter: painter,
|
||||||
selectedValue: selectedDialValue,
|
|
||||||
primaryLabels: primaryLabels,
|
|
||||||
secondaryLabels: secondaryLabels,
|
|
||||||
backgroundColor: backgroundColor,
|
|
||||||
accentColor: accentColor,
|
|
||||||
dotColor: theme.colorScheme.surface,
|
|
||||||
theta: _theta.value,
|
|
||||||
textDirection: Directionality.of(context),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -227,6 +227,7 @@ class _FlutterLogoPainter extends BoxPainter {
|
|||||||
final FlutterLogoDecoration _config;
|
final FlutterLogoDecoration _config;
|
||||||
|
|
||||||
// these are configured assuming a font size of 100.0.
|
// these are configured assuming a font size of 100.0.
|
||||||
|
// TODO(dnfield): Figure out how to dispose this https://github.com/flutter/flutter/issues/110601
|
||||||
late TextPainter _textPainter;
|
late TextPainter _textPainter;
|
||||||
late Rect _textBoundingRect;
|
late Rect _textBoundingRect;
|
||||||
|
|
||||||
|
@ -222,6 +222,7 @@ class TextPainter {
|
|||||||
bool _rebuildParagraphForPaint = true;
|
bool _rebuildParagraphForPaint = true;
|
||||||
|
|
||||||
bool get _debugAssertTextLayoutIsValid {
|
bool get _debugAssertTextLayoutIsValid {
|
||||||
|
assert(!debugDisposed);
|
||||||
if (_paragraph == null) {
|
if (_paragraph == null) {
|
||||||
throw FlutterError.fromParts(<DiagnosticsNode>[
|
throw FlutterError.fromParts(<DiagnosticsNode>[
|
||||||
ErrorSummary('Text layout not available'),
|
ErrorSummary('Text layout not available'),
|
||||||
@ -247,6 +248,7 @@ class TextPainter {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}());
|
}());
|
||||||
|
_paragraph?.dispose();
|
||||||
_paragraph = null;
|
_paragraph = null;
|
||||||
_lineMetricsCache = null;
|
_lineMetricsCache = null;
|
||||||
_previousCaretPosition = null;
|
_previousCaretPosition = null;
|
||||||
@ -271,6 +273,7 @@ class TextPainter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_text?.style != value?.style) {
|
if (_text?.style != value?.style) {
|
||||||
|
_layoutTemplate?.dispose();
|
||||||
_layoutTemplate = null;
|
_layoutTemplate = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,6 +332,7 @@ class TextPainter {
|
|||||||
}
|
}
|
||||||
_textDirection = value;
|
_textDirection = value;
|
||||||
markNeedsLayout();
|
markNeedsLayout();
|
||||||
|
_layoutTemplate?.dispose();
|
||||||
_layoutTemplate = null; // Shouldn't really matter, but for strict correctness...
|
_layoutTemplate = null; // Shouldn't really matter, but for strict correctness...
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,6 +351,7 @@ class TextPainter {
|
|||||||
}
|
}
|
||||||
_textScaleFactor = value;
|
_textScaleFactor = value;
|
||||||
markNeedsLayout();
|
markNeedsLayout();
|
||||||
|
_layoutTemplate?.dispose();
|
||||||
_layoutTemplate = null;
|
_layoutTemplate = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1060,4 +1065,33 @@ class TextPainter {
|
|||||||
assert(_debugAssertTextLayoutIsValid);
|
assert(_debugAssertTextLayoutIsValid);
|
||||||
return _lineMetricsCache ??= _paragraph!.computeLineMetrics();
|
return _lineMetricsCache ??= _paragraph!.computeLineMetrics();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _disposed = false;
|
||||||
|
|
||||||
|
/// Whether this object has been disposed or not.
|
||||||
|
///
|
||||||
|
/// Only for use when asserts are enabled.
|
||||||
|
bool get debugDisposed {
|
||||||
|
bool? disposed;
|
||||||
|
assert(() {
|
||||||
|
disposed = _disposed;
|
||||||
|
return true;
|
||||||
|
}());
|
||||||
|
return disposed ?? (throw StateError('debugDisposed only available when asserts are on.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Releases the resources associated with this painter.
|
||||||
|
///
|
||||||
|
/// After disposal this painter is unusable.
|
||||||
|
void dispose() {
|
||||||
|
assert(() {
|
||||||
|
_disposed = true;
|
||||||
|
return true;
|
||||||
|
}());
|
||||||
|
_layoutTemplate?.dispose();
|
||||||
|
_layoutTemplate = null;
|
||||||
|
_paragraph?.dispose();
|
||||||
|
_paragraph = null;
|
||||||
|
_text = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,6 +114,14 @@ mixin DebugOverflowIndicatorMixin on RenderObject {
|
|||||||
TextPainter(textDirection: TextDirection.ltr), // This label is in English.
|
TextPainter(textDirection: TextDirection.ltr), // This label is in English.
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
for (final TextPainter painter in _indicatorLabel) {
|
||||||
|
painter.dispose();
|
||||||
|
}
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
// Set to true to trigger a debug message in the console upon
|
// Set to true to trigger a debug message in the console upon
|
||||||
// the next paint call. Will be reset after each paint.
|
// the next paint call. Will be reset after each paint.
|
||||||
bool _overflowReportNeeded = true;
|
bool _overflowReportNeeded = true;
|
||||||
|
@ -388,6 +388,7 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin,
|
|||||||
_autocorrectHighlightPainter.dispose();
|
_autocorrectHighlightPainter.dispose();
|
||||||
_selectionPainter.dispose();
|
_selectionPainter.dispose();
|
||||||
_caretPainter.dispose();
|
_caretPainter.dispose();
|
||||||
|
_textPainter.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,6 +256,7 @@ class RenderParagraph extends RenderBox
|
|||||||
// _lastSelectableFragments may hold references to this RenderParagraph.
|
// _lastSelectableFragments may hold references to this RenderParagraph.
|
||||||
// Release them manually to avoid retain cycles.
|
// Release them manually to avoid retain cycles.
|
||||||
_lastSelectableFragments = null;
|
_lastSelectableFragments = null;
|
||||||
|
_textPainter.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -864,6 +865,7 @@ class RenderParagraph extends RenderBox
|
|||||||
<Color>[const Color(0xFFFFFFFF), const Color(0x00FFFFFF)],
|
<Color>[const Color(0xFFFFFFFF), const Color(0x00FFFFFF)],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
fadeSizePainter.dispose();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1515,6 +1515,13 @@ abstract class _RenderCustomClip<T> extends RenderProxyBox {
|
|||||||
return true;
|
return true;
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_debugText?.dispose();
|
||||||
|
_debugText = null;
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clips its child using a rectangle.
|
/// Clips its child using a rectangle.
|
||||||
|
@ -117,14 +117,23 @@ class BannerPainter extends CustomPainter {
|
|||||||
);
|
);
|
||||||
|
|
||||||
bool _prepared = false;
|
bool _prepared = false;
|
||||||
late TextPainter _textPainter;
|
TextPainter? _textPainter;
|
||||||
late Paint _paintShadow;
|
late Paint _paintShadow;
|
||||||
late Paint _paintBanner;
|
late Paint _paintBanner;
|
||||||
|
|
||||||
|
/// Release resources held by this painter.
|
||||||
|
///
|
||||||
|
/// After calling this method, this object is no longer usable.
|
||||||
|
void dispose() {
|
||||||
|
_textPainter?.dispose();
|
||||||
|
_textPainter = null;
|
||||||
|
}
|
||||||
|
|
||||||
void _prepare() {
|
void _prepare() {
|
||||||
_paintShadow = _shadow.toPaint();
|
_paintShadow = _shadow.toPaint();
|
||||||
_paintBanner = Paint()
|
_paintBanner = Paint()
|
||||||
..color = color;
|
..color = color;
|
||||||
|
_textPainter?.dispose();
|
||||||
_textPainter = TextPainter(
|
_textPainter = TextPainter(
|
||||||
text: TextSpan(style: textStyle, text: message),
|
text: TextSpan(style: textStyle, text: message),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
@ -144,8 +153,8 @@ class BannerPainter extends CustomPainter {
|
|||||||
..drawRect(_kRect, _paintShadow)
|
..drawRect(_kRect, _paintShadow)
|
||||||
..drawRect(_kRect, _paintBanner);
|
..drawRect(_kRect, _paintBanner);
|
||||||
const double width = _kOffset * 2.0;
|
const double width = _kOffset * 2.0;
|
||||||
_textPainter.layout(minWidth: width, maxWidth: width);
|
_textPainter!.layout(minWidth: width, maxWidth: width);
|
||||||
_textPainter.paint(canvas, _kRect.topLeft + Offset(0.0, (_kRect.height - _textPainter.height) / 2.0));
|
_textPainter!.paint(canvas, _kRect.topLeft + Offset(0.0, (_kRect.height - _textPainter!.height) / 2.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -339,6 +339,7 @@ class _SemanticsDebuggerPainter extends CustomPainter {
|
|||||||
..layout(maxWidth: rect.width);
|
..layout(maxWidth: rect.width);
|
||||||
|
|
||||||
textPainter.paint(canvas, Alignment.center.inscribe(textPainter.size, rect).topLeft);
|
textPainter.paint(canvas, Alignment.center.inscribe(textPainter.size, rect).topLeft);
|
||||||
|
textPainter.dispose();
|
||||||
canvas.restore();
|
canvas.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2777,6 +2777,13 @@ class _InspectorOverlayLayer extends Layer {
|
|||||||
TextPainter? _textPainter;
|
TextPainter? _textPainter;
|
||||||
double? _textPainterMaxWidth;
|
double? _textPainterMaxWidth;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_textPainter?.dispose();
|
||||||
|
_textPainter = null;
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void addToScene(ui.SceneBuilder builder) {
|
void addToScene(ui.SceneBuilder builder) {
|
||||||
if (!selection.active) {
|
if (!selection.active) {
|
||||||
@ -2878,6 +2885,7 @@ class _InspectorOverlayLayer extends Layer {
|
|||||||
final TextSpan? textSpan = _textPainter?.text as TextSpan?;
|
final TextSpan? textSpan = _textPainter?.text as TextSpan?;
|
||||||
if (_textPainter == null || textSpan!.text != message || _textPainterMaxWidth != maxWidth) {
|
if (_textPainter == null || textSpan!.text != message || _textPainterMaxWidth != maxWidth) {
|
||||||
_textPainterMaxWidth = maxWidth;
|
_textPainterMaxWidth = maxWidth;
|
||||||
|
_textPainter?.dispose();
|
||||||
_textPainter = TextPainter()
|
_textPainter = TextPainter()
|
||||||
..maxLines = _kMaxTooltipLines
|
..maxLines = _kMaxTooltipLines
|
||||||
..ellipsis = '...'
|
..ellipsis = '...'
|
||||||
|
@ -32,6 +32,7 @@ void main() {
|
|||||||
painter.getWordBoundary(const TextPosition(offset: 9)),
|
painter.getWordBoundary(const TextPosition(offset: 9)),
|
||||||
const TextRange(start: 8, end: 11),
|
const TextRange(start: 8, end: 11),
|
||||||
);
|
);
|
||||||
|
painter.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('TextPainter - bidi overrides in LTR', () {
|
test('TextPainter - bidi overrides in LTR', () {
|
||||||
@ -164,6 +165,7 @@ void main() {
|
|||||||
// The list currently has one extra bogus entry (the last entry, for the
|
// The list currently has one extra bogus entry (the last entry, for the
|
||||||
// trailing U+202C PDF, should be empty but is one-pixel-wide instead).
|
// trailing U+202C PDF, should be empty but is one-pixel-wide instead).
|
||||||
], skip: skipExpectsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
], skip: skipExpectsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
||||||
|
painter.dispose();
|
||||||
}, skip: skipTestsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
}, skip: skipTestsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
||||||
|
|
||||||
test('TextPainter - bidi overrides in RTL', () {
|
test('TextPainter - bidi overrides in RTL', () {
|
||||||
@ -255,6 +257,7 @@ void main() {
|
|||||||
// The list is currently in the wrong order (so selection boxes will paint in the wrong order).
|
// The list is currently in the wrong order (so selection boxes will paint in the wrong order).
|
||||||
skip: skipExpectsWithKnownBugs, // https://github.com/flutter/flutter/issues/87536
|
skip: skipExpectsWithKnownBugs, // https://github.com/flutter/flutter/issues/87536
|
||||||
);
|
);
|
||||||
|
painter.dispose();
|
||||||
}, skip: skipTestsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
}, skip: skipTestsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
||||||
|
|
||||||
test('TextPainter - forced line-wrapping with bidi', () {
|
test('TextPainter - forced line-wrapping with bidi', () {
|
||||||
@ -322,6 +325,7 @@ void main() {
|
|||||||
TextBox.fromLTRBD(0.0, 10.0, 10.0, 20.0, TextDirection.rtl), // Alef
|
TextBox.fromLTRBD(0.0, 10.0, 10.0, 20.0, TextDirection.rtl), // Alef
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
painter.dispose();
|
||||||
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/32238
|
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/32238
|
||||||
|
|
||||||
test('TextPainter - line wrap mid-word', () {
|
test('TextPainter - line wrap mid-word', () {
|
||||||
@ -356,6 +360,7 @@ void main() {
|
|||||||
// horizontal offsets are one pixel off in places; vertical offsets are good
|
// horizontal offsets are one pixel off in places; vertical offsets are good
|
||||||
skip: skipExpectsWithKnownBugs, // https://github.com/flutter/flutter/issues/87536
|
skip: skipExpectsWithKnownBugs, // https://github.com/flutter/flutter/issues/87536
|
||||||
);
|
);
|
||||||
|
painter.dispose();
|
||||||
}, skip: skipTestsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
}, skip: skipTestsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
||||||
|
|
||||||
test('TextPainter - line wrap mid-word, bidi - LTR base', () {
|
test('TextPainter - line wrap mid-word, bidi - LTR base', () {
|
||||||
@ -412,6 +417,7 @@ void main() {
|
|||||||
<TextBox>[TextBox.fromLTRBD(70.0, 28.0, 80.0, 38.0, TextDirection.ltr)],
|
<TextBox>[TextBox.fromLTRBD(70.0, 28.0, 80.0, 38.0, TextDirection.ltr)],
|
||||||
<TextBox>[TextBox.fromLTRBD(80.0, 28.0, 90.0, 38.0, TextDirection.ltr)],
|
<TextBox>[TextBox.fromLTRBD(80.0, 28.0, 90.0, 38.0, TextDirection.ltr)],
|
||||||
]);
|
]);
|
||||||
|
painter.dispose();
|
||||||
}, skip: skipTestsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
}, skip: skipTestsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
||||||
|
|
||||||
test('TextPainter - line wrap mid-word, bidi - RTL base', () {
|
test('TextPainter - line wrap mid-word, bidi - RTL base', () {
|
||||||
@ -447,6 +453,7 @@ void main() {
|
|||||||
// The list is currently in the wrong order (so selection boxes will paint in the wrong order).
|
// The list is currently in the wrong order (so selection boxes will paint in the wrong order).
|
||||||
skip: skipExpectsWithKnownBugs, // https://github.com/flutter/flutter/issues/87536
|
skip: skipExpectsWithKnownBugs, // https://github.com/flutter/flutter/issues/87536
|
||||||
);
|
);
|
||||||
|
painter.dispose();
|
||||||
}, skip: skipTestsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
}, skip: skipTestsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
||||||
|
|
||||||
test('TextPainter - multiple levels', () {
|
test('TextPainter - multiple levels', () {
|
||||||
@ -478,6 +485,7 @@ void main() {
|
|||||||
// Also currently there's an extraneous box at the start of the list.
|
// Also currently there's an extraneous box at the start of the list.
|
||||||
skip: skipExpectsWithKnownBugs, // https://github.com/flutter/flutter/issues/87536
|
skip: skipExpectsWithKnownBugs, // https://github.com/flutter/flutter/issues/87536
|
||||||
);
|
);
|
||||||
|
painter.dispose();
|
||||||
}, skip: skipTestsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
}, skip: skipTestsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
||||||
|
|
||||||
test('TextPainter - getPositionForOffset - RTL in LTR', () {
|
test('TextPainter - getPositionForOffset - RTL in LTR', () {
|
||||||
@ -561,6 +569,7 @@ void main() {
|
|||||||
painter.getPositionForOffset(const Offset(100.0, 5.0)).toString(),
|
painter.getPositionForOffset(const Offset(100.0, 5.0)).toString(),
|
||||||
const TextPosition(offset: 9, affinity: TextAffinity.upstream).toString(),
|
const TextPosition(offset: 9, affinity: TextAffinity.upstream).toString(),
|
||||||
);
|
);
|
||||||
|
painter.dispose();
|
||||||
}, skip: skipTestsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
}, skip: skipTestsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
||||||
|
|
||||||
test('TextPainter - getPositionForOffset - LTR in RTL', () {
|
test('TextPainter - getPositionForOffset - LTR in RTL', () {
|
||||||
@ -606,6 +615,7 @@ void main() {
|
|||||||
painter.getPositionForOffset(const Offset(62.0, 5.0)).toString(),
|
painter.getPositionForOffset(const Offset(62.0, 5.0)).toString(),
|
||||||
const TextPosition(offset: 3, affinity: TextAffinity.upstream).toString(),
|
const TextPosition(offset: 3, affinity: TextAffinity.upstream).toString(),
|
||||||
);
|
);
|
||||||
|
painter.dispose();
|
||||||
}, skip: skipTestsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
}, skip: skipTestsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
||||||
|
|
||||||
test('TextPainter - Spaces', () {
|
test('TextPainter - Spaces', () {
|
||||||
@ -667,6 +677,7 @@ void main() {
|
|||||||
// Horizontal offsets are currently one pixel off in places; vertical offsets are good.
|
// Horizontal offsets are currently one pixel off in places; vertical offsets are good.
|
||||||
skip: skipExpectsWithKnownBugs, // https://github.com/flutter/flutter/issues/87536
|
skip: skipExpectsWithKnownBugs, // https://github.com/flutter/flutter/issues/87536
|
||||||
);
|
);
|
||||||
|
painter.dispose();
|
||||||
}, skip: skipTestsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
}, skip: skipTestsWithKnownBugs); // https://github.com/flutter/flutter/issues/87536
|
||||||
|
|
||||||
test('TextPainter - empty text baseline', () {
|
test('TextPainter - empty text baseline', () {
|
||||||
@ -678,6 +689,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
painter.layout();
|
painter.layout();
|
||||||
expect(painter.computeDistanceToActualBaseline(TextBaseline.alphabetic), moreOrLessEquals(80.0, epsilon: 0.001));
|
expect(painter.computeDistanceToActualBaseline(TextBaseline.alphabetic), moreOrLessEquals(80.0, epsilon: 0.001));
|
||||||
|
painter.dispose();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ void main() {
|
|||||||
painter.layout();
|
painter.layout();
|
||||||
caretOffset = painter.getOffsetForCaret(ui.TextPosition(offset: text.length), ui.Rect.zero);
|
caretOffset = painter.getOffsetForCaret(ui.TextPosition(offset: text.length), ui.Rect.zero);
|
||||||
expect(caretOffset.dx, painter.width);
|
expect(caretOffset.dx, painter.width);
|
||||||
|
painter.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('TextPainter caret test with WidgetSpan', () {
|
test('TextPainter caret test with WidgetSpan', () {
|
||||||
@ -53,6 +54,7 @@ void main() {
|
|||||||
painter.layout();
|
painter.layout();
|
||||||
final Offset caretOffset = painter.getOffsetForCaret(ui.TextPosition(offset: painter.text!.toPlainText().length), ui.Rect.zero);
|
final Offset caretOffset = painter.getOffsetForCaret(ui.TextPosition(offset: painter.text!.toPlainText().length), ui.Rect.zero);
|
||||||
expect(caretOffset.dx, painter.width);
|
expect(caretOffset.dx, painter.width);
|
||||||
|
painter.dispose();
|
||||||
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/56308
|
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/56308
|
||||||
|
|
||||||
test('TextPainter null text test', () {
|
test('TextPainter null text test', () {
|
||||||
@ -78,6 +80,7 @@ void main() {
|
|||||||
expect(caretOffset.dx, 0);
|
expect(caretOffset.dx, 0);
|
||||||
caretOffset = painter.getOffsetForCaret(const ui.TextPosition(offset: 1), ui.Rect.zero);
|
caretOffset = painter.getOffsetForCaret(const ui.TextPosition(offset: 1), ui.Rect.zero);
|
||||||
expect(caretOffset.dx, 0);
|
expect(caretOffset.dx, 0);
|
||||||
|
painter.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('TextPainter caret emoji test', () {
|
test('TextPainter caret emoji test', () {
|
||||||
@ -144,6 +147,7 @@ void main() {
|
|||||||
expect(caretOffset.dx, 98); // <medium skin tone modifier>
|
expect(caretOffset.dx, 98); // <medium skin tone modifier>
|
||||||
caretOffset = painter.getOffsetForCaret(const ui.TextPosition(offset: 23), ui.Rect.zero);
|
caretOffset = painter.getOffsetForCaret(const ui.TextPosition(offset: 23), ui.Rect.zero);
|
||||||
expect(caretOffset.dx, 126); // end of string
|
expect(caretOffset.dx, 126); // end of string
|
||||||
|
painter.dispose();
|
||||||
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/56308
|
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/56308
|
||||||
|
|
||||||
test('TextPainter caret center space test', () {
|
test('TextPainter caret center space test', () {
|
||||||
@ -166,6 +170,7 @@ void main() {
|
|||||||
expect(caretOffset.dx, 35);
|
expect(caretOffset.dx, 35);
|
||||||
caretOffset = painter.getOffsetForCaret(const ui.TextPosition(offset: 2), ui.Rect.zero);
|
caretOffset = painter.getOffsetForCaret(const ui.TextPosition(offset: 2), ui.Rect.zero);
|
||||||
expect(caretOffset.dx, 49);
|
expect(caretOffset.dx, 49);
|
||||||
|
painter.dispose();
|
||||||
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/56308
|
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/56308
|
||||||
|
|
||||||
test('TextPainter error test', () {
|
test('TextPainter error test', () {
|
||||||
@ -180,6 +185,7 @@ void main() {
|
|||||||
e.toString(),
|
e.toString(),
|
||||||
contains('TextPainter.paint called when text geometry was not yet calculated'),
|
contains('TextPainter.paint called when text geometry was not yet calculated'),
|
||||||
);
|
);
|
||||||
|
painter.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('TextPainter requires textDirection', () {
|
test('TextPainter requires textDirection', () {
|
||||||
@ -203,6 +209,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
painter.layout();
|
painter.layout();
|
||||||
expect(painter.size, const Size(123.0, 123.0));
|
expect(painter.size, const Size(123.0, 123.0));
|
||||||
|
painter.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('TextPainter textScaleFactor test', () {
|
test('TextPainter textScaleFactor test', () {
|
||||||
@ -220,6 +227,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
painter.layout();
|
painter.layout();
|
||||||
expect(painter.size, const Size(20.0, 20.0));
|
expect(painter.size, const Size(20.0, 20.0));
|
||||||
|
painter.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('TextPainter textScaleFactor null style test', () {
|
test('TextPainter textScaleFactor null style test', () {
|
||||||
@ -232,6 +240,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
painter.layout();
|
painter.layout();
|
||||||
expect(painter.size, const Size(28.0, 28.0));
|
expect(painter.size, const Size(28.0, 28.0));
|
||||||
|
painter.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('TextPainter default text height is 14 pixels', () {
|
test('TextPainter default text height is 14 pixels', () {
|
||||||
@ -242,6 +251,7 @@ void main() {
|
|||||||
painter.layout();
|
painter.layout();
|
||||||
expect(painter.preferredLineHeight, 14.0);
|
expect(painter.preferredLineHeight, 14.0);
|
||||||
expect(painter.size, const Size(14.0, 14.0));
|
expect(painter.size, const Size(14.0, 14.0));
|
||||||
|
painter.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('TextPainter sets paragraph size from root', () {
|
test('TextPainter sets paragraph size from root', () {
|
||||||
@ -252,6 +262,7 @@ void main() {
|
|||||||
painter.layout();
|
painter.layout();
|
||||||
expect(painter.preferredLineHeight, 100.0);
|
expect(painter.preferredLineHeight, 100.0);
|
||||||
expect(painter.size, const Size(100.0, 100.0));
|
expect(painter.size, const Size(100.0, 100.0));
|
||||||
|
painter.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('TextPainter intrinsic dimensions', () {
|
test('TextPainter intrinsic dimensions', () {
|
||||||
@ -273,6 +284,7 @@ void main() {
|
|||||||
expect(painter.size, const Size(50.0, 10.0));
|
expect(painter.size, const Size(50.0, 10.0));
|
||||||
expect(painter.minIntrinsicWidth, 10.0);
|
expect(painter.minIntrinsicWidth, 10.0);
|
||||||
expect(painter.maxIntrinsicWidth, 50.0);
|
expect(painter.maxIntrinsicWidth, 50.0);
|
||||||
|
painter.dispose();
|
||||||
|
|
||||||
painter = TextPainter(
|
painter = TextPainter(
|
||||||
text: const TextSpan(
|
text: const TextSpan(
|
||||||
@ -286,6 +298,7 @@ void main() {
|
|||||||
expect(painter.size, const Size(50.0, 10.0));
|
expect(painter.size, const Size(50.0, 10.0));
|
||||||
expect(painter.minIntrinsicWidth, 50.0);
|
expect(painter.minIntrinsicWidth, 50.0);
|
||||||
expect(painter.maxIntrinsicWidth, 50.0);
|
expect(painter.maxIntrinsicWidth, 50.0);
|
||||||
|
painter.dispose();
|
||||||
|
|
||||||
painter = TextPainter(
|
painter = TextPainter(
|
||||||
text: const TextSpan(
|
text: const TextSpan(
|
||||||
@ -299,6 +312,7 @@ void main() {
|
|||||||
expect(painter.size, const Size(80.0, 10.0));
|
expect(painter.size, const Size(80.0, 10.0));
|
||||||
expect(painter.minIntrinsicWidth, 40.0);
|
expect(painter.minIntrinsicWidth, 40.0);
|
||||||
expect(painter.maxIntrinsicWidth, 80.0);
|
expect(painter.maxIntrinsicWidth, 80.0);
|
||||||
|
painter.dispose();
|
||||||
|
|
||||||
painter = TextPainter(
|
painter = TextPainter(
|
||||||
text: const TextSpan(
|
text: const TextSpan(
|
||||||
@ -312,6 +326,7 @@ void main() {
|
|||||||
expect(painter.size, const Size(110.0, 10.0));
|
expect(painter.size, const Size(110.0, 10.0));
|
||||||
expect(painter.minIntrinsicWidth, 70.0);
|
expect(painter.minIntrinsicWidth, 70.0);
|
||||||
expect(painter.maxIntrinsicWidth, 110.0);
|
expect(painter.maxIntrinsicWidth, 110.0);
|
||||||
|
painter.dispose();
|
||||||
|
|
||||||
painter = TextPainter(
|
painter = TextPainter(
|
||||||
text: const TextSpan(
|
text: const TextSpan(
|
||||||
@ -325,6 +340,7 @@ void main() {
|
|||||||
expect(painter.size, const Size(180.0, 10.0));
|
expect(painter.size, const Size(180.0, 10.0));
|
||||||
expect(painter.minIntrinsicWidth, 90.0);
|
expect(painter.minIntrinsicWidth, 90.0);
|
||||||
expect(painter.maxIntrinsicWidth, 180.0);
|
expect(painter.maxIntrinsicWidth, 180.0);
|
||||||
|
painter.dispose();
|
||||||
|
|
||||||
painter = TextPainter(
|
painter = TextPainter(
|
||||||
text: const TextSpan(
|
text: const TextSpan(
|
||||||
@ -338,6 +354,7 @@ void main() {
|
|||||||
expect(painter.size, const Size(180.0, 10.0));
|
expect(painter.size, const Size(180.0, 10.0));
|
||||||
expect(painter.minIntrinsicWidth, 90.0);
|
expect(painter.minIntrinsicWidth, 90.0);
|
||||||
expect(painter.maxIntrinsicWidth, 180.0);
|
expect(painter.maxIntrinsicWidth, 180.0);
|
||||||
|
painter.dispose();
|
||||||
}, skip: true); // https://github.com/flutter/flutter/issues/13512
|
}, skip: true); // https://github.com/flutter/flutter/issues/13512
|
||||||
|
|
||||||
test('TextPainter handles newlines properly', () {
|
test('TextPainter handles newlines properly', () {
|
||||||
@ -679,6 +696,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
expect(caretOffset.dx, moreOrLessEquals(0.0, epsilon: 0.0001));
|
expect(caretOffset.dx, moreOrLessEquals(0.0, epsilon: 0.0001));
|
||||||
expect(caretOffset.dy, moreOrLessEquals(0.0, epsilon: 0.0001));
|
expect(caretOffset.dy, moreOrLessEquals(0.0, epsilon: 0.0001));
|
||||||
|
painter.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('TextPainter widget span', () {
|
test('TextPainter widget span', () {
|
||||||
@ -773,6 +791,7 @@ void main() {
|
|||||||
expect(painter.inlinePlaceholderBoxes![11], const TextBox.fromLTRBD(250, 30, 300, 60, TextDirection.ltr));
|
expect(painter.inlinePlaceholderBoxes![11], const TextBox.fromLTRBD(250, 30, 300, 60, TextDirection.ltr));
|
||||||
expect(painter.inlinePlaceholderBoxes![12], const TextBox.fromLTRBD(300, 30, 351, 60, TextDirection.ltr));
|
expect(painter.inlinePlaceholderBoxes![12], const TextBox.fromLTRBD(300, 30, 351, 60, TextDirection.ltr));
|
||||||
expect(painter.inlinePlaceholderBoxes![13], const TextBox.fromLTRBD(351, 30, 401, 60, TextDirection.ltr));
|
expect(painter.inlinePlaceholderBoxes![13], const TextBox.fromLTRBD(351, 30, 401, 60, TextDirection.ltr));
|
||||||
|
painter.dispose();
|
||||||
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/87540
|
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/87540
|
||||||
|
|
||||||
// Null values are valid. See https://github.com/flutter/flutter/pull/48346#issuecomment-584839221
|
// Null values are valid. See https://github.com/flutter/flutter/pull/48346#issuecomment-584839221
|
||||||
@ -782,6 +801,7 @@ void main() {
|
|||||||
|
|
||||||
painter.textHeightBehavior = const TextHeightBehavior();
|
painter.textHeightBehavior = const TextHeightBehavior();
|
||||||
painter.textHeightBehavior = null;
|
painter.textHeightBehavior = null;
|
||||||
|
painter.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('TextPainter line metrics', () {
|
test('TextPainter line metrics', () {
|
||||||
@ -846,6 +866,7 @@ void main() {
|
|||||||
expect(lines[1].lineNumber, 1);
|
expect(lines[1].lineNumber, 1);
|
||||||
expect(lines[2].lineNumber, 2);
|
expect(lines[2].lineNumber, 2);
|
||||||
expect(lines[3].lineNumber, 3);
|
expect(lines[3].lineNumber, 3);
|
||||||
|
painter.dispose();
|
||||||
}, skip: true); // https://github.com/flutter/flutter/issues/62819
|
}, skip: true); // https://github.com/flutter/flutter/issues/62819
|
||||||
|
|
||||||
test('TextPainter caret height and line height', () {
|
test('TextPainter caret height and line height', () {
|
||||||
@ -862,6 +883,7 @@ void main() {
|
|||||||
ui.Rect.zero,
|
ui.Rect.zero,
|
||||||
)!;
|
)!;
|
||||||
expect(caretHeight, 50.0);
|
expect(caretHeight, 50.0);
|
||||||
|
painter.dispose();
|
||||||
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/56308
|
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/56308
|
||||||
|
|
||||||
group('TextPainter line-height', () {
|
group('TextPainter line-height', () {
|
||||||
@ -886,6 +908,7 @@ void main() {
|
|||||||
expect(insets.top, insets.bottom);
|
expect(insets.top, insets.bottom);
|
||||||
// The glyph box is exactly 1 logical pixel high.
|
// The glyph box is exactly 1 logical pixel high.
|
||||||
expect(insets.top, (20 - 1) / 2);
|
expect(insets.top, (20 - 1) / 2);
|
||||||
|
painter.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('half-leading with small height', () {
|
test('half-leading with small height', () {
|
||||||
@ -910,6 +933,7 @@ void main() {
|
|||||||
// The glyph box is exactly 10 logical pixel high (the height multiplier
|
// The glyph box is exactly 10 logical pixel high (the height multiplier
|
||||||
// does not scale the glyph). Negative leading.
|
// does not scale the glyph). Negative leading.
|
||||||
expect(insets.top, (1 - 10) / 2);
|
expect(insets.top, (1 - 10) / 2);
|
||||||
|
painter.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('half-leading with leading trim', () {
|
test('half-leading with leading trim', () {
|
||||||
@ -935,6 +959,7 @@ void main() {
|
|||||||
expect(painter.size, glyphBox.size);
|
expect(painter.size, glyphBox.size);
|
||||||
// The glyph box is still centered.
|
// The glyph box is still centered.
|
||||||
expect(glyphBox.topLeft, Offset.zero);
|
expect(glyphBox.topLeft, Offset.zero);
|
||||||
|
painter.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('TextLeadingDistribution falls back to paragraph style', () {
|
test('TextLeadingDistribution falls back to paragraph style', () {
|
||||||
@ -955,6 +980,7 @@ void main() {
|
|||||||
final RelativeRect insets = RelativeRect.fromSize(glyphBox, painter.size);
|
final RelativeRect insets = RelativeRect.fromSize(glyphBox, painter.size);
|
||||||
expect(insets.top, insets.bottom);
|
expect(insets.top, insets.bottom);
|
||||||
expect(insets.top, (20 - 1) / 2);
|
expect(insets.top, (20 - 1) / 2);
|
||||||
|
painter.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('TextLeadingDistribution does nothing if height multiplier is null', () {
|
test('TextLeadingDistribution does nothing if height multiplier is null', () {
|
||||||
@ -978,6 +1004,7 @@ void main() {
|
|||||||
const TextSelection(baseOffset: 0, extentOffset: 1),
|
const TextSelection(baseOffset: 0, extentOffset: 1),
|
||||||
).first.toRect();
|
).first.toRect();
|
||||||
expect(glyphBox, newGlyphBox);
|
expect(glyphBox, newGlyphBox);
|
||||||
|
painter.dispose();
|
||||||
});
|
});
|
||||||
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/87543
|
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/87543
|
||||||
|
|
||||||
@ -997,6 +1024,7 @@ void main() {
|
|||||||
// The layout should include one replacement character.
|
// The layout should include one replacement character.
|
||||||
expect(painter.width, equals(fontSize));
|
expect(painter.width, equals(fontSize));
|
||||||
expect(exception, isNotNull);
|
expect(exception, isNotNull);
|
||||||
|
painter.dispose();
|
||||||
}, skip: kIsWeb); // https://github.com/flutter/flutter/issues/87544
|
}, skip: kIsWeb); // https://github.com/flutter/flutter/issues/87544
|
||||||
|
|
||||||
test('Diacritic', () {
|
test('Diacritic', () {
|
||||||
@ -1013,6 +1041,7 @@ void main() {
|
|||||||
offset: text.length, affinity: TextAffinity.upstream),
|
offset: text.length, affinity: TextAffinity.upstream),
|
||||||
ui.Rect.zero);
|
ui.Rect.zero);
|
||||||
expect(caretOffset.dx, painter.width);
|
expect(caretOffset.dx, painter.width);
|
||||||
|
painter.dispose();
|
||||||
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/87545
|
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/87545
|
||||||
|
|
||||||
test('TextPainter line metrics update after layout', () {
|
test('TextPainter line metrics update after layout', () {
|
||||||
@ -1033,6 +1062,7 @@ void main() {
|
|||||||
|
|
||||||
lines = painter.computeLineMetrics();
|
lines = painter.computeLineMetrics();
|
||||||
expect(lines.length, 1);
|
expect(lines.length, 1);
|
||||||
|
painter.dispose();
|
||||||
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/62819
|
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/62819
|
||||||
|
|
||||||
test('TextPainter throws with stack trace when accessing text layout', () {
|
test('TextPainter throws with stack trace when accessing text layout', () {
|
||||||
@ -1068,6 +1098,7 @@ void main() {
|
|||||||
|
|
||||||
expect(exception?.message, contains('The calls that first invalidated the text layout were:'));
|
expect(exception?.message, contains('The calls that first invalidated the text layout were:'));
|
||||||
exception = null;
|
exception = null;
|
||||||
|
painter.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('TextPainter requires layout after providing different placeholder dimensions', () {
|
test('TextPainter requires layout after providing different placeholder dimensions', () {
|
||||||
@ -1105,6 +1136,7 @@ void main() {
|
|||||||
e.toString(),
|
e.toString(),
|
||||||
contains('TextPainter.paint called when text geometry was not yet calculated'),
|
contains('TextPainter.paint called when text geometry was not yet calculated'),
|
||||||
);
|
);
|
||||||
|
painter.dispose();
|
||||||
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/56308
|
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/56308
|
||||||
|
|
||||||
test('TextPainter does not require layout after providing identical placeholder dimensions', () {
|
test('TextPainter does not require layout after providing identical placeholder dimensions', () {
|
||||||
@ -1143,7 +1175,15 @@ void main() {
|
|||||||
e.toString(),
|
e.toString(),
|
||||||
isNot(contains('TextPainter.paint called when text geometry was not yet calculated')),
|
isNot(contains('TextPainter.paint called when text geometry was not yet calculated')),
|
||||||
);
|
);
|
||||||
|
painter.dispose();
|
||||||
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/56308
|
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/56308
|
||||||
|
|
||||||
|
test('TextPainter - debugDisposed', () {
|
||||||
|
final TextPainter painter = TextPainter();
|
||||||
|
expect(painter.debugDisposed, false);
|
||||||
|
painter.dispose();
|
||||||
|
expect(painter.debugDisposed, true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class MockCanvas extends Fake implements Canvas {
|
class MockCanvas extends Fake implements Canvas {
|
||||||
|
@ -1070,6 +1070,7 @@ void main() {
|
|||||||
final ui.Paragraph paragraph = builder.build();
|
final ui.Paragraph paragraph = builder.build();
|
||||||
paragraph.layout(const ui.ParagraphConstraints(width: 1000));
|
paragraph.layout(const ui.ParagraphConstraints(width: 1000));
|
||||||
expect(paragraph.getBoxesForRange(2, 2), isEmpty);
|
expect(paragraph.getBoxesForRange(2, 2), isEmpty);
|
||||||
|
paragraph.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Regression test for https://github.com/flutter/flutter/issues/65818
|
// Regression test for https://github.com/flutter/flutter/issues/65818
|
||||||
|
Loading…
x
Reference in New Issue
Block a user