diff options
Diffstat (limited to 'src/gui/font.c')
| -rw-r--r-- | src/gui/font.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/src/gui/font.c b/src/gui/font.c index 5989dd4e..5ea595f9 100644 --- a/src/gui/font.c +++ b/src/gui/font.c @@ -3,6 +3,7 @@ // fallback, and the light target for shape-preserving grayscale text. #include "font.h" #include <freetype-zig.h> +#include <freetype/ftbitmap.h> #include <stdlib.h> #include <string.h> @@ -126,7 +127,7 @@ void ui_font_cell_metrics(UIFont *f, float px, int32_t *cell_w, int32_t *cell_h, *ascent = asc > 0 ? asc : 1; } -static int raster(UIFont *f, float px, int32_t cp, uint8_t *out, +static int raster(UIFont *f, float px, int32_t cp, int bold, uint8_t *out, int32_t stride, int32_t cell_w, int32_t cell_h, int32_t ascent, int centered) { if (!f || !out || stride < cell_w || cell_w <= 0 || cell_h <= 0) @@ -140,6 +141,22 @@ static int raster(UIFont *f, float px, int32_t cp, uint8_t *out, FT_Get_Char_Index(f->face, (FT_ULong)(uint32_t)cp); if (FT_Load_Glyph(f->face, glyph_index, load_flags()) != 0) return 0; + if (bold) { + // Synthetic bold thickens the hinted outline before it is rendered, so + // the wider stems are rasterized as one shape and keep hinted edges; the + // advance is untouched, as the cell grid requires. Strength is Ghostty's + // heuristic: 1/32 of the line height in 26.6, rounded up (one pixel at a + // 32 px line). A bitmap strike has no outline: widen it by one whole pixel, + // the classic overstrike, which keeps its pixels sharp. + FT_GlyphSlot slot = f->face->glyph; + if (slot->format == FT_GLYPH_FORMAT_OUTLINE) { + const FT_Pos height = f->face->size->metrics.height; + FT_Outline_Embolden(&slot->outline, (height + 31) / 32); + } else if (slot->format == FT_GLYPH_FORMAT_BITMAP && + FT_GlyphSlot_Own_Bitmap(slot) == 0) { + FT_Bitmap_Embolden(f->library, &slot->bitmap, 64, 0); + } + } if (FT_Render_Glyph(f->face->glyph, FT_RENDER_MODE_NORMAL) != 0) return 0; @@ -187,13 +204,14 @@ static int raster(UIFont *f, float px, int32_t cp, uint8_t *out, return 1; } -int ui_font_raster(UIFont *f, float px, int32_t cp, uint8_t *out, +int ui_font_raster(UIFont *f, float px, int32_t cp, int bold, uint8_t *out, int32_t stride, int32_t cell_w, int32_t cell_h, int32_t ascent) { - return raster(f, px, cp, out, stride, cell_w, cell_h, ascent, 0); + return raster(f, px, cp, bold, out, stride, cell_w, cell_h, ascent, 0); } -int ui_font_raster_centered(UIFont *f, float px, int32_t cp, uint8_t *out, - int32_t stride, int32_t width, int32_t height) { - return raster(f, px, cp, out, stride, width, height, 0, 1); +int ui_font_raster_centered(UIFont *f, float px, int32_t cp, int bold, + uint8_t *out, int32_t stride, int32_t width, + int32_t height) { + return raster(f, px, cp, bold, out, stride, width, height, 0, 1); } |
