Skip to content

fix(annotate): loupe inner image clamped to loupe size, crosshair misaligned with placed point - #556

Merged
tstapler merged 3 commits into
mainfrom
backlog/stelekit-loupe-crosshair-alignment
Nov 4, 2026
Merged

tstapler merged 3 commits into
mainfrom
backlog/stelekit-loupe-crosshair-alignment

Conversation

@tstapler

@tstapler tstapler commented Nov 4, 2026

Copy link
Copy Markdown
Owner

Summary

The annotation loupe's crosshair did not match where the point landed on release. Root cause (measured with a probe test): inside the 120dp clipped loupe box, Modifier.size(canvas × 3) is clamped to 120dp by the parent constraints (size() = 120×120 vs requiredSize() = 1000×2000), so the 3× inner image the offset math assumes never existed.

What Changed

  • Loupe inner image uses requiredSize.
  • Offset math extracted to loupeInnerOffset (LoupeGeometry.kt) and uses roundToInt().
  • Main AsyncImage declares contentScale = ContentScale.Fit.
  • onLoupeOffset(null) now runs after onTap.
  • Tests: LoupeInnerOffsetTest (5), InProgressAnnotationCanvasGestureTest (Robolectric), plus an updateLabelText/dismiss ViewModel test.

Test plan

  • ./gradlew :kmp:testDebugUnitTest for the loupe, gesture, editor screen, parts, transform and ViewModel test classes: 0 failures
  • Check on a real device that the dot lands on the loupe crosshair center (not verified)

…redSize, round offset, explicit Fit

Root cause (measured): Modifier.size() inside the 120dp clipped loupe box is clamped to
120dp, so the 3x inner image the offset math assumes never existed. Also: roundToInt offset,
explicit contentScale on main image, clear loupe after onTap. Adds LoupeInnerOffsetTest and a
Robolectric gesture test.

Criteria 0-7
@tstapler
tstapler requested a balanced review from Copilot November 4, 2026 18:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

JVM Load Benchmark (Desktop)

1 regressed · 2 improved · 2 unchanged · 2 new · 0 removed

jvm/GraphLoad

Benchmark Base Head Change
phase1TtiMs 0 ms 1 ms 🔴 n/a (base is 0)
phase3Ms 2 ms 1 ms 🟢 -50.0% ▰▰▰▰▰

jvm/WriteLatency

Benchmark Base Head Change
jankBaselineP95Ms 37 ms 32 ms 🟢 -13.5% ▰▰▱▱▱
jankLoadP95Ms — 0 ms 🆕 new
jankFactor — 0 x 🆕 new
2 unchanged

jvm/GraphLoad

Benchmark Base Head Change
phase2Ms 0 ms 0 ms ⚪ n/a (base is 0)
totalMs 2 ms 2 ms ⚪ 0.0% ▱▱▱▱▱
Environment
Base Head
branch main HEAD
gitSha 9cc34447 532b7d9f
graphConfig xlarge xlarge
pageCount 230 230

A change counts when it is ≥ 5% and, where the data allows, statistically significant. Judged: 5 by threshold only (point estimates).

@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

JVM Load Benchmark: profiling details

Flamegraphs (this PR) **Allocation** — object allocation pressure (JDBC/SQLite churn)

Alloc flamegraph not available

CPU — method-level hotspots by on-CPU time

CPU flamegraph not available

Top allocation hotspots (this PR) `35.5%` byte[]_[k] `6.4%` java.lang.String_[k] `5.9%` int[]_[k] `5.4%` java.lang.Object[]_[k] `4.4%` java.util.LinkedHashMap$Entry_[k]
Top CPU hotspots (this PR) `97.5%` /usr/lib/x86_64-linux-gnu/libc.so.6 `0.7%` /tmp/sqlite-3.51.3.0-2df47e86-1cf4-4237-8dac-8e30b6f4d491-libsqlitejdbc.so `0.3%` __libc_pwrite `0.3%` fsync `0.2%` pthread_cond_signal

@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

CI memory (Gradle diff-coverage job, 16 GB runner)

2 benchmarks (no base to compare with)

ci-memory/diff-coverage

Benchmark Value Range
peak_used [max] 7529 MB —
min_available [min] 8454 MB —
Environment
Head
sha 532b7d9fcb336c0423136a6452cd33feb359d93f

Head-only report: add a base to see changes.

@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Android Load Benchmark (API 30 x86_64 emulator)

5 regressed · 3 improved · 1 unchanged · 0 new · 0 removed

android/GraphLoad

Benchmark Base Head Change
phase1Ms 21 ms 46 ms 🔴 +119.0% ▰▰▰▰▰
phase3Ms 2546 ms 4713 ms 🔴 +85.1% ▰▰▰▰▰

android/WriteLatency

Benchmark Base Head Change
baselineP95Ms 7 ms 12 ms 🔴 +71.4% ▰▰▰▰▰
jankFactor 2.57 x 1.08 x 🟢 -58.0% ▰▰▰▰▰
writes 14 writes 22 writes 🟢 +57.1% ▰▰▰▰▰
phase3P95Ms 18 ms 13 ms 🟢 -27.8% ▰▰▰▱▱

android/SafIo

Benchmark Base Head Change
safPerFileMs 0.13 ms 0.2 ms 🔴 +53.8% ▰▰▰▰▰
safOverhead 4 x 6 x 🔴 +50.0% ▰▰▰▰▰
1 unchanged

android/SafIo

Benchmark Base Head Change
safDirectPerFileMs 0 ms 0 ms ⚪ n/a (base is 0)
Environment
Base Head
branch main HEAD
gitSha 9cc34447 532b7d9f
pageCount 530 530

A change counts when it is ≥ 5% and, where the data allows, statistically significant. Judged: 9 by threshold only (point estimates).

diff-coverage gate failed (66% < 80%): the loupeInnerOffset call and
requiredSize/offset modifiers in LoupeOverlay only run while the loupe is
composed, and no test held a drag. Tag the overlay and assert it appears
during a held drag and is removed on release.
@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

CI memory (Bazel Android build, 16 GB runner)

2 benchmarks (no base to compare with)

ci-memory/android-build

Benchmark Value Range
peak_used [max] 11075 MB —
min_available [min] 4908 MB —
Environment
Head
sha 532b7d9fcb336c0423136a6452cd33feb359d93f

Head-only report: add a base to see changes.

@tstapler
tstapler marked this pull request as ready for review November 4, 2026 19:50
@tstapler
tstapler merged commit 0be6a65 into main Nov 4, 2026
30 of 31 checks passed
@tstapler
tstapler deleted the backlog/stelekit-loupe-crosshair-alignment branch November 4, 2026 19:51
tstapler pushed a commit that referenced this pull request Nov 6, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.106.1](v0.106.0...v0.106.1)
(2026-11-05)


### Bug Fixes

* **annotate:** loupe inner image clamped to loupe size, crosshair
misaligned with placed point
([#556](#556))
([0be6a65](0be6a65))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

2 participants