linebender / linebender/vello

Plan for glyph rendering

Open
#204 1 comment 5 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

architecture
Dominant language
Rust
Stars
4.3k
Forks
300
Avg merge
2d 13h
Merged PRs (30d)
61

Description

This issue is branched from a question raised https://github.com/linebender/xilem/pull/1 about our plan for glyph rendering, as that is the responsibility of piet-gpu rather than other layers in the stack.

For the first cut, all glyph rendering will happen as dynamic vector graphics rendering, getting the outlines from the font (currently through swash but possibly migrating to Oxidize) and assembling them into scene fragments. At first we will also not support hinting at all, nor stem darkening, nor RGB subpixel rendering. Results will be pretty good on high-dpi screens, but definitely suboptimal on low-dpi. Performance may be a problem on very low-spec GPUs as well.

The roadmap has a number of improvements. One is to support a glyph cache, which by itself doesn't change rendering quality, but will improve performance greatly (especially on low-spec GPUs, in which pulling textures from the glyph atlas will outperform rendering vectors). The infrastructure for glyph (which involves tracking the transform at which a glyph will be displayed) also enables hinting (which is fairly well implemented by swash already).

When hinting is enabled, it will be a configurable option. It is desirable for UI text (and you'd want it for displaying the text in a text editor), but it is *not* desirable when the scene is more dynamic. Cases where hinting would cause "shimmering" effects include pinch-to-zoom (or any other transform than scrolling) and animation of variable font parameters.

An important quality improvement (especially on macOS) is stem darkening. The best way to implement this is to make coarse path rasterization capable of offset as well as flattening (the same logic will support both stroke rendering and stem darkening). I've figured out the math for this and have a prototype (in JS) but haven't yet implemented it as a compute shader; there are some tricky aspects, especially dealing with joins at corners. This improvement is orthogonal to glyph caching.

Lastly, to support low-dpi screens (especially Windows) we would want to implement RGB subpixel rendering, which is mostly a change in fine rasterization.

With a glyph cache in place, we have a choice. Either this cache is filled by doing path rendering in piet-gpu, or by calling into platform glyph rendering (particularly DirectWrite on Windows). The latter would allow pixel-perfect matching to platform text, but at a performance cost and with other tradeoffs (having two pipelines rather than one always causes problems). My current inclination is to render all the glyphs ourselves, but this is something we can revisit. Note that one option for platform glyph rendering is to take a dependency on font-kit.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the glyph-rendering responsibilities described for piet-gpu, including dynamic vector rendering, glyph caching, hinting, stem darkening, and RGB subpixel rendering. The issue names no files, tests, or implementation entry point, and completion would require choosing and designing a roadmap item.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
computer-graphics
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.