Skip to content

fix(dynamic-atlas): use dynamic batch size to prevent glyph clipping at large font sizes#78

Merged
junkdog merged 1 commit into
junkdog:mainfrom
kofany:fix/issue-67-glyph-clipping-large-fonts
Jan 25, 2026
Merged

fix(dynamic-atlas): use dynamic batch size to prevent glyph clipping at large font sizes#78
junkdog merged 1 commit into
junkdog:mainfrom
kofany:fix/issue-67-glyph-clipping-large-fonts

Conversation

@kofany

@kofany kofany commented Jan 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #67

The OffscreenCanvas used for glyph rasterization has a fixed height of 1024px. When using larger font sizes (e.g., 30px resulting in ~60px cell height), the previous hardcoded batch size of 32 glyphs would exceed the canvas height (32 × 60px = 1920px > 1024px), causing glyphs beyond the canvas boundary to be clipped/empty.

This was the root cause of characters like ~, -, <, > disappearing at larger font sizes - they appeared late in the ASCII batch and were rendered beyond the canvas boundary.

Why ~ (tilde) disappeared

ASCII ~ is code 0x7E (126). In the ASCII glyph upload, it's at position 94 (126 - 32). With batch size 32:

  • Batch 0: glyphs 0-31 (space to ?)
  • Batch 1: glyphs 32-63 (@ to _)
  • Batch 2: glyphs 64-95 (` to ~)

Tilde at local position 30 in batch 2 means Y = 30 × 60px = 1800px - well beyond the 1024px canvas!

The fix

Adds CanvasRasterizer::max_batch_size() which dynamically calculates the maximum batch size based on cell height:

pub(crate) fn max_batch_size(&self) -> usize {
    (OFFSCREEN_CANVAS_HEIGHT / self.cell_metrics.padded_height).max(1) as usize
}

This keeps the batch size knowledge encapsulated in the rasterizer where it belongs, and DynamicFontAtlas simply calls self.rasterizer.max_batch_size() instead of using a hardcoded value.

Test plan

  • Tested with font sizes 25px, 30px, 35px - all ASCII characters render correctly
  • Verified emoji and CJK characters still work (they use upload_pending_glyphs which also uses dynamic batch size now)

@kofany kofany force-pushed the fix/issue-67-glyph-clipping-large-fonts branch 2 times, most recently from 840a5bd to e4ef1bc Compare January 13, 2026 12:10
@junkdog

junkdog commented Jan 15, 2026

Copy link
Copy Markdown
Owner

i like the approach but i think it's better to rescale the offscreen canvas to fit 32 glyphs, to avoid creating too many (tiny) batches.

@kofany

kofany commented Jan 15, 2026

Copy link
Copy Markdown
Contributor Author

i like the approach but i think it's better to rescale the offscreen canvas to fit 32 glyphs, to avoid creating too many (tiny) batches.

I will try this approach maybe during weekend. Thanks for pointing direction :)

… batch size

Instead of dynamically reducing batch size when cell height is large,
resize the offscreen canvas to always fit 32 glyphs. This avoids
creating many small batches which hurts GPU performance.

The canvas height is now calculated as: 32 * padded_cell_height

For example, with 60px cell height:
- Before: batch_size = 1024/60 = 17 glyphs (many small batches)
- After: canvas = 32*60 = 1920px (optimal 32-glyph batches)

Fixes junkdog#67
@kofany kofany force-pushed the fix/issue-67-glyph-clipping-large-fonts branch from e4ef1bc to efc040d Compare January 19, 2026 22:17
@kofany

kofany commented Jan 19, 2026

Copy link
Copy Markdown
Contributor Author

@junkdog Check it now please :)

@junkdog

junkdog commented Jan 25, 2026

Copy link
Copy Markdown
Owner

looking good, thanks!

@junkdog junkdog merged commit 4620b59 into junkdog:main Jan 25, 2026
5 checks passed
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.

glyphs in some .atlas files are too large, causing gaps between cells

2 participants