Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plan for glyph rendering #204

Open
raphlinus opened this issue Nov 17, 2022 · 1 comment
Open

Plan for glyph rendering #204

raphlinus opened this issue Nov 17, 2022 · 1 comment
Labels
architecture Changes to the way it's put together

Comments

@raphlinus
Copy link
Contributor

This issue is branched from a question raised linebender/xilem#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.

@raphlinus raphlinus added the architecture Changes to the way it's put together label Nov 17, 2022
@canadaduane
Copy link
Contributor

I'd just like to cross-pollinate slimsag's work here in the Zig language on curve primitives:

https://www.youtube.com/watch?v=QTybQ-5MlrE

It's still early days, so it may not be the right path in Vello (no pun intended), but maybe it will lead to more ideas.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
architecture Changes to the way it's put together
Projects
None yet
Development

No branches or pull requests

2 participants