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

Commit 24b99d5

Browse files
author
Harry Terkelsen
authored
[web] Store Paint.color as an int. Only create a ui.Color when the color getter is called. (#37092)
* Store color as the int value. Only create a color when getter is called * Refactor tests and painting * Change SurfacePaintData to have default opaque black color
1 parent 81f5c30 commit 24b99d5

22 files changed

+104
-103
lines changed

lib/web_ui/lib/src/engine/canvas_pool.dart

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,7 @@ class ContextStateHandle {
10121012
}
10131013
}
10141014
} else if (paint.color != null) {
1015-
final String? colorString = colorToCssString(paint.color);
1015+
final String? colorString = colorValueToCssString(paint.color);
10161016
fillStyle = colorString;
10171017
strokeStyle = colorString;
10181018
} else {
@@ -1036,12 +1036,8 @@ class ContextStateHandle {
10361036
if (maskFilter != null) {
10371037
context.save();
10381038
context.shadowBlur = convertSigmaToRadius(maskFilter.webOnlySigma);
1039-
if (paint.color != null) {
1040-
// Shadow color must be fully opaque.
1041-
context.shadowColor = colorToCssString(paint.color!.withAlpha(255));
1042-
} else {
1043-
context.shadowColor = colorToCssString(const ui.Color(0xFF000000));
1044-
}
1039+
// Shadow color must be fully opaque.
1040+
context.shadowColor = colorToCssString(ui.Color(paint.color).withAlpha(255));
10451041

10461042
// On the web a shadow must always be painted together with the shape
10471043
// that casts it. In order to paint just the shadow, we offset the shape

lib/web_ui/lib/src/engine/canvaskit/painting.dart

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import 'skia_object_cache.dart';
2121
class CkPaint extends ManagedSkiaObject<SkPaint> implements ui.Paint {
2222
CkPaint();
2323

24-
static const ui.Color _defaultPaintColor = ui.Color(0xFF000000);
24+
static const int _defaultPaintColor = 0xFF000000;
2525

2626
@override
2727
ui.BlendMode get blendMode => _blendMode;
@@ -103,18 +103,17 @@ class CkPaint extends ManagedSkiaObject<SkPaint> implements ui.Paint {
103103
bool _isAntiAlias = true;
104104

105105
@override
106-
ui.Color get color => _color;
106+
ui.Color get color => ui.Color(_color);
107107
@override
108108
set color(ui.Color value) {
109-
if (_color == value) {
109+
if (_color == value.value) {
110110
return;
111111
}
112-
_color =
113-
value.runtimeType == ui.Color ? value : ui.Color(value.value);
112+
_color = value.value;
114113
skiaObject.setColorInt(value.value);
115114
}
116115

117-
ui.Color _color = _defaultPaintColor;
116+
int _color = _defaultPaintColor;
118117

119118
@override
120119
bool get invertColors => _invertColors;
@@ -269,7 +268,7 @@ class CkPaint extends ManagedSkiaObject<SkPaint> implements ui.Paint {
269268
SkPaint createDefault() {
270269
final SkPaint paint = SkPaint();
271270
paint.setAntiAlias(_isAntiAlias);
272-
paint.setColorInt(_color.value);
271+
paint.setColorInt(_color);
273272
return paint;
274273
}
275274

@@ -282,7 +281,7 @@ class CkPaint extends ManagedSkiaObject<SkPaint> implements ui.Paint {
282281
paint.setStyle(toSkPaintStyle(_style));
283282
paint.setStrokeWidth(_strokeWidth);
284283
paint.setAntiAlias(_isAntiAlias);
285-
paint.setColorInt(_color.value);
284+
paint.setColorInt(_color);
286285
paint.setShader(_shader?.withQuality(_filterQuality));
287286
paint.setMaskFilter(_ckMaskFilter?.skiaObject);
288287
paint.setColorFilter(_effectiveColorFilter?.skiaObject);

lib/web_ui/lib/src/engine/html/bitmap_canvas.dart

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ class BitmapCanvas extends EngineCanvas {
399399
@override
400400
void drawColor(ui.Color color, ui.BlendMode blendMode) {
401401
final SurfacePaintData paintData = SurfacePaintData()
402-
..color = color
402+
..color = color.value
403403
..blendMode = blendMode;
404404
if (_useDomForRenderingFill(paintData)) {
405405
drawRect(_computeScreenBounds(_canvasPool.currentTransform), paintData);
@@ -592,8 +592,7 @@ class BitmapCanvas extends EngineCanvas {
592592
void _applyFilter(DomElement element, SurfacePaintData paint) {
593593
if (paint.maskFilter != null) {
594594
final bool isStroke = paint.style == ui.PaintingStyle.stroke;
595-
final String cssColor =
596-
paint.color == null ? '#000000' : colorToCssString(paint.color)!;
595+
final String cssColor = colorValueToCssString(paint.color)!;
597596
final double sigma = paint.maskFilter!.webOnlySigma;
598597
if (browserEngine == BrowserEngine.webkit && !isStroke) {
599598
// A bug in webkit leaves artifacts when this element is animated
@@ -1031,7 +1030,7 @@ class BitmapCanvas extends EngineCanvas {
10311030
: convertVertexPositions(mode, vertices.positions);
10321031
// Draw hairline for vertices if no vertex colors are specified.
10331032
save();
1034-
final ui.Color color = paint.color ?? const ui.Color(0xFF000000);
1033+
final ui.Color color = ui.Color(paint.color);
10351034
_canvasPool.contextHandle
10361035
..fillStyle = null
10371036
..strokeStyle = colorToCssString(color);
@@ -1059,7 +1058,7 @@ class BitmapCanvas extends EngineCanvas {
10591058
} else {
10601059
_drawPointsPaint.style = ui.PaintingStyle.fill;
10611060
}
1062-
_drawPointsPaint.color = paint.color ?? const ui.Color(0xFF000000);
1061+
_drawPointsPaint.color = paint.color;
10631062
_drawPointsPaint.maskFilter = paint.maskFilter;
10641063

10651064
final double dpr = ui.window.devicePixelRatio;

lib/web_ui/lib/src/engine/html/clip.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ class PersistedPhysicalShape extends PersistedContainerSurface
392392
path,
393393
SurfacePaintData()
394394
..style = ui.PaintingStyle.fill
395-
..color = color,
395+
..color = color.value,
396396
'${pathBounds2.right}',
397397
'${pathBounds2.bottom}');
398398

lib/web_ui/lib/src/engine/html/dom_canvas.dart

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -257,16 +257,15 @@ DomHTMLElement buildDrawRectElement(
257257
..transform = effectiveTransform;
258258

259259
String cssColor =
260-
paint.color == null ? '#000000' : colorToCssString(paint.color)!;
260+
paint.color == null ? '#000000' : colorValueToCssString(paint.color)!;
261261

262262
if (paint.maskFilter != null) {
263263
final double sigma = paint.maskFilter!.webOnlySigma;
264264
if (browserEngine == BrowserEngine.webkit && !isStroke) {
265265
// A bug in webkit leaves artifacts when this element is animated
266266
// with filter: blur, we use boxShadow instead.
267267
style.boxShadow = '0px 0px ${sigma * 2.0}px $cssColor';
268-
cssColor = colorToCssString(
269-
blurColor(paint.color ?? const ui.Color(0xFF000000), sigma))!;
268+
cssColor = colorToCssString(blurColor(ui.Color(paint.color), sigma))!;
270269
} else {
271270
style.filter = 'blur(${sigma}px)';
272271
}
@@ -345,16 +344,15 @@ SVGSVGElement pathToSvgElement(
345344

346345
final SVGPathElement svgPath = createSVGPathElement();
347346
root.append(svgPath);
348-
final ui.Color color = paint.color ?? const ui.Color(0xFF000000);
349347
if (paint.style == ui.PaintingStyle.stroke ||
350348
(paint.style != ui.PaintingStyle.fill &&
351349
paint.strokeWidth != 0 &&
352350
paint.strokeWidth != null)) {
353-
svgPath.setAttribute('stroke', colorToCssString(color)!);
351+
svgPath.setAttribute('stroke', colorValueToCssString(paint.color)!);
354352
svgPath.setAttribute('stroke-width', '${paint.strokeWidth ?? 1.0}');
355353
svgPath.setAttribute('fill', 'none');
356354
} else if (paint.color != null) {
357-
svgPath.setAttribute('fill', colorToCssString(color)!);
355+
svgPath.setAttribute('fill', colorValueToCssString(paint.color)!);
358356
} else {
359357
svgPath.setAttribute('fill', '#000000');
360358
}

lib/web_ui/lib/src/engine/html/painting.dart

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,15 @@ class SurfacePaint implements ui.Paint {
8383
}
8484

8585
@override
86-
ui.Color get color => _paintData.color ?? _defaultPaintColor;
86+
ui.Color get color => ui.Color(_paintData.color);
8787

8888
@override
8989
set color(ui.Color value) {
9090
if (_frozen) {
9191
_paintData = _paintData.clone();
9292
_frozen = false;
9393
}
94-
_paintData.color =
95-
value.runtimeType == ui.Color ? value : ui.Color(value.value);
94+
_paintData.color = value.value;
9695
}
9796

9897
@override
@@ -103,7 +102,7 @@ class SurfacePaint implements ui.Paint {
103102
@override
104103
set invertColors(bool value) {}
105104

106-
static const ui.Color _defaultPaintColor = ui.Color(0xFF000000);
105+
static const int _defaultPaintColor = 0xFF000000;
107106

108107
@override
109108
ui.Shader? get shader => _paintData.shader;
@@ -207,7 +206,7 @@ class SurfacePaint implements ui.Paint {
207206
result.write('${semicolon}antialias off');
208207
semicolon = '; ';
209208
}
210-
if (color != _defaultPaintColor) {
209+
if (color.value != _defaultPaintColor) {
211210
result.write('$semicolon$color');
212211
semicolon = '; ';
213212
}
@@ -225,7 +224,7 @@ class SurfacePaintData {
225224
ui.StrokeCap? strokeCap;
226225
ui.StrokeJoin? strokeJoin;
227226
bool isAntiAlias = true;
228-
ui.Color? color;
227+
int color = 0xFF000000;
229228
ui.Shader? shader;
230229
ui.MaskFilter? maskFilter;
231230
ui.FilterQuality? filterQuality;
@@ -269,7 +268,7 @@ class SurfacePaintData {
269268
buffer.write('strokeJoin = $strokeJoin; ');
270269
}
271270
if (color != null) {
272-
buffer.write('color = ${colorToCssString(color)}; ');
271+
buffer.write('color = ${colorToCssString(ui.Color(color))}; ');
273272
}
274273
if (shader != null) {
275274
buffer.write('shader = $shader; ');

lib/web_ui/lib/src/engine/html/render_vertices.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,9 @@ class _WebGlRenderer implements GlRenderer {
230230

231231
// Buffer kBGRA_8888.
232232
if (vertices.colors == null) {
233-
final ui.Color color = paint.color ?? const ui.Color(0xFF000000);
234233
final Uint32List vertexColors = Uint32List(vertexCount);
235234
for (int i = 0; i < vertexCount; i++) {
236-
vertexColors[i] = color.value;
235+
vertexColors[i] = paint.color;
237236
}
238237
gl.bufferData(vertexColors, gl.kStaticDraw);
239238
} else {

lib/web_ui/lib/src/engine/util.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,17 @@ String? colorToCssString(ui.Color? color) {
344344
return null;
345345
}
346346
final int value = color.value;
347+
return colorValueToCssString(value);
348+
}
349+
350+
// Converts a color value (as an int) into a CSS-compatible value.
351+
String? colorValueToCssString(int? value) {
352+
if (value == null) {
353+
return null;
354+
}
355+
if (value == 0xFF000000) {
356+
return '#000000';
357+
}
347358
if ((0xff000000 & value) == 0xff000000) {
348359
final String hexValue = (value & 0xFFFFFF).toRadixString(16);
349360
final int hexValueLength = hexValue.length;

lib/web_ui/test/html/bitmap_canvas_golden_test.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ Future<void> testMain() async {
126126
canvas.clipRect(const Rect.fromLTWH(0, 0, 50, 50), ClipOp.intersect);
127127
canvas.translate(25, 25);
128128
canvas.drawPaint(SurfacePaintData()
129-
..color = const Color.fromRGBO(0, 255, 0, 1.0)
129+
..color = const Color.fromRGBO(0, 255, 0, 1.0).value
130130
..style = PaintingStyle.fill);
131131

132132
appendToScene();
@@ -209,7 +209,7 @@ Future<void> testMain() async {
209209
canvas.debugChildOverdraw = true;
210210

211211
final SurfacePaintData pathPaint = SurfacePaintData()
212-
..color = const Color(0xFF7F7F7F)
212+
..color = 0xFF7F7F7F
213213
..style = PaintingStyle.fill;
214214

215215
const double r = 200.0;
@@ -227,7 +227,7 @@ Future<void> testMain() async {
227227
..close()).shift(const Offset(250, 250));
228228

229229
final SurfacePaintData borderPaint = SurfacePaintData()
230-
..color = black
230+
..color = black.value
231231
..style = PaintingStyle.stroke;
232232

233233
canvas.drawPath(path, pathPaint);

lib/web_ui/test/html/canvas_winding_rule_golden_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Future<void> testMain() async {
3737
void paintPaths(BitmapCanvas canvas) {
3838
canvas.drawRect(const Rect.fromLTRB(0, 0, 500, 500),
3939
SurfacePaintData()
40-
..color = const Color(0xFFFFFFFF)
40+
..color = 0xFFFFFFFF
4141
..style = PaintingStyle.fill); // white
4242

4343
final SurfacePaint paintFill = SurfacePaint()

0 commit comments

Comments
 (0)