Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 10f06b5

Browse files
authored
[web] Implement style inheritance during paragraph construction (#22365)
1 parent 74472ce commit 10f06b5

File tree

3 files changed

+266
-62
lines changed

3 files changed

+266
-62
lines changed

lib/web_ui/lib/src/engine/text/canvas_paragraph.dart

Lines changed: 160 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,26 @@ abstract class StyleNode {
300300
/// The resolved text style is equivalent to the entire ascendent chain of
301301
/// parent style nodes.
302302
EngineTextStyle resolveStyle();
303+
304+
ui.Color? get _color;
305+
ui.TextDecoration? get _decoration;
306+
ui.Color? get _decorationColor;
307+
ui.TextDecorationStyle? get _decorationStyle;
308+
double? get _decorationThickness;
309+
ui.FontWeight? get _fontWeight;
310+
ui.FontStyle? get _fontStyle;
311+
ui.TextBaseline? get _textBaseline;
312+
String? get _fontFamily;
313+
List<String>? get _fontFamilyFallback;
314+
List<ui.FontFeature>? get _fontFeatures;
315+
double? get _fontSize;
316+
double? get _letterSpacing;
317+
double? get _wordSpacing;
318+
double? get _height;
319+
ui.Locale? get _locale;
320+
ui.Paint? get _background;
321+
ui.Paint? get _foreground;
322+
List<ui.Shadow>? get _shadows;
303323
}
304324

305325
/// Represents a non-root [StyleNode].
@@ -315,9 +335,91 @@ class ChildStyleNode extends StyleNode {
315335

316336
@override
317337
EngineTextStyle resolveStyle() {
318-
// TODO(mdebbar): combine all styles from the parent hierarchy.
319-
return style;
338+
return EngineTextStyle(
339+
color: _color,
340+
decoration: _decoration,
341+
decorationColor: _decorationColor,
342+
decorationStyle: _decorationStyle,
343+
decorationThickness: _decorationThickness,
344+
fontWeight: _fontWeight,
345+
fontStyle: _fontStyle,
346+
textBaseline: _textBaseline,
347+
fontFamily: _fontFamily,
348+
fontFamilyFallback: _fontFamilyFallback,
349+
fontFeatures: _fontFeatures,
350+
fontSize: _fontSize,
351+
letterSpacing: _letterSpacing,
352+
wordSpacing: _wordSpacing,
353+
height: _height,
354+
locale: _locale,
355+
background: _background,
356+
foreground: _foreground,
357+
shadows: _shadows,
358+
);
320359
}
360+
361+
// Read these properties from the TextStyle associated with this node. If the
362+
// property isn't defined, go to the parent node.
363+
364+
@override
365+
ui.Color? get _color => style._color ?? parent._color;
366+
367+
@override
368+
ui.TextDecoration? get _decoration => style._decoration ?? parent._decoration;
369+
370+
@override
371+
ui.Color? get _decorationColor => style._decorationColor ?? parent._decorationColor;
372+
373+
@override
374+
ui.TextDecorationStyle? get _decorationStyle => style._decorationStyle ?? parent._decorationStyle;
375+
376+
@override
377+
double? get _decorationThickness => style._decorationThickness ?? parent._decorationThickness;
378+
379+
@override
380+
ui.FontWeight? get _fontWeight => style._fontWeight ?? parent._fontWeight;
381+
382+
@override
383+
ui.FontStyle? get _fontStyle => style._fontStyle ?? parent._fontStyle;
384+
385+
@override
386+
ui.TextBaseline? get _textBaseline => style._textBaseline ?? parent._textBaseline;
387+
388+
@override
389+
List<String>? get _fontFamilyFallback => style._fontFamilyFallback ?? parent._fontFamilyFallback;
390+
391+
@override
392+
List<ui.FontFeature>? get _fontFeatures => style._fontFeatures ?? parent._fontFeatures;
393+
394+
@override
395+
double? get _fontSize => style._fontSize ?? parent._fontSize;
396+
397+
@override
398+
double? get _letterSpacing => style._letterSpacing ?? parent._letterSpacing;
399+
400+
@override
401+
double? get _wordSpacing => style._wordSpacing ?? parent._wordSpacing;
402+
403+
@override
404+
double? get _height => style._height ?? parent._height;
405+
406+
@override
407+
ui.Locale? get _locale => style._locale ?? parent._locale;
408+
409+
@override
410+
ui.Paint? get _background => style._background ?? parent._background;
411+
412+
@override
413+
ui.Paint? get _foreground => style._foreground ?? parent._foreground;
414+
415+
@override
416+
List<ui.Shadow>? get _shadows => style._shadows ?? parent._shadows;
417+
418+
// Font family is slightly different from the other properties above. It's
419+
// never null on the TextStyle object, so we use `_isFontFamilyProvided` to
420+
// check if font family is defined or not.
421+
@override
422+
String? get _fontFamily => style._isFontFamilyProvided ? style._fontFamily : parent._fontFamily;
321423
}
322424

323425
/// The root style node for the paragraph.
@@ -342,6 +444,62 @@ class RootStyleNode extends StyleNode {
342444
}
343445
return style;
344446
}
447+
448+
@override
449+
ui.Color? get _color => null;
450+
451+
@override
452+
ui.TextDecoration? get _decoration => null;
453+
454+
@override
455+
ui.Color? get _decorationColor => null;
456+
457+
@override
458+
ui.TextDecorationStyle? get _decorationStyle => null;
459+
460+
@override
461+
double? get _decorationThickness => null;
462+
463+
@override
464+
ui.FontWeight? get _fontWeight => paragraphStyle._fontWeight;
465+
@override
466+
ui.FontStyle? get _fontStyle => paragraphStyle._fontStyle;
467+
468+
@override
469+
ui.TextBaseline? get _textBaseline => null;
470+
471+
@override
472+
String? get _fontFamily => paragraphStyle._fontFamily;
473+
474+
@override
475+
List<String>? get _fontFamilyFallback => null;
476+
477+
@override
478+
List<ui.FontFeature>? get _fontFeatures => null;
479+
480+
@override
481+
double? get _fontSize => paragraphStyle._fontSize;
482+
483+
@override
484+
double? get _letterSpacing => null;
485+
486+
@override
487+
double? get _wordSpacing => null;
488+
489+
@override
490+
double? get _height => paragraphStyle._height;
491+
492+
@override
493+
ui.Locale? get _locale => paragraphStyle._locale;
494+
495+
@override
496+
ui.Paint? get _background => null;
497+
498+
@override
499+
ui.Paint? get _foreground => null;
500+
501+
@override
502+
List<ui.Shadow>? get _shadows => null;
345503
}
346504

347505
/// Builds a [CanvasParagraph] containing text with the given styling

lib/web_ui/lib/src/engine/text/paragraph.dart

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,38 @@ class EngineParagraphStyle implements ui.ParagraphStyle {
894894

895895
/// The web implementation of [ui.TextStyle].
896896
class EngineTextStyle implements ui.TextStyle {
897-
EngineTextStyle({
897+
/// Constructs an [EngineTextStyle] with all properties being required.
898+
///
899+
/// This is good for call sites that need to be updated whenever a new
900+
/// property is added to [EngineTextStyle]. Non-updated call sites will fail
901+
/// the build otherwise.
902+
factory EngineTextStyle({
903+
required ui.Color? color,
904+
required ui.TextDecoration? decoration,
905+
required ui.Color? decorationColor,
906+
required ui.TextDecorationStyle? decorationStyle,
907+
required double? decorationThickness,
908+
required ui.FontWeight? fontWeight,
909+
required ui.FontStyle? fontStyle,
910+
required ui.TextBaseline? textBaseline,
911+
required String? fontFamily,
912+
required List<String>? fontFamilyFallback,
913+
required double? fontSize,
914+
required double? letterSpacing,
915+
required double? wordSpacing,
916+
required double? height,
917+
required ui.Locale? locale,
918+
required ui.Paint? background,
919+
required ui.Paint? foreground,
920+
required List<ui.Shadow>? shadows,
921+
required List<ui.FontFeature>? fontFeatures,
922+
}) = EngineTextStyle.only;
923+
924+
/// Constructs an [EngineTextStyle] with only the given properties.
925+
///
926+
/// This constructor should be used sparingly in tests, for example. Or when
927+
/// we know for sure that not all properties are needed.
928+
EngineTextStyle.only({
898929
ui.Color? color,
899930
ui.TextDecoration? decoration,
900931
ui.Color? decorationColor,
@@ -940,14 +971,20 @@ class EngineTextStyle implements ui.TextStyle {
940971
_foreground = foreground,
941972
_shadows = shadows;
942973

943-
factory EngineTextStyle.fromParagraphStyle(EngineParagraphStyle paragraphStyle) => EngineTextStyle(
944-
fontWeight: paragraphStyle._fontWeight,
945-
fontStyle: paragraphStyle._fontStyle,
946-
fontFamily: paragraphStyle._fontFamily,
947-
fontSize: paragraphStyle._fontSize,
948-
height: paragraphStyle._height,
949-
locale: paragraphStyle._locale,
950-
);
974+
/// Constructs an [EngineTextStyle] by reading properties from an
975+
/// [EngineParagraphStyle].
976+
factory EngineTextStyle.fromParagraphStyle(
977+
EngineParagraphStyle paragraphStyle,
978+
) {
979+
return EngineTextStyle.only(
980+
fontWeight: paragraphStyle._fontWeight,
981+
fontStyle: paragraphStyle._fontStyle,
982+
fontFamily: paragraphStyle._fontFamily,
983+
fontSize: paragraphStyle._fontSize,
984+
height: paragraphStyle._height,
985+
locale: paragraphStyle._locale,
986+
);
987+
}
951988

952989
final ui.Color? _color;
953990
final ui.TextDecoration? _decoration;
@@ -1281,10 +1318,13 @@ class DomParagraphBuilder implements ui.ParagraphBuilder {
12811318
ui.TextDecoration? decoration;
12821319
ui.Color? decorationColor;
12831320
ui.TextDecorationStyle? decorationStyle;
1321+
double? decorationThickness;
12841322
ui.FontWeight? fontWeight = _paragraphStyle._fontWeight;
12851323
ui.FontStyle? fontStyle = _paragraphStyle._fontStyle;
12861324
ui.TextBaseline? textBaseline;
12871325
String fontFamily = _paragraphStyle._fontFamily ?? DomRenderer.defaultFontFamily;
1326+
List<String>? fontFamilyFallback;
1327+
List<ui.FontFeature>? fontFeatures;
12881328
double fontSize = _paragraphStyle._fontSize ?? DomRenderer.defaultFontSize;
12891329
final ui.TextAlign textAlign = _paragraphStyle._effectiveTextAlign;
12901330
final ui.TextDirection textDirection = _paragraphStyle._effectiveTextDirection;
@@ -1316,6 +1356,9 @@ class DomParagraphBuilder implements ui.ParagraphBuilder {
13161356
if (style._decorationStyle != null) {
13171357
decorationStyle = style._decorationStyle;
13181358
}
1359+
if (style._decorationThickness != null) {
1360+
decorationThickness = style._decorationThickness;
1361+
}
13191362
if (style._fontWeight != null) {
13201363
fontWeight = style._fontWeight;
13211364
}
@@ -1326,6 +1369,12 @@ class DomParagraphBuilder implements ui.ParagraphBuilder {
13261369
textBaseline = style._textBaseline;
13271370
}
13281371
fontFamily = style._fontFamily;
1372+
if (style._fontFamilyFallback != null) {
1373+
fontFamilyFallback = style._fontFamilyFallback;
1374+
}
1375+
if (style._fontFeatures != null) {
1376+
fontFeatures = style._fontFeatures;
1377+
}
13291378
if (style._fontSize != null) {
13301379
fontSize = style._fontSize!;
13311380
}
@@ -1358,10 +1407,13 @@ class DomParagraphBuilder implements ui.ParagraphBuilder {
13581407
decoration: decoration,
13591408
decorationColor: decorationColor,
13601409
decorationStyle: decorationStyle,
1410+
decorationThickness: decorationThickness,
13611411
fontWeight: fontWeight,
13621412
fontStyle: fontStyle,
13631413
textBaseline: textBaseline,
13641414
fontFamily: fontFamily,
1415+
fontFamilyFallback: fontFamilyFallback,
1416+
fontFeatures: fontFeatures,
13651417
fontSize: fontSize,
13661418
letterSpacing: letterSpacing,
13671419
wordSpacing: wordSpacing,

0 commit comments

Comments
 (0)