Specifically:
iCurrentCursorStyle
iPreviousCursorStyle
iCurrentCursorVisible
iPreviousCursorVisible
Visibility calculated and updated independently from the typical cursor
unifrom updates to preserve cursor style even when not in the viewport
or set to be hidden
Adds palette and color scheme uniforms to custom shaders, allowing
custom shaders to access terminal color information:
- iPalette[256]: Full 256-color terminal palette (RGB)
- iBackgroundColor, iForegroundColor: Terminal colors (RGB)
- iCursorColor, iCursorText: Cursor colors (RGB)
- iSelectionBackgroundColor, iSelectionForegroundColor: Selection
colors (RGB)
Colors are normalized to [0.0, 1.0] range and update when the palette
changes via OSC sequences or configuration changes. The palette_dirty
flag tracks when colors need to be refreshed, initialized to true to
ensure correct colors on new surfaces.
This is a big'un.
- **Glyph constraint logic is now done fully on the CPU** at the
rasterization stage, so it only needs to be done once per glyph instead
of every frame. This also lets us eliminate padding between glyphs on
the atlas because we're doing nearest-neighbor sampling instead of
interpolating-- which ever so slightly increases our packing efficiency.
- **Special constraints for nerd font glyphs** are applied based roughly
on the constraints they use in their patcher. It's a simplification of
what they do, the largest difference being that they scale groups of
glyphs based on a shared bounding box so that they maintain relative
size to one another, but that would require loading all glyphs on the
group and I'd want to do that on font load TBH and at that point I'd
basically be re-implementing the nerd fonts patcher in Zig to patch
fonts at load time which is way beyond the scope I want to have. (Fixes
#7069)
- These constraints allow for **perfectly sized and centered emojis**,
this is very nice.
- **Changed the default embedded fonts** from 4 copies (regular, italic,
bold, bold italic) of a patched (and outdated) JetBrains Mono to a
single JetBrains Mono variable font and a single Nerd Fonts Symbols Only
font. This cuts the weight of those down from 9MB to 3MB!
- **FreeType's `renderGlyph` is significantly reworked**, and the new
code is, IMO, much cleaner- although there are probably some edge case
behavior differences I've introduced.
> [!NOTE]
> One breaking change I definitely introduced is changing the
`monochrome` freetype load flag config from its previous completely
backwards meaning to instead the correct one (I also changed the
default, so this won't affect any user who hasn't touched it, but users
who set the `monochrome` flag will find their fonts quite crispy after
this change because they will have no anti-aliasing anymore)
### Future work
Following this change I want to get to work on automatic font size
matching (a la CSS
[`font-size-adjust`](https://developer.mozilla.org/en-US/docs/Web/CSS/font-size-adjust)).
I set the stage for that quite some time ago so it shouldn't be too much
work and it will be a big benefit for users who regularly use multiple
writing systems and so have multiple fonts for them that aren't
necessarily size-compatible.
Now that it's done at the rasterization stage, we don't need to handle
it on the GPU. This also means that we can switch to nearest neighbor
interpolation in the Metal shader since we're guaranteed to be pixel
perfect. Accidentally, we were already nearest neighbor in the OpenGL
shaders because I used the Rectangle texture mode in the big renderer
rework, which doesn't support interpolation- anyway, that's no longer
problematic since we won't be scaling glyphs on the GPU anymore.
By using integers for the fragcoords I may have stepped on an edge case
which causes cell background positions to be shifted by 1 px under some
circumstances. I couldn't reproduce that issue in a VM, so I'm making
this commit for the user who was having the problem to test it.
We were using the Rectangle target for simpler addressing, since that
allows for pixel coordinates instead of normalized coordinates, but
there are downsides to rectangle textures, including not supporting
compressed texture formats, and we do probably want to use compressed
formats in the future, so I'm making this change now.
Adds support for background images via the `background-image` config.
Resolves#3645, supersedes PRs #4226 and #5233.
See docs of added config keys for usage details.
Also changes color atlas to always use an sRGB internal format so that
the texture reads automatically linearize the colors.
Renames the misleading `rgba` atlas format to `bgra`, since both
FreeType and CoreText are set up to draw color glyphs in bgra.
In this format it will be a lot easier to iterate on this since adding
and removing pipelines only has to be done in a single place.
This commit also separates out the main background color from individual
cell background color drawing, because sometimes kitty images need to be
between the main background and individual cell backgrounds (kitty image
z-index seems to be entirely broken at the moment, I intend to fix it in
future commits).
This commit is very large, representing about a month of work with many
interdependent changes that don't separate cleanly in to atomic commits.
The main change here is unifying the renderer logic to a single generic
renderer, implemented on top of an abstraction layer over OpenGL/Metal.
I'll write a more complete summary of the changes in the description of
the PR.
We can't use nearest neighbor filtering for sampling from the atlas
because we might not actually be doing pixel perfect sampling if the
glyph has been constrained. This will change in the future, but this
will have to be set to linear for now.
This optimization is extremely niche and seems to be related to a
strange bug experienced by Intel Mac users. Considering it costs some
amount to have this extra check here even though it's false in the vast
majority of cases, I feel it's pretty safe to just remove it entirely.
More mathematically sound approach, does a much better job of matching
the appearance of non-linear blending. Removed `experimental` from name
because it's not really an experiment anymore.
We were returning bg colors when we shouldn't have since when we have
background color transparency we need to return any bg color cells as
fully transparent rather than their actual color.
By using the `CAMetalLayer`'s `backgroundColor` property instead of
drawing the background color in our shader, it is always stretched to
cover the full surface, even when live-resizing, and it doesn't require
us to draw a frame for it to be initialized so there's no transparent
flash when a new surface is created (as in a new split/tab).
This commit also allows for hot reload of `background-opacity`,
`window-vsync`, and `window-colorspace`.
This commit is quite large because it's fairly interconnected and can't
be split up in a logical way. The main part of this commit is that alpha
blending is now always done in the Display P3 color space, and depending
on the configured `window-colorspace` colors will be converted from sRGB
or assumed to already be Display P3 colors. In addition, a config option
`text-blending` has been added which allows the user to configure linear
blending (AKA "gamma correction"). Linear alpha blending also applies to
images and makes custom shaders receive linear colors rather than sRGB.
In addition, an experimental option has been added which corrects linear
blending's tendency to make dark text look too thin and bright text look
too thick. Essentially it's a correction curve on the alpha channel that
depends on the luminance of the glyph being drawn.
There is no reason to and I do not know where this assumption came from.
It's very possible for a colored glyph to (intentionally!) exceed the
cell bounds, and we shouldn't be stopping this...
This enables the compile options and Xcode configuration so that logging
in Metal shaders shows up in our Xcode debug console. This doesn't add
any log messages, but makes it so that when we iterate on the shaders in
the future, we can add and see logs to help us out.
Metal needed to be changed to account for wide chars having decorations
on the right half and OpenGL needed to account for multiple glyphs being
under the cursor at once (decorations and combining marks) as well as
wide chars.
- Significant changes to optimize memory usage.
- Adjusted formatting of the metal shader code to improve readability.
- Normalized naming conventions in shader code.
- Abstracted repetitive code for attribute descriptors to a helper
function.
With a minimum contrast set, the colored glyphs that Powerline uses
would sometimes be set to white or black while the surrounding background
colors remain unchanged, breaking up contiguous colors on segments of
the Powerline.
This no longer happens with this patch as Powerline glyphs are now
special-cased and exempt from the minimum contrast adjustment.
There are scenarios where this configuration looks bad. This commit
introduces some heuristics to prevent it. Here are the heuristics:
* Extension is always enabled on alt screen.
* Extension is disabled if a row contains any default bg color. The
thinking is that in this scenario, using the default bg color looks
just fine.
* Extension is disabled if a row is marked as a prompt (using semantic
prompt sequences). The thinking here is that prompts often contain
perfect fit glyphs such as Powerline glyphs and those look bad when
extended.
This introduces some CPU cost to the extension feature but it should be
minimal and respects dirty tracking. This is unfortunate but the feature
makes many terminal scenarios look much better and the performance cost
is minimal so I believe it is worth it.
Further heuristics are likely warranted but this should be a good
starting set.