font/freetype: convert encoding of font names

Freetype encodes some font names internally in formats other than UTF-8.
This only affects debug logs but it was annoying me so I fixed it. There
may be other encodings that might need to be dealt with but I took care
of the one that I ran across.
pull/8204/head
Jeffrey C. Ollie 2025-08-10 17:25:13 -05:00
parent 0aaf80402b
commit 897d70982e
No known key found for this signature in database
GPG Key ID: 6F86035A6D97044E
1 changed files with 13 additions and 5 deletions

View File

@ -156,17 +156,25 @@ pub const Face = struct {
/// but sometimes allocation isn't required and a static string is
/// returned.
pub fn name(self: *const Face, buf: []u8) Allocator.Error![]const u8 {
// We don't use this today but its possible the table below
// returns UTF-16 in which case we'd want to use this for conversion.
_ = buf;
const count = self.face.getSfntNameCount();
// We look for the font family entry.
for (0..count) |i| {
const entry = self.face.getSfntName(i) catch continue;
if (entry.name_id == freetype.c.TT_NAME_ID_FONT_FAMILY) {
return entry.string[0..entry.string_len];
const string = entry.string[0..entry.string_len];
// There are other encodings that are something other than UTF-8
// but this is one we've seen "in the wild" so far.
if (entry.platform_id == freetype.c.TT_PLATFORM_MICROSOFT and entry.encoding_id == freetype.c.TT_MS_ID_UNICODE_CS) skip: {
if (string.len % 2 != 0) break :skip;
if (string.len > 1024) break :skip;
var tmp: [512]u16 = undefined;
const max = string.len / 2;
for (@as([]const u16, @alignCast(@ptrCast(string))), 0..) |c, j| tmp[j] = @byteSwap(c);
const len = std.unicode.utf16LeToUtf8(buf, tmp[0..max]) catch return string;
return buf[0..len];
}
return string;
}
}