196 Commits

Author SHA1 Message Date
Qwerasd
5bc41dc694 Nerd Font Icon Height Constraint (#7850)
Nerd font icons were ***WAY*** too big depending on your font setup,
this is because we were always using the full cell height when the nerd
font patcher instead uses an "icon height" for most things. The patcher
calculates the icon height as two thirds of the font's cap height and
one third of the line height, but I've chosen to instead use 1.2 times
the cap height for more consistent results across fonts-- if the user
wants their icons bigger, they can use the `adjust-icon-height` metric
modifier (and they can also use it to make them smaller if they want
that for some reason).

I also adjusted the attributes to user horizontal cover + vertical fit
for `^` stretch modes (proportional scaling but scale up), which makes
it so that it never exceeds the cell size, since first it covers
horizontally and then scales down to fit vertically if necessary;
previously, if there were a particularly wide glyph that was scaled with
cover/cover it would exceed the available width and overflow in to
neighboring cells which wasn't good.
2025-07-07 10:25:53 -06:00
Qwerasd
c47459b4a2 font: add icon height to nerd font constraints
Icons were often WAY too big before because they were filling the whole
cell in height, which isn't great lol. This commit adds an `icon_height`
metric which is used to constrain glyphs that shouldn't be the size of
the entire cell.
2025-07-07 10:04:11 -06:00
Qwerasd
e1e2f823ba font/coretext: fix horizontal bearing calculation
This was subtly wrong in a way that was most obvious when text switched
from regular to bold, where it would seem to wiggle since the bearings
of each letter would shift by a pixel in either direction. This affected
applications like fzf which uses bold to dynamically highlight the line
you have selected.
2025-07-07 08:57:20 -06:00
Qwerasd
08fd1688ff font: add test for size adjustment, fix small bug in resize
Previously produced very wrong values when calling Collection.setSize,
since it was assuming that the provided face had the same point size as
the primary face, which isn't true during resize-- so instead we just
have faces keep track of their set size, this is generally useful.
2025-07-06 22:45:13 -06:00
Qwerasd
db08bf1655 font: adjust fallback font sizes to match primary metrics
This better harmonizes fallback fonts with the primary font by matching
the heights of lowercase letters. This should be a big improvement for
users who use mixed scripts and so rely heavily on fallback fonts.
2025-07-06 16:55:50 -06:00
Qwerasd
d3aece21d8 font: more generic bearing adjustments
This generally adjusts the bearings of any glyph whose original advance
was narrower than the cell, which helps a lot with proportional fallback
glyphs so they aren't just left-aligned. This only applies to situations
where the glyph was originally narrower than the cell, so that we don't
mess up ligatures, and this centers the old advance width in the new one
rather than adjusting proportionally, because otherwise we can mess up
glyphs that are meant to align with others when placed vertically.
2025-07-06 16:34:31 -06:00
Qwerasd
b10b0f06c3 font: remove unused fields from Glyph
We can reintroduce `advance` if we ever want to do proportional string
drawing, but we don't use it anywhere right now. And we also don't need
`sprite` anymore since that was just there to disable constraints for
sprites back when we did them on the GPU.
2025-07-06 15:53:59 -06:00
Qwerasd
c7e65b0c1c font: respect cell width attributes in nerd font constraints
This mostly applies to powerline glyphs, but is also relevant for heavy
bracket characters, which need to always be 1 wide otherwise they look
silly because they misalign depending on if there's a space after them
or not.
2025-07-06 11:23:49 -06:00
Qwerasd
02d82720d2 font/freetype: fix negated force-autohint flag
The behavior of this flag was the opposite of its description in the
docs- luckily, at the same time, the default (true) was the opposite
from what the default actually is in freetype, so users who haven't
explicitly set this flag won't see a behavior difference from this.
2025-07-05 20:40:12 -06:00
Qwerasd
fff16bff69 font/coretext: fix bitmap size calculation, prevent clipping
Previously, many glyphs were having their top and right row/column of
pixels clipped off due to not accounting for the slight bearing in the
width and height calculation here.
2025-07-05 20:36:35 -06:00
Qwerasd
1ab2603e0f font/freetype: remove freetype_convert.zig
This is no longer needed since we're now using the FT_Bitmap_Convert
function from FreeType to do any conversions we need instead.
2025-07-04 15:47:35 -06:00
Qwerasd
e441094af0 font: add constraint logic to rasterizers
This is in preparation to move constraint off the GPU to simplify our
shaders, instead we only need to constrain once at raster time and never
again.

This also significantly reworks the freetype renderGlyph function to be
generally much cleaner and more straightforward.

This commit doesn't actually apply the constraints to anything yet, that
will be in following commits.
2025-07-04 15:47:28 -06:00
Qwerasd
c465317e4e font/atlas: fix testing code that used old enum name
Forgot to change these instances when I renamed rgb(a) to bgr(a), which
was breaking test builds. Also went ahead and fixed some code that was
assuming rgba was actually rgba order and added a note to another part.
2025-06-23 18:01:34 -06:00
Qwerasd
41ae32814f renderer: fix color glyph rendering under OpenGL
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.
2025-06-23 18:01:34 -06:00
Qwerasd
2384bd69cc style: use decl literals
This commit changes a LOT of areas of the code to use decl literals
instead of redundantly referring to the type.

These changes were mostly driven by some regex searches and then manual
adjustment on a case-by-case basis.

I almost certainly missed quite a few places where decl literals could
be used, but this is a good first step in converting things, and other
instances can be addressed when they're discovered.

I tested GLFW+Metal and building the framework on macOS and tested a GTK
build on Linux, so I'm 99% sure I didn't introduce any syntax errors or
other problems with this. (fingers crossed)
2025-05-26 21:50:14 -06:00
Qwerasd
cfedd477b2 font/freetype: introduce mutexes to ensure thread safety of Library and Face
For details see comments and FreeType docs @
https://freetype.org/freetype2/docs/reference/ft2-library_setup.html#ft_library
https://freetype.org/freetype2/docs/reference/ft2-face_creation.html#ft_face

tl;dr: FT_New_Face and FT_Done_Face require the Library to be locked for
thread safety, and FT_Load_Glyph and FT_Render_Glyph and friends need
the face to be locked for thread safety, since we're sharing faces
across threads.
2025-05-01 18:22:37 -06:00
Qwerasd
6f84a5d682 font/freetype: disable SVG glyphs, simplify color check
We don't currently support rendering SVG glyphs so they should be
ignored when loading. Additionally, the check for whether a glyph is
colored has been simplified by just checking the pixel mode of the
rendered bitmap.

This commit also fixes a bug caused by calling the color check inside of
`renderGlyph`, which caused the bitmap to be freed creating a chance for
memory corruption and garbled glyphs.
2025-03-19 12:43:18 -06:00
Tim Culverhouse
40c1140f7d font(freetype): constrain emoji to 2 cells wide
When scaling emoji, scale so that they entirely fit within 2 cells. The
previous behavior was to scale to fill vertically, however with fonts
which are narrow this would result in horizontal overflow.
2025-03-06 10:46:58 -06: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
Qwerasd
298aeb7536 refactor(font): move ownership of Metrics to Collection
This sets the stage for dynamically adjusting the sizes of fallback
fonts based on the primary font's face metrics. It also removes a lot of
unnecessary work when loading fallback fonts, since we only actually use
the metrics based on the parimary font.
2025-01-06 20:13:45 -05: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
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
ef542c6e63 Enable bitmap font usage under CoreText (#4115)
macOS bitmap-only fonts are a poorly documented format, which are often
distributed as `.dfont` or `.dfon` files. They use a 'bhed' table in
place of the usual 'head', but the table format is byte-identical, so
enabling the use of bitmap-only fonts only requires us to properly fetch
this table while calculating metrics.

ref: https://fontforge.org/docs/techref/bitmaponlysfnt.html

Reverts #3550 for obvious reasons, and may close issue #2168 because
this should now mean that bitmap fonts are properly supported under both
font backends due to #3837 - unless `otb` fonts are still not properly
supported under FreeType (they are not supported under CoreText because
CoreText does not know how to handle them).

I tested this change with the `.dfont` distribution of
[Cozette](https://github.com/slavfox/Cozette) v1.25.2 and saw no visual
issues.
2024-12-30 12:05:57 -08:00
Mitchell Hashimoto
41df2d9805 font/freetype: hardcode DPI in test to avoid variation between OS 2024-12-30 12:01:46 -08:00
Qwerasd
7a4215abd7 font/coretext: properly resolve metrics for bitmap-only fonts
macOS bitmap-only fonts are a poorly documented format, which are often
distributed as `.dfont` or `.dfon` files. They use a 'bhed' table in
place of the usual 'head', but the table format is byte-identical, so
enabling the use of bitmap-only fonts only requires us to properly fetch
this table while calculating metrics.

ref: https://fontforge.org/docs/techref/bitmaponlysfnt.html
2024-12-30 14:44:46 -05:00
sin-ack
5e14b8e501 font/freetype: Downgrade pixfmt conversion log to debug
This is an expected occurrence with bitmap glyphs and causes unnecessary
spam when using the terminal with one.
2024-12-29 04:56:17 +00:00
sin-ack
1a6d9590a2 font/freetype: Add test for crisp bitmap font rendering
Now we can be certain that bitmap fonts stay crisp. :^)
2024-12-29 04:55:29 +00:00
sin-ack
ea8fe9a4b0 font/freetype: Enable bitmap glyphs for non-color faces
This allows for crisp bitmap font rendering once again.
2024-12-29 02:27:56 +00:00
sin-ack
bfde326bcb font/freetype: Rewrite monoToGrayscale algorithm
The original version had issues converting properly and caused broken
glyphs. This version tries to be as simple as possible in order to make
it easy to understand. I haven't measured the performance but in
practice this will only happen during the first render of the glyph
after a face change (i.e. during launch or when changing font size).
2024-12-29 02:27:52 +00:00
Qwerasd
3b6d8f3175 fix tests for coretext to include cursor_height 2024-12-22 12:52:04 -05:00
Qwerasd
d624db30c6 test(metrics): fix to initialize cursor height + add comment 2024-12-22 12:38:17 -05:00
Qwerasd
08ebb6b64d fix tests for freetype to include cursor_height metric 2024-12-22 12:34:43 -05:00
Qwerasd
077dad11b4 font: add cursor-height metric, and adjust- config for it. 2024-12-21 20:15:53 -05:00
Qwerasd
0e21293d43 font(coretext): improve atlas padding calculations
- Simplifies and clarifies the math for how the bounding box for
rendered glyphs is computed
- Reduces margin from 2px between glyphs to 1px by only padding the
bottom and right side of each glyph
- Avoids excessive padding to glyph box when font thicken is enabled or
when using a synthetic bold (it was previously 4x as much padding as
necessary in some cases)
2024-12-19 13:30:52 -08:00
Mitchell Hashimoto
2b78ac4382 font: style edits for #2985 2024-12-16 12:30:34 -08:00
Qwerasd
a06388869d fix: sCapHeight and sxHeight only exist when OS/2 version >= 2 2024-12-16 15:20:26 -05:00
Qwerasd
13e4861dff font(freetype): tolerate fonts without OS/2 tables
This is more common than anticipated, so proper fallback logic has been
added. Why must fonts be like this? -.-
2024-12-16 14:53:29 -05:00
Qwerasd
5cd214066d font(coretext): tolerate fonts without OS/2 tables
This creates big problems if we don't, since a lot of symbols end up
falling back to Apple Gothic, which doesn't have an OS/2 table.
2024-12-16 14:52:07 -05:00
Qwerasd
4573890f22 font: fix sign of usWinDescent interpretation 2024-12-13 13:14:49 -05:00
Qwerasd
8a5d484729 font: more robust extraction of vertical metrics from tables
Previously always assuming the typo metrics were good caused some fonts
to have abnormally short cell heights.
2024-12-13 13:00:03 -05:00
Mitchell Hashimoto
b7dc767237 face: add more RLS types and explicit error sets 2024-12-12 19:47:58 -08:00
Qwerasd
586a7e517e font(freetype): actually take max ascii width instead of first 2024-12-12 21:30:01 -05:00
Qwerasd
0557bf8301 font(metrics): always apply minimum values after calculating 2024-12-12 13:47:13 -05:00
Qwerasd
fb50143cec font(coretext): add metrics test case for CT, fix variable font init
Variable font init used to just select the first available predefined
instance, if there were any, which is often not desirable- using
createFontDescriptorFromData instead of createFontDescritorsFromData
ensures that the default variation config is selected. In the future we
should probably allow selection of predefined instances, but for now
this is the correct behavior.

I found this bug when adding the metrics calculation test case for
CoreText, hence why fixing it is part of the same commit.
2024-12-11 21:14:21 -05:00
Qwerasd
bd18452310 font: unify metrics calculations & separate sprite metrics
Unify grid metrics calculations by relying on shared logic mostly based
on values directly from the font tables, this deduplicates a lot of code
and gives us more control over how we interpret various metrics.

Also separate metrics for underlined, strikethrough, and overline
thickness and position, and box drawing thickness, so that they can
individually be adjusted as the user desires.
2024-12-11 16:55:52 -05:00
Mitchell Hashimoto
3ee6577154 some tweaks 2024-11-09 11:03:02 -08:00
Nadir Fejzic
83c4d0077b refactor: define FreetypeLoadFlags struct and default in font.face 2024-11-09 12:34:39 +01:00
Nadir Fejzic
e7f286d83f docs: describe load_flags field in Face struct 2024-11-09 01:40:39 +01:00
Nadir Fejzic
c0b24ee60d refactor: make freetype flags void for non-freetype backend
This is an attempt to use `void` as type for Freetype Load Flags when
backend does not use these flags.
2024-11-09 01:39:10 +01:00
Nadir Fejzic
945a715b08 refactor: handle freetype load flags in face instead of renderer 2024-11-09 00:42:18 +01:00