Skip to content

Commit

Permalink
[web] Store Paint.color as an int. Only create a ui.Color when the co…
Browse files Browse the repository at this point in the history
…lor getter is called. (flutter#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
  • Loading branch information
Harry Terkelsen authored Nov 1, 2022
1 parent 81f5c30 commit 24b99d5
Show file tree
Hide file tree
Showing 22 changed files with 104 additions and 103 deletions.
10 changes: 3 additions & 7 deletions lib/web_ui/lib/src/engine/canvas_pool.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1012,7 +1012,7 @@ class ContextStateHandle {
}
}
} else if (paint.color != null) {
final String? colorString = colorToCssString(paint.color);
final String? colorString = colorValueToCssString(paint.color);
fillStyle = colorString;
strokeStyle = colorString;
} else {
Expand All @@ -1036,12 +1036,8 @@ class ContextStateHandle {
if (maskFilter != null) {
context.save();
context.shadowBlur = convertSigmaToRadius(maskFilter.webOnlySigma);
if (paint.color != null) {
// Shadow color must be fully opaque.
context.shadowColor = colorToCssString(paint.color!.withAlpha(255));
} else {
context.shadowColor = colorToCssString(const ui.Color(0xFF000000));
}
// Shadow color must be fully opaque.
context.shadowColor = colorToCssString(ui.Color(paint.color).withAlpha(255));

// On the web a shadow must always be painted together with the shape
// that casts it. In order to paint just the shadow, we offset the shape
Expand Down
15 changes: 7 additions & 8 deletions lib/web_ui/lib/src/engine/canvaskit/painting.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import 'skia_object_cache.dart';
class CkPaint extends ManagedSkiaObject<SkPaint> implements ui.Paint {
CkPaint();

static const ui.Color _defaultPaintColor = ui.Color(0xFF000000);
static const int _defaultPaintColor = 0xFF000000;

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

@override
ui.Color get color => _color;
ui.Color get color => ui.Color(_color);
@override
set color(ui.Color value) {
if (_color == value) {
if (_color == value.value) {
return;
}
_color =
value.runtimeType == ui.Color ? value : ui.Color(value.value);
_color = value.value;
skiaObject.setColorInt(value.value);
}

ui.Color _color = _defaultPaintColor;
int _color = _defaultPaintColor;

@override
bool get invertColors => _invertColors;
Expand Down Expand Up @@ -269,7 +268,7 @@ class CkPaint extends ManagedSkiaObject<SkPaint> implements ui.Paint {
SkPaint createDefault() {
final SkPaint paint = SkPaint();
paint.setAntiAlias(_isAntiAlias);
paint.setColorInt(_color.value);
paint.setColorInt(_color);
return paint;
}

Expand All @@ -282,7 +281,7 @@ class CkPaint extends ManagedSkiaObject<SkPaint> implements ui.Paint {
paint.setStyle(toSkPaintStyle(_style));
paint.setStrokeWidth(_strokeWidth);
paint.setAntiAlias(_isAntiAlias);
paint.setColorInt(_color.value);
paint.setColorInt(_color);
paint.setShader(_shader?.withQuality(_filterQuality));
paint.setMaskFilter(_ckMaskFilter?.skiaObject);
paint.setColorFilter(_effectiveColorFilter?.skiaObject);
Expand Down
9 changes: 4 additions & 5 deletions lib/web_ui/lib/src/engine/html/bitmap_canvas.dart
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ class BitmapCanvas extends EngineCanvas {
@override
void drawColor(ui.Color color, ui.BlendMode blendMode) {
final SurfacePaintData paintData = SurfacePaintData()
..color = color
..color = color.value
..blendMode = blendMode;
if (_useDomForRenderingFill(paintData)) {
drawRect(_computeScreenBounds(_canvasPool.currentTransform), paintData);
Expand Down Expand Up @@ -592,8 +592,7 @@ class BitmapCanvas extends EngineCanvas {
void _applyFilter(DomElement element, SurfacePaintData paint) {
if (paint.maskFilter != null) {
final bool isStroke = paint.style == ui.PaintingStyle.stroke;
final String cssColor =
paint.color == null ? '#000000' : colorToCssString(paint.color)!;
final String cssColor = colorValueToCssString(paint.color)!;
final double sigma = paint.maskFilter!.webOnlySigma;
if (browserEngine == BrowserEngine.webkit && !isStroke) {
// A bug in webkit leaves artifacts when this element is animated
Expand Down Expand Up @@ -1031,7 +1030,7 @@ class BitmapCanvas extends EngineCanvas {
: convertVertexPositions(mode, vertices.positions);
// Draw hairline for vertices if no vertex colors are specified.
save();
final ui.Color color = paint.color ?? const ui.Color(0xFF000000);
final ui.Color color = ui.Color(paint.color);
_canvasPool.contextHandle
..fillStyle = null
..strokeStyle = colorToCssString(color);
Expand Down Expand Up @@ -1059,7 +1058,7 @@ class BitmapCanvas extends EngineCanvas {
} else {
_drawPointsPaint.style = ui.PaintingStyle.fill;
}
_drawPointsPaint.color = paint.color ?? const ui.Color(0xFF000000);
_drawPointsPaint.color = paint.color;
_drawPointsPaint.maskFilter = paint.maskFilter;

final double dpr = ui.window.devicePixelRatio;
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/lib/src/engine/html/clip.dart
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ class PersistedPhysicalShape extends PersistedContainerSurface
path,
SurfacePaintData()
..style = ui.PaintingStyle.fill
..color = color,
..color = color.value,
'${pathBounds2.right}',
'${pathBounds2.bottom}');

Expand Down
10 changes: 4 additions & 6 deletions lib/web_ui/lib/src/engine/html/dom_canvas.dart
Original file line number Diff line number Diff line change
Expand Up @@ -257,16 +257,15 @@ DomHTMLElement buildDrawRectElement(
..transform = effectiveTransform;

String cssColor =
paint.color == null ? '#000000' : colorToCssString(paint.color)!;
paint.color == null ? '#000000' : colorValueToCssString(paint.color)!;

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

final SVGPathElement svgPath = createSVGPathElement();
root.append(svgPath);
final ui.Color color = paint.color ?? const ui.Color(0xFF000000);
if (paint.style == ui.PaintingStyle.stroke ||
(paint.style != ui.PaintingStyle.fill &&
paint.strokeWidth != 0 &&
paint.strokeWidth != null)) {
svgPath.setAttribute('stroke', colorToCssString(color)!);
svgPath.setAttribute('stroke', colorValueToCssString(paint.color)!);
svgPath.setAttribute('stroke-width', '${paint.strokeWidth ?? 1.0}');
svgPath.setAttribute('fill', 'none');
} else if (paint.color != null) {
svgPath.setAttribute('fill', colorToCssString(color)!);
svgPath.setAttribute('fill', colorValueToCssString(paint.color)!);
} else {
svgPath.setAttribute('fill', '#000000');
}
Expand Down
13 changes: 6 additions & 7 deletions lib/web_ui/lib/src/engine/html/painting.dart
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,15 @@ class SurfacePaint implements ui.Paint {
}

@override
ui.Color get color => _paintData.color ?? _defaultPaintColor;
ui.Color get color => ui.Color(_paintData.color);

@override
set color(ui.Color value) {
if (_frozen) {
_paintData = _paintData.clone();
_frozen = false;
}
_paintData.color =
value.runtimeType == ui.Color ? value : ui.Color(value.value);
_paintData.color = value.value;
}

@override
Expand All @@ -103,7 +102,7 @@ class SurfacePaint implements ui.Paint {
@override
set invertColors(bool value) {}

static const ui.Color _defaultPaintColor = ui.Color(0xFF000000);
static const int _defaultPaintColor = 0xFF000000;

@override
ui.Shader? get shader => _paintData.shader;
Expand Down Expand Up @@ -207,7 +206,7 @@ class SurfacePaint implements ui.Paint {
result.write('${semicolon}antialias off');
semicolon = '; ';
}
if (color != _defaultPaintColor) {
if (color.value != _defaultPaintColor) {
result.write('$semicolon$color');
semicolon = '; ';
}
Expand All @@ -225,7 +224,7 @@ class SurfacePaintData {
ui.StrokeCap? strokeCap;
ui.StrokeJoin? strokeJoin;
bool isAntiAlias = true;
ui.Color? color;
int color = 0xFF000000;
ui.Shader? shader;
ui.MaskFilter? maskFilter;
ui.FilterQuality? filterQuality;
Expand Down Expand Up @@ -269,7 +268,7 @@ class SurfacePaintData {
buffer.write('strokeJoin = $strokeJoin; ');
}
if (color != null) {
buffer.write('color = ${colorToCssString(color)}; ');
buffer.write('color = ${colorToCssString(ui.Color(color))}; ');
}
if (shader != null) {
buffer.write('shader = $shader; ');
Expand Down
3 changes: 1 addition & 2 deletions lib/web_ui/lib/src/engine/html/render_vertices.dart
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,9 @@ class _WebGlRenderer implements GlRenderer {

// Buffer kBGRA_8888.
if (vertices.colors == null) {
final ui.Color color = paint.color ?? const ui.Color(0xFF000000);
final Uint32List vertexColors = Uint32List(vertexCount);
for (int i = 0; i < vertexCount; i++) {
vertexColors[i] = color.value;
vertexColors[i] = paint.color;
}
gl.bufferData(vertexColors, gl.kStaticDraw);
} else {
Expand Down
11 changes: 11 additions & 0 deletions lib/web_ui/lib/src/engine/util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,17 @@ String? colorToCssString(ui.Color? color) {
return null;
}
final int value = color.value;
return colorValueToCssString(value);
}

// Converts a color value (as an int) into a CSS-compatible value.
String? colorValueToCssString(int? value) {
if (value == null) {
return null;
}
if (value == 0xFF000000) {
return '#000000';
}
if ((0xff000000 & value) == 0xff000000) {
final String hexValue = (value & 0xFFFFFF).toRadixString(16);
final int hexValueLength = hexValue.length;
Expand Down
6 changes: 3 additions & 3 deletions lib/web_ui/test/html/bitmap_canvas_golden_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ Future<void> testMain() async {
canvas.clipRect(const Rect.fromLTWH(0, 0, 50, 50), ClipOp.intersect);
canvas.translate(25, 25);
canvas.drawPaint(SurfacePaintData()
..color = const Color.fromRGBO(0, 255, 0, 1.0)
..color = const Color.fromRGBO(0, 255, 0, 1.0).value
..style = PaintingStyle.fill);

appendToScene();
Expand Down Expand Up @@ -209,7 +209,7 @@ Future<void> testMain() async {
canvas.debugChildOverdraw = true;

final SurfacePaintData pathPaint = SurfacePaintData()
..color = const Color(0xFF7F7F7F)
..color = 0xFF7F7F7F
..style = PaintingStyle.fill;

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

final SurfacePaintData borderPaint = SurfacePaintData()
..color = black
..color = black.value
..style = PaintingStyle.stroke;

canvas.drawPath(path, pathPaint);
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/test/html/canvas_winding_rule_golden_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Future<void> testMain() async {
void paintPaths(BitmapCanvas canvas) {
canvas.drawRect(const Rect.fromLTRB(0, 0, 500, 500),
SurfacePaintData()
..color = const Color(0xFFFFFFFF)
..color = 0xFFFFFFFF
..style = PaintingStyle.fill); // white

final SurfacePaint paintFill = SurfacePaint()
Expand Down
8 changes: 4 additions & 4 deletions lib/web_ui/test/html/drawing/canvas_arc_golden_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Future<void> testMain() async {
..addArc(Rect.fromCircle(center: rect.center,
radius: rect.size.shortestSide / 2), 0.25 * math.pi, 1.5 * math.pi);
canvas.drawPath(p, SurfacePaintData()
..color = const Color(0xFFFF9800) // orange
..color = 0xFFFF9800 // orange
..style = PaintingStyle.fill);

domDocument.body!.append(canvas.rootElement);
Expand All @@ -72,7 +72,7 @@ Future<void> testMain() async {
4.71238898038469 - 5.759586531581287, true);
path.lineTo(149.999999999999997, 20);
canvas.drawPath(path, SurfacePaintData()
..color = const Color(0xFFFF9800) // orange
..color = 0xFFFF9800 // orange
..style = PaintingStyle.fill);

domDocument.body!.append(canvas.rootElement);
Expand All @@ -91,7 +91,7 @@ void paintArc(BitmapCanvas canvas, Offset offset,
Rect.fromLTRB(startP.dx, startP.dy, endP.dx, endP.dy),
SurfacePaintData()
..strokeWidth = 1
..color = const Color(0xFFFF9800) // orange
..color = 0xFFFF9800 // orange
..style = PaintingStyle.stroke);
final Path path = Path();
path.moveTo(startP.dx, startP.dy);
Expand All @@ -104,6 +104,6 @@ void paintArc(BitmapCanvas canvas, Offset offset,
path,
SurfacePaintData()
..strokeWidth = 2
..color = const Color(0x61000000) // black38
..color = 0x61000000 // black38
..style = PaintingStyle.stroke);
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Future<void> testMain() async {
test('draws points in all 3 modes', () async {
final SurfacePaintData paint = SurfacePaintData();
paint.strokeWidth = 2.0;
paint.color = const Color(0xFF0000FF);
paint.color = 0xFF0000FF;
final Float32List points = offsetListToFloat32List(const <Offset>[
Offset(10, 10),
Offset(50, 10),
Expand Down Expand Up @@ -60,17 +60,17 @@ Future<void> testMain() async {

test('Should draw points with strokeWidth', () async {
final SurfacePaintData nullStrokePaint =
SurfacePaintData()..color = const Color(0xffff0000);
SurfacePaintData()..color = 0xffff0000;
canvas.drawPoints(PointMode.lines, Float32List.fromList(<double>[
30.0, 20.0, 200.0, 20.0]), nullStrokePaint);
final SurfacePaintData strokePaint1 = SurfacePaintData()
..strokeWidth = 1.0
..color = const Color(0xff0000ff);
..color = 0xff0000ff;
canvas.drawPoints(PointMode.lines, Float32List.fromList(<double>[
30.0, 30.0, 200.0, 30.0]), strokePaint1);
final SurfacePaintData strokePaint3 = SurfacePaintData()
..strokeWidth = 3.0
..color = const Color(0xff00a000);
..color = 0xff00a000;
canvas.drawPoints(PointMode.lines, Float32List.fromList(<double>[
30.0, 40.0, 200.0, 40.0]), strokePaint3);
canvas.drawPoints(PointMode.points, Float32List.fromList(<double>[
Expand Down
12 changes: 6 additions & 6 deletions lib/web_ui/test/html/drawing/canvas_lines_golden_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ void paintLines(BitmapCanvas canvas) {
..strokeWidth = 1.0
..style = PaintingStyle.stroke;
final SurfacePaintData paint1 = SurfacePaintData()
..color = const Color(0xFF9E9E9E) // Colors.grey
..color = 0xFF9E9E9E // Colors.grey
..strokeWidth = 1.0
..style = PaintingStyle.stroke;
final SurfacePaintData paint2 = SurfacePaintData()
..color = const Color(0x7fff0000)
..color = 0x7fff0000
..strokeWidth = 1.0
..style = PaintingStyle.stroke;
final SurfacePaintData paint3 = SurfacePaintData()
..color = const Color(0xFF4CAF50) //Colors.green
..color = 0xFF4CAF50 //Colors.green
..strokeWidth = 1.0
..style = PaintingStyle.stroke;
// Draw markers around 100x100 box
Expand All @@ -61,12 +61,12 @@ void paintLines(BitmapCanvas canvas) {
canvas.drawLine(const Offset(50, 50), const Offset(150, 150), paint2);
// Draw horizontal
paint3.strokeWidth = 1.0;
paint3.color = const Color(0xFFFF0000);
paint3.color = 0xFFFF0000;
canvas.drawLine(const Offset(50, 55), const Offset(150, 55), paint3);
paint3.strokeWidth = 2.0;
paint3.color = const Color(0xFF2196F3); // Colors.blue;
paint3.color = 0xFF2196F3; // Colors.blue;
canvas.drawLine(const Offset(50, 60), const Offset(150, 60), paint3);
paint3.strokeWidth = 4.0;
paint3.color = const Color(0xFFFF9800); // Colors.orange;
paint3.color = 0xFFFF9800; // Colors.orange;
canvas.drawLine(const Offset(50, 70), const Offset(150, 70), paint3);
}
Loading

0 comments on commit 24b99d5

Please sign in to comment.