Last active
February 4, 2026 22:42
-
-
Save flar/aaaea226126c5e435f6cf25fe5fbd7b1 to your computer and use it in GitHub Desktop.
Second attempt to demonstrate issue with caching FrameData in TextFrame in Impeller
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import 'dart:math'; | |
| import 'dart:ui'; | |
| import 'package:flutter/material.dart'; | |
| void main() { | |
| runApp(const MyApp()); | |
| } | |
| class MyApp extends StatelessWidget { | |
| const MyApp({super.key}); | |
| @override | |
| Widget build(BuildContext context) { | |
| return MaterialApp( | |
| title: 'Flutter Demo', | |
| theme: ThemeData( | |
| colorScheme: .fromSeed(seedColor: Colors.deepPurple), | |
| ), | |
| home: const MyHomePage(title: 'Flutter Demo Home Page'), | |
| ); | |
| } | |
| } | |
| class MyHomePage extends StatefulWidget { | |
| const MyHomePage({super.key, required this.title}); | |
| final String title; | |
| @override | |
| State<MyHomePage> createState() => _MyHomePageState(); | |
| } | |
| class _MyHomePageState extends State<MyHomePage> { | |
| bool reuseDisplayList = true; | |
| @override | |
| Widget build(BuildContext context) { | |
| return Scaffold( | |
| appBar: AppBar( | |
| backgroundColor: Theme.of(context).colorScheme.inversePrimary, | |
| title: Text(widget.title), | |
| ), | |
| body: Center( | |
| child: CustomPaint( | |
| painter: _MyPainter(reuseDisplayList: reuseDisplayList), | |
| size: Size(600, 400), | |
| ), | |
| ), | |
| bottomNavigationBar: BottomAppBar( | |
| child: Row( | |
| mainAxisAlignment: .center, | |
| children: [ | |
| Text('Reuse DL: '), | |
| Checkbox(value: reuseDisplayList, onChanged: (value) { | |
| setState(() { | |
| reuseDisplayList = value!; | |
| }); | |
| },) | |
| ], | |
| ), | |
| ), | |
| ); | |
| } | |
| } | |
| class _MyPainter extends CustomPainter { | |
| static final Random random = Random(); | |
| static final staticPicture = makePicture(); | |
| static Picture makePicture() { | |
| PictureRecorder recorder = PictureRecorder(); | |
| Canvas canvas = Canvas(recorder, Rect.fromLTRB(0, 0, 40, 40)); | |
| canvas.drawRect( | |
| Rect.fromLTRB(5, 5, 35, 35), | |
| Paint() | |
| ..color = Colors.blue | |
| ..strokeWidth = 2 | |
| ..style = .stroke, | |
| ); | |
| TextSpan span = TextSpan( | |
| text: 'Hi', | |
| style: TextStyle(color: Colors.purple), | |
| ); | |
| TextPainter painter = TextPainter( | |
| text: span, | |
| textDirection: .ltr, | |
| textAlign: .center | |
| ); | |
| painter.layout(); | |
| Offset offset = Offset( | |
| (40 - painter.width) * 0.5, | |
| (40 - painter.height) * 0.5); | |
| painter.paint(canvas, offset); | |
| return recorder.endRecording(); | |
| } | |
| _MyPainter({required this.reuseDisplayList}); | |
| final bool reuseDisplayList; | |
| @override | |
| void paint(Canvas canvas, Size size) { | |
| for (int x = 0; x < size.width; x += 40) { | |
| for (int y = 0; y < size.height; y += 40) { | |
| canvas.save(); | |
| double zoom = random.nextDouble() * 0.75 + 0.5; | |
| canvas.translate(x + 20, y + 20); | |
| canvas.scale(zoom, zoom); | |
| canvas.translate(-20, -20); | |
| canvas.drawPicture(reuseDisplayList ? staticPicture : makePicture()); | |
| canvas.restore(); | |
| } | |
| } | |
| } | |
| @override | |
| bool shouldRepaint(covariant CustomPainter oldDelegate) => true; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment