Skip to content

Commit d1692d4

Browse files
author
Harry Terkelsen
authored
Update canvaskit backend (#12318)
* Improve the CanvasKit backend for Flutter Web - Improve font handling by trying to load a "normal" font face instead of using the first face matching the family. - Implement Vertices and drawVertices * Add license header to vertices.dart * Remove unused 'encodedPositions' * Delete commented old code. Don't use Skia by default * Add `vertices.dart` to licenses file
1 parent b790d48 commit d1692d4

File tree

8 files changed

+257
-123
lines changed

8 files changed

+257
-123
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ FILE: ../../../flutter/lib/web_ui/lib/src/engine/compositor/recording_canvas.dar
372372
FILE: ../../../flutter/lib/web_ui/lib/src/engine/compositor/runtime_delegate.dart
373373
FILE: ../../../flutter/lib/web_ui/lib/src/engine/compositor/surface.dart
374374
FILE: ../../../flutter/lib/web_ui/lib/src/engine/compositor/util.dart
375+
FILE: ../../../flutter/lib/web_ui/lib/src/engine/compositor/vertices.dart
375376
FILE: ../../../flutter/lib/web_ui/lib/src/engine/compositor/viewport_metrics.dart
376377
FILE: ../../../flutter/lib/web_ui/lib/src/engine/conic.dart
377378
FILE: ../../../flutter/lib/web_ui/lib/src/engine/dom_canvas.dart

lib/web_ui/lib/src/engine.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ part 'engine/compositor/recording_canvas.dart';
4141
part 'engine/compositor/runtime_delegate.dart';
4242
part 'engine/compositor/surface.dart';
4343
part 'engine/compositor/util.dart';
44+
part 'engine/compositor/vertices.dart';
4445
part 'engine/compositor/viewport_metrics.dart';
4546
part 'engine/conic.dart';
4647
part 'engine/dom_canvas.dart';

lib/web_ui/lib/src/engine/compositor/fonts.dart

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,35 @@ class SkiaFontCollection {
7373

7474
js.JsObject getFont(String family, double size) {
7575
if (_registeredTypefaces[family] == null) {
76-
if (family == 'sans-serif') {
77-
// If it's the default font, return a default SkFont
78-
return js.JsObject(canvasKit['SkFont'], <dynamic>[null, size]);
76+
if (assertionsEnabled) {
77+
html.window.console.warn('Using unregistered font: $family');
7978
}
80-
throw Exception('Unregistered font: $family');
79+
return js.JsObject(canvasKit['SkFont'], <dynamic>[null, size]);
8180
}
82-
final js.JsObject skTypeface = _registeredTypefaces[family].values.first;
81+
82+
// We don't attempt to find a Typeface matching the text style. Instead, we
83+
// try to find the "default" typeface. The default typeface either has no
84+
// descriptors, or only has a descriptor of font-weight 400 (the default).
85+
final Map<Map<String, String>, js.JsObject> typefaces =
86+
_registeredTypefaces[family];
87+
js.JsObject skTypeface;
88+
89+
for (MapEntry<Map<String, String>, js.JsObject> entry
90+
in typefaces.entries) {
91+
final Map<String, String> descriptors = entry.key;
92+
if (descriptors.isEmpty ||
93+
(descriptors.length == 1 && descriptors['weight'] == '400')) {
94+
skTypeface = entry.value;
95+
break;
96+
}
97+
}
98+
99+
// If we couldn't find a suitable default, just use any typeface in the
100+
// family.
101+
if (skTypeface == null) {
102+
skTypeface = typefaces.values.first;
103+
}
104+
83105
return js.JsObject(canvasKit['SkFont'], <dynamic>[skTypeface, size]);
84106
}
85107

lib/web_ui/lib/src/engine/compositor/recording_canvas.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,17 @@ class SkRecordingCanvas implements RecordingCanvas {
220220
drawSkShadow(skCanvas, path, color, elevation, transparentOccluder);
221221
}
222222

223+
@override
224+
void drawVertices(
225+
ui.Vertices vertices, ui.BlendMode blendMode, ui.Paint paint) {
226+
SkVertices skVertices = vertices;
227+
skCanvas.callMethod('drawVertices', <js.JsObject>[
228+
skVertices.skVertices,
229+
makeSkBlendMode(blendMode),
230+
makeSkPaint(paint)
231+
]);
232+
}
233+
223234
@override
224235
bool get hasArbitraryPaint => true;
225236

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

Lines changed: 59 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -17,148 +17,96 @@ js.JsArray<double> makeSkPoint(ui.Offset point) {
1717
return skPoint;
1818
}
1919

20-
js.JsObject makeSkPaint(ui.Paint paint) {
21-
final dynamic skPaint = js.JsObject(canvasKit['SkPaint']);
22-
23-
if (paint.shader != null) {
24-
final EngineGradient engineShader = paint.shader;
25-
skPaint.callMethod(
26-
'setShader', <js.JsObject>[engineShader.createSkiaShader()]);
27-
}
28-
29-
if (paint.color != null) {
30-
skPaint.callMethod('setColor', <int>[paint.color.value]);
31-
}
32-
33-
js.JsObject skPaintStyle;
34-
switch (paint.style) {
35-
case ui.PaintingStyle.stroke:
36-
skPaintStyle = canvasKit['PaintStyle']['Stroke'];
37-
break;
38-
case ui.PaintingStyle.fill:
39-
skPaintStyle = canvasKit['PaintStyle']['Fill'];
40-
break;
41-
}
42-
skPaint.callMethod('setStyle', <js.JsObject>[skPaintStyle]);
43-
44-
js.JsObject skBlendMode;
45-
switch (paint.blendMode) {
20+
js.JsObject makeSkBlendMode(ui.BlendMode blendMode) {
21+
switch (blendMode) {
4622
case ui.BlendMode.clear:
47-
skBlendMode = canvasKit['BlendMode']['Clear'];
48-
break;
49-
23+
return canvasKit['BlendMode']['Clear'];
5024
case ui.BlendMode.src:
51-
skBlendMode = canvasKit['BlendMode']['Src'];
52-
break;
53-
25+
return canvasKit['BlendMode']['Src'];
5426
case ui.BlendMode.dst:
55-
skBlendMode = canvasKit['BlendMode']['Dst'];
56-
break;
57-
27+
return canvasKit['BlendMode']['Dst'];
5828
case ui.BlendMode.srcOver:
59-
skBlendMode = canvasKit['BlendMode']['SrcOver'];
60-
break;
61-
29+
return canvasKit['BlendMode']['SrcOver'];
6230
case ui.BlendMode.dstOver:
63-
skBlendMode = canvasKit['BlendMode']['DstOver'];
64-
break;
65-
31+
return canvasKit['BlendMode']['DstOver'];
6632
case ui.BlendMode.srcIn:
67-
skBlendMode = canvasKit['BlendMode']['SrcIn'];
68-
break;
69-
33+
return canvasKit['BlendMode']['SrcIn'];
7034
case ui.BlendMode.dstIn:
71-
skBlendMode = canvasKit['BlendMode']['DstIn'];
72-
break;
73-
35+
return canvasKit['BlendMode']['DstIn'];
7436
case ui.BlendMode.srcOut:
75-
skBlendMode = canvasKit['BlendMode']['SrcOut'];
76-
break;
77-
37+
return canvasKit['BlendMode']['SrcOut'];
7838
case ui.BlendMode.dstOut:
79-
skBlendMode = canvasKit['BlendMode']['DstOut'];
80-
break;
81-
39+
return canvasKit['BlendMode']['DstOut'];
8240
case ui.BlendMode.srcATop:
83-
skBlendMode = canvasKit['BlendMode']['SrcATop'];
84-
break;
85-
41+
return canvasKit['BlendMode']['SrcATop'];
8642
case ui.BlendMode.dstATop:
87-
skBlendMode = canvasKit['BlendMode']['DstATop'];
88-
break;
89-
43+
return canvasKit['BlendMode']['DstATop'];
9044
case ui.BlendMode.xor:
91-
skBlendMode = canvasKit['BlendMode']['Xor'];
92-
break;
93-
45+
return canvasKit['BlendMode']['Xor'];
9446
case ui.BlendMode.plus:
95-
skBlendMode = canvasKit['BlendMode']['Plus'];
96-
break;
97-
47+
return canvasKit['BlendMode']['Plus'];
9848
case ui.BlendMode.modulate:
99-
skBlendMode = canvasKit['BlendMode']['Modulate'];
100-
break;
101-
49+
return canvasKit['BlendMode']['Modulate'];
10250
case ui.BlendMode.screen:
103-
skBlendMode = canvasKit['BlendMode']['Screen'];
104-
break;
105-
51+
return canvasKit['BlendMode']['Screen'];
10652
case ui.BlendMode.overlay:
107-
skBlendMode = canvasKit['BlendMode']['Overlay'];
108-
break;
109-
53+
return canvasKit['BlendMode']['Overlay'];
11054
case ui.BlendMode.darken:
111-
skBlendMode = canvasKit['BlendMode']['Darken'];
112-
break;
113-
55+
return canvasKit['BlendMode']['Darken'];
11456
case ui.BlendMode.lighten:
115-
skBlendMode = canvasKit['BlendMode']['Lighten'];
116-
break;
117-
57+
return canvasKit['BlendMode']['Lighten'];
11858
case ui.BlendMode.colorDodge:
119-
skBlendMode = canvasKit['BlendMode']['ColorDodge'];
120-
break;
121-
59+
return canvasKit['BlendMode']['ColorDodge'];
12260
case ui.BlendMode.colorBurn:
123-
skBlendMode = canvasKit['BlendMode']['ColorBurn'];
124-
break;
125-
61+
return canvasKit['BlendMode']['ColorBurn'];
12662
case ui.BlendMode.hardLight:
127-
skBlendMode = canvasKit['BlendMode']['HardLight'];
128-
break;
129-
63+
return canvasKit['BlendMode']['HardLight'];
13064
case ui.BlendMode.softLight:
131-
skBlendMode = canvasKit['BlendMode']['SoftLight'];
132-
break;
133-
65+
return canvasKit['BlendMode']['SoftLight'];
13466
case ui.BlendMode.difference:
135-
skBlendMode = canvasKit['BlendMode']['Difference'];
136-
break;
137-
67+
return canvasKit['BlendMode']['Difference'];
13868
case ui.BlendMode.exclusion:
139-
skBlendMode = canvasKit['BlendMode']['Exclusion'];
140-
break;
141-
69+
return canvasKit['BlendMode']['Exclusion'];
14270
case ui.BlendMode.multiply:
143-
skBlendMode = canvasKit['BlendMode']['Multiply'];
144-
break;
145-
71+
return canvasKit['BlendMode']['Multiply'];
14672
case ui.BlendMode.hue:
147-
skBlendMode = canvasKit['BlendMode']['Hue'];
148-
break;
149-
73+
return canvasKit['BlendMode']['Hue'];
15074
case ui.BlendMode.saturation:
151-
skBlendMode = canvasKit['BlendMode']['Saturation'];
152-
break;
153-
75+
return canvasKit['BlendMode']['Saturation'];
15476
case ui.BlendMode.color:
155-
skBlendMode = canvasKit['BlendMode']['Color'];
156-
break;
157-
77+
return canvasKit['BlendMode']['Color'];
15878
case ui.BlendMode.luminosity:
159-
skBlendMode = canvasKit['BlendMode']['Luminosity'];
79+
return canvasKit['BlendMode']['Luminosity'];
80+
default:
81+
return null;
82+
}
83+
}
84+
85+
js.JsObject makeSkPaint(ui.Paint paint) {
86+
final dynamic skPaint = js.JsObject(canvasKit['SkPaint']);
87+
88+
if (paint.shader != null) {
89+
final EngineGradient engineShader = paint.shader;
90+
skPaint.callMethod(
91+
'setShader', <js.JsObject>[engineShader.createSkiaShader()]);
92+
}
93+
94+
if (paint.color != null) {
95+
skPaint.callMethod('setColor', <int>[paint.color.value]);
96+
}
97+
98+
js.JsObject skPaintStyle;
99+
switch (paint.style) {
100+
case ui.PaintingStyle.stroke:
101+
skPaintStyle = canvasKit['PaintStyle']['Stroke'];
102+
break;
103+
case ui.PaintingStyle.fill:
104+
skPaintStyle = canvasKit['PaintStyle']['Fill'];
160105
break;
161106
}
107+
skPaint.callMethod('setStyle', <js.JsObject>[skPaintStyle]);
108+
109+
js.JsObject skBlendMode = makeSkBlendMode(paint.blendMode);
162110
if (skBlendMode != null) {
163111
skPaint.callMethod('setBlendMode', <js.JsObject>[skBlendMode]);
164112
}

0 commit comments

Comments
 (0)