mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
font: support aliased entries in the font collection style table
This commit is contained in:
@ -16,6 +16,7 @@
|
|||||||
const Collection = @This();
|
const Collection = @This();
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const assert = std.debug.assert;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const font = @import("main.zig");
|
const font = @import("main.zig");
|
||||||
const options = font.options;
|
const options = font.options;
|
||||||
@ -104,7 +105,21 @@ pub fn add(
|
|||||||
pub fn getFace(self: *Collection, index: Index) !*Face {
|
pub fn getFace(self: *Collection, index: Index) !*Face {
|
||||||
if (index.special() != null) return error.SpecialHasNoFace;
|
if (index.special() != null) return error.SpecialHasNoFace;
|
||||||
const list = self.faces.getPtr(index.style);
|
const list = self.faces.getPtr(index.style);
|
||||||
const item = &list.items[index.idx];
|
const item: *Entry = item: {
|
||||||
|
var item = &list.items[index.idx];
|
||||||
|
switch (item.*) {
|
||||||
|
.alias => |ptr| item = ptr,
|
||||||
|
|
||||||
|
.deferred,
|
||||||
|
.fallback_deferred,
|
||||||
|
.loaded,
|
||||||
|
.fallback_loaded,
|
||||||
|
=> {},
|
||||||
|
}
|
||||||
|
assert(item.* != .alias);
|
||||||
|
break :item item;
|
||||||
|
};
|
||||||
|
|
||||||
return switch (item.*) {
|
return switch (item.*) {
|
||||||
inline .deferred, .fallback_deferred => |*d, tag| deferred: {
|
inline .deferred, .fallback_deferred => |*d, tag| deferred: {
|
||||||
const opts = self.load_options orelse
|
const opts = self.load_options orelse
|
||||||
@ -125,6 +140,10 @@ pub fn getFace(self: *Collection, index: Index) !*Face {
|
|||||||
},
|
},
|
||||||
|
|
||||||
.loaded, .fallback_loaded => |*f| f,
|
.loaded, .fallback_loaded => |*f| f,
|
||||||
|
|
||||||
|
// When setting `item` above, we ensure we don't end up with
|
||||||
|
// an alias.
|
||||||
|
.alias => unreachable,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,6 +187,23 @@ pub fn hasCodepoint(
|
|||||||
return list.items[index.idx].hasCodepoint(cp, p_mode);
|
return list.items[index.idx].hasCodepoint(cp, p_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensure we have an option for all styles in the collection, such
|
||||||
|
/// as italic and bold.
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
pub fn completeStyles(self: *Collection, alloc: Allocator) !void {
|
||||||
|
const regular_list = self.faces.getPtr(.regular);
|
||||||
|
assert(regular_list.items.len > 0);
|
||||||
|
|
||||||
|
// If we don't have bold, use the regular font.
|
||||||
|
const bold_list = self.faces.getPtr(.bold);
|
||||||
|
if (bold_list.items.len == 0) {}
|
||||||
|
|
||||||
|
_ = alloc;
|
||||||
|
}
|
||||||
|
|
||||||
/// Automatically create an italicized font from the regular
|
/// Automatically create an italicized font from the regular
|
||||||
/// font face if we don't have one already. If we already have
|
/// font face if we don't have one already. If we already have
|
||||||
/// an italicized font face, this does nothing.
|
/// an italicized font face, this does nothing.
|
||||||
@ -243,10 +279,16 @@ pub fn setSize(self: *Collection, size: DesiredSize) !void {
|
|||||||
var it = self.faces.iterator();
|
var it = self.faces.iterator();
|
||||||
while (it.next()) |entry| {
|
while (it.next()) |entry| {
|
||||||
for (entry.value.items) |*elem| switch (elem.*) {
|
for (entry.value.items) |*elem| switch (elem.*) {
|
||||||
.deferred, .fallback_deferred => continue,
|
|
||||||
.loaded, .fallback_loaded => |*f| try f.setSize(
|
.loaded, .fallback_loaded => |*f| try f.setSize(
|
||||||
opts.faceOptions(),
|
opts.faceOptions(),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// Deferred aren't loaded so we don't need to set their size.
|
||||||
|
// The size for when they're loaded is set since `opts` changed.
|
||||||
|
.deferred, .fallback_deferred => continue,
|
||||||
|
|
||||||
|
// Alias faces don't own their size.
|
||||||
|
.alias => continue,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -318,6 +360,10 @@ pub const Entry = union(enum) {
|
|||||||
fallback_deferred: DeferredFace,
|
fallback_deferred: DeferredFace,
|
||||||
fallback_loaded: Face,
|
fallback_loaded: Face,
|
||||||
|
|
||||||
|
// An alias to another entry. This is used to share the same face,
|
||||||
|
// avoid memory duplication. An alias must point to a non-alias entry.
|
||||||
|
alias: *Entry,
|
||||||
|
|
||||||
pub fn deinit(self: *Entry) void {
|
pub fn deinit(self: *Entry) void {
|
||||||
switch (self.*) {
|
switch (self.*) {
|
||||||
inline .deferred,
|
inline .deferred,
|
||||||
@ -325,6 +371,10 @@ pub const Entry = union(enum) {
|
|||||||
.fallback_deferred,
|
.fallback_deferred,
|
||||||
.fallback_loaded,
|
.fallback_loaded,
|
||||||
=> |*v| v.deinit(),
|
=> |*v| v.deinit(),
|
||||||
|
|
||||||
|
// Aliased fonts are not owned by this entry so we let them
|
||||||
|
// be deallocated by the owner.
|
||||||
|
.alias => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,6 +383,7 @@ pub const Entry = union(enum) {
|
|||||||
return switch (self) {
|
return switch (self) {
|
||||||
.deferred, .fallback_deferred => true,
|
.deferred, .fallback_deferred => true,
|
||||||
.loaded, .fallback_loaded => false,
|
.loaded, .fallback_loaded => false,
|
||||||
|
.alias => |v| v.isDeferred(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,6 +394,8 @@ pub const Entry = union(enum) {
|
|||||||
p_mode: PresentationMode,
|
p_mode: PresentationMode,
|
||||||
) bool {
|
) bool {
|
||||||
return switch (self) {
|
return switch (self) {
|
||||||
|
.alias => |v| v.hasCodepoint(cp, p_mode),
|
||||||
|
|
||||||
// Non-fallback fonts require explicit presentation matching but
|
// Non-fallback fonts require explicit presentation matching but
|
||||||
// otherwise don't care about presentation
|
// otherwise don't care about presentation
|
||||||
.deferred => |v| switch (p_mode) {
|
.deferred => |v| switch (p_mode) {
|
||||||
|
Reference in New Issue
Block a user