Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ FILE: ../../../flutter/lib/web_ui/lib/src/engine/compositor/recording_canvas.dar
FILE: ../../../flutter/lib/web_ui/lib/src/engine/compositor/runtime_delegate.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/compositor/surface.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/compositor/util.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/compositor/vertices.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/compositor/viewport_metrics.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/conic.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/dom_canvas.dart
Expand Down
1 change: 1 addition & 0 deletions lib/web_ui/lib/src/engine.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ part 'engine/compositor/recording_canvas.dart';
part 'engine/compositor/runtime_delegate.dart';
part 'engine/compositor/surface.dart';
part 'engine/compositor/util.dart';
part 'engine/compositor/vertices.dart';
part 'engine/compositor/viewport_metrics.dart';
part 'engine/conic.dart';
part 'engine/dom_canvas.dart';
Expand Down
32 changes: 27 additions & 5 deletions lib/web_ui/lib/src/engine/compositor/fonts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,35 @@ class SkiaFontCollection {

js.JsObject getFont(String family, double size) {
if (_registeredTypefaces[family] == null) {
if (family == 'sans-serif') {
// If it's the default font, return a default SkFont
return js.JsObject(canvasKit['SkFont'], <dynamic>[null, size]);
if (assertionsEnabled) {
html.window.console.warn('Using unregistered font: $family');
}
throw Exception('Unregistered font: $family');
return js.JsObject(canvasKit['SkFont'], <dynamic>[null, size]);
}
final js.JsObject skTypeface = _registeredTypefaces[family].values.first;

// We don't attempt to find a Typeface matching the text style. Instead, we
// try to find the "default" typeface. The default typeface either has no
// descriptors, or only has a descriptor of font-weight 400 (the default).
final Map<Map<String, String>, js.JsObject> typefaces =
_registeredTypefaces[family];
js.JsObject skTypeface;

for (MapEntry<Map<String, String>, js.JsObject> entry
in typefaces.entries) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: forEach might be faster here because it doesn't need to allocate a MapEntry on each iteration.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

forEach doesn't allow you to terminate iteration early, keeping the for-loop for now

final Map<String, String> descriptors = entry.key;
if (descriptors.isEmpty ||
(descriptors.length == 1 && descriptors['weight'] == '400')) {
skTypeface = entry.value;
break;
}
}

// If we couldn't find a suitable default, just use any typeface in the
// family.
if (skTypeface == null) {
skTypeface = typefaces.values.first;
}

return js.JsObject(canvasKit['SkFont'], <dynamic>[skTypeface, size]);
}

Expand Down
11 changes: 11 additions & 0 deletions lib/web_ui/lib/src/engine/compositor/recording_canvas.dart
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,17 @@ class SkRecordingCanvas implements RecordingCanvas {
drawSkShadow(skCanvas, path, color, elevation, transparentOccluder);
}

@override
void drawVertices(
ui.Vertices vertices, ui.BlendMode blendMode, ui.Paint paint) {
SkVertices skVertices = vertices;
skCanvas.callMethod('drawVertices', <js.JsObject>[
skVertices.skVertices,
makeSkBlendMode(blendMode),
makeSkPaint(paint)
]);
}

@override
bool get hasArbitraryPaint => true;

Expand Down
170 changes: 59 additions & 111 deletions lib/web_ui/lib/src/engine/compositor/util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,148 +17,96 @@ js.JsArray<double> makeSkPoint(ui.Offset point) {
return skPoint;
}

js.JsObject makeSkPaint(ui.Paint paint) {
final dynamic skPaint = js.JsObject(canvasKit['SkPaint']);

if (paint.shader != null) {
final EngineGradient engineShader = paint.shader;
skPaint.callMethod(
'setShader', <js.JsObject>[engineShader.createSkiaShader()]);
}

if (paint.color != null) {
skPaint.callMethod('setColor', <int>[paint.color.value]);
}

js.JsObject skPaintStyle;
switch (paint.style) {
case ui.PaintingStyle.stroke:
skPaintStyle = canvasKit['PaintStyle']['Stroke'];
break;
case ui.PaintingStyle.fill:
skPaintStyle = canvasKit['PaintStyle']['Fill'];
break;
}
skPaint.callMethod('setStyle', <js.JsObject>[skPaintStyle]);

js.JsObject skBlendMode;
switch (paint.blendMode) {
js.JsObject makeSkBlendMode(ui.BlendMode blendMode) {
switch (blendMode) {
case ui.BlendMode.clear:
skBlendMode = canvasKit['BlendMode']['Clear'];
break;

return canvasKit['BlendMode']['Clear'];
case ui.BlendMode.src:
skBlendMode = canvasKit['BlendMode']['Src'];
break;

return canvasKit['BlendMode']['Src'];
case ui.BlendMode.dst:
skBlendMode = canvasKit['BlendMode']['Dst'];
break;

return canvasKit['BlendMode']['Dst'];
case ui.BlendMode.srcOver:
skBlendMode = canvasKit['BlendMode']['SrcOver'];
break;

return canvasKit['BlendMode']['SrcOver'];
case ui.BlendMode.dstOver:
skBlendMode = canvasKit['BlendMode']['DstOver'];
break;

return canvasKit['BlendMode']['DstOver'];
case ui.BlendMode.srcIn:
skBlendMode = canvasKit['BlendMode']['SrcIn'];
break;

return canvasKit['BlendMode']['SrcIn'];
case ui.BlendMode.dstIn:
skBlendMode = canvasKit['BlendMode']['DstIn'];
break;

return canvasKit['BlendMode']['DstIn'];
case ui.BlendMode.srcOut:
skBlendMode = canvasKit['BlendMode']['SrcOut'];
break;

return canvasKit['BlendMode']['SrcOut'];
case ui.BlendMode.dstOut:
skBlendMode = canvasKit['BlendMode']['DstOut'];
break;

return canvasKit['BlendMode']['DstOut'];
case ui.BlendMode.srcATop:
skBlendMode = canvasKit['BlendMode']['SrcATop'];
break;

return canvasKit['BlendMode']['SrcATop'];
case ui.BlendMode.dstATop:
skBlendMode = canvasKit['BlendMode']['DstATop'];
break;

return canvasKit['BlendMode']['DstATop'];
case ui.BlendMode.xor:
skBlendMode = canvasKit['BlendMode']['Xor'];
break;

return canvasKit['BlendMode']['Xor'];
case ui.BlendMode.plus:
skBlendMode = canvasKit['BlendMode']['Plus'];
break;

return canvasKit['BlendMode']['Plus'];
case ui.BlendMode.modulate:
skBlendMode = canvasKit['BlendMode']['Modulate'];
break;

return canvasKit['BlendMode']['Modulate'];
case ui.BlendMode.screen:
skBlendMode = canvasKit['BlendMode']['Screen'];
break;

return canvasKit['BlendMode']['Screen'];
case ui.BlendMode.overlay:
skBlendMode = canvasKit['BlendMode']['Overlay'];
break;

return canvasKit['BlendMode']['Overlay'];
case ui.BlendMode.darken:
skBlendMode = canvasKit['BlendMode']['Darken'];
break;

return canvasKit['BlendMode']['Darken'];
case ui.BlendMode.lighten:
skBlendMode = canvasKit['BlendMode']['Lighten'];
break;

return canvasKit['BlendMode']['Lighten'];
case ui.BlendMode.colorDodge:
skBlendMode = canvasKit['BlendMode']['ColorDodge'];
break;

return canvasKit['BlendMode']['ColorDodge'];
case ui.BlendMode.colorBurn:
skBlendMode = canvasKit['BlendMode']['ColorBurn'];
break;

return canvasKit['BlendMode']['ColorBurn'];
case ui.BlendMode.hardLight:
skBlendMode = canvasKit['BlendMode']['HardLight'];
break;

return canvasKit['BlendMode']['HardLight'];
case ui.BlendMode.softLight:
skBlendMode = canvasKit['BlendMode']['SoftLight'];
break;

return canvasKit['BlendMode']['SoftLight'];
case ui.BlendMode.difference:
skBlendMode = canvasKit['BlendMode']['Difference'];
break;

return canvasKit['BlendMode']['Difference'];
case ui.BlendMode.exclusion:
skBlendMode = canvasKit['BlendMode']['Exclusion'];
break;

return canvasKit['BlendMode']['Exclusion'];
case ui.BlendMode.multiply:
skBlendMode = canvasKit['BlendMode']['Multiply'];
break;

return canvasKit['BlendMode']['Multiply'];
case ui.BlendMode.hue:
skBlendMode = canvasKit['BlendMode']['Hue'];
break;

return canvasKit['BlendMode']['Hue'];
case ui.BlendMode.saturation:
skBlendMode = canvasKit['BlendMode']['Saturation'];
break;

return canvasKit['BlendMode']['Saturation'];
case ui.BlendMode.color:
skBlendMode = canvasKit['BlendMode']['Color'];
break;

return canvasKit['BlendMode']['Color'];
case ui.BlendMode.luminosity:
skBlendMode = canvasKit['BlendMode']['Luminosity'];
return canvasKit['BlendMode']['Luminosity'];
default:
return null;
}
}

js.JsObject makeSkPaint(ui.Paint paint) {
final dynamic skPaint = js.JsObject(canvasKit['SkPaint']);

if (paint.shader != null) {
final EngineGradient engineShader = paint.shader;
skPaint.callMethod(
'setShader', <js.JsObject>[engineShader.createSkiaShader()]);
}

if (paint.color != null) {
skPaint.callMethod('setColor', <int>[paint.color.value]);
}

js.JsObject skPaintStyle;
switch (paint.style) {
case ui.PaintingStyle.stroke:
skPaintStyle = canvasKit['PaintStyle']['Stroke'];
break;
case ui.PaintingStyle.fill:
skPaintStyle = canvasKit['PaintStyle']['Fill'];
break;
}
skPaint.callMethod('setStyle', <js.JsObject>[skPaintStyle]);

js.JsObject skBlendMode = makeSkBlendMode(paint.blendMode);
if (skBlendMode != null) {
skPaint.callMethod('setBlendMode', <js.JsObject>[skBlendMode]);
}
Expand Down
Loading