338 Commits

Author SHA1 Message Date
Mitchell Hashimoto
a8b9c5bea5 config: remove experimental linear and merge into text-blending 2025-01-13 13:59:37 -08:00
Qwerasd
fca336c32d Metal: blend in Display P3 color space, add option for linear blending
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.
2025-01-13 13:50:29 -08:00
Mitchell Hashimoto
300884d50f refactor(font): move Metrics from Face to Collection (#4739)
This refactor enables two very significant improvements to our font
handling, which I will be implementing next:
1. Automatically adjust size of fallback faces to better align with the
primary face, a la CSS
[`font-size-adjust`](https://developer.mozilla.org/en-US/docs/Web/CSS/font-size-adjust).
[^1]
2. Move glyph resizing/positioning out of GPU-land and in to
`renderGlyph` and apply alignment/resizing rules from the nerd fonts
patcher[^2] to the glyphs at rasterization time, so that we can ensure
exact cell fits and swap out our embedded JB Mono with an unpatched
version with a separate dedicated symbols-only nerd font.

In addition to being necessary prep work for those two changes, this PR
is also a minor but real stand-alone improvement. By only computing the
cell metrics for our primary font, we avoid a *lot* of wasted work when
loading fallback fonts, and also avoid that being a source of load
errors, which we don't yet handle gracefully[^3].

To validate this PR I've run the full set of font backend tests locally
on my Mac with no failures, and did a sanity check of running Ghostty
with both renderers and with CoreText and FreeType font backends and
then `cat`ing a file that requires fallback fonts to render, and
everything looks correct.

[^1]: #3029

[^2]: The alignment and resizing rules for the nerd font symbols are
defined in the patcher
[here](6d0b8ba05a/font-patcher (L866-L1151))

[^3]: #2991
2025-01-07 20:43:48 -08:00
Gregory Anders
b2716375ac renderer: respect reverse with cursor-invert-fg-bg 2025-01-07 12:01:45 -06:00
Qwerasd
540fcc0b69 refactor(font): move Metrics out of face
in preparation to move ownership of metrics from faces to collections
2025-01-06 20:13:45 -05:00
yonihemi
63a47d0ba5 iOS: Fix crash on device 2025-01-06 22:01:41 +08:00
Qwerasd
25a112469c font(coretext): add config to adjust strength of font-thicken.
This is achieved by rendering to an alpha-only context rather than a
normal single-channel context, and adjusting the brightness at which
coretext thinks it's drawing the glyph, which affects how it applies
font smoothing (which is what `font-thicken` enables).
2025-01-03 14:19:19 -05:00
Mitchell Hashimoto
64ea3a1a29 renderer: track if fg/bg/cursor color is explicitly set by an OSC (#3228)
The renderer must track if the foreground, background, and cursor colors
are explicitly set by an OSC so that changes are not overridden when the
config file is reloaded.

Fixes: https://github.com/ghostty-org/ghostty/issues/2795
2024-12-29 09:05:37 -08:00
Xiaoyan Li
2993d12de7 Use premultiplied alpha for renderer clearColor
Fixes #3324
2024-12-28 19:37:24 -08:00
Gregory Anders
eef9664ef8 renderer: track if fg/bg/cursor color is explicitly set by an OSC
The renderer must track if the foreground, background, and cursor colors
are explicitly set by an OSC so that changes are not overridden when the
config file is reloaded.
2024-12-26 20:18:45 -06:00
Mitchell Hashimoto
bd90a6dd3b kittygfx: placement with rows (r) param scrolls properly out of viewport
Fixes #2332

Two bugs fixed to fix this behavior:

1. Our destination height didn't account for the top-left being
   offscreen.

2. We were using the wrong height for the source rectangle. When a rows
   param (r=) is specified, the image height and destination height are
   at different scales. We were using the viewport scale for the offset
   but it should be the image scale.
2024-12-23 14:11:14 -08:00
Mitchell Hashimoto
a908aca563 kittygfx: z-index handling fixes
Fixes #2921

Our z-index handling was pretty much completely broken, hence I can't
think of a better initial commit message. We were splitting the
placements at the wrong points and just generally putting images in the
wrong z-index. I'm shocked this didn't come up earlier.
2024-12-23 12:46:46 -08:00
Mitchell Hashimoto
f8a8b0464c renderer/opengl: fix memory leak when copying font features 2024-11-20 14:08:00 -08:00
Mitchell Hashimoto
1792ddfff1 remove some unused structs 2024-11-14 14:25:42 -08:00
Mitchell Hashimoto
b3b5e15e96 renderer/metal: use new size struct 2024-11-14 13:44:05 -08:00
Mitchell Hashimoto
aed51fd0b0 terminal: PageList rename "page" to "node" everywhere
This is more correct: a pagelist is a linked list of nodes, not pages.
The nodes themselves contain pages but we were previously calling the
nodes "pages" which was confusing, especially as I plan some future
changes to the way pages are stored.
2024-11-07 13:44:39 -08:00
Emily
20a77123d4 renderer/metal: prefer low‐power GPUs
Some Intel MacBook Pro laptops have both an integrated and discrete
GPU and support automatically switching between them. The system
uses the integrated GPU by default, but the default Metal device on
those systems is the discrete GPU. This means that Metal‐using
applications activate it by default, presumably as the intended
audience is high‐performance graphics applications.

This is unfortunate for productivity applications like terminals,
however, as the discrete GPU decreases battery life and worsens the
thermal throttling problems these machines have always had. Prefer
to use an integrated GPU when present and not using an external GPU.

The behaviour should be unchanged on Apple Silicon, as the platform
only supports one GPU. I have confirmed that the resulting app runs,
works, and doesn’t activate the AMD GPU on my MacBook Pro, but have
not done any measurements of the resulting performance impact. If
it is considered sufficiently noticeable, a GPU preference setting
could be added.

See <https://github.com/zed-industries/zed/issues/5124>,
<https://github.com/zed-industries/zed/pull/13685>,
<https://github.com/zed-industries/zed/pull/14738>, and
<https://github.com/zed-industries/zed/pull/14744> for discussion,
measurements, and changes relating to this issue in the Zed
project. The logic implemented here reflects what Zed ended up
settling on.

The [Metal documentation] recommends using
`MTLCopyAllDevicesWithObserver` to receive notifications of when
the list of available GPUs changes, such as when [external GPUs
are connected or disconnected]. I didn’t bother implementing that
because it seemed like a lot of fussy work to deal with migrating
everything to a new GPU on the fly just for a niche use case on a
legacy platform. Zed doesn’t implement it and I haven’t heard
about anyone complaining that their computer caught fire when they
unplugged an external GPU, so hopefully it’s fine.

[Metal documentation]: https://developer.apple.com/documentation/metal/gpu_devices_and_work_submission/multi-gpu_systems/finding_multiple_gpus_on_an_intel-based_mac
[external GPUs are connected or disconnected]: https://developer.apple.com/documentation/metal/gpu_devices_and_work_submission/multi-gpu_systems/handling_external_gpu_additions_and_removals

Closes: #2572
2024-11-04 00:35:21 +00:00
Emily
9c8b00f87d renderer/metal: release device on deinit() 2024-11-04 00:21:39 +00:00
Emily
e5f9f222b2 renderer/metal: use release() consistently
I’m not sure why this variation was here previously – maybe it
predated the introduction of `release()`?
2024-11-04 00:21:39 +00:00
Marijn Besseling
4496e7d314 implement overline decoration (SGR 53/55) 2024-10-21 08:36:08 -04:00
Qwerasd
0bb176d22c renderer: cleanup, reduce nesting, more comments 2024-10-09 15:53:02 -04:00
Qwerasd
7686cacde6 renderer, shaper: don't use null cells, handle bg and decorations separately
Significant rework that also removes a lot of unnecessarily duplicated
work while rebuilding cells in both renderers. Fixes multiple issues
with decorations and bg colors on wide chars and ligatures, while
reducing the amount of special case handling required.
2024-10-08 23:10:43 -04:00
Mitchell Hashimoto
89fadfc202 renderer: fg/bg/cursor change must mark the screen as dirty
Fixes #2372
2024-10-04 06:58:50 -10:00
Mitchell Hashimoto
7aa2e2b24f renderer: some tweaks 2024-10-02 15:44:06 -07:00
Qwerasd
dfc0894d5d fix(renderer): make all decorations and combining marks visible under cursor
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.
2024-10-02 17:18:26 -04:00
Qwerasd
f9e2cb6aec fix(renderer): use 1-wide ul/st chars, ignore null shaper cells
This makes sure that underline styles are consistent and not stretched,
and avoids rendering overlapping text decorations or extraneous
background cells for the right halves of wide chars.
2024-10-02 16:38:31 -04:00
Qwerasd
bf2794f90f renderer: draw underlines below text to improve legibility 2024-09-23 18:31:39 -06:00
Mitchell Hashimoto
5c469a0b44 renderer: render lock for password input 2024-09-18 11:14:37 -07:00
Mitchell Hashimoto
e811ea859d renderer/metal: fix compilation issues 2024-09-18 09:10:18 -07:00
Gregory Anders
64abbd0ea6 config: move optional path parsing into RepeatablePath
This commit refactors RepeatablePath to contain a list of tagged unions
containing "optional" and "required" variants. Both variants have a null
terminated file path as their payload, but the tag dictates whether the
path must exist or not. This implemenation is used to force consumers to
handle the optional vs. required distinction.

This also moves the parsing of optional file paths into RepeatablePath's
parseCLI function. This allows the code to be better unit tested. Since
RepeatablePath no longer contains a simple list of RepeatableStrings,
many other of its methods needed to be reimplemented as well.

Because all of this functionality is built into the RepeatablePath type,
other config options which also use RepeatablePath gain the ability to
specify optional paths as well. Right now this is only the
"custom-shaders" option. The code paths in the renderer to load shader
files has been updated accordingly.

In the original optional config file parsing, the leading ? character
was removed when paths were expanded. Thus, when config files were
actually loaded recursively, they appeared to be regular (required)
config files and an error occurred if the file did not exist. **This
issue was not found during testing because the presence of the
"theme" option masks the error**. I am not sure why the presence of
"theme" does this, I did not dig into that.

Now because the "optional" or "required" state of each path is tracked
in the enum tag the "optional" status of the path is preserved after
being expanded to an absolute path.

Finally, this commit fixes a bug where missing "config-file" files were
not included in the +show-config command (i.e. if a user had
`config-file = foo.conf` and `foo.conf` did not exist, then `ghostty
+show-config` would only display `config-file =`). This bug applied to
`custom-shaders` too, where it has also been fixed.
2024-09-17 22:08:59 -05:00
Qwerasd
ff0c1141da renderer: add updateFrame critical region timings for dev benchmark 2024-08-27 01:23:29 -04:00
Mitchell Hashimoto
cff907940f renderer: do not extend padding color if any cell has default bg color
Before, cells that were explicitly set to match the default bg color
were treated as if they did NOT have the default and extending would
occur. We now check the exact RGB of each cell.
2024-08-22 14:57:46 -07:00
Mitchell Hashimoto
2ee54879a4 renderer: use fg as extension color for covering glyphs (U+2588)
Fixes #2099

This is another heuristic of sorts to make `window-padding-color=extend`
look better by default. If a fully covering glyph is used then we use
the fg color to extend rather than the background.

This doesn't account for fonts that may do this for whatever codepoints,
but I think that's a special scenario that we should just recommend
disabling this feature.
2024-08-18 11:56:50 -07:00
Qwerasd
37872afbce kitty graphics: support loading 1 channel grayscale images 2024-08-15 21:38:46 -04:00
Qwerasd
4c2fbe8f74 fix(renderer/Metal): bail out of drawFrame if we haven't sized screen yet 2024-08-15 15:12:49 -04:00
Qwerasd
900aab10f2 renderer: don't update frame if renderer grid size != terminal size 2024-08-14 22:43:58 -04:00
Qwerasd
7929e0bc09 fix: prevent flicker while shrinking screen by eliminating thread race
Before this fix, if vsync was on the GPU cells buffer could be cleared
for a frame while resizing the terminal down. This was due to the fact
that the surface sent messages for the resize to both the renderer and
the IO thread. If the renderer thread was processed first then the GPU
cells buffer(s) would be cleared and not rebuilt, because the terminal
state would be larger than the GPU cell buffers causing updateFrame to
bail out early, leaving empty cell buffers.

This fixes the problem by changing the origin of the renderer's resize
message to be the IO thread, only after properly updating the terminal
state, to avoid clearing the GPU cells buffers at a time they can't be
successfully rebuilt.
2024-08-14 19:46:24 -04:00
Qwerasd
10b8ca3c69 spelling: normalize grey -> gray 2024-08-11 18:31:01 -04:00
Mitchell Hashimoto
f7f8c655df renderer: remove alt-screen extend-always 2024-08-10 10:39:10 -07:00
Mitchell Hashimoto
9f06e74353 config: add window-padding-color=extend-always to force always 2024-08-10 10:34:12 -07:00
Mitchell Hashimoto
40b3d4c72e config: clarify padding color default 2024-08-10 10:27:59 -07:00
Qwerasd
f47ab3e5b5 fix: add Contents.bgCell to avoid accidentally indexing with undersized ints 2024-08-08 21:02:26 -04:00
Qwerasd
d68906563e renderer/metal: properly support padding color = background (not extend) 2024-08-08 19:03:39 -04:00
Qwerasd
e5241cb659 renderer/Metal: remove extraneous len arg from drawCellBgs 2024-08-07 18:30:44 -04:00
Qwerasd
3a58b89ef1 fix: use single triangle for metal post shader vertex 2024-08-07 18:17:49 -04:00
Qwerasd
6339f9bae9 renderer: metal shaders rework
- 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.
2024-08-07 17:39:31 -04:00
Mitchell Hashimoto
0f8ed39766 Merge pull request #2049 from pluiedev/fix/exempt-powerline-from-minimum-contrast
renderer: exempt Powerline cells from minimum contrast requirements
2024-08-06 10:12:14 -07:00
Leah Amelia Chen
503dfae6ff renderer: exempt Powerline cells from minimum contrast requirements
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.
2024-08-06 15:28:50 +08:00
Łukasz Niemier
f9be02a20f chore: clean up typos 2024-08-05 13:56:57 +02:00
Mitchell Hashimoto
ea551990eb renderer: disable window-padding-color=extend in certain scenarios
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.
2024-08-03 21:56:19 -07:00