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 1 commit
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
Prev Previous commit
Next Next commit
fix StrutStyle and SwkasmParagraphStyle
  • Loading branch information
yjbanov committed Jan 18, 2024
commit 96dc0dbaac4f2ad3886297c2523374b1d7d01976
2 changes: 1 addition & 1 deletion lib/web_ui/lib/src/engine/canvaskit/text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ class CkStrutStyle implements ui.StrutStyle {
@override
int get hashCode => Object.hash(
_fontFamily,
_fontFamilyFallback,
_fontFamilyFallback != null ? Object.hashAll(_fontFamilyFallback) : null,
_fontSize,
_height,
_leading,
Expand Down
178 changes: 172 additions & 6 deletions lib/web_ui/lib/src/engine/skwasm/skwasm_impl/paragraph.dart
Original file line number Diff line number Diff line change
Expand Up @@ -549,17 +549,17 @@ class SkwasmTextStyle implements ui.TextStyle {
}
}

class SkwasmStrutStyle extends SkwasmObjectWrapper<RawStrutStyle> implements ui.StrutStyle {
final class SkwasmStrutStyle extends SkwasmObjectWrapper<RawStrutStyle> implements ui.StrutStyle {
factory SkwasmStrutStyle({
String? fontFamily,
List<String>? fontFamilyFallback,
double? fontSize,
double? height,
ui.TextLeadingDistribution? leadingDistribution,
double? leading,
ui.FontWeight? fontWeight,
ui.FontStyle? fontStyle,
bool? forceStrutHeight,
ui.TextLeadingDistribution? leadingDistribution,
}) {
final StrutStyleHandle handle = strutStyleCreate();
if (fontFamily != null || fontFamilyFallback != null) {
Expand Down Expand Up @@ -595,13 +595,72 @@ class SkwasmStrutStyle extends SkwasmObjectWrapper<RawStrutStyle> implements ui.
if (forceStrutHeight != null) {
strutStyleSetForceStrutHeight(handle, forceStrutHeight);
}
return SkwasmStrutStyle._(handle);
return SkwasmStrutStyle._(
handle,
fontFamily,
fontFamilyFallback,
fontSize,
height,
leadingDistribution,
leading,
fontWeight,
fontStyle,
forceStrutHeight,
);
}

SkwasmStrutStyle._(StrutStyleHandle handle) : super(handle, _registry);
SkwasmStrutStyle._(
StrutStyleHandle handle,
this._fontFamily,
this._fontFamilyFallback,
this._fontSize,
this._height,
this._leadingDistribution,
this._leading,
this._fontWeight,
this._fontStyle,
this._forceStrutHeight,
) : super(handle, _registry);

static final SkwasmFinalizationRegistry<RawStrutStyle> _registry =
SkwasmFinalizationRegistry<RawStrutStyle>(strutStyleDispose);

final String? _fontFamily;
final List<String>? _fontFamilyFallback;
final double? _fontSize;
final double? _height;
final double? _leading;
final ui.FontWeight? _fontWeight;
final ui.FontStyle? _fontStyle;
final bool? _forceStrutHeight;
final ui.TextLeadingDistribution? _leadingDistribution;

@override
bool operator ==(Object other) {
return other is SkwasmStrutStyle &&
other._fontFamily == _fontFamily &&
other._fontSize == _fontSize &&
other._height == _height &&
other._leading == _leading &&
other._leadingDistribution == _leadingDistribution &&
other._fontWeight == _fontWeight &&
other._fontStyle == _fontStyle &&
other._forceStrutHeight == _forceStrutHeight &&
listEquals<String>(other._fontFamilyFallback, _fontFamilyFallback);
}

@override
int get hashCode => Object.hash(
_fontFamily,
_fontFamilyFallback != null ? Object.hashAll(_fontFamilyFallback) : null,
_fontSize,
_height,
_leading,
_leadingDistribution,
_fontWeight,
_fontStyle,
_forceStrutHeight,
);
}

class SkwasmParagraphStyle extends SkwasmObjectWrapper<RawParagraphStyle> implements ui.ParagraphStyle {
Expand Down Expand Up @@ -678,20 +737,127 @@ class SkwasmParagraphStyle extends SkwasmObjectWrapper<RawParagraphStyle> implem
skStringFree(localeHandle);
}
paragraphStyleSetTextStyle(handle, textStyleHandle);
return SkwasmParagraphStyle._(handle, textStyle, fontFamily);
return SkwasmParagraphStyle._(
handle,
textStyle,
fontFamily,
textAlign,
textDirection,
fontWeight,
fontStyle,
maxLines,
fontFamily,
fontSize,
height,
textHeightBehavior,
strutStyle,
ellipsis,
locale,
);
}

SkwasmParagraphStyle._(
ParagraphStyleHandle handle,
this.textStyle,
this.defaultFontFamily
this.defaultFontFamily,
this._textAlign,
this._textDirection,
this._fontWeight,
this._fontStyle,
this._maxLines,
this._fontFamily,
this._fontSize,
this._height,
this._textHeightBehavior,
this._strutStyle,
this._ellipsis,
this._locale,
) : super(handle, _registry);

static final SkwasmFinalizationRegistry<RawParagraphStyle> _registry =
SkwasmFinalizationRegistry<RawParagraphStyle>(paragraphStyleDispose);

final SkwasmNativeTextStyle textStyle;
final String? defaultFontFamily;

final ui.TextAlign? _textAlign;
final ui.TextDirection? _textDirection;
final ui.FontWeight? _fontWeight;
final ui.FontStyle? _fontStyle;
final int? _maxLines;
final String? _fontFamily;
final double? _fontSize;
final double? _height;
final ui.TextHeightBehavior? _textHeightBehavior;
final ui.StrutStyle? _strutStyle;
final String? _ellipsis;
final ui.Locale? _locale;

@override
bool operator ==(Object other) {
if (identical(this, other)) {
return true;
}
if (other.runtimeType != runtimeType) {
return false;
}
return other is SkwasmParagraphStyle &&
other._textAlign == _textAlign &&
other._textDirection == _textDirection &&
other._fontWeight == _fontWeight &&
other._fontStyle == _fontStyle &&
other._maxLines == _maxLines &&
other._fontFamily == _fontFamily &&
other._fontSize == _fontSize &&
other._height == _height &&
other._textHeightBehavior == _textHeightBehavior &&
other._strutStyle == _strutStyle &&
other._ellipsis == _ellipsis &&
other._locale == _locale;
}

@override
int get hashCode {
return Object.hash(
_textAlign,
_textDirection,
_fontWeight,
_fontStyle,
_maxLines,
_fontFamily,
_fontSize,
_height,
_textHeightBehavior,
_strutStyle,
_ellipsis,
_locale,
);
}

@override
String toString() {
String result = super.toString();
assert(() {
final double? fontSize = _fontSize;
final double? height = _height;
result = 'ParagraphStyle('
'textAlign: ${_textAlign ?? "unspecified"}, '
'textDirection: ${_textDirection ?? "unspecified"}, '
'fontWeight: ${_fontWeight ?? "unspecified"}, '
'fontStyle: ${_fontStyle ?? "unspecified"}, '
'maxLines: ${_maxLines ?? "unspecified"}, '
'textHeightBehavior: ${_textHeightBehavior ?? "unspecified"}, '
'fontFamily: ${_fontFamily ?? "unspecified"}, '
'fontSize: ${fontSize != null ? fontSize.toStringAsFixed(1) : "unspecified"}, '
'height: ${height != null ? "${height.toStringAsFixed(1)}x" : "unspecified"}, '
'strutStyle: ${_strutStyle ?? "unspecified"}, '
'ellipsis: ${_ellipsis != null ? '"$_ellipsis"' : "unspecified"}, '
'locale: ${_locale ?? "unspecified"}'
')';
return true;
}());
return result;
}
}

class SkwasmParagraphBuilder extends SkwasmObjectWrapper<RawParagraphBuilder> implements ui.ParagraphBuilder {
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/lib/src/engine/text/paragraph.dart
Original file line number Diff line number Diff line change
Expand Up @@ -848,7 +848,7 @@ class EngineStrutStyle implements ui.StrutStyle {
@override
int get hashCode => Object.hash(
_fontFamily,
_fontFamilyFallback,
_fontFamilyFallback != null ? Object.hashAll(_fontFamilyFallback) : null,
_fontSize,
_height,
_leading,
Expand Down
152 changes: 152 additions & 0 deletions lib/web_ui/test/ui/strut_style_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// 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/ui.dart' as ui;

import '../common/test_initialization.dart';

void main() {
internalBootstrapBrowserTest(() => testMain);
}

Future<void> testMain() async {
setUpUnitTests(
emulateTesterEnvironment: false,
setUpTestViewDimensions: false,
);

test('blanks are equal to each other', () {
final ui.StrutStyle a = ui.StrutStyle();
final ui.StrutStyle b = ui.StrutStyle();
expect(a, b);
expect(a.hashCode, b.hashCode);
});

test('each property individually equal', () {
for (final String property in _populatorsA.keys) {
final _StrutStylePropertyPopulator populator = _populatorsA[property]!;

final _TestStrutStyleBuilder aBuilder = _TestStrutStyleBuilder();
populator(aBuilder);
final ui.StrutStyle a = aBuilder.build();

final _TestStrutStyleBuilder bBuilder = _TestStrutStyleBuilder();
populator(bBuilder);
final ui.StrutStyle b = bBuilder.build();

expect(reason: '$property property is equal', a, b);
expect(reason: '$property hashCode is equal', a.hashCode, b.hashCode);
}
});

test('each property individually not equal', () {
for (final String property in _populatorsA.keys) {
final _StrutStylePropertyPopulator populatorA = _populatorsA[property]!;

final _TestStrutStyleBuilder aBuilder = _TestStrutStyleBuilder();
populatorA(aBuilder);
final ui.StrutStyle a = aBuilder.build();

final _StrutStylePropertyPopulator populatorB = _populatorsB[property]!;
final _TestStrutStyleBuilder bBuilder = _TestStrutStyleBuilder();
populatorB(bBuilder);
final ui.StrutStyle b = bBuilder.build();

expect(reason: '$property property is not equal', a, isNot(b));
expect(reason: '$property hashCode is not equal', a.hashCode, isNot(b.hashCode));
}
});

test('all properties altogether equal', () {
final _TestStrutStyleBuilder aBuilder = _TestStrutStyleBuilder();
final _TestStrutStyleBuilder bBuilder = _TestStrutStyleBuilder();

for (final String property in _populatorsA.keys) {
final _StrutStylePropertyPopulator populator = _populatorsA[property]!;
populator(aBuilder);
populator(bBuilder);
}

final ui.StrutStyle a = aBuilder.build();
final ui.StrutStyle b = bBuilder.build();

expect(a, b);
expect(a.hashCode, b.hashCode);
});

test('all properties altogether not equal', () {
final _TestStrutStyleBuilder aBuilder = _TestStrutStyleBuilder();
final _TestStrutStyleBuilder bBuilder = _TestStrutStyleBuilder();

for (final String property in _populatorsA.keys) {
final _StrutStylePropertyPopulator populatorA = _populatorsA[property]!;
populatorA(aBuilder);

final _StrutStylePropertyPopulator populatorB = _populatorsB[property]!;
populatorB(bBuilder);
}

final ui.StrutStyle a = aBuilder.build();
final ui.StrutStyle b = bBuilder.build();

expect(a, isNot(b));
expect(a.hashCode, isNot(b.hashCode));
});
}

typedef _StrutStylePropertyPopulator = void Function(_TestStrutStyleBuilder builder);

final Map<String, _StrutStylePropertyPopulator> _populatorsA = <String, _StrutStylePropertyPopulator>{
'fontFamily': (_TestStrutStyleBuilder builder) { builder.fontFamily = 'Arial'; },
// Intentionally do not use const List to make sure Object.hashAll is used to compute hashCode
'fontFamilyFallback': (_TestStrutStyleBuilder builder) { builder.fontFamilyFallback = <String>['Roboto']; },
'fontSize': (_TestStrutStyleBuilder builder) { builder.fontSize = 12; },
'height': (_TestStrutStyleBuilder builder) { builder.height = 13; },
'leading': (_TestStrutStyleBuilder builder) { builder.leading = 0.1; },
'fontWeight': (_TestStrutStyleBuilder builder) { builder.fontWeight = ui.FontWeight.w400; },
'fontStyle': (_TestStrutStyleBuilder builder) { builder.fontStyle = ui.FontStyle.normal; },
'forceStrutHeight': (_TestStrutStyleBuilder builder) { builder.forceStrutHeight = false; },
'leadingDistribution': (_TestStrutStyleBuilder builder) { builder.leadingDistribution = ui.TextLeadingDistribution.proportional; },
};

final Map<String, _StrutStylePropertyPopulator> _populatorsB = <String, _StrutStylePropertyPopulator>{
'fontFamily': (_TestStrutStyleBuilder builder) { builder.fontFamily = 'Noto'; },
// Intentionally do not use const List to make sure Object.hashAll is used to compute hashCode
'fontFamilyFallback': (_TestStrutStyleBuilder builder) { builder.fontFamilyFallback = <String>['Verdana']; },
'fontSize': (_TestStrutStyleBuilder builder) { builder.fontSize = 12.1; },
'height': (_TestStrutStyleBuilder builder) { builder.height = 13.1; },
'leading': (_TestStrutStyleBuilder builder) { builder.leading = 0.2; },
'fontWeight': (_TestStrutStyleBuilder builder) { builder.fontWeight = ui.FontWeight.w600; },
'fontStyle': (_TestStrutStyleBuilder builder) { builder.fontStyle = ui.FontStyle.italic; },
'forceStrutHeight': (_TestStrutStyleBuilder builder) { builder.forceStrutHeight = true; },
'leadingDistribution': (_TestStrutStyleBuilder builder) { builder.leadingDistribution = ui.TextLeadingDistribution.even; },
};

class _TestStrutStyleBuilder {
String? fontFamily;
List<String>? fontFamilyFallback;
double? fontSize;
double? height;
double? leading;
ui.FontWeight? fontWeight;
ui.FontStyle? fontStyle;
bool? forceStrutHeight;
ui.TextLeadingDistribution? leadingDistribution;

ui.StrutStyle build() {
return ui.StrutStyle(
fontFamily: fontFamily,
fontFamilyFallback: fontFamilyFallback,
fontSize: fontSize,
height: height,
leading: leading,
fontWeight: fontWeight,
fontStyle: fontStyle,
forceStrutHeight: forceStrutHeight,
leadingDistribution: leadingDistribution,
);
}
}
Loading