mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
font: add stylistic variants for built-in font, fix naming convention
Fixes #2364 This adds the bold, italic, and bold italic variants of JB Mono so it is built-in. This also fixes up the naming convention for the embedded font files across tests and removes redundant embedded font files.
This commit is contained in:
@ -4338,8 +4338,3 @@ fn presentSurface(self: *Surface) !void {
|
||||
{},
|
||||
);
|
||||
}
|
||||
|
||||
pub const face_ttf = @embedFile("font/res/JetBrainsMono-Regular.ttf");
|
||||
pub const face_bold_ttf = @embedFile("font/res/JetBrainsMono-Bold.ttf");
|
||||
pub const face_emoji_ttf = @embedFile("font/res/NotoColorEmoji.ttf");
|
||||
pub const face_emoji_text_ttf = @embedFile("font/res/NotoEmoji-Regular.ttf");
|
||||
|
@ -376,9 +376,9 @@ const DescriptorCache = std.HashMapUnmanaged(
|
||||
test getIndex {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
const testFont = @import("test.zig").fontRegular;
|
||||
const testEmoji = @import("test.zig").fontEmoji;
|
||||
const testEmojiText = @import("test.zig").fontEmojiText;
|
||||
const testFont = font.embedded.regular;
|
||||
const testEmoji = font.embedded.emoji;
|
||||
const testEmojiText = font.embedded.emoji_text;
|
||||
|
||||
var lib = try Library.init();
|
||||
defer lib.deinit();
|
||||
@ -456,7 +456,7 @@ test getIndex {
|
||||
test "getIndex disabled font style" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
const testFont = @import("test.zig").fontRegular;
|
||||
const testFont = font.embedded.regular;
|
||||
|
||||
var atlas_grayscale = try font.Atlas.init(alloc, 512, .grayscale);
|
||||
defer atlas_grayscale.deinit(alloc);
|
||||
|
@ -203,11 +203,11 @@ pub const CompleteError = Allocator.Error || error{
|
||||
};
|
||||
|
||||
/// Ensure we have an option for all styles in the collection, such
|
||||
/// as italic and bold.
|
||||
/// as italic and bold by synthesizing them if necessary from the
|
||||
/// first regular face that has text glyphs.
|
||||
///
|
||||
/// This requires that a regular font face is already loaded.
|
||||
/// This is asserted. If a font style is missing, we will synthesize
|
||||
/// it if possible. Otherwise, we will use the regular font style.
|
||||
/// If there is no regular face that has text glyphs, then this
|
||||
/// does nothing.
|
||||
pub fn completeStyles(
|
||||
self: *Collection,
|
||||
alloc: Allocator,
|
||||
@ -229,7 +229,7 @@ pub fn completeStyles(
|
||||
// if a user configures something like an Emoji font first.
|
||||
const regular_entry: *Entry = entry: {
|
||||
const list = self.faces.getPtr(.regular);
|
||||
assert(list.count() > 0);
|
||||
if (list.count() == 0) return;
|
||||
|
||||
// Find our first regular face that has text glyphs.
|
||||
var it = list.iterator(0);
|
||||
@ -663,7 +663,7 @@ test init {
|
||||
test "add full" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
const testFont = @import("test.zig").fontRegular;
|
||||
const testFont = font.embedded.regular;
|
||||
|
||||
var lib = try Library.init();
|
||||
defer lib.deinit();
|
||||
@ -709,7 +709,7 @@ test "add deferred without loading options" {
|
||||
test getFace {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
const testFont = @import("test.zig").fontRegular;
|
||||
const testFont = font.embedded.regular;
|
||||
|
||||
var lib = try Library.init();
|
||||
defer lib.deinit();
|
||||
@ -733,7 +733,7 @@ test getFace {
|
||||
test getIndex {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
const testFont = @import("test.zig").fontRegular;
|
||||
const testFont = font.embedded.regular;
|
||||
|
||||
var lib = try Library.init();
|
||||
defer lib.deinit();
|
||||
@ -764,7 +764,7 @@ test getIndex {
|
||||
test completeStyles {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
const testFont = @import("test.zig").fontRegular;
|
||||
const testFont = font.embedded.regular;
|
||||
|
||||
var lib = try Library.init();
|
||||
defer lib.deinit();
|
||||
@ -791,7 +791,7 @@ test completeStyles {
|
||||
test setSize {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
const testFont = @import("test.zig").fontRegular;
|
||||
const testFont = font.embedded.regular;
|
||||
|
||||
var lib = try Library.init();
|
||||
defer lib.deinit();
|
||||
@ -814,7 +814,7 @@ test setSize {
|
||||
test hasCodepoint {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
const testFont = @import("test.zig").fontRegular;
|
||||
const testFont = font.embedded.regular;
|
||||
|
||||
var lib = try Library.init();
|
||||
defer lib.deinit();
|
||||
@ -838,7 +838,7 @@ test "hasCodepoint emoji default graphical" {
|
||||
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
const testEmoji = @import("test.zig").fontEmoji;
|
||||
const testEmoji = font.embedded.emoji;
|
||||
|
||||
var lib = try Library.init();
|
||||
defer lib.deinit();
|
||||
|
@ -323,7 +323,7 @@ const GlyphKey = struct {
|
||||
const TestMode = enum { normal };
|
||||
|
||||
fn testGrid(mode: TestMode, alloc: Allocator, lib: Library) !SharedGrid {
|
||||
const testFont = @import("test.zig").fontRegular;
|
||||
const testFont = font.embedded.regular;
|
||||
|
||||
var c = Collection.init();
|
||||
c.load_options = .{ .library = lib };
|
||||
|
@ -245,13 +245,46 @@ fn collection(
|
||||
}
|
||||
}
|
||||
|
||||
// Complete our styles to ensure we have something to satisfy every
|
||||
// possible style request. We do this before adding our built-in font
|
||||
// because we want to ensure our built-in styles are fallbacks to
|
||||
// the configured styles.
|
||||
try c.completeStyles(self.alloc, config.@"font-synthetic-style");
|
||||
|
||||
// Our built-in font will be used as a backup
|
||||
_ = try c.add(
|
||||
self.alloc,
|
||||
.regular,
|
||||
.{ .fallback_loaded = try Face.init(
|
||||
self.font_lib,
|
||||
face_ttf,
|
||||
font.embedded.regular,
|
||||
load_options.faceOptions(),
|
||||
) },
|
||||
);
|
||||
_ = try c.add(
|
||||
self.alloc,
|
||||
.bold,
|
||||
.{ .fallback_loaded = try Face.init(
|
||||
self.font_lib,
|
||||
font.embedded.bold,
|
||||
load_options.faceOptions(),
|
||||
) },
|
||||
);
|
||||
_ = try c.add(
|
||||
self.alloc,
|
||||
.italic,
|
||||
.{ .fallback_loaded = try Face.init(
|
||||
self.font_lib,
|
||||
font.embedded.italic,
|
||||
load_options.faceOptions(),
|
||||
) },
|
||||
);
|
||||
_ = try c.add(
|
||||
self.alloc,
|
||||
.bold_italic,
|
||||
.{ .fallback_loaded = try Face.init(
|
||||
self.font_lib,
|
||||
font.embedded.bold_italic,
|
||||
load_options.faceOptions(),
|
||||
) },
|
||||
);
|
||||
@ -284,7 +317,7 @@ fn collection(
|
||||
.regular,
|
||||
.{ .fallback_loaded = try Face.init(
|
||||
self.font_lib,
|
||||
face_emoji_ttf,
|
||||
font.embedded.emoji,
|
||||
load_options.faceOptions(),
|
||||
) },
|
||||
);
|
||||
@ -293,16 +326,12 @@ fn collection(
|
||||
.regular,
|
||||
.{ .fallback_loaded = try Face.init(
|
||||
self.font_lib,
|
||||
face_emoji_text_ttf,
|
||||
font.embedded.emoji_text,
|
||||
load_options.faceOptions(),
|
||||
) },
|
||||
);
|
||||
}
|
||||
|
||||
// Complete our styles to ensure we have something to satisfy every
|
||||
// possible style request.
|
||||
try c.completeStyles(self.alloc, config.@"font-synthetic-style");
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
@ -633,11 +662,6 @@ pub const Key = struct {
|
||||
}
|
||||
};
|
||||
|
||||
const face_ttf = @embedFile("res/JetBrainsMono-Regular.ttf");
|
||||
const face_bold_ttf = @embedFile("res/JetBrainsMono-Bold.ttf");
|
||||
const face_emoji_ttf = @embedFile("res/NotoColorEmoji.ttf");
|
||||
const face_emoji_text_ttf = @embedFile("res/NotoEmoji-Regular.ttf");
|
||||
|
||||
test "Key" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
35
src/font/embedded.zig
Normal file
35
src/font/embedded.zig
Normal file
@ -0,0 +1,35 @@
|
||||
//! Fonts that can be embedded with Ghostty. Note they are only actually
|
||||
//! embedded in the binary if they are referenced by the code, so fonts
|
||||
//! used for tests will not result in the final binary being larger.
|
||||
//!
|
||||
//! Be careful to ensure that any fonts you embed are licensed for
|
||||
//! redistribution and include their license as necessary.
|
||||
|
||||
/// Default fonts that we prefer for Ghostty.
|
||||
pub const regular = @embedFile("res/JetBrainsMonoNerdFont-Regular.ttf");
|
||||
pub const bold = @embedFile("res/JetBrainsMonoNerdFont-Bold.ttf");
|
||||
pub const italic = @embedFile("res/JetBrainsMonoNerdFont-Italic.ttf");
|
||||
pub const bold_italic = @embedFile("res/JetBrainsMonoNerdFont-BoldItalic.ttf");
|
||||
pub const emoji = @embedFile("res/NotoColorEmoji.ttf");
|
||||
pub const emoji_text = @embedFile("res/NotoEmoji-Regular.ttf");
|
||||
|
||||
/// Fonts with general properties
|
||||
pub const variable = @embedFile("res/Lilex-VF.ttf");
|
||||
|
||||
/// Font with nerd fonts embedded.
|
||||
pub const nerd_font = @embedFile("res/JetBrainsMonoNerdFont-Regular.ttf");
|
||||
|
||||
/// Specific font families below:
|
||||
pub const code_new_roman = @embedFile("res/CodeNewRoman-Regular.otf");
|
||||
pub const inconsolata = @embedFile("res/Inconsolata-Regular.ttf");
|
||||
pub const geist_mono = @embedFile("res/GeistMono-Regular.ttf");
|
||||
pub const jetbrains_mono = @embedFile("res/JetBrainsMonoNoNF-Regular.ttf");
|
||||
pub const julia_mono = @embedFile("res/JuliaMono-Regular.ttf");
|
||||
|
||||
/// Cozette is a unique font because it embeds some emoji characters
|
||||
/// but has a text presentation.
|
||||
pub const cozette = @embedFile("res/CozetteVector.ttf");
|
||||
|
||||
/// Monaspace has weird ligature behaviors we want to test in our shapers
|
||||
/// so we embed it here.
|
||||
pub const monaspace_neon = @embedFile("res/MonaspaceNeon-Regular.otf");
|
@ -798,7 +798,7 @@ test "emoji" {
|
||||
test "in-memory" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
const testFont = @import("../test.zig").fontRegular;
|
||||
const testFont = font.embedded.regular;
|
||||
|
||||
var atlas = try font.Atlas.init(alloc, 512, .grayscale);
|
||||
defer atlas.deinit(alloc);
|
||||
@ -820,7 +820,7 @@ test "in-memory" {
|
||||
test "variable" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
const testFont = @import("../test.zig").fontVariable;
|
||||
const testFont = font.embedded.variable;
|
||||
|
||||
var atlas = try font.Atlas.init(alloc, 512, .grayscale);
|
||||
defer atlas.deinit(alloc);
|
||||
@ -842,7 +842,7 @@ test "variable" {
|
||||
test "variable set variation" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
const testFont = @import("../test.zig").fontVariable;
|
||||
const testFont = font.embedded.variable;
|
||||
|
||||
var atlas = try font.Atlas.init(alloc, 512, .grayscale);
|
||||
defer atlas.deinit(alloc);
|
||||
@ -868,7 +868,7 @@ test "variable set variation" {
|
||||
test "svg font table" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
const testFont = @import("../test.zig").fontJuliaMono;
|
||||
const testFont = font.embedded.julia_mono;
|
||||
|
||||
var lib = try font.Library.init();
|
||||
defer lib.deinit();
|
||||
@ -884,7 +884,7 @@ test "svg font table" {
|
||||
|
||||
test "glyphIndex colored vs text" {
|
||||
const testing = std.testing;
|
||||
const testFont = @import("../test.zig").fontJuliaMono;
|
||||
const testFont = font.embedded.julia_mono;
|
||||
|
||||
var lib = try font.Library.init();
|
||||
defer lib.deinit();
|
||||
|
@ -742,7 +742,7 @@ pub const Face = struct {
|
||||
};
|
||||
|
||||
test {
|
||||
const testFont = @import("../test.zig").fontRegular;
|
||||
const testFont = font.embedded.inconsolata;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var lib = try Library.init();
|
||||
@ -771,13 +771,13 @@ test {
|
||||
|
||||
try ft_font.setSize(.{ .size = .{ .points = 24, .xdpi = 96, .ydpi = 96 } });
|
||||
const g2 = try ft_font.renderGlyph(alloc, &atlas, ft_font.glyphIndex('A').?, .{});
|
||||
try testing.expectEqual(@as(u32, 21), g2.height);
|
||||
try testing.expectEqual(@as(u32, 20), g2.height);
|
||||
}
|
||||
}
|
||||
|
||||
test "color emoji" {
|
||||
const alloc = testing.allocator;
|
||||
const testFont = @import("../test.zig").fontEmoji;
|
||||
const testFont = font.embedded.emoji;
|
||||
|
||||
var lib = try Library.init();
|
||||
defer lib.deinit();
|
||||
@ -819,7 +819,7 @@ test "color emoji" {
|
||||
}
|
||||
|
||||
test "metrics" {
|
||||
const testFont = @import("../test.zig").fontRegular;
|
||||
const testFont = font.embedded.inconsolata;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var lib = try Library.init();
|
||||
@ -860,7 +860,7 @@ test "metrics" {
|
||||
|
||||
test "mono to rgba" {
|
||||
const alloc = testing.allocator;
|
||||
const testFont = @import("../test.zig").fontEmoji;
|
||||
const testFont = font.embedded.emoji;
|
||||
|
||||
var lib = try Library.init();
|
||||
defer lib.deinit();
|
||||
@ -877,7 +877,7 @@ test "mono to rgba" {
|
||||
|
||||
test "svg font table" {
|
||||
const alloc = testing.allocator;
|
||||
const testFont = @import("../test.zig").fontJuliaMono;
|
||||
const testFont = font.embedded.julia_mono;
|
||||
|
||||
var lib = try font.Library.init();
|
||||
defer lib.deinit();
|
||||
|
@ -6,6 +6,7 @@ const library = @import("library.zig");
|
||||
|
||||
pub const Atlas = @import("Atlas.zig");
|
||||
pub const discovery = @import("discovery.zig");
|
||||
pub const embedded = @import("embedded.zig");
|
||||
pub const face = @import("face.zig");
|
||||
pub const CodepointMap = @import("CodepointMap.zig");
|
||||
pub const CodepointResolver = @import("CodepointResolver.zig");
|
||||
|
@ -95,7 +95,7 @@ pub const SVG = struct {
|
||||
test "SVG" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
const testFont = @import("../test.zig").fontJuliaMono;
|
||||
const testFont = font.embedded.julia_mono;
|
||||
|
||||
var lib = try font.Library.init();
|
||||
defer lib.deinit();
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
src/font/res/JetBrainsMonoNerdFont-BoldItalic.ttf
Normal file
BIN
src/font/res/JetBrainsMonoNerdFont-BoldItalic.ttf
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1732,15 +1732,15 @@ fn testShaper(alloc: Allocator) !TestShaper {
|
||||
}
|
||||
|
||||
fn testShaperWithFont(alloc: Allocator, font_req: TestFont) !TestShaper {
|
||||
const testEmoji = @import("../test.zig").fontEmoji;
|
||||
const testEmojiText = @import("../test.zig").fontEmojiText;
|
||||
const testEmoji = font.embedded.emoji;
|
||||
const testEmojiText = font.embedded.emoji_text;
|
||||
const testFont = switch (font_req) {
|
||||
.code_new_roman => @import("../test.zig").fontCodeNewRoman,
|
||||
.inconsolata => @import("../test.zig").fontRegular,
|
||||
.geist_mono => @import("../test.zig").fontGeistMono,
|
||||
.jetbrains_mono => @import("../test.zig").fontJetBrainsMono,
|
||||
.monaspace_neon => @import("../test.zig").fontMonaspaceNeon,
|
||||
.nerd_font => @import("../test.zig").fontNerdFont,
|
||||
.code_new_roman => font.embedded.code_new_roman,
|
||||
.inconsolata => font.embedded.inconsolata,
|
||||
.geist_mono => font.embedded.geist_mono,
|
||||
.jetbrains_mono => font.embedded.jetbrains_mono,
|
||||
.monaspace_neon => font.embedded.monaspace_neon,
|
||||
.nerd_font => font.embedded.nerd_font,
|
||||
};
|
||||
|
||||
var lib = try Library.init();
|
||||
|
@ -1197,11 +1197,11 @@ fn testShaper(alloc: Allocator) !TestShaper {
|
||||
}
|
||||
|
||||
fn testShaperWithFont(alloc: Allocator, font_req: TestFont) !TestShaper {
|
||||
const testEmoji = @import("../test.zig").fontEmoji;
|
||||
const testEmojiText = @import("../test.zig").fontEmojiText;
|
||||
const testEmoji = font.embedded.emoji;
|
||||
const testEmojiText = font.embedded.emoji_text;
|
||||
const testFont = switch (font_req) {
|
||||
.inconsolata => @import("../test.zig").fontRegular,
|
||||
.monaspace_neon => @import("../test.zig").fontMonaspaceNeon,
|
||||
.inconsolata => font.embedded.inconsolata,
|
||||
.monaspace_neon => font.embedded.monaspace_neon,
|
||||
};
|
||||
|
||||
var lib = try Library.init();
|
||||
|
@ -1,30 +0,0 @@
|
||||
//! Fonts that can be embedded with Ghostty. Note they are only actually
|
||||
//! embedded in the binary if they are referenced by the code, so fonts
|
||||
//! used for tests will not result in the final binary being larger.
|
||||
//!
|
||||
//! Be careful to ensure that any fonts you embed are licensed for
|
||||
//! redistribution and include their license as necessary.
|
||||
|
||||
/// Fonts with general properties
|
||||
pub const fontRegular = @embedFile("res/Inconsolata-Regular.ttf");
|
||||
pub const fontBold = @embedFile("res/Inconsolata-Bold.ttf");
|
||||
pub const fontEmoji = @embedFile("res/NotoColorEmoji.ttf");
|
||||
pub const fontEmojiText = @embedFile("res/NotoEmoji-Regular.ttf");
|
||||
pub const fontVariable = @embedFile("res/Lilex-VF.ttf");
|
||||
|
||||
/// Font with nerd fonts embedded.
|
||||
pub const fontNerdFont = @embedFile("res/JetBrainsMonoNerdFont-Regular.ttf");
|
||||
|
||||
/// Specific font families below:
|
||||
pub const fontCodeNewRoman = @embedFile("res/CodeNewRoman-Regular.otf");
|
||||
pub const fontGeistMono = @embedFile("res/GeistMono-Regular.ttf");
|
||||
pub const fontJetBrainsMono = @embedFile("res/JetBrainsMonoNoNF-Regular.ttf");
|
||||
pub const fontJuliaMono = @embedFile("res/JuliaMono-Regular.ttf");
|
||||
|
||||
/// Cozette is a unique font because it embeds some emoji characters
|
||||
/// but has a text presentation.
|
||||
pub const fontCozette = @embedFile("res/CozetteVector.ttf");
|
||||
|
||||
/// Monaspace has weird ligature behaviors we want to test in our shapers
|
||||
/// so we embed it here.
|
||||
pub const fontMonaspaceNeon = @embedFile("res/MonaspaceNeon-Regular.otf");
|
@ -9,6 +9,7 @@ const Allocator = std.mem.Allocator;
|
||||
const builtin = @import("builtin");
|
||||
const cimgui = @import("cimgui");
|
||||
const Surface = @import("../Surface.zig");
|
||||
const font = @import("../font/main.zig");
|
||||
const input = @import("../input.zig");
|
||||
const terminal = @import("../terminal/main.zig");
|
||||
const inspector = @import("main.zig");
|
||||
@ -130,8 +131,8 @@ pub fn setup() void {
|
||||
font_config.FontDataOwnedByAtlas = false;
|
||||
_ = cimgui.c.ImFontAtlas_AddFontFromMemoryTTF(
|
||||
io.Fonts,
|
||||
@constCast(@ptrCast(Surface.face_ttf)),
|
||||
Surface.face_ttf.len,
|
||||
@constCast(@ptrCast(font.embedded.regular)),
|
||||
font.embedded.regular.len,
|
||||
font_size,
|
||||
font_config,
|
||||
null,
|
||||
|
Reference in New Issue
Block a user