827d94a seems to have broken building on aarch64. The fix is pretty
much adapted from bf962c8.
I know little about rust, so I might've missed some obvious issues with
this PR - it seems to work so far, though.
This commit adds support for computing the codepoint coverage for fonts
loaded from font-dirs and the built-in, in-memory fonts.
What this means is that if you have eg: a font with chinese glyphs in
your font-dirs but not explicitly listed in your wezterm config, if
chinese text is rendered and no match from your config is found, wezterm
will be able to find the font from your font-dirs and use that
implicitly.
Computing the codepoint coverage is relatively expensive so we defer it
until we need to perform it, and cache it.
Previously, we'd enumerate the font dirs on every font resolve for
every bit of styled text.
This moves the new FontDatabase instances to be single instanced
in the FontConfiguration. The font-dirs will be scanned once
on a config reload, but the built-in in-memory fonts will only
every be enumerated once per FontConfiguration instance.
This tidies up the font-dir and built-in font management a little
bit and paves the way for codepoint -> font resolution for fonts
discovered in font-dirs.
The recent addition of dynamic fallback resolution highlighted this
issue.
The test scenario is:
1. Output some glyphs that need dynamic fallback
2. ctrl-+ to change the font scaling
3. rasterization fails because of some bad cached state; the font_idx's
were invalidated by the scale change which reset the dynamically
discovered fallback fonts.
The resolution is to blow the glyph and shape caches when scaling
is changed.
By default, freetype doesn't include error strings and FT_Error_String
will always return NULL. Turn on the compile time option that makes
this function useful!
This commit uses a bit of DirectWrite to discover which font(s)
can be used to render a set of codepoints.
While hooking this up, I found that the method we were using
to extract the font data didn't handle TTC data so this commit
improves some parser diagnostics and handling for that.
refs: https://github.com/wez/wezterm/issues/299
Profiling showed that set_font_size was a hotspot. While there was
caching of the size info at the shaper layer, it was also needed in
the raster layer, so move it into the raster layer from the shaper
layer.
refs: #353
98f289f511 causes more metrics retrieval
than in earlier versions; each unchached glyph render would trigger
a metrics recompute for the relevant font.
Add a simple cache for this.
refs: #353
This commit makes some adjustments to FontConfiguration and LoadedFont
such that it the shaper is unable to resolve a (non-last-resort) font
for a set of codepoints, the locator can be used to try to find a
font that has coverage for those codepoints.
At the moment this is a bit limited:
* Only the font-config locator implements this function
* The directory based locator isn't actually an implementor of the
locator trait and doesn't have a way to be invoked for this.
Adds an option to control how wide glyphs (more specifically: square
aspect glyphs) are scaled to conform to their specified width.
The three options are `Never`, `Always`, and `WhenFollowedBySpace`.
When a glyph is loaded, if it is approximately square, this option is
consulted. If overflow is permitted then the glyph will be scaled
to fit only the height of the cell, rather than ensuring that it fits
in both the height and width of the cell.
refs: #342
Make an effort to explain what failed to load and where it came from,
and funnel users to the documentation on font configuration.
The message presented is slightly different depending on whether
we think that the font was their primary font, an explicitly
specified font_rule or an implicitly synthesized font_rule.
refs: #340
Use the scaling factor between the font metrics for the base font
and those of the fallback font selected for a given glyph.
The scenario is this: the base font is typically the first one selected
from the font configuration. There may be multiple fallback fonts that
are different sizes; for instance, the Font Awesome font has glyphs that
are square in aspect and are thus about twice the width of a typical
textual monospace font. Similarly, Noto Color Emoji is another square
font but that has a single set of bitmap strikes at a fixed 128 px
square.
The shaper returns advance metrics in the scale of the containing font,
and the rasterizer will target the supplied size and dpi.
We need to scale these to match the base metrics.
Previously we used a crude heuristic to decide whether to scale,
and that happened to work for Noto Color Emoji but not for Font Awesome,
whose metrics were just inside the bounds of the heuristic.
This commit allows retrieving the metrics for a given font_idx so
that we can compute the correct scale factor without any heuristics,
and applies that to the rasterized glyph.
refs: https://github.com/wez/wezterm/issues/342
Don't short circuit on just the family portion of the name;
if the criteria don't match there, we should fall back to
test against the full font name.
closes: https://github.com/wez/wezterm/issues/341
Weird that this was set to not enable C++, but I suspect it is the
reason why the C++11 compiler flag isn't being added to resolve this:
```
warning: harfbuzz/src/hb-meta.hh:41:18: warning: variadic templates are a C++11 extension [-Wc++11-extensions]
warning: template<typename... Ts> struct _hb_void_t { typedef void type; };
```
This is one of those massive time sinks that I almost regret...
As part of recent changes to dust-off the allsorts shaper, I noticed
that the harfbuzz shaper wasn't shaping as well as the allsorts one.
This commit:
* Adds emoji-test.txt, a text file you can `cat` to see how well
the emoji are shaped and rendered.
* Fixes (or at least, improves) the column width calculation for
combining sequences such as "deaf man" which was previously calculated
at 3 cells in width when it should have just been 2 cells wide, which
resulted in a weird "prismatic" effect during rendering where the
glyph would be rendered with an extra RHS portion of the glyph across
3 cells.
* Improved/simplified the clustering logic used to compute fallbacks.
Previously we could end up with some wonky/disjoint sequence of
undefined glyphs which wouldn't be successfully resolved from a
fallback font. We now make a better effort to consolidate runs of
undefined glyphs for fallback.
* For sequences such as "woman with veil: dark skin tone" that occupy a
single cell, the shaper may return 3 clusters with 3 glyphs in the
case that the font doesn't fully support this grapheme. At render
time we'd just take the last glyph from that sequence and render it,
resulting in eg: a female symbol in this particular case. It is
generally a bit more useful to show the first glyph in the sequence
(eg: person with veil) rather than the gender or skin tone, so the
renderer now checks for this kind of overlapping sequence and renders
only the first glyph from the sequence.
Bundle the *Last Resort High-Efficiency* font from
https://github.com/unicode-org/last-resort-font/
version 13.001 (Oct 22 2020).
This provides a more useful fallback glyph than we'd otherwise
produce if there is no matching glyph in any of the fonts.
Its license is OFL-1.1 which is compatible with the other
bundled fonts.
There are a number of cases where font-loader might panic on windows,
and the optional font-loader dep causes problems with `cargo vendor`
in #337, so this is a step to removing that dep.
This commit makes direct GDI calls to enumerate monospace truetype
fonts from the system and then applies our normal matching on the
result.
The current master of allsorts supports color fonts in both bitmap and
svg varieties. I'm interested to see if I can teach wezterm to render
the svg based variety in a subsequent diff.
First though, it's times to dust off our allsorts shaper logic.
This commit updates to point to the current master of allsorts at the
time of writing; there's a little bit of API fanout that makes it a bit
easier to manage font fallback.
The fallback logic has been improved so that we can now successfully
fall back to the emoji font.
The shaping logic has been improved so that we turn on the options that
enable ZWJ for combining sequences of emoji, such as "man health
worker".
Running with the allsorts shaper enabled produces generally superior
emoji/ligature substitution results compared to harfbuzz with Noto Color
Emoji; the "man health worker" and the flags (eg: `flag: England`) from
the subdivsion-flag section don't get substituted at all with harfbuzz,
but do produce appropriate glyphs with allsorts.
refs: https://github.com/wez/wezterm/issues/66
This causes `tmux -CC attach` to enter control mode and patch
into the terminal, printing out parsed event messages.
refs: https://github.com/wez/wezterm/issues/336
When subpixel or greyscale AA are in use, the glyph data includes
some lighter and darker shaded pixels. That's their purpose,
but if the fg and bg color are the same, the expectation is that
the glyph is invisible and we don't want "phantom" pixels around
the character.
This commit adjusts the shader to set the color to transparent
when the fg and bg are the same, and we are not rendering a color
emoji.
refs: #331