Conversation
Covers flutter/flutter#185152: soft hyphens (U+00AD) now render at line breaks, and TextStyle.getParagraphStyle gained a hyphens parameter.
Lines still break in the same places, and hit testing isn't affected. Note that the web doesn't render soft hyphens yet, and that editable text and SelectableText can't opt out yet. Use \u00AD escapes in the code samples so the soft hyphen is visible.
9 tasks
lamek
self-requested a review
October 2, 2026 17:30
mboetger
pushed a commit
to mboetger/flutter
that referenced
this pull request
Oct 3, 2026
…5152) ## Summary Adds visible soft hyphen (U+00AD) rendering at line breaks, with a new `Hyphens` API to opt out. Fixes flutter#18443 on native platforms; web rendering is tracked in flutter#193506. A line break that falls on a soft hyphen now renders a visible `-` by default. A new `Hyphens { manual, hidden }` enum controls this: - `Hyphens.manual` (default): render a hyphen at the break. - `Hyphens.hidden`: don't render the hyphen. The soft hyphen is still a break opportunity. `hyphens` is a parameter on `Text` / `RichText`, `TextPainter`, `RenderParagraph`, `TextStyle.getParagraphStyle` and `dart:ui`'s `ParagraphStyle`, following `textAlign` / `maxLines`. It is not a `TextStyle` field. Customizing the hyphen string is deferred to flutter#189617. Design doc: [flutter.dev/go/soft-hyphens](https://flutter.dev/go/soft-hyphens) (tracking issue flutter#185154). ## Background Flutter already breaks lines at U+00AD but never draws the hyphen, so it behaves like a zero-width space. This change doesn't add any new break opportunities or change where lines break, but the rendered hyphen makes its line wider, so it can change `Paragraph.longestLine` and the size of text laid out with `TextWidthBasis.longestLine`. The Skia side landed in [`98daf58d`](google/skia@98daf58d4c) (Skia CL [1208837](https://skia-review.googlesource.com/c/skia/+/1208837)), behind `ParagraphStyle::setRenderSoftHyphens(bool)`, which defaults to `false` for other Skia clients. ## Changes **Engine** - `txt::ParagraphStyle` gains a `render_soft_hyphens` flag (default `true`), which `ParagraphBuilderSkia::TxtToSkia` forwards to `setRenderSoftHyphens`. The Impeller interop toolkit builds `txt::ParagraphStyle` too, so it also gets the new default. - `paragraph_builder.cc` decodes `ParagraphStyle.hyphens` from the FFI buffer (mask bit 13, slot 7). - `dart:ui` adds the public `Hyphens` enum and `ParagraphStyle.hyphens`. The web `dart:ui` accepts and stores the value; web rendering is flutter#193506. **Framework** - `Hyphens` is re-exported from `dart:ui` via `painting/basic_types.dart`. - `hyphens` is threaded through `TextStyle.getParagraphStyle` → `TextPainter` → `RenderParagraph` → `RichText` → `Text` / `Text.rich`, including the selectable-text path. ## Breaking change - **API:** adding `hyphens` to `TextStyle.getParagraphStyle` breaks classes that override it. In practice that's test doubles like the `_TextStyleProxy` in `test/material/theme_test.dart`, updated here; material_ui's copy was removed in flutter/packages#12728. The fix is to add `Hyphens? hyphens` to the override. Migration guide: flutter/website#13945. - **Rendering:** text containing U+00AD now shows a hyphen at soft-hyphen line breaks by default. `Hyphens.hidden` restores the old look. ## Known limitations - The hyphen is appended after line breaking, so a line can exceed `maxWidth` by the hyphen's advance. - The rendered hyphen isn't included in selection highlight rects (flutter#189234). - `EditableText` (and so `TextField`) and `SelectableText` don't take a `hyphens` parameter yet, so they always render the hyphen. - Skia also draws the hyphen when a line ends in U+00AD without breaking there (text ending in U+00AD, or U+00AD right before a space or newline). The Skia fix is in review ([CL 1378356](https://skia-review.googlesource.com/c/skia/+/1378356)) and will come in with a Skia roll once it lands. ## Test plan - [ ] `paragraph_builder_skia_tests.cc::RenderSoftHyphensEnabled`: `render_soft_hyphens` maps onto Skia in both states - [ ] `testing/dart/text_test.dart`: `ParagraphStyle.hyphens` encodes and round-trips in `toString` - [ ] `testing/dart/paragraph_test.dart`: `ParagraphStyle.hyphens` reaches the text layout (a line that breaks at a soft hyphen is wider with `manual` than with `hidden`, and unset matches `manual`), which covers decoding the setting in the engine - [ ] `test/widgets/rich_text_test.dart`: `RichText` exposes `hyphens` via `debugFillProperties` - [ ] `test/widgets/text_test.dart`: `Text` forwards `hyphens` to `RenderParagraph` (incl. selectable path); default resolves to `Hyphens.manual` - [ ] `test/rendering/paragraph_test.dart`: `RenderParagraph.hyphens` setter triggers relayout - [ ] `test/painting/text_painter_test.dart`: `TextPainter.hyphens` setter; the same width check through `TextPainter`, and changing `hyphens` after layout changes the width - [ ] Google internal testing - [ ] Manual smoke: `Text('inter\u00ADnational')` in a narrow container shows `inter-` / `national`
sfshaza2
reviewed
Oct 5, 2026
| This change affects apps in two ways. | ||
|
|
||
| **Rendering.** Text that contains a soft hyphen now shows a hyphen | ||
| wherever a line breaks at it. |
Contributor
There was a problem hiding this comment.
Suggested change
| wherever a line breaks at it. | |
| wherever a line breaks. |
Contributor
Author
There was a problem hiding this comment.
Tweaked this slightly so it doesn't read as every line break: "Text now shows a hyphen wherever a line breaks at a soft hyphen."
Say the hyphen shows wherever a line breaks at a soft hyphen, and fill in the version where the change landed on master.
dbebawy
marked this pull request as ready for review
October 5, 2026 18:52
Contributor
There was a problem hiding this comment.
Code Review
This pull request adds a new breaking change document explaining that soft hyphens (U+00AD) now render at line breaks in Flutter, introducing the Hyphens enum and a new hyphens parameter in TextStyle.getParagraphStyle. The review feedback suggests improving the grammar and style guide compliance of a sentence regarding editable text widgets, and updating the migration code example to use the ui. prefix for the Hyphens type to ensure correct compilation.
SelectableText isn't editable, but it's built on EditableText, as TextField is.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description of what this PR is changing or adding, and why:
Adds a breaking change page for flutter/flutter#185152. Soft hyphens (U+00AD) now render as a visible hyphen at line breaks, controlled by a new
Hyphensenum, andTextStyle.getParagraphStylegained ahyphensparameter, which breaks classes that override it. The page covers both, with a migration for each.Issues fixed by this PR (if any):
None.
PRs or commits this PR depends on (if any):
flutter/flutter#185152, which landed on master on October 3.
Presubmit checklist
of 80 characters or fewer.