Variable font support for the Flutter Web CanvasKit renderer (flutter/engine#35808)

This commit is contained in:
Jason Simmons 2022-09-14 16:56:04 -07:00 committed by GitHub
parent dc7ef4eb87
commit 6fa91b41f3
4 changed files with 94 additions and 0 deletions

View File

@ -2026,6 +2026,7 @@ extension SkTextStylePropertiesExtension on SkTextStyleProperties {
external set fontStyle(SkFontStyle? value);
external set shadows(List<SkTextShadow>? value);
external set fontFeatures(List<SkFontFeature>? value);
external set fontVariations(List<SkFontVariation>? value);
}
@JS()
@ -2075,6 +2076,16 @@ extension SkFontFeatureExtension on SkFontFeature {
external set value(int? value);
}
@JS()
@anonymous
@staticInterop
class SkFontVariation {}
extension SkFontVariationExtension on SkFontVariation {
external set axis(String? value);
external set value(double? value);
}
@JS()
@anonymous
@staticInterop

View File

@ -303,6 +303,7 @@ class CanvasKitRenderer implements Renderer {
foreground: foreground as CkPaint?,
shadows: shadows,
fontFeatures: fontFeatures,
fontVariations: fontVariations,
);
@override

View File

@ -220,6 +220,7 @@ class CkTextStyle implements ui.TextStyle {
CkPaint? foreground,
List<ui.Shadow>? shadows,
List<ui.FontFeature>? fontFeatures,
List<ui.FontVariation>? fontVariations,
}) {
return CkTextStyle._(
color,
@ -242,6 +243,7 @@ class CkTextStyle implements ui.TextStyle {
foreground,
shadows,
fontFeatures,
fontVariations,
);
}
@ -266,6 +268,7 @@ class CkTextStyle implements ui.TextStyle {
this.foreground,
this.shadows,
this.fontFeatures,
this.fontVariations,
);
final ui.Color? color;
@ -288,6 +291,7 @@ class CkTextStyle implements ui.TextStyle {
final CkPaint? foreground;
final List<ui.Shadow>? shadows;
final List<ui.FontFeature>? fontFeatures;
final List<ui.FontVariation>? fontVariations;
/// Merges this text style with [other] and returns the new text style.
///
@ -315,6 +319,7 @@ class CkTextStyle implements ui.TextStyle {
foreground: other.foreground ?? foreground,
shadows: other.shadows ?? shadows,
fontFeatures: other.fontFeatures ?? fontFeatures,
fontVariations: other.fontVariations ?? fontVariations,
);
}
@ -345,6 +350,7 @@ class CkTextStyle implements ui.TextStyle {
final CkPaint? foreground = this.foreground;
final List<ui.Shadow>? shadows = this.shadows;
final List<ui.FontFeature>? fontFeatures = this.fontFeatures;
final List<ui.FontVariation>? fontVariations = this.fontVariations;
final SkTextStyleProperties properties = SkTextStyleProperties();
@ -450,6 +456,17 @@ class CkTextStyle implements ui.TextStyle {
properties.fontFeatures = skFontFeatures;
}
if (fontVariations != null) {
final List<SkFontVariation> skFontVariations = <SkFontVariation>[];
for (final ui.FontVariation fontVariation in fontVariations) {
final SkFontVariation skFontVariation = SkFontVariation();
skFontVariation.axis = fontVariation.axis;
skFontVariation.value = fontVariation.value;
skFontVariations.add(skFontVariation);
}
properties.fontVariations = skFontVariations;
}
return canvasKit.TextStyle(properties);
}();
}

View File

@ -0,0 +1,65 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart' as ui;
import 'common.dart';
void main() {
internalBootstrapBrowserTest(() => testMain);
}
void testMain() {
setUpAll(() async {
await ui.webOnlyInitializePlatform();
});
group('font variation', () {
test('is correctly rendered', () async {
const double testWidth = 300;
final CkPictureRecorder recorder = CkPictureRecorder();
final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
final CkParagraphBuilder builder =
CkParagraphBuilder(CkParagraphStyle(
fontSize: 40.0,
textDirection: ui.TextDirection.ltr,
));
builder.pushStyle(CkTextStyle(
fontFamily: 'RobotoVariable',
));
builder.addText('Normal\n');
builder.pop();
ui.FontVariation weight(double w) => ui.FontVariation('wght', w);
builder.pushStyle(CkTextStyle(
fontFamily: 'RobotoVariable',
fontVariations: <ui.FontVariation>[weight(900)],
));
builder.addText('Heavy\n');
builder.pop();
builder.pushStyle(CkTextStyle(
fontFamily: 'RobotoVariable',
fontVariations: <ui.FontVariation>[weight(100)],
));
builder.addText('Light\n');
builder.pop();
final CkParagraph paragraph = builder.build();
paragraph.layout(const ui.ParagraphConstraints(width: testWidth - 20));
canvas.drawParagraph(paragraph, const ui.Offset(10, 10));
final CkPicture picture = recorder.endRecording();
await matchPictureGolden(
'font_variation.jpg',
picture,
region: ui.Rect.fromLTRB(0, 0, testWidth, paragraph.height + 20),
);
});
});
}