Skip to content

fix(replay): text layouts with center/end alignment return incorrect masking bounding box#5218

Merged
markushi merged 9 commits intomainfrom
markushi/fix/jpc-masking-mismatch-weighted-text
Mar 25, 2026
Merged

fix(replay): text layouts with center/end alignment return incorrect masking bounding box#5218
markushi merged 9 commits intomainfrom
markushi/fix/jpc-masking-mismatch-weighted-text

Conversation

@markushi
Copy link
Member

@markushi markushi commented Mar 20, 2026

Description

Fix Compose text masking for layouts where text alignment (TextAlign.Center, TextAlign.End) or weighted layouts produce incorrect masking bounding boxes.

Root Cause

Compose's MultiParagraph always uses constraints.maxWidth as the paragraph width, but the Text composable may size its node to a smaller content width. This causes getLineLeft/getLineRight to return positions in the paragraph coordinate system that don't match the node's actual bounds, resulting in masking rects placed at wrong positions (e.g. off-screen for end-aligned weighted text).

Changes

  • Simplified TextLayout interface: replaced getPrimaryHorizontal, getEllipsisCount, getLineVisibleEnd, getLineStart with getLineLeft/getLineRight — directly using the layout's line bounds instead of computing them from character offsets
  • Fixed paragraph/node width mismatch: when paragraph width exceeds the node width, fall back to lineWidth starting from x=0, since text alignment has no visible effect in content-wrapped nodes
  • Removed hasFillModifier workaround: no longer needed since we use getLineLeft/getLineRight directly
  • removed obsolete fill modifier detection

Motivation and Context

The Fill modifier detection was a fragile workaround that didn't cover all cases (e.g. weighted text). The new approach correctly handles all text alignment and sizing scenarios by comparing the paragraph width against the actual node width.

How did you test it?

  • Tested with the Android sample app using various Compose text layouts: blank, fillMaxWidth, center-aligned, end-aligned, weighted, and multiline
  • Existing screenshot snapshot tests pass with updated baselines

Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 20, 2026

Semver Impact of This PR

🟢 Patch (bug fixes)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

  • (core) Add configurable IScopesStorageFactory to SentryOptions by adinauer in #5199
  • (replay) Add beforeErrorSampling callback to Session Replay by romtsn in #5214

Bug Fixes 🐛

  • (replay) Text layouts with center/end alignment return incorrect masking bounding box by markushi in #5218

Internal Changes 🔧

  • (deps) Update Native SDK to v0.13.3 by github-actions in #5215
  • (opentelemetry) Bump OpenTelemetry dependencies by adinauer in #5225

🤖 This preview updates automatically when you update the PR.

@sentry
Copy link

sentry bot commented Mar 20, 2026

Sentry Build Distribution

App Name App ID Version Configuration Install Page
SDK Size io.sentry.tests.size 8.36.0 (1) release Install Build

@github-actions
Copy link
Contributor

github-actions bot commented Mar 20, 2026

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 312.65 ms 366.79 ms 54.15 ms
Size 0 B 0 B 0 B

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
abfcc92 304.04 ms 370.33 ms 66.29 ms
3699cd5 423.60 ms 495.52 ms 71.92 ms
b3d8889 371.33 ms 426.24 ms 54.92 ms
55aaf9b 336.43 ms 364.14 ms 27.71 ms
6727e14 337.22 ms 373.94 ms 36.71 ms
f634d01 359.58 ms 433.88 ms 74.30 ms
ee747ae 374.71 ms 455.18 ms 80.47 ms
bbc35bb 324.88 ms 425.73 ms 100.85 ms
f064536 327.04 ms 405.35 ms 78.31 ms
ee747ae 400.46 ms 423.61 ms 23.15 ms

App size

Revision Plain With Sentry Diff
abfcc92 1.58 MiB 2.13 MiB 557.31 KiB
3699cd5 1.58 MiB 2.10 MiB 533.45 KiB
b3d8889 1.58 MiB 2.10 MiB 535.07 KiB
55aaf9b 0 B 0 B 0 B
6727e14 1.58 MiB 2.28 MiB 718.64 KiB
f634d01 1.58 MiB 2.10 MiB 533.40 KiB
ee747ae 1.58 MiB 2.10 MiB 530.95 KiB
bbc35bb 1.58 MiB 2.12 MiB 553.01 KiB
f064536 1.58 MiB 2.20 MiB 633.90 KiB
ee747ae 1.58 MiB 2.10 MiB 530.95 KiB

Previous results on branch: markushi/fix/jpc-masking-mismatch-weighted-text

Startup times

Revision Plain With Sentry Diff
0f34885 305.96 ms 359.02 ms 53.07 ms
c20e90d 301.13 ms 349.74 ms 48.61 ms
4af8342 390.10 ms 494.80 ms 104.69 ms
cfbf883 337.76 ms 386.96 ms 49.20 ms

App size

Revision Plain With Sentry Diff
0f34885 0 B 0 B 0 B
c20e90d 0 B 0 B 0 B
4af8342 0 B 0 B 0 B
cfbf883 0 B 0 B 0 B

@markushi markushi changed the title fix(replay): Remove Fill modifier workaround and shortcut single-line text masking fix(replay): text layouts with center/end alignment return incorrect masking bounding box Mar 20, 2026
@markushi markushi marked this pull request as ready for review March 23, 2026 14:31
Copy link
Member

@romtsn romtsn left a comment

Choose a reason for hiding this comment

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

sick!

markushi and others added 2 commits March 24, 2026 11:57
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@markushi markushi merged commit 23b2680 into main Mar 25, 2026
71 of 73 checks passed
@markushi markushi deleted the markushi/fix/jpc-masking-mismatch-weighted-text branch March 25, 2026 07:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants