Repository navigation
Add ParagraphStyle.hyphenCharacter to dart:ui - #195345
Conversation
3a4d22a to
96ed910
Compare
96ed910 to
278163b
Compare
There was a problem hiding this comment.
Code Review
This pull request adds support for a custom hyphenCharacter in ParagraphStyle across the Flutter engine, including the native C++ Skia implementation and the Web UI (CanvasKit, Skwasm, and HTML) backends. It also adds corresponding unit tests. The review feedback suggests a minor improvement in the Skwasm implementation to remove a redundant null-assertion operator, leveraging Dart's automatic type promotion.
| if (style.hyphenCharacter != null) { | ||
| final SkStringHandle hyphenCharacterHandle = skStringFromDartString(style.hyphenCharacter!); | ||
| paragraphStyleSetSoftHyphenString(handle, hyphenCharacterHandle); | ||
| skStringFree(hyphenCharacterHandle); | ||
| } |
There was a problem hiding this comment.
Since style.hyphenCharacter is a final field on EngineParagraphStyle, Dart's type promotion automatically promotes it to a non-nullable String inside the if block. The null-assertion operator ! on style.hyphenCharacter! is redundant and can be safely removed to improve code cleanliness and leverage Dart's type system idiomatic promotion.
| if (style.hyphenCharacter != null) { | |
| final SkStringHandle hyphenCharacterHandle = skStringFromDartString(style.hyphenCharacter!); | |
| paragraphStyleSetSoftHyphenString(handle, hyphenCharacterHandle); | |
| skStringFree(hyphenCharacterHandle); | |
| } | |
| if (style.hyphenCharacter != null) { | |
| final SkStringHandle hyphenCharacterHandle = skStringFromDartString(style.hyphenCharacter); | |
| paragraphStyleSetSoftHyphenString(handle, hyphenCharacterHandle); | |
| skStringFree(hyphenCharacterHandle); | |
| } |
References
- Follow Effective Dart guidelines and idiomatic Dart style, leveraging Dart's type promotion without redundant null assertions. (link)
There was a problem hiding this comment.
I think this would not compile, since hyphenCharacter is a public field from another library and Dart only promotes private final fields. I am happy to switch to a local variable like the CanvasKit path if a reviewer prefers it.
278163b to
f622039
Compare
gaaclarke
left a comment
There was a problem hiding this comment.
This looks good to me. I glanced over the web stuff and didn't notice anything, the second reviewer can be from the web team. I just have one request to better document the weird asserts we have in the tests.
Lets apps choose the string drawn at a soft hyphen (U+00AD) line break, instead of always drawing "-". Native and Skwasm pass it to Skia's ParagraphStyle::setSoftHyphenString. CanvasKit and WebParagraph store it for now: CanvasKit gets it once its softHyphenString binding rolls in, and WebParagraph does not draw soft hyphens yet (flutter#193506). Part of flutter#189617.
CanvasKit's ParagraphStyle gained softHyphenString in Skia 1bd2b0627c, which rolled into Flutter in flutter#195339. CkParagraphStyle now sets it from ParagraphStyle.hyphenCharacter, so the hyphenCharacter test runs on CanvasKit too. Part of flutter#189617.
f622039 to
e1c6d88
Compare
|
@dbebawy friendly reminder, when you want someone to rereview your PR, make sure to hit the "re-request review" button next to their name |
mdebbar
left a comment
There was a problem hiding this comment.
Looks good to me. Thanks for contributing this!
flutter/flutter@09175cd...e36b370 2026-11-07 [email protected] Roll Fuchsia Linux SDK from KIc0XZbhLmvDpTluZ... to Sf2yvdTiFXAKkfLkD... (flutter/flutter#196160) 2026-11-07 [email protected] Roll pub packages (flutter/flutter#196155) 2026-11-07 [email protected] [iOS a11y] Use a real `UIScrollView` as a11y scrollable container (flutter/flutter#195731) 2026-11-07 [email protected] Add ParagraphStyle.hyphenCharacter to dart:ui (flutter/flutter#195345) 2026-11-07 [email protected] Roll pub packages (flutter/flutter#196143) 2026-11-06 [email protected] [Linux] Fix layer position when compositing without glBlitFramebuffer (flutter/flutter#196083) 2026-11-06 [email protected] Add support for riscv64 desktop linux engine (flutter/flutter#178712) 2026-11-06 [email protected] Add ResizeImagePolicy.cover (flutter/flutter#194665) 2026-11-06 [email protected] Roll Skia from f533d4034900 to b11315d0a096 (6 revisions) (flutter/flutter#196138) 2026-11-06 [email protected] iOS: Remove dead code/unused imports from FlutterPlatformViewsController (flutter/flutter#196084) 2026-11-06 [email protected] Replace pull_request_target workflows with pull_request + workflow_run (flutter/flutter#195536) 2026-11-06 [email protected] [master] Update Flutter DEPS to Dart 3b174b7217fe09b21da836ea623932b5f041b091 (flutter/flutter#196004) 2026-11-06 [email protected] Fix android_hardware_smoke_test retry mechanisms (flutter/flutter#195708) 2026-11-06 [email protected] Roll Skia from 452b9c1e5db6 to f533d4034900 (1 revision) (flutter/flutter#196129) 2026-11-06 [email protected] [flutter_tools] Use `ErrorHandlingFileSystem.deleteIfExists` for `IOSCoreDeviceControl` temp directory cleanup (flutter/flutter#195913) 2026-11-06 [email protected] Adds guideline tests to flutter create samples (flutter/flutter#195827) 2026-11-06 [email protected] refactor(flutter_tools): unify OptionDescriptor identity and addTo (flutter/flutter#196076) 2026-11-06 [email protected] Roll pub packages (flutter/flutter#196114) 2026-11-06 [email protected] Roll Skia from 5ce64e63a0e7 to 452b9c1e5db6 (5 revisions) (flutter/flutter#196111) 2026-11-06 [email protected] Add PlatformDispatcher.onAlwaysUse24HourFormatChanged callback (flutter/flutter#194670) 2026-11-06 [email protected] Roll Packages from 0478162 to 63881f9 (10 revisions) (flutter/flutter#196108) 2026-11-06 [email protected] Roll Skia from 793b8ac73d4b to 5ce64e63a0e7 (4 revisions) (flutter/flutter#196107) If this roll has caused a breakage, revert this CL and set the roller to dry run mode using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Adds
hyphenCharactertodart:ui'sParagraphStyle, so apps can choose the string drawn at the end of a line that breaks at a soft hyphen (U+00AD) instead of always "-". If it is null, "-" is drawn as before. The empty string draws nothing, and the line still breaks there.The engine passes it to Skia's
ParagraphStyle::setSoftHyphenString, which already reserves the string's width when breaking lines and includes it in selection boxes. Skwasm gets aparagraphStyle_setSoftHyphenStringbinding for the same call, and CanvasKit sets thesoftHyphenStringproperty that rolled in with #195339.This is the additive
dart:uipart of #189617. The name and shape follow the API question there, and I am happy to change them. The framework side (TextStyle.getParagraphStyle,TextPainter,RenderParagraph,RichTextandText) is ready as a follow-up PR, along with a breaking change page for flutter/website, since a newgetParagraphStyleparameter breaks classes that override it. I will open both once this lands.WebParagraph stores the value but does not draw soft hyphens yet. #195366 adds soft hyphens there for #193506, and can use this value once both land.
Part of #189617.
Pre-launch Checklist
///).