mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 08:46:08 +03:00
font: CodepointResolver style disabling test
This commit is contained in:
@ -72,6 +72,15 @@ pub fn deinit(self: *CodepointResolver, alloc: Allocator) void {
|
||||
/// presentation for the codepoint.
|
||||
/// a code point.
|
||||
///
|
||||
/// An allocator is required because certain functionality (codepoint
|
||||
/// mapping, fallback fonts, etc.) may require memory allocation. Curiously,
|
||||
/// this function cannot error! If an error occurs for any reason, including
|
||||
/// memory allocation, the associated functionality is ignored and the
|
||||
/// resolver attempts to use a different method to satisfy the codepoint.
|
||||
/// This behavior is intentional to make the resolver apply best-effort
|
||||
/// logic to satisfy the codepoint since its better to render something
|
||||
/// than nothing.
|
||||
///
|
||||
/// This logic is relatively complex so the exact algorithm is documented
|
||||
/// here. If this gets out of sync with the code, ask questions.
|
||||
///
|
||||
@ -118,7 +127,7 @@ pub fn getIndex(
|
||||
}
|
||||
|
||||
// Codepoint overrides.
|
||||
if (self.indexForCodepointOverride(alloc, cp)) |idx_| {
|
||||
if (self.getIndexCodepointOverride(alloc, cp)) |idx_| {
|
||||
if (idx_) |idx| return idx;
|
||||
} else |err| {
|
||||
log.warn("codepoint override failed codepoint={} err={}", .{ cp, err });
|
||||
@ -208,7 +217,7 @@ pub fn getIndex(
|
||||
|
||||
/// Checks if the codepoint is in the map of codepoint overrides,
|
||||
/// finds the override font, and returns it.
|
||||
fn indexForCodepointOverride(
|
||||
fn getIndexCodepointOverride(
|
||||
self: *CodepointResolver,
|
||||
alloc: Allocator,
|
||||
cp: u32,
|
||||
@ -265,7 +274,7 @@ fn indexForCodepointOverride(
|
||||
const idx = idx_ orelse return null;
|
||||
|
||||
// We need to verify that this index has the codepoint we want.
|
||||
if (self.collection.hasCodepoint(idx, cp, null)) {
|
||||
if (self.collection.hasCodepoint(idx, cp, .{ .any = {} })) {
|
||||
log.debug("codepoint override based on config codepoint={} family={s}", .{
|
||||
cp,
|
||||
desc.family orelse "",
|
||||
@ -385,3 +394,59 @@ test getIndex {
|
||||
try testing.expect(r.getIndex(alloc, 0x1FB00, .regular, null) == null);
|
||||
}
|
||||
}
|
||||
|
||||
test "getIndex 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 c = try Collection.init(alloc);
|
||||
c.load_options = .{ .library = lib };
|
||||
|
||||
_ = try c.add(alloc, .regular, .{ .loaded = try Face.init(
|
||||
lib,
|
||||
testFont,
|
||||
.{ .size = .{ .points = 12, .xdpi = 96, .ydpi = 96 } },
|
||||
) });
|
||||
_ = try c.add(alloc, .bold, .{ .loaded = try Face.init(
|
||||
lib,
|
||||
testFont,
|
||||
.{ .size = .{ .points = 12, .xdpi = 96, .ydpi = 96 } },
|
||||
) });
|
||||
_ = try c.add(alloc, .italic, .{ .loaded = try Face.init(
|
||||
lib,
|
||||
testFont,
|
||||
.{ .size = .{ .points = 12, .xdpi = 96, .ydpi = 96 } },
|
||||
) });
|
||||
|
||||
var r: CodepointResolver = .{ .collection = c };
|
||||
defer r.deinit(alloc);
|
||||
r.styles.set(.bold, false); // Disable bold
|
||||
|
||||
// Regular should work fine
|
||||
{
|
||||
const idx = r.getIndex(alloc, 'A', .regular, null).?;
|
||||
try testing.expectEqual(Style.regular, idx.style);
|
||||
try testing.expectEqual(@as(Collection.Index.IndexInt, 0), idx.idx);
|
||||
}
|
||||
|
||||
// Bold should go to regular
|
||||
{
|
||||
const idx = r.getIndex(alloc, 'A', .bold, null).?;
|
||||
try testing.expectEqual(Style.regular, idx.style);
|
||||
try testing.expectEqual(@as(Collection.Index.IndexInt, 0), idx.idx);
|
||||
}
|
||||
|
||||
// Italic should still work
|
||||
{
|
||||
const idx = r.getIndex(alloc, 'A', .italic, null).?;
|
||||
try testing.expectEqual(Style.italic, idx.style);
|
||||
try testing.expectEqual(@as(Collection.Index.IndexInt, 0), idx.idx);
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ const Collection = @This();
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const font = @import("main.zig");
|
||||
const options = font.options;
|
||||
const DeferredFace = font.DeferredFace;
|
||||
const DesiredSize = font.face.DesiredSize;
|
||||
const Face = font.Face;
|
||||
@ -160,14 +161,11 @@ pub fn hasCodepoint(
|
||||
self: *const Collection,
|
||||
index: Index,
|
||||
cp: u32,
|
||||
p: ?Presentation,
|
||||
p_mode: PresentationMode,
|
||||
) bool {
|
||||
const list = self.faces.get(index.style);
|
||||
if (index.idx >= list.items.len) return false;
|
||||
return list.items[index.idx].hasCodepoint(
|
||||
cp,
|
||||
if (p) |v| .{ .explicit = v } else .{ .any = {} },
|
||||
);
|
||||
return list.items[index.idx].hasCodepoint(cp, p_mode);
|
||||
}
|
||||
|
||||
/// Automatically create an italicized font from the regular
|
||||
@ -601,3 +599,50 @@ test setSize {
|
||||
try c.setSize(.{ .points = 24 });
|
||||
try testing.expectEqual(@as(u32, 24), c.load_options.?.size.points);
|
||||
}
|
||||
|
||||
test hasCodepoint {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
const testFont = @import("test.zig").fontRegular;
|
||||
|
||||
var lib = try Library.init();
|
||||
defer lib.deinit();
|
||||
|
||||
var c = try init(alloc);
|
||||
defer c.deinit(alloc);
|
||||
c.load_options = .{ .library = lib };
|
||||
|
||||
const idx = try c.add(alloc, .regular, .{ .loaded = try Face.init(
|
||||
lib,
|
||||
testFont,
|
||||
.{ .size = .{ .points = 12, .xdpi = 96, .ydpi = 96 } },
|
||||
) });
|
||||
|
||||
try testing.expect(c.hasCodepoint(idx, 'A', .{ .any = {} }));
|
||||
try testing.expect(!c.hasCodepoint(idx, '🥸', .{ .any = {} }));
|
||||
}
|
||||
|
||||
test "hasCodepoint emoji default graphical" {
|
||||
if (options.backend != .fontconfig_freetype) return error.SkipZigTest;
|
||||
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
const testEmoji = @import("test.zig").fontEmoji;
|
||||
|
||||
var lib = try Library.init();
|
||||
defer lib.deinit();
|
||||
|
||||
var c = try init(alloc);
|
||||
defer c.deinit(alloc);
|
||||
c.load_options = .{ .library = lib };
|
||||
|
||||
const idx = try c.add(alloc, .regular, .{ .loaded = try Face.init(
|
||||
lib,
|
||||
testEmoji,
|
||||
.{ .size = .{ .points = 12, .xdpi = 96, .ydpi = 96 } },
|
||||
) });
|
||||
|
||||
try testing.expect(!c.hasCodepoint(idx, 'A', .{ .any = {} }));
|
||||
try testing.expect(c.hasCodepoint(idx, '🥸', .{ .any = {} }));
|
||||
// TODO(fontmem): test explicit/implicit
|
||||
}
|
||||
|
Reference in New Issue
Block a user