Open pskink opened 3 months ago
Reproducible using the code sample provided above.
Labeling for futher investigation.
forgot to add that the problem occurs both in x and y axis (when the bottom edge of center
rect is equal to the bottom edge of drawn nine-patch image
)
FYI @flar I think you are the only person I know that actually understands drawImageNine, so you might be able to confirm/deny the bug here.
@pskink just to confirm, this is running on Android?
@jonahwilliams, it's Linux desktop
I can demonstrate this with Skia directly: https://fiddle.skia.org/c/122ecd0e0c45ad7f3866106fbd2f93bb
It looks like Impeller will happily render out of the bounds which is inconsistent with historic behavior (if we added an edge sampling mode, it might be appropriate, though)
The asymmetry between the second and the second-to-last images in the example appears to be a quirk of Skia's implementation.
The second image is using the center rectangle Rect.fromLTRB(0.0, 2.0, 4.0, 6.0)
which lies along the left border of the source image. The logic in SkLatticeIter::Valid
consider this to be valid.
The second-to-last image is using the center rectangle Rect.fromLTRB(4.0, 2.0, 8.0, 6.0)
which lies along the right border. SkLatticeIter::Valid
rejects this, so SkCanvas::drawImageNine
and SkCanvas::drawImageLattice
just draw the input image without the nine patch effect.
As seen above, Impeller does not do the SkLatticeIter::Valid
checks and always tries to render a nine patch even if the center rectangle is out of bounds.
I filed a bug against Skia: https://issuetracker.google.com/issues/349428795
And running on web:
Steps to reproduce
run the attached code, it will call
Canvas.drawImageNine
7 times, each case contains two images: the left one is the result of callingCanvas.drawImageNine
while the right image shows how thecenter
parameter is positioned within inputui.Image
Expected results
i would expect the case 6 (the one with the red "center" rectangle) to be similar like the case 2 (only reversed / mirrored)
Actual results
the case 6 is the same as cases 1 and 7 where the "center" rectangle is invalid (it is not completely within the image bounds), also i would like to know if the way the image is drawn in those two cases is correct since the official docs don't mention how to deal with the incorrect "center" rect
Code sample
Code sample
```dart import 'dart:typed_data'; import 'dart:ui' as ui; import 'package:flutter/material.dart'; late ui.Image nineImage; void main() async { WidgetsFlutterBinding.ensureInitialized(); final bytes = [ 0x52, 0x49, 0x46, 0x46, 0x46, 0x00, 0x00, 0x00, 0x57, 0x45, 0x42, 0x50, 0x56, 0x50, 0x38, 0x4c, 0x39, 0x00, 0x00, 0x00, 0x2f, 0x07, 0xc0, 0x01, 0x00, 0x1f, 0x20, 0x24, 0x20, 0x9a, 0x03, 0x96, 0xfa, 0x1f, 0xdc, 0x10, 0xd3, 0x10, 0x09, 0x4c, 0xff, 0x8a, 0x22, 0xb8, 0xc4, 0x34, 0xc4, 0xa4, 0xd6, 0x4c, 0x36, 0xe7, 0xfc, 0x07, 0x54, 0xd1, 0xba, 0x81, 0x2c, 0xc0, 0x84, 0x61, 0x02, 0xd1, 0xec, 0x4b, 0x37, 0xa1, 0xac, 0x22, 0xfa, 0x1f, 0xa0, 0xcf, 0xfa, 0xac, 0xa0, 0x00, ]; nineImage = await decodeImageFromList(Uint8List.fromList(bytes)); runApp(MaterialApp( home: Scaffold( body: Padding( padding: const EdgeInsets.all(8), child: SizedBox.expand( child: CustomPaint( painter: FooPainter(), ), ), ), ), )); } class FooPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { double top = 0; final imagePaint = Paint()..color = Colors.black; final imageRect = Offset.zero & const Size(8, 8); for (int i = -1; i < 6; i++) { final center = Rect.fromLTWH(i.toDouble(), 2, 4, 4); final dst = Rect.fromLTWH(0, top, 64, 64); canvas ..drawImageNine(nineImage, center, dst, imagePaint) ..save() ..translate(dst.right + 8, dst.top) ..scale(dst.height / 8) ..translate(1, 0) ..drawRect(imageRect, imagePaint) ..drawRect(center, Paint()..color = switch(i) { -1 || 5 => const Color(0xffff8800), 4 => const Color(0xffff0000), _ => const Color(0xff00ff00), }) ..restore(); top += dst.height + 4; } } @override bool shouldRepaint(FooPainter oldDelegate) => false; } ```Screenshots or Video
Screenshots / Video demonstration
![screenshot](https://github.com/flutter/flutter/assets/5962376/a316de76-b055-4eb2-ba17-adeb39df681f)Logs
Logs
```console [Paste your logs here] ```Flutter Doctor output
Doctor output
```console Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel stable, 3.22.0, on Arch Linux 6.8.1-arch1-1, locale C.UTF-8) [!] Android toolchain - develop for Android devices (Android SDK version 30.0.3) ✗ Could not determine java version [✓] Chrome - develop for the web [✓] Linux toolchain - develop for Linux desktop [✓] Android Studio (version 4.0) [✓] Android Studio (version 3.4) [✓] Android Studio (version 3.6) [✓] Android Studio (version 3.5) [✓] IntelliJ IDEA Community Edition (version 2017.1) [✓] IntelliJ IDEA Community Edition (version 2023.2) [✓] Connected device (3 available) [✓] Network resources ! Doctor found issues in 1 category. ```