microsoft / microsoft/terminal

Add support for subpixel positioning and fractional cell sizes

Open
#15,805 0 comments 7 reactions 0 assignees View on GitHub
Area-Rendering Issue-Task Product-Terminal
Dominant language
C++
Stars
105k
Forks
9.6k
Avg merge
3d 17h
Merged PRs (30d)
29

Description

# 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.

Contributor guide

Open the contributing guide

Research direction

Start in AtlasEngine and trace the glyph cache, including AtlasGlyphEntry and its glyphIndex key. Then map the uses of til::point, til::size, and other integer viewport-coordinate types. Done means fractional coordinates and fractional cell sizes work with subpixel glyph variants without overlaps or gaps; the issue names no specific test to run.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
computer-graphics, desktop
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.