Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 8ef3af3

Browse files
author
Jonah Williams
authored
[ui] fix missing color conversion in drawAtlas. (#54750)
Ensure that int32 ui colors are correctly converted to Dl Colors (convert instead of reinterpret cast).
1 parent d370085 commit 8ef3af3

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

lib/ui/painting/canvas.cc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -596,12 +596,17 @@ Dart_Handle Canvas::drawAtlas(Dart_Handle paint_objects,
596596
tonic::Int32List colors(colors_handle);
597597
tonic::Float32List cull_rect(cull_rect_handle);
598598

599+
std::vector<DlColor> dl_color(colors.num_elements());
600+
size_t count = colors.num_elements();
601+
for (size_t i = 0; i < count; i++) {
602+
dl_color[i] = DlColor(colors[i]);
603+
}
604+
599605
DlPaint dl_paint;
600606
const DlPaint* opt_paint = paint.paint(dl_paint, kDrawAtlasWithPaintFlags);
601607
builder()->DrawAtlas(
602608
dl_image, reinterpret_cast<const SkRSXform*>(transforms.data()),
603-
reinterpret_cast<const SkRect*>(rects.data()),
604-
reinterpret_cast<const DlColor*>(colors.data()),
609+
reinterpret_cast<const SkRect*>(rects.data()), dl_color.data(),
605610
rects.num_elements() / 4, // SkRect have four floats.
606611
blend_mode, sampling, reinterpret_cast<const SkRect*>(cull_rect.data()),
607612
opt_paint);

testing/dart/canvas_test.dart

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,52 @@ void main() async {
12671267
expect(paintCopy.colorFilter, equals(const ColorFilter.mode(Color(0xFF00FF00), BlendMode.color)));
12681268
expect(paintCopy.imageFilter, equals(ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0)));
12691269
});
1270+
1271+
test('DrawAtlas correctly copies color values into display list format', () async {
1272+
final Image testImage = await createTestImage();
1273+
final PictureRecorder recorder = PictureRecorder();
1274+
final Canvas canvas = Canvas(recorder);
1275+
// Make a drawAtlas call that should be solid red.
1276+
canvas.drawAtlas(
1277+
testImage,
1278+
[
1279+
RSTransform.fromComponents(
1280+
rotation: 0,
1281+
scale: 10,
1282+
anchorX: 0,
1283+
anchorY: 0,
1284+
translateX: 0,
1285+
translateY: 0,
1286+
),
1287+
],
1288+
[
1289+
const Rect.fromLTWH(0, 0, 1, 1)
1290+
],
1291+
[
1292+
const Color.fromARGB(255, 255, 0, 0)
1293+
],
1294+
BlendMode.dst,
1295+
null,
1296+
Paint(),
1297+
);
1298+
1299+
final Image resultImage = await recorder.endRecording().toImage(1, 1);
1300+
final ByteData? data = await resultImage.toByteData();
1301+
if (data == null) {
1302+
fail('Expected non-null byte data');
1303+
return;
1304+
}
1305+
final int rgba = data.buffer.asUint32List()[0];
1306+
expect(rgba, 0xFF0000FF);
1307+
});
1308+
}
1309+
1310+
Future<Image> createTestImage() async {
1311+
final PictureRecorder recorder = PictureRecorder();
1312+
final Canvas recorderCanvas = Canvas(recorder);
1313+
recorderCanvas.scale(1.0, 1.0);
1314+
final Picture picture = recorder.endRecording();
1315+
return picture.toImage(1, 1);
12701316
}
12711317

12721318
Matcher listEquals(ByteData expected) => (dynamic v) {

0 commit comments

Comments
 (0)