Skip to content

Fixing GetLineBoundaries with hard line break at the end#188868

Open
Rusino wants to merge 4 commits into
flutter:masterfrom
Rusino:fix3
Open

Fixing GetLineBoundaries with hard line break at the end#188868
Rusino wants to merge 4 commits into
flutter:masterfrom
Rusino:fix3

Conversation

@Rusino

@Rusino Rusino commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Jul 1, 2026
@github-actions github-actions Bot added engine flutter/engine related. See also e: labels. platform-web Web applications specifically team-web Owned by Web platform team labels Jul 1, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the web paragraph layout logic to track the index of a hard line break (hardLineBreakStart) instead of a boolean flag, and corrects baseline calculations for strut styles. A review comment identifies a critical bug in getLineBoundary where soft-wrapped lines return incorrect boundaries at the line transition index, offering a clear counter-example and test case to address the issue.

Comment on lines 848 to +850
if (line.allLineTextRange.start <= codepointPosition &&
line.allLineTextRange.end > codepointPosition) {
return ui.TextRange(start: line.allLineTextRange.start, end: line.allLineTextRange.end);
line.hardLineBreakStart >= codepointPosition) {
return ui.TextRange(start: line.allLineTextRange.start, end: line.hardLineBreakStart);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Bug: Incorrect Line Boundary for Offsets at Line Start

When codepointPosition is at the boundary between two lines (i.e., equal to the start of the second line, which is also the end of the first line), and the first line does not end with a hard line break, line.hardLineBreakStart for the first line is equal to line.allLineTextRange.end.

Because of the >= operator in line.hardLineBreakStart >= codepointPosition, the first line will match codepointPosition, and getLineBoundary will incorrectly return the boundary of the first line instead of the second line.

Counter-Example:

For a paragraph with text "Hello World" wrapped into two lines:

  • Line 1: start = 0, end = 6, hardLineBreakStart = 6 ("Hello ")
  • Line 2: start = 6, end = 11, hardLineBreakStart = 11 ("World")

If we query getLineBoundary(6) (the index of 'W'):

  • For Line 1: 0 <= 6 and 6 >= 6 are both true, so it matches Line 1 and returns [0, 6).
  • However, index 6 is 'W', which belongs to Line 2. It should return [6, 11).

Proposed Test Case:

test('getLineBoundary handles soft-wrapped multiline text correctly at line boundaries', () {
  final paragraphStyle = WebParagraphStyle(
    fontFamily: 'Arial',
    fontSize: 20,
  );
  const text = 'Hello World';
  final builder = WebParagraphBuilder(paragraphStyle);
  builder.addText(text);
  final WebParagraph paragraph = builder.build();
  paragraph.layout(const ui.ParagraphConstraints(width: 60)); // Force wrap between Hello and World

  final ui.TextRange boundary = paragraph.getLineBoundary(6);
  expect(boundary, const ui.TextRange(start: 6, end: 11));
});
      if (line.allLineTextRange.start <= codepointPosition &&
          (line.allLineTextRange.end > codepointPosition ||
           (line.lineNumber == lines.length - 1 && line.allLineTextRange.end == codepointPosition))) {
        return ui.TextRange(start: line.allLineTextRange.start, end: line.hardLineBreakStart);
References
  1. Search for counter-examples: Identify scenarios or edge cases that the proposed code does not handle. If a counter-example is found, propose a test case to demonstrate the gap. (link)

@flutter-dashboard

Copy link
Copy Markdown

Golden file changes have been found for this pull request. Click here to view and triage (e.g. because this is an intentional change).

If you are still iterating on this change and are not ready to resolve the images on the Flutter Gold dashboard, consider marking this PR as a draft pull request above. You will still be able to view image results on the dashboard, commenting will be silenced, and the check will not try to resolve itself until marked ready for review.

For more guidance, visit Writing a golden file test for package:flutter.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

Changes reported for pull request #188868 at sha 9c3aadb

@flutter-dashboard flutter-dashboard Bot added the will affect goldens Changes to golden files label Jul 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD engine flutter/engine related. See also e: labels. platform-web Web applications specifically team-web Owned by Web platform team will affect goldens Changes to golden files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant