deferred face hasCodepoint

This commit is contained in:
Mitchell Hashimoto
2022-09-16 15:29:13 -07:00
parent 141182aa13
commit 1c1da63c7e
2 changed files with 41 additions and 7 deletions

View File

@ -11,6 +11,7 @@ const assert = std.debug.assert;
const fontconfig = @import("fontconfig"); const fontconfig = @import("fontconfig");
const options = @import("main.zig").options; const options = @import("main.zig").options;
const Face = @import("main.zig").Face; const Face = @import("main.zig").Face;
const Presentation = @import("main.zig").Presentation;
/// The loaded face (once loaded). /// The loaded face (once loaded).
face: ?Face = null, face: ?Face = null,
@ -35,3 +36,42 @@ pub fn deinit(self: *DeferredFace) void {
pub inline fn loaded(self: DeferredFace) bool { pub inline fn loaded(self: DeferredFace) bool {
return self.face != null; return self.face != null;
} }
/// Returns true if this face can satisfy the given codepoint and
/// presentation. If presentation is null, then it just checks if the
/// codepoint is present at all.
///
/// This should not require the face to be loaded IF we're using a
/// discovery mechanism (i.e. fontconfig). If no discovery is used,
/// the face is always expected to be loaded.
pub fn hasCodepoint(self: DeferredFace, cp: u32, p: ?Presentation) bool {
// If we have the face, use the face.
if (self.face) |face| {
if (p) |desired| if (face.presentation != desired) return false;
return face.glyphIndex(cp) != null;
}
// If we are using fontconfig, use the fontconfig metadata to
// avoid loading the face.
if (options.fontconfig) {
// Check if char exists
if (!self.fc.charset.hasChar(cp)) return false;
// If we have a presentation, check it matches
if (p) |desired| {
const emoji_lang = "und-zsye";
const actual: Presentation = if (self.fc.langset.hasLang(emoji_lang))
.emoji
else
.text;
return desired == actual;
}
return true;
}
// This is unreachable because discovery mechanisms terminate, and
// if we're not using a discovery mechanism, the face MUST be loaded.
unreachable;
}

View File

@ -112,13 +112,7 @@ pub fn indexForCodepoint(
fn indexForCodepointExact(self: Group, cp: u32, style: Style, p: ?Presentation) ?FontIndex { fn indexForCodepointExact(self: Group, cp: u32, style: Style, p: ?Presentation) ?FontIndex {
for (self.faces.get(style).items) |deferred, i| { for (self.faces.get(style).items) |deferred, i| {
const face = deferred.face.?; if (deferred.hasCodepoint(cp, p)) {
// If the presentation is null, we allow the first presentation we
// can find. Otherwise, we check for the specific one requested.
if (p != null and face.presentation != p.?) continue;
if (face.glyphIndex(cp) != null) {
return FontIndex{ return FontIndex{
.style = style, .style = style,
.idx = @intCast(FontIndex.IndexInt, i), .idx = @intCast(FontIndex.IndexInt, i),