mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +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.
|
/// presentation for the codepoint.
|
||||||
/// a code point.
|
/// 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
|
/// This logic is relatively complex so the exact algorithm is documented
|
||||||
/// here. If this gets out of sync with the code, ask questions.
|
/// here. If this gets out of sync with the code, ask questions.
|
||||||
///
|
///
|
||||||
@ -118,7 +127,7 @@ pub fn getIndex(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Codepoint overrides.
|
// Codepoint overrides.
|
||||||
if (self.indexForCodepointOverride(alloc, cp)) |idx_| {
|
if (self.getIndexCodepointOverride(alloc, cp)) |idx_| {
|
||||||
if (idx_) |idx| return idx;
|
if (idx_) |idx| return idx;
|
||||||
} else |err| {
|
} else |err| {
|
||||||
log.warn("codepoint override failed codepoint={} err={}", .{ cp, 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,
|
/// Checks if the codepoint is in the map of codepoint overrides,
|
||||||
/// finds the override font, and returns it.
|
/// finds the override font, and returns it.
|
||||||
fn indexForCodepointOverride(
|
fn getIndexCodepointOverride(
|
||||||
self: *CodepointResolver,
|
self: *CodepointResolver,
|
||||||
alloc: Allocator,
|
alloc: Allocator,
|
||||||
cp: u32,
|
cp: u32,
|
||||||
@ -265,7 +274,7 @@ fn indexForCodepointOverride(
|
|||||||
const idx = idx_ orelse return null;
|
const idx = idx_ orelse return null;
|
||||||
|
|
||||||
// We need to verify that this index has the codepoint we want.
|
// 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}", .{
|
log.debug("codepoint override based on config codepoint={} family={s}", .{
|
||||||
cp,
|
cp,
|
||||||
desc.family orelse "",
|
desc.family orelse "",
|
||||||
@ -385,3 +394,59 @@ test getIndex {
|
|||||||
try testing.expect(r.getIndex(alloc, 0x1FB00, .regular, null) == null);
|
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 std = @import("std");
|
||||||
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 DeferredFace = font.DeferredFace;
|
const DeferredFace = font.DeferredFace;
|
||||||
const DesiredSize = font.face.DesiredSize;
|
const DesiredSize = font.face.DesiredSize;
|
||||||
const Face = font.Face;
|
const Face = font.Face;
|
||||||
@ -160,14 +161,11 @@ pub fn hasCodepoint(
|
|||||||
self: *const Collection,
|
self: *const Collection,
|
||||||
index: Index,
|
index: Index,
|
||||||
cp: u32,
|
cp: u32,
|
||||||
p: ?Presentation,
|
p_mode: PresentationMode,
|
||||||
) bool {
|
) bool {
|
||||||
const list = self.faces.get(index.style);
|
const list = self.faces.get(index.style);
|
||||||
if (index.idx >= list.items.len) return false;
|
if (index.idx >= list.items.len) return false;
|
||||||
return list.items[index.idx].hasCodepoint(
|
return list.items[index.idx].hasCodepoint(cp, p_mode);
|
||||||
cp,
|
|
||||||
if (p) |v| .{ .explicit = v } else .{ .any = {} },
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Automatically create an italicized font from the regular
|
/// Automatically create an italicized font from the regular
|
||||||
@ -601,3 +599,50 @@ test setSize {
|
|||||||
try c.setSize(.{ .points = 24 });
|
try c.setSize(.{ .points = 24 });
|
||||||
try testing.expectEqual(@as(u32, 24), c.load_options.?.size.points);
|
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