Skip to content

Instantly share code, notes, and snippets.

@venkatd
Last active November 22, 2020 21:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save venkatd/86c0185e38d5a482c2f04ecf5aeb057b to your computer and use it in GitHub Desktop.
Save venkatd/86c0185e38d5a482c2f04ecf5aeb057b to your computer and use it in GitHub Desktop.
import 'package:flutter/widgets.dart';
// original credit to https://medium.com/swlh/flutter-line-metrics-fd98ab180a64
class LineMetricsDebug extends StatelessWidget {
LineMetricsDebug({
this.text,
this.style,
this.width,
this.height,
}) : assert(text != null),
assert(style != null),
assert(width != null),
assert(height != null);
final String text;
final TextStyle style;
final double width;
final double height;
@override
Widget build(BuildContext context) {
return CustomPaint(
size: Size(width, height),
painter: _LineMetricsDebugPainter(
text: text,
style: style,
width: width,
height: height,
),
);
}
}
const _redColor = Color(0xFFF44336);
const _blueColor = Color(0xFF2196F3);
class _LineMetricsDebugPainter extends CustomPainter {
_LineMetricsDebugPainter({
@required this.text,
@required this.style,
@required this.width,
@required this.height,
}) : assert(text != null),
assert(style != null),
assert(width != null),
assert(height != null);
final String text;
final TextStyle style;
final double width;
final double height;
final bluePaint = Paint()
..color = _blueColor
..style = PaintingStyle.stroke
..strokeWidth = 1;
final redPaint = Paint()
..color = _redColor
..style = PaintingStyle.stroke
..strokeWidth = 1;
@override
void paint(Canvas canvas, Size size) {
final textSpan = TextSpan(text: text, style: style);
final textPainter = TextPainter(
text: textSpan,
textDirection: TextDirection.ltr,
);
textPainter.layout(
minWidth: 0,
maxWidth: size.width,
);
textPainter.paint(canvas, Offset.zero);
final lines = textPainter.computeLineMetrics();
for (final line in lines) {
final baseline = line.baseline;
final left = line.left;
final top = line.baseline - line.ascent;
final right = left + line.width;
final bottom = line.baseline + line.descent;
final rect = Rect.fromLTRB(left, top, right, bottom);
canvas.drawLine(
Offset(left, baseline),
Offset(right, baseline),
bluePaint,
);
canvas.drawRect(rect, redPaint);
}
}
@override
bool shouldRepaint(CustomPainter old) => false;
}
import 'package:flutter/material.dart';
import 'line_metrics_debug.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: LineMetricsTester(),
),
);
}
}
class LineMetricsTester extends StatefulWidget {
@override
_LineMetricsTesterState createState() => _LineMetricsTesterState();
}
class _LineMetricsTesterState extends State<LineMetricsTester> {
var text = 'My text line.\nThis line wraps to the next.\nAnother line.';
var style = const TextStyle(color: Colors.black, fontSize: 30);
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 300,
height: 300,
child: TextFormField(
style: style,
maxLines: 10,
initialValue: text,
onChanged: (value) {
setState(() {
text = value;
});
},
),
),
const SizedBox(height: 10),
Container(
alignment: Alignment.center,
child: LineMetricsDebug(
text: text,
style: style,
width: 300,
height: 300,
),
),
],
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment