Skip to content

feat(canvas): measure labels with real font metrics via engine callback (DasherCore v0.2.4) - #33

Merged
willwade merged 1 commit into
mainfrom
feat/text-size-callback
Aug 24, 2026
Merged

feat(canvas): measure labels with real font metrics via engine callback (DasherCore v0.2.4)#33
willwade merged 1 commit into
mainfrom
feat/text-size-callback

Conversation

@willwade

@willwade willwade commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Wires DasherCore v0.2.4's dasher_set_text_size_callback (#28's Windows-side actions; engine fix = DasherCore #56 / PR #57): the engine now asks the frontend to measure single-line labels with real font metrics instead of its code-points × fontSize/2 estimate. The estimate under-measured wide Segoe UI glyphs by up to ~2× and the error compounded down the ancestor label chain — long sentences ended with jumbled, squashed, cut-off labels at the right edge (the reporting user's screenshots; she runs v5 on Windows without the problem).

  • measuring and drawing share CommandRenderer.ResolveTypeface (user-selected Dasher font, or Segoe UI) so layout can never disagree with rendering
  • dasher_text_metrics_changed() invalidates the engine's measurement cache whenever SP_DASHER_FONT changes (font picker, settings import)
  • measurement failures return 0 → the engine falls back to its estimate without caching and retries next frame
  • callback fires on the dasher_frame() thread = the UI thread (DispatcherTimer), so FormattedText is safe

Submodule pin: v0.2.4 (bumped in the stacked #32).

Issue / RFC: #28, DasherCore #56, DasherCore #57

Type of change

  • Bug fix (v5-parity rendering regression)
  • New feature
  • Cross-platform / parity change (Windows first; GTK/Android/web can adopt the same callback — engine seam is documented in DasherCore v0.2.4 release notes)

Cross-platform impact

  • This changes a capability that users see on other platforms. (frontend-local fix; other frontends get the same fix by wiring the same seam)
  • This introduces a new UX or hardware interaction.

Manual verification (RFC 0011)

  • Build green, 0 warnings; suite 43/43
  • Smoke run against v0.2.4 DLL: 12s session, canvas renders, no faults
  • Acceptance test = the user's screenshots: long-sentence run shows frontier labels staying legible at the right edge; re-run after changing the canvas font

Definition of Done

  • CI is green
  • Tests added for new behaviour (measurement needs Avalonia's text pipeline — manual pass per RFC 0011; engine caches per label × size so steady-state makes zero callbacks)
  • Feature matrix updated (n/a — correctness fix)
  • Docs updated (DasherCore v0.2.4 release notes document the seam)
  • Commits are signed off (DCO)

Stacked on #30#31#32. Fixes #28

Greptile Summary

The PR integrates DasherCore’s text-size callback so label layout uses the same Avalonia typeface metrics as rendering.

  • Registers and roots the native text-measurement callback.
  • Refreshes the selected font and invalidates cached metrics before each affected frame.
  • Centralizes typeface resolution between measurement and drawing.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/Dasher.Windows/Controls/DasherCanvas.cs Registers the text-size callback, measures labels through Avalonia, and refreshes and invalidates font metrics before frame generation; both previously reported lifecycle and ordering issues are fixed.
src/Dasher.Windows/Engine/CommandRenderer.cs Extracts shared typeface resolution so measurement and rendering select the same font.
src/Dasher.Windows/Engine/NativeBridge.cs Adds the DasherCore v0.2.4 callback delegate, registration export, and metric-cache invalidation export.

Sequence Diagram

sequenceDiagram
    participant Timer as UI DispatcherTimer
    participant Canvas as DasherCanvas
    participant Core as DasherCore
    participant Renderer as CommandRenderer
    Timer->>Canvas: OnTick()
    Canvas->>Core: Read SP_DASHER_FONT
    alt Font changed
        Canvas->>Core: dasher_text_metrics_changed()
    end
    Canvas->>Core: dasher_frame()
    Core->>Canvas: OnTextSize(label, size)
    Canvas->>Renderer: ResolveTypeface(_dasherFont)
    Canvas-->>Core: measured width and height
    Core-->>Canvas: drawing commands
    Canvas->>Renderer: Render(..., _dasherFont)
Loading

Reviews (3): Last reviewed commit: "feat(canvas): measure labels with real f..." | Re-trigger Greptile

Comment thread src/Dasher.Windows/Controls/DasherCanvas.cs
Comment thread src/Dasher.Windows/Controls/DasherCanvas.cs Outdated
@willwade
willwade force-pushed the fix/speed-bounds-from-engine branch from 9795046 to 2a49d13 Compare August 24, 2026 21:02
willwade added a commit that referenced this pull request Aug 24, 2026
SP_DASHER_FONT was read after dasher_frame() returned, so on the frame
following a font change the engine measured labels with the previous
font while the renderer drew the commands with the new one - one
transient frame of clipped/overlapping labels per font change (caught
in review of #33). Read + invalidate before the frame so measurement
and rendering always see the same typeface.

Signed-off-by: will wade <willwade@gmail.com>
@willwade
willwade force-pushed the feat/text-size-callback branch from 8e46dab to 9671a4b Compare August 24, 2026 21:02
@willwade
willwade changed the base branch from fix/speed-bounds-from-engine to main August 24, 2026 21:16
Wire DasherCore v0.2.4's dasher_set_text_size_callback: the engine
measures single-line labels with the same typeface the canvas draws
opcode-5 text with (the user-selected Dasher font, or Segoe UI) instead
of its code-points x fontSize/2 estimate, which under-measured wide
Segoe UI glyphs by up to 2x and compounded into the jumbled, squashed,
cut-off labels at the right edge on long sentences (#28, DasherCore
#56; the reporting user runs v5 on Windows without the problem).

- measuring and drawing share CommandRenderer.ResolveTypeface so they
  can never disagree
- SP_DASHER_FONT is read and dasher_text_metrics_changed() invalidates
  the engine's measurement cache BEFORE dasher_frame(), so measurement
  never lags rendering after a font change
- failures return 0: the engine falls back to its estimate and retries
  next frame without caching

Recreated from the stacked branch onto post-merge main; content
identical to the reviewed commits.

Fixes #28

Signed-off-by: will wade <willwade@gmail.com>
@willwade
willwade force-pushed the feat/text-size-callback branch from 9671a4b to e01a5f0 Compare August 24, 2026 21:18
@willwade

Copy link
Copy Markdown
Contributor Author

@greptile re-review

@willwade
willwade merged commit 3cf23ed into main Aug 24, 2026
3 checks passed
@willwade
willwade deleted the feat/text-size-callback branch August 24, 2026 21:37
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.

Long sentences: labels/boxes jumble and squash at the right edge of the canvas (engine TextSize estimate)

1 participant