Add support for subpixel positioning and fractional cell sizes #20341

Open
opened 2026-01-31 07:10:52 +00:00 by claunia · 0 comments
Owner

Originally created by @lhecker on GitHub (Aug 7, 2023).

Description of the new feature/enhancement

Subpixel positioning is a popular technique among modern text renderers to increase the horizontal (and sometimes vertical) resolution of glyph origins. With our current approach you get 1 variant of each glyph. No matter where the glyph is supposed to be drawn (e.g. at {84.3px, 19.6px}), the origin of the glyph's bitmap is rounded to the nearest pixel and the bitmap is bit-blit on the screen.

But with a 2x resolution you prepare 2 variants of each glyph, where the additional one is shifted by 0.5px during the initial rasterization into a bitmap. This ends up giving slightly, but noticeably different results. A 3x resolution seems to be the most common.

For instance, Chromium:
image

A great introduction for this is this document from a Google employee: http://goo.gl/yf3M7

Adding support for subpixel positioning would also significantly improve our support for block glyphs like those found in Nerd Fonts, because the font's advance width is seldomly an integer pixel value, which results in either block glyph overlaps (= cut-off appearance), or, even worse, gaps between glyphs.

Proposed technical implementation details (optional)

Supporting this in AtlasEngine is trivial. Direct2D has support for subpixel positioning (at 3x). Keying our glyph cache by subpixel offset would be easily possible by adding another field to the AtlasGlyphEntry structure to form a pair with the glyphIndex.

The real problem is all the code that uses til::point, til::size or other integer values to represent viewport coordinates in pixels. If those were gone and replaced with floats, implementing the rest would be fairly simple.

Originally created by @lhecker on GitHub (Aug 7, 2023). # Description of the new feature/enhancement Subpixel positioning is a popular technique among modern text renderers to increase the horizontal (and sometimes vertical) resolution of glyph origins. With our current approach you get 1 variant of each glyph. No matter where the glyph is supposed to be drawn (e.g. at `{84.3px, 19.6px}`), the origin of the glyph's bitmap is rounded to the nearest pixel and the bitmap is bit-blit on the screen. But with a 2x resolution you prepare 2 variants of each glyph, where the additional one is shifted by 0.5px during the initial rasterization into a bitmap. This ends up giving slightly, but noticeably different results. A 3x resolution seems to be the most common. For instance, Chromium: ![image](https://github.com/microsoft/terminal/assets/2256941/0c0e4deb-884a-4f0f-b6ef-5ff03534a4d6) A great introduction for this is this document from a Google employee: http://goo.gl/yf3M7 Adding support for subpixel positioning would also significantly improve our support for block glyphs like those found in Nerd Fonts, because the font's advance width is seldomly an integer pixel value, which results in either block glyph overlaps (= cut-off appearance), or, even worse, gaps between glyphs. # Proposed technical implementation details (optional) Supporting this in AtlasEngine is trivial. Direct2D has support for subpixel positioning (at 3x). Keying our glyph cache by subpixel offset would be easily possible by adding another field to the `AtlasGlyphEntry` structure to form a pair with the `glyphIndex`. The real problem is all the code that uses `til::point`, `til::size` or other integer values to represent viewport coordinates in pixels. If those were gone and replaced with floats, implementing the rest would be fairly simple.
claunia added the Area-RenderingIssue-TaskProduct-Terminal labels 2026-01-31 07:10:52 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#20341