Compare commits

...

1 Commits

Author SHA1 Message Date
af5f035830 media: stbtt kerning table iterator 2026-09-20 15:42:19 +02:00
2 changed files with 77 additions and 0 deletions

View File

@@ -100,6 +100,12 @@ const import = struct {
padding: u8,
};
const stbtt_kerning_table_iterator = extern struct {
data: [*]u8,
k: c_int,
length: c_int,
};
extern fn stbtt_GetNumberOfFonts(data: [*]const u8) c_int;
extern fn stbtt_GetFontOffsetForIndex(index: c_int, data: [*]const u8) c_int;
extern fn stbtt_InitFont(info: *stbtt_fontinfo, data: [*]const u8, offset: c_int) c_int;
@@ -117,6 +123,8 @@ const import = struct {
extern fn stbtt_UnitsPerEm(info: *const stbtt_fontinfo) c_int;
extern fn stbtt_GetFontCapHeight(info: *const stbtt_fontinfo, capHeight: ?*c_int) c_int;
extern fn stbtt_KerningTableIterator(info: *const stbtt_fontinfo, it: *stbtt_kerning_table_iterator) void;
extern fn stbtt_KerningTableNext(it: *stbtt_kerning_table_iterator, entry: *stbtt_kerningentry) c_int;
};
pub fn initFont(self: *Self, data: []const u8) !*Font {
@@ -212,6 +220,13 @@ pub const Font = opaque {
return null;
}
pub fn kerningTableIterator(self: *const Font) KerningTableIterator {
const info = @as(*const import.stbtt_fontinfo, @ptrCast(@alignCast(self)));
var it: import.stbtt_kerning_table_iterator = undefined;
import.stbtt_KerningTableIterator(info, &it);
return .{ .it = it };
}
test "refAllDecls" {
std.testing.refAllDecls(@This());
}
@@ -229,6 +244,25 @@ pub const GlyphMetrics = struct {
left_side_bearing: i16,
};
pub const KerningTableEntry = struct {
glyph_prev: u16,
glyph_next: u16,
advance: i16,
};
pub const KerningTableIterator = struct {
it: import.stbtt_kerning_table_iterator,
pub fn next(self: *KerningTableIterator) ?KerningTableEntry {
var entry: import.stbtt_kerningentry = undefined;
return if (import.stbtt_KerningTableNext(&self.it, &entry) != 0) .{
.glyph_prev = @intCast(entry.glyph1),
.glyph_next = @intCast(entry.glyph2),
.advance = @intCast(entry.advance),
} else null;
}
};
// --- MALLOC INTERFACE --------------------------------------------------------
export fn castle_media_stbtt_malloc(self: *Self, size: usize) callconv(.c) VoidPtr {

View File

@@ -22,3 +22,46 @@ STBTT_DEF int stbtt_GetFontCapHeight(const stbtt_fontinfo *info, int *capHeight)
if (capHeight) *capHeight = ttSHORT(info->data+tab + 88);
return 1;
}
typedef struct stbtt_kerning_table_iterator {
stbtt_uint8 *data;
int k;
int length;
} stbtt_kerning_table_iterator;
STBTT_DEF void stbtt_KerningTableIterator(const stbtt_fontinfo *info, stbtt_kerning_table_iterator *it)
{
stbtt_uint8 *data = info->data + info->kern;
it->data = data;
it->k = 0;
it->length = 0;
if (!info->kern)
return;
if (ttUSHORT(data+2) < 1) // number of tables, need at least 1
return;
if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format
return;
it->length = ttUSHORT(data+10);
}
STBTT_DEF int stbtt_KerningTableNext(stbtt_kerning_table_iterator *it, stbtt_kerningentry *entry)
{
stbtt_uint8 *data = it->data;
int k = it->k;
int length = it->length;
if (k < length)
{
entry->glyph1 = ttUSHORT(data+18+(k*6));
entry->glyph2 = ttUSHORT(data+20+(k*6));
entry->advance = ttSHORT(data+22+(k*6));
it->k += 1;
return 1;
}
return 0;
}