~eliasnaur/gio

4 2

Status of text rendering

Details
Message ID
<2f5fca85-b10e-837c-b778-f157a5361529@meessen.net>
DKIM signature
pass
Download raw message
Hello, I’m new to the GIO community and consider to contribute to the 
project.

I have noticed that Text rendering is not optimal. It appears grey and 
fuzzy instead of black and crisp on my display.

Is there anybody already working on this issue ? If not, I’ll try to 
understand why and if possible suggest a fix.

By the way, I prefer working with github. What is the status of the 
github mirror. There are a few pending pull requests.

-- 
Bien cordialement,
Ch.Meessen
Details
Message ID
<CA4MU4EPT33T.3H0QKNBFZOYW5@themachine>
In-Reply-To
<2f5fca85-b10e-837c-b778-f157a5361529@meessen.net> (view parent)
DKIM signature
fail
Download raw message
DKIM signature: fail
On Tue Mar 23, 2021 at 10:14, Christophe Meessen wrote:
> Hello, I’m new to the GIO community and consider to contribute to the 
> project.
>
> I have noticed that Text rendering is not optimal. It appears grey and 
> fuzzy instead of black and crisp on my display.
>

Indeed, Gio text rendering lacks in (at least) in two dimensions:

First, text rendering is light/fuzzy in particular on low-dpi screens. I
believe the primary cause is that Gio anti-aliases rendering in an sRGB
correct way with the usual gamma value (~2.2), but fonts are authored to
match popular font renderers that use lower (~1.8) or no gamma (1.0).

I'm definitely not an expert in this area, but I found a few
articles[0][1] that explains things better than I can.

One solution to compensate for the lower gamma value of fonts is to do
stem-widening, that is slightly stretching glyphs in the horizontal
direction.

Gio doesn't implement sub-pixel anti-aliasing, but I'm not sure it's
worth doing, considering that Apple's macOS (and iOS) is moving away
from that.

The second dimension is proper text shaping, crucial for scripts such as
Hebrew and Arabic. Gio only implements a simple text layout algorithm
suitable for Western scripts. See [2] for some investigation into this
issue.

> Is there anybody already working on this issue ? If not, I’ll try to 
> understand why and if possible suggest a fix.
>

I'm not sure, but I don't think so. Speaking for myself, I'm unlikely to
work on the issue in the immediate future.

> By the way, I prefer working with github. What is the status of the 
> github mirror. There are a few pending pull requests.
>

I actively review PRs on GH. I believe the active PRs all have pending
review comments or are incomplete.

> -- 
> Bien cordialement,
> Ch.Meessen

[0] https://www.freetype.org/freetype2/docs/hinting/text-rendering-general.html
[1] https://www.puredevsoftware.com/blog/2019/01/22/sub-pixel-gamma-correct-font-rendering/
[2] https://gioui.org/issue/146
Details
Message ID
<f8be0d96-0e92-b3e0-e6ae-40bb09d479cf@meessen.net>
In-Reply-To
<CA4MU4EPT33T.3H0QKNBFZOYW5@themachine> (view parent)
DKIM signature
pass
Download raw message
Hello,

after exploring a bit GIO code it seam that GIO is building text as a 
sequence of glyph paths. I assume the path is then filled by the GPU to 
render the text. Please correct me if I’m wrong.

The fuzziness may then result from a "misalignment" of the glyphs with 
the pixel grid. A letter I for instance may end up partially covering 
two vertical pixel stripes, instead of one. As a consequence, the 
anti-aliazing rasterizer will render it as a fat gray vertical line 
instead of a one pixel wide black vertical line. This problem could be 
fixed by enforcing an alignment of the glyphs to the pixel grid, but GIO 
make abstraction of the pixel grid and display resolution. So I don’t 
know how it could be possible to fix that.

Another possible source of problem is the rasterization and filling 
process of the glyph paths. I couldn’t find this algorithm in GIO to see 
how it works. There is a balance between speed and precision with such 
type of algorithms. It might be not precise enough for font glyph 
rendering. golang.org/x/image/font uses analytic surface computation by 
the CPU to determine the "grayness" of pixels. It is the most precise, 
but it is also computationally expensive. For this reason, font glyphs 
are usually rendered once in cached image buffers at a specified 
resolution, and the images are simply copied in place when text is 
drawn. This optimizes the speed and quality of text drawing. The 
disadvantage of this method is that the display pixel grid and 
resolution can’t be left abstract as is currently the case in GIO.


-- 
Bien cordialement,
Ch.Meessen
Details
Message ID
<CA68R9NAYGGO.2F889X0CS1UZP@testmac>
In-Reply-To
<f8be0d96-0e92-b3e0-e6ae-40bb09d479cf@meessen.net> (view parent)
DKIM signature
fail
Download raw message
DKIM signature: fail
On Wed Mar 24, 2021 at 18:14 CET, Christophe Meessen wrote:
> Hello,
>
> after exploring a bit GIO code it seam that GIO is building text as a 
> sequence of glyph paths. I assume the path is then filled by the GPU to 
> render the text. Please correct me if I’m wrong.
>

Correct.

> The fuzziness may then result from a "misalignment" of the glyphs with 
> the pixel grid. A letter I for instance may end up partially covering 
> two vertical pixel stripes, instead of one. As a consequence, the 
> anti-aliazing rasterizer will render it as a fat gray vertical line 
> instead of a one pixel wide black vertical line. This problem could be 
> fixed by enforcing an alignment of the glyphs to the pixel grid, but GIO 
> make abstraction of the pixel grid and display resolution. So I don’t 
> know how it could be possible to fix that.
>

All coordinates in Gio is in pixel coordinates. The abstraction of
display resolution is at a higher level, through unit.Metric and related
types.

So text layout does happen on top of the pixel grid.

Further, Gio uses "full hinting" for glyph paths, see for example [0]
and other references in the same file.

It's quite possible that there is a bug in the hinting process, or that
the underlying golang.org/x/image/font/sfnt and related packages somehow
fail to apply hinting. However, I don't believe there is a fundamental
reason Gio couldn't apply text hintint correctly.

> Another possible source of problem is the rasterization and filling 
> process of the glyph paths. I couldn’t find this algorithm in GIO to see 
> how it works. There is a balance between speed and precision with such 
> type of algorithms. It might be not precise enough for font glyph 
> rendering. golang.org/x/image/font uses analytic surface computation by 
> the CPU to determine the "grayness" of pixels. It is the most precise, 
> but it is also computationally expensive. For this reason, font glyphs 
> are usually rendered once in cached image buffers at a specified 
> resolution, and the images are simply copied in place when text is 
> drawn. This optimizes the speed and quality of text drawing. The 
> disadvantage of this method is that the display pixel grid and 
> resolution can’t be left abstract as is currently the case in GIO.
>

Both Gio renderers apply analytic anti-aliasing. There are two
implementations in package gpu, the current default[1] and the newer
compute based renderer[2] that will become the default.

The rendered paths are not (currently) reused across frames. They are
always rendered from scratch. In future they may be cached across
frames, but even then they will only be reused for pixel-grid aligned
(integer) offsets to ensure their anti-aliasing remain valid.

Elias

[0] https://git.sr.ht/~eliasnaur/gio/tree/main/item/font/opentype/opentype.go#L93
[1] https://git.sr.ht/~eliasnaur/gio/tree/main/item/gpu/shaders/stencil.frag
[2] https://git.sr.ht/~eliasnaur/gio/tree/main/item/gpu/shaders/kernel4.comp#L183
Details
Message ID
<9d46d734-6400-60d6-b674-a540b0a4e961@meessen.net>
In-Reply-To
<CA4MU4EPT33T.3H0QKNBFZOYW5@themachine> (view parent)
DKIM signature
pass
Download raw message
I checked HintingNone and HintingFull gives better result.

Since this mailing list is text only, I can’t provide images to show the 
result.

Does GIO perform gamma correction ? If yes, could it be possible to 
disable it to see if the problem result from gamma correction ?

My impression is that image/font doesn’t do gamma correction.




-- 
Bien cordialement,
Ch.Meessen
Reply to thread Export thread (mbox)