tiny.filigree.font.names
Defined in font.
API (3)
Actions
Public operations.
Types and contracts
Public types and contracts.
Source
Source: lib/filigree/src/font/names.zig
zig
const std = @import("std");const binary = @import("binary.zig");const model = @import("model.zig");const FontError = model.FontError;const Table = binary.Table;const readU16 = binary.readU16;pub const NameRecordBytes = struct { platform_id: u16, encoding_id: u16, language_id: u16, name_id: u16, bytes: []const u8,};pub fn bestNameRecord(data: []const u8, name_table: Table, name_id: u16) FontError!?NameRecordBytes { if (name_table.len < 6) return error.InvalidFont; const version = try readU16(data, name_table.offset); if (version != 0 and version != 1) return error.InvalidFont; const count = try readU16(data, name_table.offset + 2); const storage_offset = try readU16(data, name_table.offset + 4); const records_offset = name_table.offset + 6; if (@as(u64, count) * 12 > @as(u64, name_table.len - 6)) return error.InvalidFont; if (storage_offset > name_table.len) return error.InvalidFont; var best_score: u16 = 0; var best: ?NameRecordBytes = null; for (0..count) |record_index| { const record_offset = records_offset + record_index * 12; const platform_id = try readU16(data, record_offset); const encoding_id = try readU16(data, record_offset + 2); const language_id = try readU16(data, record_offset + 4); const current_name_id = try readU16(data, record_offset + 6); if (current_name_id != name_id) continue; const len = try readU16(data, record_offset + 8); const relative = try readU16(data, record_offset + 10); if (!nameRecordIsUtf16(platform_id, encoding_id)) continue; if (relative > name_table.len - storage_offset) return error.InvalidFont; const storage_start = name_table.offset + storage_offset; const start = storage_start + @as(usize, relative); const storage_remaining = name_table.len - storage_offset - @as(usize, relative); if (@as(usize, len) > storage_remaining) return error.InvalidFont; if (len % 2 != 0) return error.InvalidFont; const score = nameRecordScore(platform_id, encoding_id, language_id); if (score <= best_score) continue; best_score = score; best = .{ .platform_id = platform_id, .encoding_id = encoding_id, .language_id = language_id, .name_id = current_name_id, .bytes = data[start..][0..len], }; } return best;}pub fn utf16BeToUtf8Alloc(allocator: std.mem.Allocator, bytes: []const u8) ![]u8 { var utf8_len: usize = 0; var read_index: usize = 0; while (read_index < bytes.len) { const codepoint = try readUtf16BeScalar(bytes, &read_index); utf8_len += try std.unicode.utf8CodepointSequenceLength(codepoint); } const result = try allocator.alloc(u8, utf8_len); errdefer allocator.free(result); var write_index: usize = 0; read_index = 0; while (read_index < bytes.len) { const codepoint = try readUtf16BeScalar(bytes, &read_index); write_index += try std.unicode.utf8Encode(codepoint, result[write_index..]); } return result;}fn nameRecordIsUtf16(platform_id: u16, encoding_id: u16) bool { return platform_id == 0 or (platform_id == 3 and (encoding_id == 1 or encoding_id == 10));}fn nameRecordScore(platform_id: u16, encoding_id: u16, language_id: u16) u16 { if (platform_id == 3 and encoding_id == 10 and language_id == 0x0409) return 500; if (platform_id == 3 and encoding_id == 1 and language_id == 0x0409) return 450; if (platform_id == 3 and encoding_id == 10) return 400; if (platform_id == 3 and encoding_id == 1) return 350; if (platform_id == 0) return 300; return 0;}fn readUtf16BeScalar(bytes: []const u8, index: *usize) FontError!u21 { const unit = try readUtf16BeUnit(bytes, index.*); index.* += 2; if (unit >= 0xd800 and unit <= 0xdbff) { if (index.* >= bytes.len) return error.InvalidFont; const low = try readUtf16BeUnit(bytes, index.*); if (low < 0xdc00 or low > 0xdfff) return error.InvalidFont; index.* += 2; return @intCast(0x10000 + (((@as(u32, unit) - 0xd800) << 10) | (@as(u32, low) - 0xdc00))); } if (unit >= 0xdc00 and unit <= 0xdfff) return error.InvalidFont; return @intCast(unit);}fn readUtf16BeUnit(bytes: []const u8, offset: usize) FontError!u16 { if (offset > bytes.len or bytes.len - offset < 2) return error.InvalidFont; return std.mem.readInt(u16, bytes[offset..][0..2], .big);}Source: lib/filigree/src/font/root.zig:15
zig
pub const names = @import("names.zig");Audit
| Definitions | 4 |
|---|---|
| Public names | 4 |
| Members | 5 |
| Version | 26.7.0 |
| Revision | daab053ee433 |