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 5 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
2 changes: 1 addition & 1 deletion lib/ui/dart_ui.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ typedef CanvasPath Path;
V(Gradient::Create, 1) \
V(ImageFilter::Create, 1) \
V(ImageShader::Create, 1) \
V(ParagraphBuilder::Create, 9) \
V(ParagraphBuilder::Create, 10) \
V(PathMeasure::Create, 3) \
V(Path::Create, 1) \
V(PictureRecorder::Create, 1) \
Expand Down
14 changes: 10 additions & 4 deletions lib/ui/text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1762,6 +1762,7 @@ class ParagraphStyle {
StrutStyle? strutStyle,
String? ellipsis,
Locale? locale,
bool applyRoundingHack = true,
}) : _encoded = _encodeParagraphStyle(
textAlign,
textDirection,
Expand All @@ -1782,6 +1783,7 @@ class ParagraphStyle {
_strutStyle = strutStyle,
_ellipsis = ellipsis,
_locale = locale,
_applyRoundingHack = applyRoundingHack,
_leadingDistribution = textHeightBehavior?.leadingDistribution ?? TextLeadingDistribution.proportional;

final Int32List _encoded;
Expand All @@ -1792,6 +1794,7 @@ class ParagraphStyle {
final String? _ellipsis;
final Locale? _locale;
final TextLeadingDistribution _leadingDistribution;
final bool _applyRoundingHack;

@override
bool operator ==(Object other) {
Expand All @@ -1809,11 +1812,12 @@ class ParagraphStyle {
&& other._ellipsis == _ellipsis
&& other._locale == _locale
&& other._leadingDistribution == _leadingDistribution
&& other._applyRoundingHack == _applyRoundingHack
&& _listEquals<int>(other._encoded, _encoded);
}

@override
int get hashCode => Object.hash(Object.hashAll(_encoded), _fontFamily, _fontSize, _height, _ellipsis, _locale, _leadingDistribution);
int get hashCode => Object.hash(Object.hashAll(_encoded), _fontFamily, _fontSize, _height, _ellipsis, _locale, _leadingDistribution, _applyRoundingHack);

@override
String toString() {
Expand Down Expand Up @@ -3131,11 +3135,12 @@ base class _NativeParagraphBuilder extends NativeFieldWrapperClass1 implements P
style._fontSize ?? 0,
style._height ?? 0,
style._ellipsis ?? '',
_encodeLocale(style._locale)
_encodeLocale(style._locale),
style._applyRoundingHack,
);
}

@Native<Void Function(Handle, Handle, Handle, Handle, Handle, Double, Double, Handle, Handle)>(symbol: 'ParagraphBuilder::Create')
@Native<Void Function(Handle, Handle, Handle, Handle, Handle, Double, Double, Handle, Handle, Bool)>(symbol: 'ParagraphBuilder::Create')
external void _constructor(
Int32List encoded,
ByteData? strutData,
Expand All @@ -3144,7 +3149,8 @@ base class _NativeParagraphBuilder extends NativeFieldWrapperClass1 implements P
double fontSize,
double height,
String ellipsis,
String locale);
String locale,
bool applyRoundingHack);

@override
int get placeholderCount => _placeholderCount;
Expand Down
9 changes: 6 additions & 3 deletions lib/ui/text/paragraph_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,12 @@ void ParagraphBuilder::Create(Dart_Handle wrapper,
double fontSize,
double height,
const std::u16string& ellipsis,
const std::string& locale) {
const std::string& locale,
bool applyRoundingHack) {
UIDartState::ThrowIfUIOperationsProhibited();
auto res = fml::MakeRefCounted<ParagraphBuilder>(
encoded_handle, strutData, fontFamily, strutFontFamilies, fontSize,
height, ellipsis, locale);
height, ellipsis, locale, applyRoundingHack);
res->AssociateWithDartWrapper(wrapper);
}

Expand Down Expand Up @@ -230,7 +231,8 @@ ParagraphBuilder::ParagraphBuilder(
double fontSize,
double height,
const std::u16string& ellipsis,
const std::string& locale) {
const std::string& locale,
bool applyRoundingHack) {
int32_t mask = 0;
txt::ParagraphStyle style;
{
Expand Down Expand Up @@ -291,6 +293,7 @@ ParagraphBuilder::ParagraphBuilder(
if (mask & kPSLocaleMask) {
style.locale = locale;
}
style.apply_rounding_hack = applyRoundingHack;

FontCollection& font_collection = UIDartState::Current()
->platform_configuration()
Expand Down
6 changes: 4 additions & 2 deletions lib/ui/text/paragraph_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ class ParagraphBuilder : public RefCountedDartWrappable<ParagraphBuilder> {
double fontSize,
double height,
const std::u16string& ellipsis,
const std::string& locale);
const std::string& locale,
bool applyRoundingHack);

~ParagraphBuilder() override;

Expand Down Expand Up @@ -76,7 +77,8 @@ class ParagraphBuilder : public RefCountedDartWrappable<ParagraphBuilder> {
double fontSize,
double height,
const std::u16string& ellipsis,
const std::string& locale);
const std::string& locale,
bool applyRoundingHack);

std::unique_ptr<txt::ParagraphBuilder> m_paragraphBuilder;
};
Expand Down
2 changes: 2 additions & 0 deletions lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2722,6 +2722,8 @@ extension SkParagraphStylePropertiesExtension on SkParagraphStyleProperties {
@JS('replaceTabCharacters')
external set _replaceTabCharacters(JSBoolean? bool);
set replaceTabCharacters(bool? bool) => _replaceTabCharacters = bool?.toJS;

external set applyRoundingHack(bool applyRoundingHack);
}

@JS()
Expand Down
4 changes: 3 additions & 1 deletion lib/web_ui/lib/src/engine/canvaskit/renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,8 @@ class CanvasKitRenderer implements Renderer {
ui.FontStyle? fontStyle,
ui.StrutStyle? strutStyle,
String? ellipsis,
ui.Locale? locale
ui.Locale? locale,
bool applyRoundingHack = true,
}) => CkParagraphStyle(
textAlign: textAlign,
textDirection: textDirection,
Expand All @@ -328,6 +329,7 @@ class CanvasKitRenderer implements Renderer {
strutStyle: strutStyle,
ellipsis: ellipsis,
locale: locale,
applyRoundingHack: applyRoundingHack,
);

@override
Expand Down
4 changes: 4 additions & 0 deletions lib/web_ui/lib/src/engine/canvaskit/text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class CkParagraphStyle implements ui.ParagraphStyle {
ui.StrutStyle? strutStyle,
String? ellipsis,
ui.Locale? locale,
bool applyRoundingHack = true,
}) : skParagraphStyle = toSkParagraphStyle(
textAlign,
textDirection,
Expand All @@ -45,6 +46,7 @@ class CkParagraphStyle implements ui.ParagraphStyle {
strutStyle,
ellipsis,
locale,
applyRoundingHack,
),
_fontFamily = _effectiveFontFamily(fontFamily),
_fontSize = fontSize,
Expand Down Expand Up @@ -144,6 +146,7 @@ class CkParagraphStyle implements ui.ParagraphStyle {
ui.StrutStyle? strutStyle,
String? ellipsis,
ui.Locale? locale,
bool applyRoundingHack,
) {
final SkParagraphStyleProperties properties = SkParagraphStyleProperties();

Expand Down Expand Up @@ -180,6 +183,7 @@ class CkParagraphStyle implements ui.ParagraphStyle {
properties.replaceTabCharacters = true;
properties.textStyle = toSkTextStyleProperties(
fontFamily, fontSize, height, fontWeight, fontStyle);
properties.applyRoundingHack = applyRoundingHack;

return canvasKit.ParagraphStyle(properties);
}
Expand Down
4 changes: 3 additions & 1 deletion lib/web_ui/lib/src/engine/html/renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,9 @@ class HtmlRenderer implements Renderer {
ui.FontStyle? fontStyle,
ui.StrutStyle? strutStyle,
String? ellipsis,
ui.Locale? locale
ui.Locale? locale,
// Not used: the HTML renderer does not use SkParagraph.
bool applyRoundingHack = true,
}) => EngineParagraphStyle(
textAlign: textAlign,
textDirection: textDirection,
Expand Down
1 change: 1 addition & 0 deletions lib/web_ui/lib/src/engine/renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ abstract class Renderer {
ui.StrutStyle? strutStyle,
String? ellipsis,
ui.Locale? locale,
bool applyRoundingHack = true,
});

ui.StrutStyle createStrutStyle({
Expand Down
2 changes: 2 additions & 0 deletions lib/web_ui/lib/src/engine/skwasm/skwasm_impl/paragraph.dart
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@ class SkwasmParagraphStyle extends SkwasmObjectWrapper<RawParagraphStyle> implem
ui.StrutStyle? strutStyle,
String? ellipsis,
ui.Locale? locale,
bool applyRoundingHack = true,
}) {
final ParagraphStyleHandle handle = paragraphStyleCreate();
if (textAlign != null) {
Expand Down Expand Up @@ -535,6 +536,7 @@ class SkwasmParagraphStyle extends SkwasmObjectWrapper<RawParagraphStyle> implem
skStringFree(localeHandle);
}
paragraphStyleSetTextStyle(handle, textStyleHandle);
paragraphStyleSetApplyRoundingHack(handle, applyRoundingHack);
return SkwasmParagraphStyle._(handle, textStyle, fontFamily);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,6 @@ external void paragraphStyleSetStrutStyle(ParagraphStyleHandle handle, StrutStyl

@Native<Void Function(ParagraphStyleHandle, TextStyleHandle)>(symbol: 'paragraphStyle_setTextStyle', isLeaf: true)
external void paragraphStyleSetTextStyle(ParagraphStyleHandle handle, TextStyleHandle textStyle);

@Native<Void Function(ParagraphStyleHandle, Bool)>(symbol: 'paragraphStyle_setApplyRoundingHack', isLeaf: true)
external void paragraphStyleSetApplyRoundingHack(ParagraphStyleHandle handle, bool applyRoundingHack);
4 changes: 3 additions & 1 deletion lib/web_ui/lib/src/engine/skwasm/skwasm_impl/renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,8 @@ class SkwasmRenderer implements Renderer {
ui.FontStyle? fontStyle,
ui.StrutStyle? strutStyle,
String? ellipsis,
ui.Locale? locale
ui.Locale? locale,
bool applyRoundingHack = true,
}) => SkwasmParagraphStyle(
textAlign: textAlign,
textDirection: textDirection,
Expand All @@ -168,6 +169,7 @@ class SkwasmRenderer implements Renderer {
strutStyle: strutStyle,
ellipsis: ellipsis,
locale: locale,
applyRoundingHack: applyRoundingHack,
);

@override
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/lib/src/engine/skwasm/skwasm_stub/renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class SkwasmRenderer implements Renderer {
}

@override
ui.ParagraphStyle createParagraphStyle({ui.TextAlign? textAlign, ui.TextDirection? textDirection, int? maxLines, String? fontFamily, double? fontSize, double? height, ui.TextHeightBehavior? textHeightBehavior, ui.FontWeight? fontWeight, ui.FontStyle? fontStyle, ui.StrutStyle? strutStyle, String? ellipsis, ui.Locale? locale}) {
ui.ParagraphStyle createParagraphStyle({ui.TextAlign? textAlign, ui.TextDirection? textDirection, int? maxLines, String? fontFamily, double? fontSize, double? height, ui.TextHeightBehavior? textHeightBehavior, ui.FontWeight? fontWeight, ui.FontStyle? fontStyle, ui.StrutStyle? strutStyle, String? ellipsis, ui.Locale? locale, bool applyRoundingHack = true}) {
throw UnimplementedError('Skwasm not implemented on this platform.');
}

Expand Down
2 changes: 2 additions & 0 deletions lib/web_ui/lib/text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ abstract class ParagraphStyle {
StrutStyle? strutStyle,
String? ellipsis,
Locale? locale,
bool applyRoundingHack = true,
}) => engine.renderer.createParagraphStyle(
textAlign: textAlign,
textDirection: textDirection,
Expand All @@ -393,6 +394,7 @@ abstract class ParagraphStyle {
strutStyle: strutStyle,
ellipsis: ellipsis,
locale: locale,
applyRoundingHack: applyRoundingHack,
);
}

Expand Down
5 changes: 5 additions & 0 deletions lib/web_ui/skwasm/text/paragraph_style.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,8 @@ SKWASM_EXPORT void paragraphStyle_setTextStyle(ParagraphStyle* style,
TextStyle* textStyle) {
style->setTextStyle(*textStyle);
}

SKWASM_EXPORT void paragraphStyle_setApplyRoundingHack(ParagraphStyle* style,
bool applyRoundingHack) {
style->setApplyRoundingHack(applyRoundingHack);
}
35 changes: 34 additions & 1 deletion lib/web_ui/test/canvaskit/text_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,40 @@ void testMain() {
}
});
});

test('applyRoundingHack defaults to true', () {
const double fontSize = 1.25;
const String text = '12345';
assert((fontSize * text.length).truncate() != fontSize * text.length);
final ui.ParagraphBuilder builder = ui.ParagraphBuilder(
ui.ParagraphStyle(fontSize: fontSize, fontFamily: 'FlutterTest'),
);
builder.addText(text);
final ui.Paragraph paragraph = builder.build()
..layout(const ui.ParagraphConstraints(width: text.length * fontSize));

expect(paragraph.computeLineMetrics(), hasLength(2));
});

test('applyRoundingHack works', () {
const double fontSize = 1.25;
const String text = '12345';
assert((fontSize * text.length).truncate() != fontSize * text.length);
final ui.ParagraphBuilder builder = ui.ParagraphBuilder(
ui.ParagraphStyle(fontSize: fontSize, fontFamily: 'FlutterTest', applyRoundingHack: false),
);
builder.addText(text);
final ui.Paragraph paragraph = builder.build()
..layout(const ui.ParagraphConstraints(width: text.length * fontSize));

expect(paragraph.maxIntrinsicWidth, text.length * fontSize);
switch (paragraph.computeLineMetrics()) {
case [ui.LineMetrics(width: final double width)]:
expect(width, text.length * fontSize);
case final List<ui.LineMetrics> metrics:
expect(metrics, hasLength(1));
}
});
// TODO(hterkelsen): https://github.com/flutter/flutter/issues/71520
}, skip: isSafari || isFirefox);

}
30 changes: 30 additions & 0 deletions testing/dart/paragraph_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -233,4 +233,34 @@ void main() {
expect(callback, throwsStateError);
}
});

test('applyRoundingHack defaults to true', () {
const double fontSize = 1.25;
const String text = '12345';
assert((fontSize * text.length).truncate() != fontSize * text.length);
final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle(fontSize: fontSize));
builder.addText(text);
final Paragraph paragraph = builder.build()
..layout(const ParagraphConstraints(width: text.length * fontSize));

expect(paragraph.computeLineMetrics(), hasLength(2));
});

test('applyRoundingHack works', () {
const double fontSize = 1.25;
const String text = '12345';
assert((fontSize * text.length).truncate() != fontSize * text.length);
final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle(fontSize: fontSize, applyRoundingHack: false));
builder.addText(text);
final Paragraph paragraph = builder.build()
..layout(const ParagraphConstraints(width: text.length * fontSize));

expect(paragraph.maxIntrinsicWidth, text.length * fontSize);
switch (paragraph.computeLineMetrics()) {
case [LineMetrics(width: final double width)]:
expect(width, text.length * fontSize);
case final List<LineMetrics> metrics:
expect(metrics, hasLength(1));
}
});
}
1 change: 1 addition & 0 deletions third_party/txt/src/skia/paragraph_builder_skia.cc
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ skt::ParagraphStyle ParagraphBuilderSkia::TxtToSkia(const ParagraphStyle& txt) {

skia.turnHintingOff();
skia.setReplaceTabCharacters(true);
skia.setApplyRoundingHack(txt.apply_rounding_hack);

return skia;
}
Expand Down
8 changes: 8 additions & 0 deletions third_party/txt/src/txt/paragraph_style.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ class ParagraphStyle {
std::u16string ellipsis;
std::string locale;

// Temporary flag that indicates whether the Paragraph should report its
// metrics with rounding hacks applied.
//
// This flag currently defaults to true and will be flipped to false once the
// migration is complete.
// TODO(LongCatIsLooong): https://github.com/flutter/flutter/issues/31707
bool apply_rounding_hack = true;

TextStyle GetTextStyle() const;

bool unlimited_lines() const;
Expand Down