Skip to content
Open
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
4 changes: 4 additions & 0 deletions packages/rfw/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.1.4

* Fixes `fontWeight` not being applied in release mode for `Text` and `StrutStyle` widgets.

## 1.1.3

* Fixes dartdoc comments that accidentally used HTML.
Expand Down
54 changes: 47 additions & 7 deletions packages/rfw/lib/src/flutter/argument_decoders.dart
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,46 @@ class ArgumentDecoders {
return null;
}

/// Returns a [FontWeight] from the specified string or integer.
///
/// This does not use [FontWeight.toString], which is not guaranteed to be
/// stable in release builds (since [FontWeight] is not a real Dart enum).
///
/// Supported string values: `"w100"` through `"w900"`, `"normal"` (mapped to
/// [FontWeight.w400]), and `"bold"` (mapped to [FontWeight.w700]).
///
/// Supported integer values: `100` through `900` in increments of 100.
static FontWeight? fontWeight(DataSource source, List<Object> key) {
final int? numeric = source.v<int>(key);
if (numeric != null) {
switch (numeric) {
case 100: return FontWeight.w100;
case 200: return FontWeight.w200;
case 300: return FontWeight.w300;
case 400: return FontWeight.w400;
case 500: return FontWeight.w500;
case 600: return FontWeight.w600;
case 700: return FontWeight.w700;
case 800: return FontWeight.w800;
case 900: return FontWeight.w900;
}
Comment thread
iam-abhijha marked this conversation as resolved.
}
switch (source.v<String>(key)) {
case 'w100': return FontWeight.w100;
case 'w200': return FontWeight.w200;
case 'w300': return FontWeight.w300;
case 'w400':
case 'normal': return FontWeight.w400;
case 'w500': return FontWeight.w500;
case 'w600': return FontWeight.w600;
case 'w700':
case 'bold': return FontWeight.w700;
case 'w800': return FontWeight.w800;
case 'w900': return FontWeight.w900;
}
return null;
}

/// Returns a [FontFeature] from the specified map.
///
/// The `feature` key is used as the font feature name (defaulting to the
Expand Down Expand Up @@ -1243,7 +1283,7 @@ class ArgumentDecoders {
case 'sweep':
return gradient(source, key)!.createShader(
rect(source, [...key, 'rect']) ?? Rect.zero,
textDirection: enumValue<TextDirection>(TextDirection.values, source, ['textDirection']) ?? TextDirection.ltr,
textDirection: enumValue<TextDirection>(TextDirection.values, source, [...key, 'textDirection']) ?? TextDirection.ltr,
);
default:
final ArgumentDecoder<Shader?>? decoder = shaderDecoders[type];
Expand Down Expand Up @@ -1276,7 +1316,7 @@ class ArgumentDecoders {
/// following keys: 'fontFamily` (string), `fontFamilyFallback` ([list] of
/// [string]), `fontSize` (double), `height` (double), `leadingDistribution`
/// ([enumValue] of [TextLeadingDistribution]), `leading` (double),
/// `fontWeight` ([enumValue] of [FontWeight]), `fontStyle` ([enumValue] of
/// `fontWeight` ([fontWeight]), `fontStyle` ([enumValue] of
/// [FontStyle]), `forceStrutHeight` (boolean).
static StrutStyle? strutStyle(DataSource source, List<Object> key) {
if (!source.isMap(key)) {
Expand All @@ -1289,7 +1329,7 @@ class ArgumentDecoders {
height: source.v<double>([...key, 'height']),
leadingDistribution: enumValue<TextLeadingDistribution>(TextLeadingDistribution.values, source, [...key, 'leadingDistribution']),
leading: source.v<double>([...key, 'leading']),
fontWeight: enumValue<FontWeight>(FontWeight.values, source, [...key, 'fontWeight']),
fontWeight: fontWeight(source, [...key, 'fontWeight']),
fontStyle: enumValue<FontStyle>(FontStyle.values, source, [...key, 'fontStyle']),
forceStrutHeight: source.v<bool>([...key, 'forceStrutHeight']),
);
Expand Down Expand Up @@ -1350,7 +1390,7 @@ class ArgumentDecoders {
///
/// Otherwise (even if it has no keys), the [TextStyle] is created from the
/// following keys: `color` ([color]), `backgroundColor` ([color]), `fontSize`
/// (double), `fontWeight` ([enumValue] of [FontWeight]), `fontStyle`
/// (double), `fontWeight` ([fontWeight]), `fontStyle`
/// ([enumValue] of [FontStyle]), `letterSpacing` (double), `wordSpacing`
/// (double), `textBaseline` ([enumValue] of [TextBaseline]), `height`
/// (double), `leadingDistribution` ([enumValue] of
Expand All @@ -1369,11 +1409,11 @@ class ArgumentDecoders {
color: color(source, [...key, 'color']),
backgroundColor: color(source, [...key, 'backgroundColor']),
fontSize: source.v<double>([...key, 'fontSize']),
fontWeight: enumValue<FontWeight>(FontWeight.values, source, [...key, 'fontWeight']),
fontWeight: fontWeight(source, [...key, 'fontWeight']),
fontStyle: enumValue<FontStyle>(FontStyle.values, source, [...key, 'fontStyle']),
letterSpacing: source.v<double>([...key, 'letterSpacing']),
wordSpacing: source.v<double>([...key, 'wordSpacing']),
textBaseline: enumValue<TextBaseline>(TextBaseline.values, source, ['textBaseline']),
textBaseline: enumValue<TextBaseline>(TextBaseline.values, source, [...key, 'textBaseline']),
height: source.v<double>([...key, 'height']),
leadingDistribution: enumValue<TextLeadingDistribution>(TextLeadingDistribution.values, source, [...key, 'leadingDistribution']),
locale: locale(source, [...key, 'locale']),
Expand All @@ -1387,7 +1427,7 @@ class ArgumentDecoders {
decorationThickness: source.v<double>([...key, 'decorationThickness']),
fontFamily: source.v<String>([...key, 'fontFamily']),
fontFamilyFallback: list<String>(source, [...key, 'fontFamilyFallback'], string),
overflow: enumValue<TextOverflow>(TextOverflow.values, source, ['overflow']),
overflow: enumValue<TextOverflow>(TextOverflow.values, source, [...key, 'overflow']),
);
}

Expand Down
2 changes: 1 addition & 1 deletion packages/rfw/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: rfw
description: "Remote Flutter widgets: a library for rendering declarative widget description files at runtime."
repository: https://github.com/flutter/packages/tree/main/packages/rfw
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+rfw%22
version: 1.1.3
version: 1.1.4

environment:
sdk: ^3.9.0
Expand Down
107 changes: 107 additions & 0 deletions packages/rfw/test/argument_decoders_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -551,4 +551,111 @@ void main() {

expect(eventLog, isEmpty);
}, skip: kIsWeb || !isMainChannel); // https://github.com/flutter/flutter/pull/129851

testWidgets('fontWeight decoder', (WidgetTester tester) async {
final runtime = Runtime()
..update(const LibraryName(<String>['core']), createCoreWidgets())
..update(const LibraryName(<String>['test']), parseLibraryFile('import core; widget root = SizedBox();'));
addTearDown(runtime.dispose);
await tester.pumpWidget(
RemoteWidget(
runtime: runtime,
data: DynamicContent(),
widget: const FullyQualifiedWidgetName(LibraryName(<String>['test']), 'root'),
onEvent: (String name, DynamicMap arguments) { },
),
);

// String values w100–w900 in textStyle.
for (final (String name, FontWeight weight) in <(String, FontWeight)>[
('w100', FontWeight.w100), ('w200', FontWeight.w200), ('w300', FontWeight.w300),
('w400', FontWeight.w400), ('w500', FontWeight.w500), ('w600', FontWeight.w600),
('w700', FontWeight.w700), ('w800', FontWeight.w800), ('w900', FontWeight.w900),
('normal', FontWeight.w400), ('bold', FontWeight.w700),
]) {
runtime.update(const LibraryName(<String>['test']), parseLibraryFile('''
import core;
widget root = Directionality(
textDirection: "ltr",
child: Text(text: "hello", style: { fontWeight: "$name", fontSize: 16.0 }),
);
'''));
await tester.pump();
expect(tester.widget<Text>(find.byType(Text)).style?.fontWeight, weight, reason: 'string "$name"');
}

// Integer values 100–900 in textStyle.
for (final (int value, FontWeight weight) in <(int, FontWeight)>[
(100, FontWeight.w100), (200, FontWeight.w200), (300, FontWeight.w300),
(400, FontWeight.w400), (500, FontWeight.w500), (600, FontWeight.w600),
(700, FontWeight.w700), (800, FontWeight.w800), (900, FontWeight.w900),
]) {
runtime.update(const LibraryName(<String>['test']), parseLibraryFile('''
import core;
widget root = Directionality(
textDirection: "ltr",
child: Text(text: "hello", style: { fontWeight: $value, fontSize: 16.0 }),
);
'''));
await tester.pump();
expect(tester.widget<Text>(find.byType(Text)).style?.fontWeight, weight, reason: 'int $value');
}

// Unknown string returns null.
runtime.update(const LibraryName(<String>['test']), parseLibraryFile('''
import core;
widget root = Directionality(
textDirection: "ltr",
child: Text(text: "hello", style: { fontWeight: "heavy", fontSize: 16.0 }),
);
'''));
await tester.pump();
expect(tester.widget<Text>(find.byType(Text)).style?.fontWeight, isNull);

// Missing key returns null.
runtime.update(const LibraryName(<String>['test']), parseLibraryFile('''
import core;
widget root = Directionality(
textDirection: "ltr",
child: Text(text: "hello", style: { fontSize: 16.0 }),
);
'''));
await tester.pump();
expect(tester.widget<Text>(find.byType(Text)).style?.fontWeight, isNull);

// String values w100–w900 in strutStyle.
for (final (String name, FontWeight weight) in <(String, FontWeight)>[
('w100', FontWeight.w100), ('w200', FontWeight.w200), ('w300', FontWeight.w300),
('w400', FontWeight.w400), ('w500', FontWeight.w500), ('w600', FontWeight.w600),
('w700', FontWeight.w700), ('w800', FontWeight.w800), ('w900', FontWeight.w900),
('normal', FontWeight.w400), ('bold', FontWeight.w700),
]) {
runtime.update(const LibraryName(<String>['test']), parseLibraryFile('''
import core;
widget root = Directionality(
textDirection: "ltr",
child: Text(text: "hello", strutStyle: { fontWeight: "$name", fontSize: 16.0 }),
);
'''));
await tester.pump();
expect(tester.widget<Text>(find.byType(Text)).strutStyle?.fontWeight, weight, reason: 'strutStyle string "$name"');
}

// Integer values 100–900 in strutStyle.
for (final (int value, FontWeight weight) in <(int, FontWeight)>[
(100, FontWeight.w100), (200, FontWeight.w200), (300, FontWeight.w300),
(400, FontWeight.w400), (500, FontWeight.w500), (600, FontWeight.w600),
(700, FontWeight.w700), (800, FontWeight.w800), (900, FontWeight.w900),
]) {
runtime.update(const LibraryName(<String>['test']), parseLibraryFile('''
import core;
widget root = Directionality(
textDirection: "ltr",
child: Text(text: "hello", strutStyle: { fontWeight: $value, fontSize: 16.0 }),
);
'''));
await tester.pump();
expect(tester.widget<Text>(find.byType(Text)).strutStyle?.fontWeight, weight, reason: 'strutStyle int $value');
}
});
}