-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Closed
Labels
r: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer version
Description
This is a low level issue that causes other problems whenever line metrics from Skia paragraph renderer are used - e.g. vertical runs using keyboad Down/Up buttons when editing text.
It exists on all platforms but it's more easily seen on desktop.
Steps to Reproduce
- Execute
flutter runon the code sample on destkop - Click on the floating button to read the last text metrics and total paragraph height from TextPainter
- Resize the app window so that the number of text lines is different
- Click on the floating button again to update the metrics
Expected results: Line metrics change alongside total height
Actual results: Line metrics don't change
Code sample
import 'dart:math' as math;
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final GlobalKey _paragraphKey = GlobalKey();
List<String> _lineMetricData = <String>[];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Paragraph(
key: _paragraphKey,
inlineSpan: const TextSpan(
text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do '
'eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim '
'ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut '
'aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit '
'in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur '
'sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt '
'mollit anim id est laborum.',
style: TextStyle(fontSize: 16.0, color: Colors.black),
),
),
const SizedBox(height: 50.0),
for (String metricData in _lineMetricData) Text(metricData),
],
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.abc),
onPressed: _getLineMetrics,
),
);
}
void _getLineMetrics() {
RenderParagraph renderParagraph = _paragraphKey.currentContext!.findRenderObject()! as RenderParagraph;
List<ui.LineMetrics> lineMetrics = renderParagraph.lineMetrics;
_lineMetricData = lineMetrics.map((metrics) => '#${metrics.lineNumber} baseLine=${metrics.baseline}').toList();
_lineMetricData.add('Total text height: ${renderParagraph.height}');
setState(() { });
}
}
class Paragraph extends SingleChildRenderObjectWidget {
const Paragraph({Key? key, required this.inlineSpan}) : super(key: key);
final InlineSpan inlineSpan;
@override
RenderParagraph createRenderObject(BuildContext context) {
return RenderParagraph(inlineSpan: inlineSpan);
}
}
class RenderParagraph extends RenderBox {
RenderParagraph({required this.inlineSpan})
: _textPainter = TextPainter(
text: inlineSpan,
textDirection: TextDirection.ltr,
);
final InlineSpan inlineSpan;
final TextPainter _textPainter;
List<ui.LineMetrics> get lineMetrics => _textPainter.computeLineMetrics();
double get height => _textPainter.height;
@override
double computeMinIntrinsicWidth(double height) {
_layoutText();
return _textPainter.minIntrinsicWidth;
}
@override
double computeMaxIntrinsicWidth(double height) {
_layoutText();
return _textPainter.maxIntrinsicWidth;
}
@override
Size computeDryLayout(BoxConstraints constraints) {
_layoutText(minWidth: constraints.minWidth, maxWidth: constraints.maxWidth);
return Size(constraints.maxWidth, _textPainter.height);
}
@override
void performLayout() {
final BoxConstraints constraints = this.constraints;
_layoutText(minWidth: constraints.minWidth, maxWidth: constraints.maxWidth);
size = Size(math.min(_textPainter.width, constraints.maxWidth), _textPainter.height);
}
void _layoutText({double minWidth = 0.0, double maxWidth = double.infinity}) {
final double availableMaxWidth = math.max(0.0, maxWidth);
_textPainter.layout(minWidth: availableMaxWidth, maxWidth: availableMaxWidth);
}
@override
void paint(PaintingContext context, Offset offset) {
_textPainter.paint(context.canvas, offset);
}
}Logs
% flutter doctor -v
[✓] Flutter (Channel master, 2.9.0-1.0.pre.494, on macOS 12.1 21C52 darwin-x64, locale en-GB)
• Flutter version 2.9.0-1.0.pre.494 at /Library/Frameworks/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 78de12b82f (23 hours ago), 2022-01-25 09:55:10 -0800
• Engine revision b5162c93f5
• Dart version 2.17.0 (build 2.17.0-51.0.dev)
• DevTools version 2.9.2
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
• Android SDK at /Users/tgucio/Library/Android/sdk
• Platform android-31, build-tools 30.0.3
• Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 13.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• CocoaPods version 1.11.2
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2020.3)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165)
[✓] VS Code (version 1.63.2)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.32.0
[✓] Connected device (2 available)
• macOS (desktop) • macos • darwin-x64 • macOS 12.1 21C52 darwin-x64
• Chrome (web) • chrome • web-javascript • Google Chrome 97.0.4692.99
[✓] HTTP Host Availability
• All required HTTP hosts are available
• No issues found!
Metadata
Metadata
Assignees
Labels
r: fixedIssue is closed as already fixed in a newer versionIssue is closed as already fixed in a newer version