Instead of blindly pushing default font to the start of the monospace
fallbacks map. Actually collect codepoint support info for it, and if
it supports all codepoints, skip collecting that info from other
monospace fonts. If it doesn't, push it to the start of the map as
before.
This actually provides a big performance boost, while the sophisticated
monospace fallback process is still done whenever needed.
Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com>
When font fallback involves monospace fonts, and if word has known
scripts, limit the fonts tried for fallback to ones that support at
least one requested script.
Codepoint support info is still collected for these fonts to guide
the fallback order selection process.
A map of per-script monospace font-ids is pre-populated in font system
to acquire lists of wanted font ids efficiently.
Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com>
For the simplest case of " " words, a quick binary search in
`supported` vec will suffice, instead of using `slice::contains()`
for all monospace fonts, where some of them may support thousands of
codepoints.
Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com>
When matching on weights smaller than normal, "equal or smaller"
weight restriction may cause monospace fallback to fail, depending
on font support at such weights for the text to be shaped.
So remove that restriction, and calculate weight differences instead
of offsets.
In case of no exact weight match, and with all other factors being
equal, smaller weights will be picked before bigger ones. So, this
should generally not cause any behavioral changes when matching on
normal weight or bigger.
Should fixpop-os/cosmic-term#104.
Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com>
`Attrs` contains info like color and metadata which are not relevant
to font matching.
So, add a new struct `FontMatchAttrs` which only contains the relevant
info, and use it as a key in `FontSystem`'s `font_matches_cache`.
Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com>
In `FontSystem`, `font_matches_cache` is an ever growing cache.
It can also be a fast growing one in stress tests like running this
in `cosmic-term`:
mpv -speed 3 -vo tct <some_video>
So this commit adds a size limit to that cache, and clears the cache
when that limit is reached, which shouldn't be a common occurrence in
normal usage.
Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com>
This should/could improve fallback order.
This could also probably be utilized for non-Monospace fallback too.
But I didn't want to touch that code to avoid accidentally breaking
anything.
Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com>
A combination of some ideas:
* Try all Monospace fonts before giving up.
* Relax exact weight restriction on font matching when trying Monospace
fall-back. Try smaller weights if needed.
* Make the fall-back try order weight-offset aware, AND script-aware.
* And finally, add the option to adjust the font size of glyphs using
fall-back Monospace fonts, so the width of them matches the default
font width.
For my use-case, the current fall-back attempt always fails with
Arabic script. And none of the Arabic-supporting Monospace fonts in
my system also support medium weight. So, if my default font is set
to medium weight, script-aware fall-back alone will still not work.
Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com>
- Scroll is identified by line index and layout index, instead of just
layout index
- Shaping has the option to prune, where caches outside of the scroll
view are cleared
- Syntax editor no longer requires layout of all lines, only of lines
inside scroll
- BufferLine has a metadata field that can be used by other abstractions
to know when text was changed
This commit adds a new ShapeBuffer type, which contains some buffers tha
are commonly re-created during the shaping process. New APIs are added
that take this structure, and old APIs are turned into wrappers around
the new API.
The goal is to reduce the number of per-layout allocations that happen
in a typical layout call.
This reduces compilation time by removing a dependency on syn and other
dependencies of ouroboros_macros. In addition it saves a lot of unused
codegened methods.
On my laptop (2 core + HT) this reduces compilation time by ~20%. On a
many core system this doesn't help much though as the critical path path
consists of both ttf-parser -> rustybuzz and swash. Further gains will
likely need to be made by reducing compilation time for these crates.
Benchmark 1: cargo build
Time (mean ± σ): 25.150 s ± 0.167 s [User: 84.414 s, System: 7.335 s]
Range (min … max): 24.909 s … 25.444 s 10 runs
Benchmark 1: cargo build
Time (mean ± σ): 19.819 s ± 0.226 s [User: 67.754 s, System: 5.592 s]
Range (min … max): 19.492 s … 20.140 s 10 runs
The code is based on an expansion of the ouroboros macro, cleaned up to
remove all unused methods and inline most functions that are only called
once.
This exposes `rustybuzz` on top of `fontdb`. This is in particular
useful if you want to query the font for additional information. This is
already publically exposed via `Font::rustybuzz()`, but the types were
not re-exported, so it was impossible to properly use that function.