mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
font: Group can enable/disable styles
This commit is contained in:
@ -33,6 +33,9 @@ const log = std.log.scoped(.font_group);
|
|||||||
// to the user so we can change this later.
|
// to the user so we can change this later.
|
||||||
const StyleArray = std.EnumArray(Style, std.ArrayListUnmanaged(GroupFace));
|
const StyleArray = std.EnumArray(Style, std.ArrayListUnmanaged(GroupFace));
|
||||||
|
|
||||||
|
/// Packed array of booleans to indicate if a style is enabled or not.
|
||||||
|
const StyleStatus = std.EnumArray(Style, bool);
|
||||||
|
|
||||||
/// Map of descriptors to faces. This is used with manual codepoint maps
|
/// Map of descriptors to faces. This is used with manual codepoint maps
|
||||||
/// to ensure that we don't load the same font multiple times.
|
/// to ensure that we don't load the same font multiple times.
|
||||||
///
|
///
|
||||||
@ -72,6 +75,12 @@ size: font.face.DesiredSize,
|
|||||||
/// Instead, use the functions available on Group.
|
/// Instead, use the functions available on Group.
|
||||||
faces: StyleArray,
|
faces: StyleArray,
|
||||||
|
|
||||||
|
/// The set of statuses and whether they're enabled or not. This defaults
|
||||||
|
/// to true. This can be changed at runtime with no ill effect. If you
|
||||||
|
/// change this at runtime and are using a GroupCache, the GroupCache
|
||||||
|
/// must be reset.
|
||||||
|
styles: StyleStatus = StyleStatus.initFill(true),
|
||||||
|
|
||||||
/// If discovery is available, we'll look up fonts where we can't find
|
/// If discovery is available, we'll look up fonts where we can't find
|
||||||
/// the codepoint. This can be set after initialization.
|
/// the codepoint. This can be set after initialization.
|
||||||
discover: ?*font.Discover = null,
|
discover: ?*font.Discover = null,
|
||||||
@ -150,13 +159,6 @@ pub fn addFace(self: *Group, style: Style, face: GroupFace) !FontIndex {
|
|||||||
return .{ .style = style, .idx = @intCast(idx) };
|
return .{ .style = style, .idx = @intCast(idx) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if we have a face for the given style, though the face may
|
|
||||||
/// not be loaded yet.
|
|
||||||
pub fn hasFaceForStyle(self: Group, style: Style) bool {
|
|
||||||
const list = self.faces.get(style);
|
|
||||||
return list.items.len > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This will automatically create an italicized font from the regular
|
/// This will automatically create an italicized font from the regular
|
||||||
/// font face if we don't have any italicized fonts.
|
/// font face if we don't have any italicized fonts.
|
||||||
pub fn italicize(self: *Group) !void {
|
pub fn italicize(self: *Group) !void {
|
||||||
@ -278,6 +280,11 @@ pub fn indexForCodepoint(
|
|||||||
style: Style,
|
style: Style,
|
||||||
p: ?Presentation,
|
p: ?Presentation,
|
||||||
) ?FontIndex {
|
) ?FontIndex {
|
||||||
|
// If we've disabled a font style, then fall back to regular.
|
||||||
|
if (style != .regular and !self.styles.get(style)) {
|
||||||
|
return self.indexForCodepoint(cp, .regular, p);
|
||||||
|
}
|
||||||
|
|
||||||
// Codepoint overrides.
|
// Codepoint overrides.
|
||||||
if (self.indexForCodepointOverride(cp)) |idx_| {
|
if (self.indexForCodepointOverride(cp)) |idx_| {
|
||||||
if (idx_) |idx| return idx;
|
if (idx_) |idx| return idx;
|
||||||
@ -669,6 +676,50 @@ test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "disabled font style" {
|
||||||
|
const testing = std.testing;
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
const testFont = @import("test.zig").fontRegular;
|
||||||
|
|
||||||
|
var atlas_greyscale = try font.Atlas.init(alloc, 512, .greyscale);
|
||||||
|
defer atlas_greyscale.deinit(alloc);
|
||||||
|
|
||||||
|
var lib = try Library.init();
|
||||||
|
defer lib.deinit();
|
||||||
|
|
||||||
|
var group = try init(alloc, lib, .{ .points = 12 });
|
||||||
|
defer group.deinit();
|
||||||
|
|
||||||
|
// Disable bold
|
||||||
|
group.styles.set(.bold, false);
|
||||||
|
|
||||||
|
// Same font but we can test the style in the index
|
||||||
|
_ = try group.addFace(.regular, .{ .loaded = try Face.init(lib, testFont, .{ .points = 12 }) });
|
||||||
|
_ = try group.addFace(.bold, .{ .loaded = try Face.init(lib, testFont, .{ .points = 12 }) });
|
||||||
|
_ = try group.addFace(.italic, .{ .loaded = try Face.init(lib, testFont, .{ .points = 12 }) });
|
||||||
|
|
||||||
|
// Regular should work fine
|
||||||
|
{
|
||||||
|
const idx = group.indexForCodepoint('A', .regular, null).?;
|
||||||
|
try testing.expectEqual(Style.regular, idx.style);
|
||||||
|
try testing.expectEqual(@as(FontIndex.IndexInt, 0), idx.idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bold should go to regular
|
||||||
|
{
|
||||||
|
const idx = group.indexForCodepoint('A', .bold, null).?;
|
||||||
|
try testing.expectEqual(Style.regular, idx.style);
|
||||||
|
try testing.expectEqual(@as(FontIndex.IndexInt, 0), idx.idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Italic should still work
|
||||||
|
{
|
||||||
|
const idx = group.indexForCodepoint('A', .italic, null).?;
|
||||||
|
try testing.expectEqual(Style.italic, idx.style);
|
||||||
|
try testing.expectEqual(@as(FontIndex.IndexInt, 0), idx.idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
test "face count limit" {
|
test "face count limit" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
Reference in New Issue
Block a user