1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-25 22:33:52 +03:00
Commit Graph

245 Commits

Author SHA1 Message Date
Wez Furlong
f35d58a031 fixup win32 build
refs: https://github.com/wez/wezterm/issues/655
2021-04-07 18:17:29 -07:00
Wez Furlong
04cf0de1af fixup build on linux
refs: https://github.com/wez/wezterm/issues/655
2021-04-07 18:14:19 -07:00
Wez Furlong
e200605b8f fonts: add support for "variable" fonts
With this configuration:

```lua
local wezterm = require 'wezterm'

return {
  font_dirs = {"/Users/wez/Downloads/Inconsolata"},
  font = wezterm.font("Inconsolata"),
  font_locator = "ConfigDirsOnly"
}
```

wezterm is now able to see the 74 variations that are available
in the single inconsolata ttf.

Running `WEZTERM_LOG=wezterm_font=trace wezterm` will log the
variations.

refs: https://github.com/wez/wezterm/issues/655
2021-04-07 17:45:38 -07:00
Wez Furlong
38d6c45194 fonts: switch parsing over to freetype
This is leading up to multi-master font support
2021-04-07 16:14:58 -07:00
Wez Furlong
cf9f9c849b fixup; wasn't actually returning distinct load/render settings
refs: https://github.com/wez/wezterm/issues/639
2021-04-07 12:38:20 -07:00
Wez Furlong
b03300404a Allow specifying distinct load and render targets
refs: https://github.com/wez/wezterm/issues/639
2021-04-07 12:15:03 -07:00
Wez Furlong
d2419fb99e fonts: subpixel had blue/red flipped
refs: #639
2021-04-06 09:04:34 -07:00
Wez Furlong
a5bb5be80a fonts: fix other platforms and tests
Ungh, shouldn't push before I'm awake :-/

refs: #648
2021-04-05 09:27:01 -07:00
Wez Furlong
2c7e5196ac fonts: improve debugging for windows font loading
We didn't have as much info here as I thought; improve it!

refs: https://github.com/wez/wezterm/issues/624
2021-04-03 17:42:44 -07:00
Wez Furlong
4e25a399b2 fonts: improve trace diagnostics
refs: #607
2021-04-02 09:09:09 -07:00
Wez Furlong
cfe6894e83 fix warning on win32 2021-03-26 09:10:32 -07:00
Aaron Abramov
786888ce0a update k9 to 0.11.0 to make it work with rustc@1.51.0
1.51.0 no longer takes non string literals in `panic()`. k9@0.11.0 fixes that
2021-03-25 10:39:00 -07:00
Wez Furlong
3bec6fb5c0 lint: remove redundant semicolons
Newer versions of Rust emit warnings for these
2021-03-25 09:44:27 -07:00
Wez Furlong
be8c3be910 clear no_glyphs cache when font scale changes
refs: https://github.com/wez/wezterm/issues/508
2021-03-22 22:49:31 -07:00
Wez Furlong
8f856d0b81 font: make system fallback async wrt. rendering
If shaping can't resolve some glyphs, queue the font locator
fallback resolution to another thread; meanwhile, a last resort
glyph is used.

That thread can trigger an invalidation once the fallback resolve
is complete, the window is invalidated and the last resort glyph
is replaced by the resolve glyph.

refs: https://github.com/wez/wezterm/issues/559
refs: https://github.com/wez/wezterm/issues/508
2021-03-22 20:42:03 -07:00
Wez Furlong
e69485d3ca avoid hang if several glyphs fail to resolve in quick succession
The channel to the connui was bounded to 16 and could easily be
saturated from the main thread.  The saturated queue would block
the main thread.
2021-03-22 15:53:56 -07:00
Wez Furlong
6b92cf7539 fonts: show config error window when glyphs cannot be resolved
Keep track of the glyphs we've already advised about (until the
config is reloaded) so that we don't keep spamming the user.

refs: https://github.com/wez/wezterm/issues/559
2021-03-22 15:29:03 -07:00
Wez Furlong
f7b0ea2eb7 fonts: tune up fallback font resolution
* Check built-in fonts before asking the system for codepoint coverage
* If one of the earlier stages resolved some fonts, skip the remaining
  stages and speculatively shape what we have.  This avoids triggering
  the system font lookup for fonts that are present in the font_dirs
  or that are built-in, such as powerline symbols.

refs: https://github.com/wez/wezterm/issues/559
2021-03-22 15:03:50 -07:00
Wez Furlong
961e4ef9f7 fonts: improve FontDataHandle ordering/comparison
Don't include in-memory data in these operations
2021-03-22 14:49:00 -07:00
Wez Furlong
1b7c980646 fonts: avoid querying macos fallback list multiple times 2021-03-22 12:46:58 -07:00
Wez Furlong
af84d1ee7f fonts: prefer dwrote over gdi so that we can get OnDisk handles
The dwrote crate offers functions that can extract the underlying
font file name(s) from the system, so let's use those to get
OnDisk font handles and save some memory.

refs: https://github.com/wez/wezterm/issues/559
2021-03-21 01:44:41 -07:00
Wez Furlong
2c37d2eeb5 fonts: fixup win32 build
refs: https://github.com/wez/wezterm/issues/559
2021-03-20 23:32:19 -07:00
Wez Furlong
70c4cd1a53 fonts: use Cow instead of making a Vec copy for Memory handles
This doesn't change much, just makes things slightly tidier.

refs: https://github.com/wez/wezterm/issues/559
2021-03-20 23:15:33 -07:00
Wez Furlong
eafe01e946 fonts: avoid making an in-memory copy of OnDisk font handles
In an earlier incarnation of both wezterm and freetype, FT_New_Face
would lead file descriptors into child processes because it didn't
set O_CLOEXEC.  That led to the slightly pessimistic approach of
loading the font into memory for the lifetime of the wezterm process.

With the improved fallback handling on macos, this can result in
hundreds of MB of font data being loaded, in some cases multiple
times.

Since those days, freetype now sets O_CLOEXEC and wezterm has some
logic to close other random fds, so the descriptor leaking problem
is gone and we can now let freetype manage a file handle instead
of a memory-baked font.

This reduces the memory utilization by at least 1GB in the case
that a glyphs need to be resolved from the system fallback fonts.

refs: https://github.com/wez/wezterm/issues/559
2021-03-20 23:00:53 -07:00
Wez Furlong
72f2ff850f fonts: avoid making copies of Memory font handles
refs: https://github.com/wez/wezterm/issues/559
2021-03-20 22:49:27 -07:00
Wez Furlong
5eb6a15312 macos: reduce memory utilization in font fallback case
refs: https://github.com/wez/wezterm/issues/559
2021-03-20 22:27:08 -07:00
Wez Furlong
f4a8b14a2c tidy up the error message when no fallback is found
on macos there's no guarantee that the fallback set has glyphs
for the requested range.
2021-03-20 22:09:23 -07:00
Wez Furlong
1cf335cb45 fonts: handle bitmap-only fonts better
terminus-bold.otb reports 0 height!

Detect and force that case to go through the bitmap strike loading
code path.

Improve the size selection heuristic for bitmap strikes: previously,
we would just pick the largest bitmap and allow it to be scaled down,
which was OK for emoji fonts that just had 128px square glyphs, but
is not ok for pre-rendered pixel strikes like terminus.

Note that IncreaseFontSize works in terms of percentages only,
so using a font like this may have "gaps" when ctrl-+ or - to change
the font size.

refs: https://github.com/wez/wezterm/issues/560
2021-03-20 12:52:20 -07:00
Wez Furlong
1ee4d52a1c deps: update ttf_parser 0.9 -> 0.12 2021-03-18 22:08:07 -07:00
Wez Furlong
1441462624 fonts: add explicit fallback to Apple Symbols font
This is a bit unfortunate, but necessary, because the system fallback
list contains a handful of special fonts that apple doesn't ship on
disk in ttf/otf files.

One of those is `.AppleSymbolsFB` which would normally satisfy
the symbol lookup.

This commit hard codes the "Apple Symbols" font to use instead,
which is a disk based font.  I don't know what the difference
is between it and `.AppleSymbolsFB`, but this is sufficient
to satisfy the glyph in question from the referenced issue.

refs: https://github.com/wez/wezterm/issues/506
2021-03-17 21:56:14 -07:00
Wez Furlong
09081d2189 improve texture upload performance, part 2
Continuing along the same lines as the prior commit, the goal
of this commit is to remove the buffer transformation that was
part of uploading the texture to the GPU provided surface.

In order to do so:

* The sense of our local textures needs to change from bgra32 to rgba32.
  bgra32 was a hangover from earlier versions of our window crate that
  allowed direct-to-fb writes in software mode.  We had to pick bgra32
  for that for the broadest OS compatibility.  I believe that that
  constraint has been totally removed, although there is a chance that
  this will flip the colors on macos.
* There was an additional linear-to-srgb conversion inlined in that
  buffer transformation.  I have no idea where that is needed because
  the source data is carefully constructed as SRGB.  I don't yet know
  how to signal that, but for now I've moved that gamma correction
  into the shader when we sample the texture.

With this change, timg playback now has vtparse as the hottest
region of code.

refs: #537
2021-03-14 09:14:30 -07:00
Wez Furlong
18cb179227 x11: query Xft.dpi from the root window
We should now be using the root window specified default dpi
if the dpi is left unspecified in the wezterm configuration.

refs: #515
2021-03-08 22:19:44 -08:00
Wez Furlong
4b7f774bc5 Bundle PowerlineExtraSymbols as a fallback font 2021-03-06 19:12:35 -08:00
Wez Furlong
d56c5178da shaping: add test for FiraCode
Adds a test and seemingly a fix for https://github.com/wez/wezterm/issues/478#issuecomment-787520977

Fira Code is OFL-1.1 licensed like the other fonts we include,
however, I'm not distributing Fira Code with wezterm.
2021-02-28 13:35:00 -08:00
Wez Furlong
db08b8c1dc add window:set_config_overrides lua method
This commit expands on the prior commits to introduce the concept
of per-window configuration overrides.

Each TermWindow maintains json compatible object value holding
a map of config key -> config value overrides.

When the window notices that the config has changed, the config
file is loaded, the CLI overrides (if any) are applied, and then
finally the per-window overrides, before attempting to coerce
the resultant lua value into a Config object.

This mechanism has some important constraints:

* Only data can be assigned to the overrides.  Closures or special
  lua userdata object handles are not permitted.  This is because
  the lifetime of those objects is tied to the lua context in which
  they were parsed, which doesn't really exist in the context of
  the window.
* Only simple keys are supported for the per-window overrides.
  That means that trying to override a very specific field of
  a deeply structured value (eg: something like `font_rules[1].italic = false`
  isn't able to be expressed in this scheme.  Instead, you would
  need to assign the entire `font_rules` key.  I don't anticipate
  this being a common desire at this time; if more advance manipulations
  are required, then I have some thoughts on an event where arbitrary
  lua modifications can be applied.

The implementation details are fairly straight-forward, but in testing
the two examplary use cases I noticed that some hangovers from
supporting overrides for a couple of font related options meant that the
window-specific config wasn't being honored.  I've removed the code that
handled those overrides in favor of the newer more general CLI option
override support, and threaded the config through to the font code.

closes: #469
closes: #329
2021-02-27 14:53:19 -08:00
Wez Furlong
4e27607615 macos: fonts: fix a potential unterminated loop
for fonts located by core text, if they are singular TTF files rather
than TTC files, and the font doesn't exactly match the search critiera,
we could loop forever re-parsing the same file over and over again.

This commit restructures the logic to definitively check the number
of contained font entries and constrain the loop to that number.

In addition, it adjusts the name matching, as macos can return
names like "Cascadia Code Roman" when the underlying font is named
"Cascadia Code".

refs: https://github.com/wez/wezterm/issues/475
2021-02-25 20:47:02 -08:00
Wez Furlong
01f587d1d0 fixup tests for macos
refs: #478
2021-02-22 20:38:24 -08:00
Wez Furlong
3e44abcca8 Adopt new shaper logic in gui
Connect the gui to the new shaping logic; this means that we
can now correctly render fg/bg color when the cursor moves
through the cells that comprise a ligature.

refs: https://github.com/wez/wezterm/issues/478
2021-02-22 19:17:24 -08:00
Wez Furlong
ee17e4e174 Add shaper post-processing function
This function is intended to deal with certain kinds of ligatures
and certain combining sequences that don't have corresponding glyphs.

It isn't hooked up to the gui yet, but does have unit tests that
are probably mostly correct.

refs: https://github.com/wez/wezterm/issues/478
2021-02-22 19:17:24 -08:00
Wez Furlong
82fc53d736 rasterize: refine blending math
Refine the colorization logic to make it more of a blending operation.
Previously, we were relying on opengl to carry out blending between
layers on our behalf, but that wasn't perfect.

This commit is inspired by this post:
https://www.puredevsoftware.com/blog/2019/01/22/sub-pixel-gamma-correct-font-rendering/
and factors in the background color when computing the colorized
glyph.

This appears to reduce the dark fringes/edges that we were seeing
before, without noticeably changing the brightness of the result.

refs: #491
2021-02-20 18:00:23 -08:00
Wez Furlong
4e2b2eddba split shaders, adjust srgb opengl render settings
https://learnopengl.com/Advanced-Lighting/Gamma-Correction suggests
some good practices:

* Only enable SRGB output on the final draw call, so that all prior
  stages can operate on linear values and avoid converting to/from
  linear multiple times.
* The SRGBA textures automatically linearize when sampled, but:
  * The RGB data must be SRGB (non-linear)
  * The A channel is assumed to be linear!

This commit nudges us closer to that by:

* Converting the freetype coverage map from its linear value to
  non-linear when rasterizing.
* Splitting the shader files into one per stage (background, lines,
  glyphs) and only setting outputs_srgb for the glyph stage

refs: #491
2021-02-20 17:12:36 -08:00
Wez Furlong
dd70a8a53b introduce freetype_load_flags and freetype_load_target config
In the earlier times wezterm supported different font rasterizers,
and the configuration was a bit vague and generic to accomodate
differences in how the rasterizers worked.

Since then, we've standardized on freetype.

One of the things that's been bothering me for a while is that
we have some fiddly logic to transform from the config to the freetype
flags.

This commit does away with the transformation and simply exposes
the two sets of freetype options.

The main thing that I expect people to play with is
`freetype_load_target` which can have one of the following values:

```
pub enum FreeTypeLoadTarget {
    /// This corresponds to the default hinting algorithm, optimized
    for standard gray-level rendering.
    Normal,
    /// A lighter hinting algorithm for non-monochrome modes. Many
    generated glyphs are more fuzzy but better resemble its original
    shape. A bit like rendering on Mac OS X.  This target implies
    FT_LOAD_FORCE_AUTOHINT.
    Light,
    /// Strong hinting algorithm that should only be used for
    monochrome output. The result is probably unpleasant if the glyph
    is rendered in non-monochrome modes.
    Mono,
    /// A variant of Normal optimized for horizontally decimated LCD displays.
    HorizontalLcd,
    /// A variant of Normal optimized for vertically decimated LCD displays.
    VerticalLcd,
}
```

I expect most people will want to set this to one of `Normal`, `Light`
or `HorizontalLcd`.  `HorizontalLcd` is what `font_antialias=Subpixel`
used to select.

refs: #491
2021-02-20 14:00:38 -08:00
Wez Furlong
475260d3e3 Update bundled JetBrainsMono font to 2.225
refs: #452
2021-02-11 23:56:07 -08:00
Wez Furlong
005b492a8b deps: update to ordered-float 2.1 2021-02-07 22:54:02 -08:00
Wez Furlong
d9275e110c deps: update metrics from 0.12 -> 0.14 2021-02-03 23:50:29 -08:00
Wez Furlong
b49c7a7a72 font: fontconfig: also allow dual spacing fonts in fallback
refs: #446
2021-01-30 08:44:12 -08:00
Leiser Fernández Gallo
f6fc1c6524
Add dual font support (#446) 2021-01-30 08:43:41 -08:00
Wez Furlong
4bbe67aac3 gui: refuse to scale to sizes where cell height would be < 2 pixels
refs: https://github.com/wez/wezterm/issues/428
2021-01-16 08:45:38 -08:00
Wez Furlong
db964a91a0 gui: handle a failure to compute font metrics at very small scales
https://github.com/wez/wezterm/issues/428
2021-01-16 08:27:32 -08:00
Wez Furlong
4d8cc1bb26 font: consider "random" glyphs when computing metrics for symbol fonts
If a font doesn't have any latin glyphs then we'd compute 0 as the
average width.  Later, during rendering, we'd compute an `inf` scaling
factor and then subsequently fail to allocate texture space.

This commit takes the average width from a "random" selection of glyphs
(whatever the first few glyphs in the font may be) to avoid that
situation.

refs: https://github.com/wez/wezterm/issues/404
2020-12-28 09:02:30 -08:00
Wez Furlong
7cbbb49ab4 deps: ordered-float -> 2.0 2020-12-28 08:25:43 -08:00
Wez Furlong
979368c4eb font: add freetype_interpreter_version configuration option
This defaults to None, taking the default from the freetype library.
You can select an integer value to tell the library to use an
alternative version.

Versions that are available in the build used by wezterm are 35, 38 and
40.

See https://freetype.org/freetype2/docs/subpixel-hinting.html for
more information.
2020-12-21 09:15:13 -08:00
Wez Furlong
80214319ae adjust log levels
Revise logging so that we use info level for things that we want
to always log, and adjust the logger config to always log info
level messages.

That means shifting some warning level logs down lower to debug level so
that they aren't noisy.

closes: https://github.com/wez/wezterm/issues/388
2020-12-20 22:01:06 -08:00
Wez Furlong
c948fff0d2 font: make fewer overall passes to compute Names struct 2020-12-20 12:24:04 -08:00
Wez Furlong
eff3a13847 font: switch parser to ttf_parser
My original goal was to update to allsorts 0.5 but the API
changes are significant and not clearly described.

To make that transition easier, the prior commit moved the shaping
logic into our allsorts shaper module, leaving the name parsing
here in parser.rs.

This commit now replaces that logic with ttf_parser, which is
potentially faster (there's more emphasis on optimal code in that
crate than in allsorts) but definitely simpler.

It's not a slam-dunk transition: ttf_parser doesn't know how to
decode MacRoman encoded text, so there's a bit of logic borrowed
from allsorts here to handle that.
2020-12-19 21:55:24 -08:00
Wez Furlong
6bc1e50350 font: move some of the allsorts code into the shaper module 2020-12-19 18:21:52 -08:00
Wez Furlong
ad7362d3f7 add error handling to getting best match
refs: #383
2020-12-19 09:23:05 -08:00
Wez Furlong
dc83c6de2a fix locating Hasklig
The root cause of this was that I'd added a fontformat=TrueType
constraint to the fontconfig pattern and since fontconfig has
fontformat=CFF for Hasklig, it wasn't the primary font candidate.

When I cut out redundant fontconfig checks in
ee1d84829a it meant that we'd never
"see" the hasklig result that turns up ~20 or so fonts into the
fallback list.

This commit removes the TrueType constraint so that the results
are ranked correctly again.

I've also switched the main font lookup path to using an alternative
font config API that returns only the best match as that more closely
aligns our intent in this function; originally, fallback was intended
to be handled in this code path, but these days it has its own separate
method.

closes: https://github.com/wez/wezterm/issues/383
refs: https://github.com/wez/wezterm/issues/379
2020-12-19 09:12:41 -08:00
Wez Furlong
ee1d84829a fonts: font-config: stop after first match
font-config can return very long lists of fallback fonts like:

```
 2020-12-16T16:23:13.306Z TRACE wezterm_font::locator::font_config > query font-config for Pattern(Operator Mono SSm Lig Medium,DejaVu Sans,PT Sans,PT Sans Caption,Bitstream Vera Sans,DejaVu Sans,Verdana,Arial,Albany AMT,Luxi Sans,Nimbus Sans L,Nimbus Sans,Nimbus Sans,Helvetica,Nimbus Sans,Lucida Sans Unicode,BPG Glaho International,Tahoma,Comfortaa,Montserrat,URW Gothic,Nimbus Sans,Nimbus Sans Narrow,Carlito,Droid Sans,Nachlieli,Lucida Sans Unicode,Yudit Unicode,Kerkis,ArmNet Helvetica,Artsounk,BPG UTF8 M,Waree,Loma,Garuda,Umpush,Saysettha Unicode,JG Lao Old Arial,GF Zemen Unicode,Pigiarniq,B Davat,B Compset,Kacst\-Qr,Urdu Nastaliq Unicode,Raghindi,Mukti Narrow,malayalam,Sampige,padmaa,Hapax Berbère,MS Gothic,UmePlus P Gothic,Microsoft YaHei,Microsoft JhengHei,WenQuanYi Zen Hei,WenQuanYi Bitmap Song,AR PL ShanHeiSun Uni,AR PL New Sung,MgOpen Modata,VL Gothic,IPAMonaGothic,IPAGothic,Sazanami Gothic,Kochi Gothic,AR PL KaitiM GB,AR PL KaitiM Big5,AR PL ShanHeiSun Uni,AR PL SungtiL GB,AR PL Mingti2L Big5,MS ゴシック,ZYSong18030,TSCu_Paranar,NanumGothic,UnDotum,Baekmuk Dotum,Baekmuk Gulim,KacstQura,Lohit Bengali,Lohit Gujarati,Lohit Hindi,Lohit Marathi,Lohit Maithili,Lohit Kashmiri,Lohit Konkani,Lohit Nepali,Lohit Sindhi,Lohit Punjabi,Lohit Tamil,Meera,Lohit Malayalam,Lohit Kannada,Lohit Telugu,Lohit Oriya,LKLUG,Mingzat,Padauk,Nuosu SIL,FreeSans,FreeSans,Arial Unicode MS,Arial Unicode,Code2000,Code2001,sans\-serif,Roya,Koodak,Terafik,sans\-serif,sans\-serif,sans\-serif,ITC Avant Garde Gothic,URW Gothic,sans\-serif,sans\-serif,Helvetica,Helvetica Narrow,Nimbus Sans Narrow,sans\-serif,sans\-serif,sans\-serif:slant=0:weight=80:spacing=100:fontformat=TrueType) took 1.344155ms
 ```

In the context of that particular call, we only care about whether the
first result matches what we're looking up.  The fallbacks are processed
separately in a different method.

Therefore, we can skip additional processing and save a non-trivial
number of milliseconds overall parsing/re-parsing them to verify
whether they are the one we wanted to match.

refs: https://github.com/wez/wezterm/issues/379
2020-12-16 08:26:24 -08:00
Wez Furlong
7e49377313 font: avoid parsing fallback results from font-config
font-config can return a long list of fallback results for a given
font family, and we parse those to see if they match; once we've
found a match there's zero chance that that errort is helpful,
so break out of the loop.

Add some more trace logging to see if that helps.

refs: https://github.com/wez/wezterm/issues/379
2020-12-14 23:41:45 -08:00
Wez Furlong
c1fa08319e deps: upgrade euclid -> 0.22 2020-12-10 10:03:30 -08:00
Wez Furlong
22b4e99c82 tidy up default_dpi vs DEFAULT_DPI
This commit breaks the dependency from config -> window,
which in turn breaks the dependency from mux-server -> x11 libs
on linux.
2020-12-09 13:48:23 -08:00
Wez Furlong
2888428dda wezterm-font: add system font fallback on macOS
Teach the core text locator how to obtain the system fallback list
and add that to the fallback.

Fixup handling of ttc files on macOS; we'd always assume index 0
when extracting font info from the font descriptor.  We now make
the effort to enumerate the contents of the TTC and find a match.
2020-12-06 22:23:39 -08:00
Wez Furlong
ba9bc30b79 harfbuzz: skip some unused bits
don't bother building the coretext or uniscribe bits of harfbuzz
2020-12-05 14:19:47 -08:00
evs-ch
1a42b17727
Fixes building on aarch64 (#356)
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.
2020-11-26 20:41:04 -08:00
Wez Furlong
214390ba5a wezterm-font: remove some dead code 2020-11-25 22:12:40 -08:00
Wez Furlong
6ccef46989 wezterm-font: compute codepoint coverage for font-dirs
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.
2020-11-25 20:41:09 -08:00
Wez Furlong
d934a0ae88 wezterm-font: move FontDatabase into FontConfiguration
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.
2020-11-25 19:21:51 -08:00
Wez Furlong
b0bee3b036 wezterm-font: introduce FontDatabase
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.
2020-11-25 19:15:08 -08:00
Wez Furlong
80488ea14d improve freetype error context
Tag some font related errors with more context.
This makes it a bit easier to understand where a problem
is coming from.
2020-11-25 16:19:56 -08:00
Wez Furlong
4fd574cc7f freetype: enable FT_Error_String
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!
2020-11-25 16:19:56 -08:00
Wez Furlong
ba44548d46 wezterm-font: teach gdi locator how to search for fallback fonts
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
2020-11-25 16:19:56 -08:00
Wez Furlong
58eb8e3614 wezterm-font: move caching of freetype font size into Face
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
2020-11-25 09:20:14 -08:00
Wez Furlong
5fbb6a4400 wezterm-font: cache metrics lookup in harfbuzz shaper
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
2020-11-24 18:19:49 -08:00
Wez Furlong
827d94a9a8 wezterm-font: add find-fall-back-for-codepoints concept
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.
2020-11-24 18:03:32 -08:00
Wez Furlong
3652a8360f wezterm-font: fix typo in error message 2020-11-24 12:37:11 -08:00
Wez Furlong
6e8f8298af wezterm: explain where the font came from in fallback errors
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
2020-11-24 08:49:26 -08:00
Wez Furlong
98f289f511 wezterm-font: improve fallback font scaling
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
2020-11-23 16:59:30 -08:00
Wez Furlong
65ac2269dd wezterm-font: fix exact match of full font name
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
2020-11-23 15:01:19 -08:00
Wez Furlong
a063d20cf0 wezterm: improve shaping of emoji
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.
2020-11-23 13:45:38 -08:00
Wez Furlong
69d56fc868 wezterm-font: remove some dead code 2020-11-23 08:43:53 -08:00
Wez Furlong
3bd8d8c845 wezterm-font: bundle a last resort font
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.
2020-11-22 16:12:20 -08:00
Wez Furlong
4500510d5c wezterm-font: improve perf of windows font locator
This avoids enumerating and parsing all fonts on startup, and improves
matching in general.
2020-11-22 12:39:29 -08:00
Wez Furlong
534cdfeaf2 wezterm-font: cargo fmt and fix comment
refs: #337
2020-11-22 11:23:58 -08:00
Wez Furlong
30cc10d4cf wezterm-font: remove font-loader dependency
This commit replaces it with the underlying core text calls
on macos.

refs: #337
2020-11-22 11:19:44 -08:00
Wez Furlong
9ca428c4e1 wezterm-font: remove font-loader dep on windows
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.
2020-11-22 10:27:48 -08:00
Wez Furlong
ddc4c1b624 wezterm: fixup some allsorts shaping cases
* Fixes `keycap 0` by plucking out the prior character for an
  EnclosingMark
* Fixes lookahead for VariationSelector

refs: #66
2020-11-20 18:44:28 -08:00
Wez Furlong
a2a64e80a7 wezterm: update allsorts shaper
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
2020-11-20 16:56:07 -08:00
Wez Furlong
720a6fd9b6 wezterm: fixup dark edges on text
9892b16d40 adjusted how the text
colors are produced; it resulted in some ugly dark edges, especially
on lighter backgrounds.

This commit routes that tint via an alpha compositing helper which
produces smoother edges.

refs: #320
2020-11-15 15:17:23 -08:00
Wez Furlong
9892b16d40 wezterm-font: tidy up some font hinting/aa options
This commit more cleanly separates the load from the render flags,
and fixes up the render call; at some point this got messed up such
that we'd never end up with freetype returning subpixel format data
(LCD) and instead we'd only ever get grayscale data.

With that fixed, it's apparent that the colorization of the glyph
data was wonky in the shader so this commit also cleans this up.

refs: #320
refs: #121
2020-11-14 17:27:31 -08:00
Wez Furlong
72492c1517 font: tidy up imports/exports a bit 2020-11-11 20:31:26 -08:00
Jeremy Fitzhardinge
bf962c8b1a Use right char type for ffi binding
On aarch64, `char` is unsigned (unlike x86-64 where it's signed), so use
`c_char` for the pointer so that it always matches the architecture.
2020-11-11 20:31:18 -08:00
Wez Furlong
ea0d8d6f11 wezterm-font: remove font-kit dep
This wasn't used by anything and the version was getting pretty stale.
Upgrading is awkward because newer versions pull in an incompatible
freetype library version.
2020-10-24 22:01:00 -07:00
Wez Furlong
7d843c6b24 wezterm: fixup win32 build for wezterm-gui changes
refs: #301
2020-10-24 17:00:07 -07:00
Wez Furlong
7e8c5a06bb split gui into wezterm-gui executable
This commit moves a bunch of stuff around such that `wezterm` is now a
lighter-weight executable that knows how to spawn the gui, talk to
the mux or emit some escape sequences for imgcat.

The gui portion has been moved into `wezterm-gui`, a separate executable
that doesn't know about the CLI or imgcat functionality.

Importantly, `wezterm.exe` is no longer a window subsystem executable
on windows, which makes interactions such as `wezterm -h` feel more
natural when spawned from `cmd`, and should allow
`type foo.png | wezterm imgcat` to work as expected.

That said, I've only tested this on linux so far, and there's a good
chance that something mac or windows specific is broken by this
change and will need fixing up.

refs: #301
2020-10-24 16:40:15 -07:00