Unverified Commit 96cb84a1 authored by Gary Qian's avatar Gary Qian Committed by GitHub

Expose decorationThickness in TextStyle. Roll engine (12 commits) (#28751)

31b289f27 Fix indexing error in dart:ui TextStyle.toString (flutter/engine#8143)
fc2e6b61c Typo "fast an inline" to "fast and inline" (flutter/engine#8142)
0f19b2de0 Reland PerformanceOverlayLayer golden test (flutter/engine#8140)
073aadde1 Fix TextStyle decode misalignment (flutter/engine#8141)
d87d29054 Roll src/third_party/skia 406b068942f0..2eecc3ea3d71 (11 commits) (flutter/engine#8138)
5cef4a022 Use final state passed to dart before initialization as the initial lifecycleState. (flutter/engine#8124)
ffef51be6 Roll src/third_party/skia 665bc64a2dc4..406b068942f0 (8 commits) (flutter/engine#8137)
48efd0fb7 Roll src/third_party/skia 762ddd7e4352..665bc64a2dc4 (2 commits) (flutter/engine#8129)
f666adbbd Roll src/third_party/skia 2932a458957d..762ddd7e4352 (3 commits) (flutter/engine#8128)
8b0df6ded Bugfix #29203: NPE in getAccessibilityProvider in old FlutterView. (flutter/engine#8126)
8f7b18345 Roll src/third_party/skia c6d8781c4036..2932a458957d (2 commits) (flutter/engine#8125)
52b67fdd5 Expose decorationThickness to dart:ui (flutter/engine#8008)
parent 275769b8
5ccee95373348854bc4877cfe240024a36847d2d
31b289f277c653ea91e20d75309958ac0dd0b865
......@@ -317,6 +317,7 @@ class TextStyle extends Diagnosticable {
this.decoration,
this.decorationColor,
this.decorationStyle,
this.decorationThickness,
this.debugLabel,
String fontFamily,
List<String> fontFamilyFallback,
......@@ -482,6 +483,8 @@ class TextStyle extends Diagnosticable {
final Paint background;
/// The decorations to paint near the text (e.g., an underline).
///
/// Multiple decorations can be applied using [TextDecoration.combine].
final TextDecoration decoration;
/// The color in which to paint the text decorations.
......@@ -490,6 +493,51 @@ class TextStyle extends Diagnosticable {
/// The style in which to paint the text decorations (e.g., dashed).
final TextDecorationStyle decorationStyle;
/// The thickness of the decoration stroke as a muliplier of the thickness
/// defined by the font.
///
/// The font provides a base stroke width for [decoration]s which scales off
/// of the [fontSize]. This property may be used to achieve a thinner or
/// thicker decoration stroke, without changing the [fontSize]. For example,
/// a [decorationThickness] of 2.0 will draw a decoration twice as thick as
/// the font defined decoration thickness.
///
/// {@tool sample}
/// To achieve a bolded strike-through, we can apply a thicker stroke for the
/// decoration.
///
/// ```dart
/// Text(
/// 'This has a very BOLD strike through!',
/// style: TextStyle(
/// decoration: TextDecoration.lineThrough,
/// decorationThickness: 2.85,
/// ),
/// )
/// ```
/// {@end-tool}
///
/// {@tool sample}
/// We can apply a very thin and subtle wavy underline (perhaps, when words
/// are misspelled) by using a [decorationThickness] < 1.0.
///
/// ```dart
/// Text(
/// 'oopsIforgottousespaces!',
/// style: TextStyle(
/// decoration: TextDecoration.underline,
/// decorationStyle: TextDecorationStyle.wavy,
/// decorationColor: Colors.red,
/// decorationThickness: 0.5,
/// ),
/// )
/// ```
/// {@end-tool}
///
/// The default [decorationThickness] is 1.0, which will use the font's base
/// stroke thickness/width.
final double decorationThickness;
/// A human-readable description of this text style.
///
/// This property is maintained only in debug builds.
......@@ -541,6 +589,7 @@ class TextStyle extends Diagnosticable {
TextDecoration decoration,
Color decorationColor,
TextDecorationStyle decorationStyle,
double decorationThickness,
String debugLabel,
}) {
assert(color == null || foreground == null, _kColorForegroundWarning);
......@@ -571,6 +620,7 @@ class TextStyle extends Diagnosticable {
decoration: decoration ?? this.decoration,
decorationColor: decorationColor ?? this.decorationColor,
decorationStyle: decorationStyle ?? this.decorationStyle,
decorationThickness: decorationThickness ?? this.decorationThickness,
debugLabel: newDebugLabel,
);
}
......@@ -610,6 +660,8 @@ class TextStyle extends Diagnosticable {
TextDecoration decoration,
Color decorationColor,
TextDecorationStyle decorationStyle,
double decorationThicknessFactor = 1.0,
double decorationThicknessDelta = 0.0,
String fontFamily,
List<String> fontFamilyFallback,
double fontSizeFactor = 1.0,
......@@ -636,6 +688,9 @@ class TextStyle extends Diagnosticable {
assert(heightFactor != null);
assert(heightDelta != null);
assert(heightFactor != null || (heightFactor == 1.0 && heightDelta == 0.0));
assert(decorationThicknessFactor != null);
assert(decorationThicknessDelta != null);
assert(decorationThickness != null || (decorationThicknessFactor == 1.0 && decorationThicknessDelta == 0.0));
String modifiedDebugLabel;
assert(() {
......@@ -664,6 +719,7 @@ class TextStyle extends Diagnosticable {
decoration: decoration ?? this.decoration,
decorationColor: decorationColor ?? this.decorationColor,
decorationStyle: decorationStyle ?? this.decorationStyle,
decorationThickness: decorationThickness == null ? null : decorationThickness * decorationThicknessFactor + decorationThicknessDelta,
debugLabel: modifiedDebugLabel,
);
}
......@@ -721,6 +777,7 @@ class TextStyle extends Diagnosticable {
decoration: other.decoration,
decorationColor: other.decorationColor,
decorationStyle: other.decorationStyle,
decorationThickness: other.decorationThickness,
debugLabel: mergedDebugLabel,
);
}
......@@ -772,6 +829,7 @@ class TextStyle extends Diagnosticable {
shadows: t < 0.5 ? null : b.shadows,
decorationColor: Color.lerp(null, b.decorationColor, t),
decorationStyle: t < 0.5 ? null : b.decorationStyle,
decorationThickness: t < 0.5 ? null : b.decorationThickness,
debugLabel: lerpDebugLabel,
);
}
......@@ -797,6 +855,7 @@ class TextStyle extends Diagnosticable {
decoration: t < 0.5 ? a.decoration : null,
decorationColor: Color.lerp(a.decorationColor, null, t),
decorationStyle: t < 0.5 ? a.decorationStyle : null,
decorationThickness: t < 0.5 ? a.decorationThickness : null,
debugLabel: lerpDebugLabel,
);
}
......@@ -829,6 +888,7 @@ class TextStyle extends Diagnosticable {
decoration: t < 0.5 ? a.decoration : b.decoration,
decorationColor: Color.lerp(a.decorationColor, b.decorationColor, t),
decorationStyle: t < 0.5 ? a.decorationStyle : b.decorationStyle,
decorationThickness: ui.lerpDouble(a.decorationThickness ?? b.decorationThickness, b.decorationThickness ?? a.decorationThickness, t),
debugLabel: lerpDebugLabel,
);
}
......@@ -840,6 +900,7 @@ class TextStyle extends Diagnosticable {
decoration: decoration,
decorationColor: decorationColor,
decorationStyle: decorationStyle,
decorationThickness: decorationThickness,
fontWeight: fontWeight,
fontStyle: fontStyle,
textBaseline: textBaseline,
......@@ -937,7 +998,8 @@ class TextStyle extends Diagnosticable {
backgroundColor != other.backgroundColor ||
decoration != other.decoration ||
decorationColor != other.decorationColor ||
decorationStyle != other.decorationStyle)
decorationStyle != other.decorationStyle ||
decorationThickness != other.decorationThickness)
return RenderComparison.paint;
return RenderComparison.identical;
}
......@@ -966,6 +1028,7 @@ class TextStyle extends Diagnosticable {
decoration == typedOther.decoration &&
decorationColor == typedOther.decorationColor &&
decorationStyle == typedOther.decorationStyle &&
decorationThickness == typedOther.decorationThickness &&
listEquals(shadows, typedOther.shadows) &&
listEquals(fontFamilyFallback, typedOther.fontFamilyFallback);
}
......@@ -1031,7 +1094,7 @@ class TextStyle extends Diagnosticable {
styles.add(DiagnosticsProperty<Locale>('${prefix}locale', locale, defaultValue: null));
styles.add(DiagnosticsProperty<Paint>('${prefix}foreground', foreground, defaultValue: null));
styles.add(DiagnosticsProperty<Paint>('${prefix}background', background, defaultValue: null));
if (decoration != null || decorationColor != null || decorationStyle != null) {
if (decoration != null || decorationColor != null || decorationStyle != null || decorationThickness != null) {
final List<String> decorationDescription = <String>[];
if (decorationStyle != null)
decorationDescription.add(describeEnum(decorationStyle));
......@@ -1051,6 +1114,7 @@ class TextStyle extends Diagnosticable {
decorationDescription.add('$decoration');
assert(decorationDescription.isNotEmpty);
styles.add(MessageProperty('${prefix}decoration', decorationDescription.join(' ')));
styles.add(DoubleProperty('${prefix}decorationThickness', decorationThickness, unit: 'x', defaultValue: null));
}
final bool styleSpecified = styles.any((DiagnosticsNode n) => !n.isFiltered(DiagnosticLevel.info));
......
......@@ -678,6 +678,8 @@ class _TextStyleProxy implements TextStyle {
@override
TextDecorationStyle get decorationStyle => _delegate.decorationStyle;
@override
double get decorationThickness => _delegate.decorationThickness;
@override
String get fontFamily => _delegate.fontFamily;
@override
List<String> get fontFamilyFallback => _delegate.fontFamilyFallback;
......@@ -721,7 +723,26 @@ class _TextStyleProxy implements TextStyle {
}
@override
TextStyle apply({ Color color, Color backgroundColor, TextDecoration decoration, Color decorationColor, TextDecorationStyle decorationStyle, String fontFamily, List<String> fontFamilyFallback, double fontSizeFactor = 1.0, double fontSizeDelta = 0.0, int fontWeightDelta = 0, double letterSpacingFactor = 1.0, double letterSpacingDelta = 0.0, double wordSpacingFactor = 1.0, double wordSpacingDelta = 0.0, double heightFactor = 1.0, double heightDelta = 0.0 }) {
TextStyle apply({
Color color,
Color backgroundColor,
TextDecoration decoration,
Color decorationColor,
TextDecorationStyle decorationStyle,
double decorationThicknessFactor = 1.0,
double decorationThicknessDelta = 0.0,
String fontFamily,
List<String> fontFamilyFallback,
double fontSizeFactor = 1.0,
double fontSizeDelta = 0.0,
int fontWeightDelta = 0,
double letterSpacingFactor = 1.0,
double letterSpacingDelta = 0.0,
double wordSpacingFactor = 1.0,
double wordSpacingDelta = 0.0,
double heightFactor = 1.0,
double heightDelta = 0.0
}) {
throw UnimplementedError();
}
......@@ -731,7 +752,29 @@ class _TextStyleProxy implements TextStyle {
}
@override
TextStyle copyWith({ bool inherit, Color color, Color backgroundColor, String fontFamily, List<String> fontFamilyFallback, double fontSize, FontWeight fontWeight, FontStyle fontStyle, double letterSpacing, double wordSpacing, TextBaseline textBaseline, double height, Locale locale, ui.Paint foreground, ui.Paint background, List<Shadow> shadows, TextDecoration decoration, Color decorationColor, TextDecorationStyle decorationStyle, String debugLabel }) {
TextStyle copyWith({
bool inherit,
Color color,
Color backgroundColor,
String fontFamily,
List<String> fontFamilyFallback,
double fontSize,
FontWeight fontWeight,
FontStyle fontStyle,
double letterSpacing,
double wordSpacing,
TextBaseline textBaseline,
double height,
Locale locale,
ui.Paint foreground,
ui.Paint background,
List<Shadow> shadows,
TextDecoration decoration,
Color decorationColor,
TextDecorationStyle decorationStyle,
double decorationThickness,
String debugLabel
}) {
throw UnimplementedError();
}
......@@ -741,7 +784,20 @@ class _TextStyleProxy implements TextStyle {
}
@override
ui.ParagraphStyle getParagraphStyle({ TextAlign textAlign, TextDirection textDirection, double textScaleFactor = 1.0, String ellipsis, int maxLines, Locale locale, String fontFamily, double fontSize, FontWeight fontWeight, FontStyle fontStyle, double height, StrutStyle strutStyle }) {
ui.ParagraphStyle getParagraphStyle({
TextAlign textAlign,
TextDirection textDirection,
double textScaleFactor = 1.0,
String ellipsis,
int maxLines,
Locale locale,
String fontFamily,
double fontSize,
FontWeight fontWeight,
FontStyle fontStyle,
double height,
StrutStyle strutStyle
}) {
throw UnimplementedError();
}
......
......@@ -169,10 +169,10 @@ void main() {
final ui.TextStyle ts5 = s5.getTextStyle();
expect(ts5, equals(ui.TextStyle(fontWeight: FontWeight.w700, fontSize: 12.0, height: 123.0)));
expect(ts5.toString(), 'TextStyle(color: unspecified, decoration: unspecified, decorationColor: unspecified, decorationStyle: unspecified, fontWeight: FontWeight.w700, fontStyle: unspecified, textBaseline: unspecified, fontFamily: unspecified, fontFamilyFallback: unspecified, fontSize: 12.0, letterSpacing: unspecified, wordSpacing: unspecified, height: 123.0x, locale: unspecified, background: unspecified, foreground: unspecified, shadows: unspecified)');
expect(ts5.toString(), 'TextStyle(color: unspecified, decoration: unspecified, decorationColor: unspecified, decorationStyle: unspecified, decorationThickness: unspecified, fontWeight: FontWeight.w700, fontStyle: unspecified, textBaseline: unspecified, fontFamily: unspecified, fontFamilyFallback: unspecified, fontSize: 12.0, letterSpacing: unspecified, wordSpacing: unspecified, height: 123.0x, locale: unspecified, background: unspecified, foreground: unspecified, shadows: unspecified)');
final ui.TextStyle ts2 = s2.getTextStyle();
expect(ts2, equals(ui.TextStyle(color: const Color(0xFF00FF00), fontWeight: FontWeight.w800, fontSize: 10.0, height: 100.0)));
expect(ts2.toString(), 'TextStyle(color: Color(0xff00ff00), decoration: unspecified, decorationColor: unspecified, decorationStyle: unspecified, fontWeight: FontWeight.w800, fontStyle: unspecified, textBaseline: unspecified, fontFamily: unspecified, fontFamilyFallback: unspecified, fontSize: 10.0, letterSpacing: unspecified, wordSpacing: unspecified, height: 100.0x, locale: unspecified, background: unspecified, foreground: unspecified, shadows: unspecified)');
expect(ts2.toString(), 'TextStyle(color: Color(0xff00ff00), decoration: unspecified, decorationColor: unspecified, decorationStyle: unspecified, decorationThickness: unspecified, fontWeight: FontWeight.w800, fontStyle: unspecified, textBaseline: unspecified, fontFamily: unspecified, fontFamilyFallback: unspecified, fontSize: 10.0, letterSpacing: unspecified, wordSpacing: unspecified, height: 100.0x, locale: unspecified, background: unspecified, foreground: unspecified, shadows: unspecified)');
final ui.ParagraphStyle ps2 = s2.getParagraphStyle(textAlign: TextAlign.center);
expect(ps2, equals(ui.ParagraphStyle(textAlign: TextAlign.center, fontWeight: FontWeight.w800, fontSize: 10.0, height: 100.0)));
......@@ -196,11 +196,11 @@ void main() {
test('TextStyle using package font', () {
const TextStyle s6 = TextStyle(fontFamily: 'test');
expect(s6.fontFamily, 'test');
expect(s6.getTextStyle().toString(), 'TextStyle(color: unspecified, decoration: unspecified, decorationColor: unspecified, decorationStyle: unspecified, fontWeight: unspecified, fontStyle: unspecified, textBaseline: unspecified, fontFamily: test, fontFamilyFallback: unspecified, fontSize: unspecified, letterSpacing: unspecified, wordSpacing: unspecified, height: unspecified, locale: unspecified, background: unspecified, foreground: unspecified, shadows: unspecified)');
expect(s6.getTextStyle().toString(), 'TextStyle(color: unspecified, decoration: unspecified, decorationColor: unspecified, decorationStyle: unspecified, decorationThickness: unspecified, fontWeight: unspecified, fontStyle: unspecified, textBaseline: unspecified, fontFamily: test, fontFamilyFallback: unspecified, fontSize: unspecified, letterSpacing: unspecified, wordSpacing: unspecified, height: unspecified, locale: unspecified, background: unspecified, foreground: unspecified, shadows: unspecified)');
const TextStyle s7 = TextStyle(fontFamily: 'test', package: 'p');
expect(s7.fontFamily, 'packages/p/test');
expect(s7.getTextStyle().toString(), 'TextStyle(color: unspecified, decoration: unspecified, decorationColor: unspecified, decorationStyle: unspecified, fontWeight: unspecified, fontStyle: unspecified, textBaseline: unspecified, fontFamily: packages/p/test, fontFamilyFallback: unspecified, fontSize: unspecified, letterSpacing: unspecified, wordSpacing: unspecified, height: unspecified, locale: unspecified, background: unspecified, foreground: unspecified, shadows: unspecified)');
expect(s7.getTextStyle().toString(), 'TextStyle(color: unspecified, decoration: unspecified, decorationColor: unspecified, decorationStyle: unspecified, decorationThickness: unspecified, fontWeight: unspecified, fontStyle: unspecified, textBaseline: unspecified, fontFamily: packages/p/test, fontFamilyFallback: unspecified, fontSize: unspecified, letterSpacing: unspecified, wordSpacing: unspecified, height: unspecified, locale: unspecified, background: unspecified, foreground: unspecified, shadows: unspecified)');
const TextStyle s8 = TextStyle(fontFamilyFallback: <String>['test', 'test2'], package: 'p');
expect(s8.fontFamilyFallback[0], 'packages/p/test');
......@@ -236,7 +236,7 @@ void main() {
expect(s4.fontFamilyFallback.isEmpty, true);
final ui.TextStyle uis1 = s2.getTextStyle();
expect(uis1.toString(), 'TextStyle(color: unspecified, decoration: unspecified, decorationColor: unspecified, decorationStyle: unspecified, fontWeight: unspecified, fontStyle: unspecified, textBaseline: unspecified, fontFamily: foo, fontFamilyFallback: [Roboto, test], fontSize: unspecified, letterSpacing: unspecified, wordSpacing: unspecified, height: unspecified, locale: unspecified, background: unspecified, foreground: unspecified, shadows: unspecified)');
expect(uis1.toString(), 'TextStyle(color: unspecified, decoration: unspecified, decorationColor: unspecified, decorationStyle: unspecified, decorationThickness: unspecified, fontWeight: unspecified, fontStyle: unspecified, textBaseline: unspecified, fontFamily: foo, fontFamilyFallback: [Roboto, test], fontSize: unspecified, letterSpacing: unspecified, wordSpacing: unspecified, height: unspecified, locale: unspecified, background: unspecified, foreground: unspecified, shadows: unspecified)');
});
test('TextStyle.debugLabel', () {
......
......@@ -443,4 +443,81 @@ void main() {
);
}, skip: true); // Should only be on linux (skip: !Platform.isLinux).
// Disabled for now until font inconsistency is resolved.
testWidgets('Decoration thickness', (WidgetTester tester) async {
final TextDecoration allDecorations = TextDecoration.combine(
<TextDecoration>[
TextDecoration.underline,
TextDecoration.overline,
TextDecoration.lineThrough,
]
);
await tester.pumpWidget(
Center(
child: RepaintBoundary(
child: Container(
width: 300.0,
height: 100.0,
decoration: const BoxDecoration(
color: Color(0xff00ff00),
),
child: Text(
'Hello, wor!\nabcd.',
style: TextStyle(
fontSize: 25,
decoration: allDecorations,
decorationColor: Colors.blue,
decorationStyle: TextDecorationStyle.dashed,
),
textDirection: TextDirection.rtl,
),
),
),
),
);
await expectLater(
find.byType(Container),
matchesGoldenFile('text_golden.Decoration.1.0.png'),
);
}, skip: !Platform.isLinux); // Coretext uses different thicknesses for decoration
testWidgets('Decoration thickness', (WidgetTester tester) async {
final TextDecoration allDecorations = TextDecoration.combine(
<TextDecoration>[
TextDecoration.underline,
TextDecoration.overline,
TextDecoration.lineThrough,
]
);
await tester.pumpWidget(
Center(
child: RepaintBoundary(
child: Container(
width: 300.0,
height: 100.0,
decoration: const BoxDecoration(
color: Color(0xff00ff00),
),
child: Text(
'Hello, wor!\nabcd.',
style: TextStyle(
fontSize: 25,
decoration: allDecorations,
decorationColor: Colors.blue,
decorationStyle: TextDecorationStyle.wavy,
decorationThickness: 4,
),
textDirection: TextDirection.rtl,
),
),
),
),
);
await expectLater(
find.byType(Container),
matchesGoldenFile('text_golden.DecorationThickness.1.0.png'),
);
}, skip: !Platform.isLinux); // Coretext uses different thicknesses for decoration
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment