Skip to content

[web] Fix WebParagraph subpixel text stretching and letter jittering - #191030

Merged
auto-submit[bot] merged 5 commits into
flutter:masterfrom
mdebbar:web_paragraph_dpr_fix
Aug 17, 2026
Merged

auto-submit[bot] merged 5 commits into
flutter:masterfrom
mdebbar:web_paragraph_dpr_fix

Conversation

@mdebbar

@mdebbar mdebbar commented Aug 12, 2026 •

Copy link
Copy Markdown
Contributor

Description

Fixes subpixel text stretching, distortion, and letter jittering issues in WebParagraph when rendered with CanvasKit/Skwasm.

Root Cause

  1. Letter Jittering: targetRect applied .floorToDouble() to its origin (dx, dy). Snapping logical coordinates to integer pixels while the text canvas was rasterized with floating-point origins caused 1-pixel positioning shifts and letter jittering during smooth scrolling or subpixel placement.
  2. Subpixel Text Stretching: targetRect applied .ceilToDouble() to sourceRect.width / devicePixelRatio and sourceRect.height / devicePixelRatio. On fractional or high-DPI displays (e.g. 2.0 DPR where sourceRect.width = 21 physical px), rounding the logical width to 11.0 caused CanvasKit to render the 21 physical pixel source bitmap across 22 physical screen pixels. With FilterQuality.none, nearest-neighbor sampling stretched the texture, producing distorted glyphs and non-uniform pixel columns.
  3. Offscreen Canvas Style Overhead: _resizePaintCanvas unnecessarily mutated .style.width and .style.height on an unattached offscreen DomHTMLCanvasElement.

Fix

  • Removes .ceilToDouble() from targetRect dimensions, preserving exact sourceRect.width / devicePixelRatio physical-to-logical ratio for 1:1 screen pixel mapping.
  • Removes .floorToDouble() from targetRect origin coordinates, preserving subpixel positioning accuracy.
  • Removes redundant CSS style assignments on the offscreen paint canvas.
  • Adds comprehensive unit tests in paragraph_test.dart asserting DPR ratio and subpixel accuracy across fractional and integer DPR values.

Tests

  • Added test('WebParagraph correctly handles fractional devicePixelRatio') in paragraph_test.dart.

Fixes #188321

Fixes targetRect calculation in WebParagraph painting:
- Removes .ceilToDouble() from targetRect width/height, preserving exact sourceRect.width / devicePixelRatio ratio for 1:1 physical pixel mapping without non-uniform scaling artifacts.
- Removes .floorToDouble() from targetRect offset coordinates, preserving subpixel positioning and preventing letter jittering.
- Removes unnecessary CSS style assignments on offscreen 2D paint canvas.
- Adds unit tests covering WebParagraph painting across fractional and integer devicePixelRatio values.
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Aug 12, 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 Aug 12, 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 updates the web paragraph painter to correctly handle fractional device pixel ratios by removing explicit canvas style width/height resizing and avoiding rounding or flooring of target rectangle coordinates and dimensions. A test is added to verify subpixel precision and correct mapping under fractional DPRs. The review feedback suggests renaming a misleadingly named style variable to improve readability and modifying the mock canvas's fallback method to return null instead of throwing to increase robustness.

@mdebbar
mdebbar requested a review from Rusino August 13, 2026 14:20
@mdebbar mdebbar added the autosubmit Merge PR when tree becomes green via auto submit App label Aug 17, 2026
@auto-submit
auto-submit Bot added this pull request to the merge queue Aug 17, 2026
Merged via the queue into flutter:master with commit 6386b76 Aug 17, 2026
21 of 22 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Aug 17, 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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[WebParagraph] Visual: Text doesn't animate smoothly

2 participants