diff --git a/src/font/discovery.zig b/src/font/discovery.zig index a42055d5a..e73ea626f 100644 --- a/src/font/discovery.zig +++ b/src/font/discovery.zig @@ -362,16 +362,9 @@ pub const CoreText = struct { const list = set.createMatchingFontDescriptors(); defer list.release(); - // Bring the list of descriptors in to zig land - var zig_list = try copyMatchingDescriptors(alloc, list); - errdefer alloc.free(zig_list); - - // Filter them. We don't use `CTFontCollectionSetExclusionDescriptors` - // to do this because that requires a mutable collection. This way is - // much more straight forward. - zig_list = try alloc.realloc(zig_list, filterDescriptors(zig_list)); - // Sort our descriptors + const zig_list = try copyMatchingDescriptors(alloc, list); + errdefer alloc.free(zig_list); sortMatchingDescriptors(&desc, zig_list); return DiscoverIterator{ @@ -558,47 +551,13 @@ pub const CoreText = struct { for (0..result.len) |i| { result[i] = list.getValueAtIndex(macos.text.FontDescriptor, i); - // We need to retain because once the list - // is freed it will release all its members. + // We need to retain becauseonce the list is freed it will + // release all its members. result[i].retain(); } return result; } - /// Filter any descriptors out of the list that aren't acceptable for - /// some reason or another (e.g. the font isn't in a format we can handle). - /// - /// Invalid descriptors are filled in from the end of - /// the list and the new length for the list is returned. - fn filterDescriptors(list: []*macos.text.FontDescriptor) usize { - var end = list.len; - var i: usize = 0; - while (i < end) { - if (validDescriptor(list[i])) { - i += 1; - } else { - list[i].release(); - end -= 1; - list[i] = list[end]; - } - } - return end; - } - - /// Used by `filterDescriptors` to decide whether a descriptor is valid. - fn validDescriptor(desc: *macos.text.FontDescriptor) bool { - if (desc.copyAttribute(macos.text.FontAttribute.format)) |format| { - defer format.release(); - var value: c_int = undefined; - assert(format.getValue(.int, &value)); - - // Bitmap fonts are not currently supported. - if (value == macos.text.c.kCTFontFormatBitmap) return false; - } - - return true; - } - fn sortMatchingDescriptors( desc: *const Descriptor, list: []*macos.text.FontDescriptor, diff --git a/src/font/face/coretext.zig b/src/font/face/coretext.zig index 92ab4d396..dd4f6432e 100644 --- a/src/font/face/coretext.zig +++ b/src/font/face/coretext.zig @@ -515,8 +515,17 @@ pub const Face = struct { fn calcMetrics(ct_font: *macos.text.Font) CalcMetricsError!font.face.Metrics { // Read the 'head' table out of the font data. const head: opentype.Head = head: { - const tag = macos.text.FontTableTag.init("head"); - const data = ct_font.copyTable(tag) orelse return error.CopyTableError; + // macOS bitmap-only fonts use a 'bhed' tag rather than 'head', but + // the table format is byte-identical to the 'head' table, so if we + // can't find 'head' we try 'bhed' instead before failing. + // + // ref: https://fontforge.org/docs/techref/bitmaponlysfnt.html + const head_tag = macos.text.FontTableTag.init("head"); + const bhed_tag = macos.text.FontTableTag.init("bhed"); + const data = + ct_font.copyTable(head_tag) orelse + ct_font.copyTable(bhed_tag) orelse + return error.CopyTableError; defer data.release(); const ptr = data.getPointer(); const len = data.getLength();