Skip to documentation
SLOP

tiny.filigree.font.gdef

Reference tiny.filigree font gdef

Defined in font.

API (8)

Actions

Public operations.

Types and contracts

Public types and contracts.

No direct callersNo direct callsfontgdef
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallstest sourcelib.filigree.src.font.facetest: GDEF reads mark attachment clas...private sourcelib.filigree.src.font.gdefglyphClassFromValuefont.gdef.GdefglyphClass
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallsprivate sourcelib.filigree.src.font.faceinitDirectoryImpltest sourcelib.filigree.src.font.facetest: GDEF reads mark attachment clas...test sourcelib.filigree.src.font.facetest: lookup filters use GDEF mark cl...private sourcelib.filigree.src.font.gdefgdefChildOffsetprivate sourcelib.filigree.src.font.gdefgdefChildOffset32private sourcelib.filigree.src.font.gdefreadGdefU16private sourcelib.filigree.src.font.gdefreadGdefU32private sourcelib.filigree.src.font.gdefvalidateGdefLigCaretList+2 morefont.gdef.Gdefinit
Static calls · unresolved targets: 1 · external targets: 1.
Called byCallsNo direct callersprivate sourcelib.filigree.src.font.gdefgdefChildOffsetprivate sourcelib.filigree.src.font.gdefgdefLigGlyphOffsetprivate sourcelib.filigree.src.font.gdefhasGdefBytesprivate sourcelib.filigree.src.font.gdefreadGdefCaretValueprivate sourcelib.filigree.src.font.gdefreadGdefU16font.gdef.GdefligatureCaret
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersprivate sourcelib.filigree.src.font.gdefgdefLigGlyphOffsetprivate sourcelib.filigree.src.font.gdefreadGdefU16font.gdef.GdefligatureCaretCount
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.filigree.src.font.facetest: GDEF reads mark attachment clas...font.gdef.GdefmarkAttachmentClass
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallstest sourcelib.filigree.src.font.facetest: GDEF reads mark attachment clas...private sourcelib.filigree.src.font.gdefgdefChildOffset32private sourcelib.filigree.src.font.gdefhasGdefBytesprivate sourcelib.filigree.src.font.gdefreadGdefU16private sourcelib.filigree.src.font.gdefreadGdefU32font.gdef.GdefmarkGlyphSetContains
Static calls · unresolved targets: 0 · external targets: 2.

Source: lib/filigree/src/font/gdef.zig

zig
const std = @import("std");const binary = @import("binary.zig");const layout = @import("../layout/root.zig");const model = @import("model.zig");const variations = @import("variations.zig");const FontError = model.FontError;const GlyphClass = model.GlyphClass;const LigatureCaret = model.LigatureCaret;const Table = binary.Table;const VariationSetting = model.VariationSetting;const DeltaSetIndex = variations.DeltaSetIndex;const ItemVariationStore = variations.ItemVariationStore;pub const Gdef = struct {    table: Table,    glyph_class_def_offset: ?usize,    mark_attach_class_def_offset: ?usize,    mark_glyph_sets_def_offset: ?usize,    lig_caret_list_offset: ?usize,    variation_store: ?ItemVariationStore,    pub fn init(data: []const u8, gdef_table: Table, axis_count: ?u16) FontError!Gdef {        const bytes = data[gdef_table.offset..][0..gdef_table.len];        if (bytes.len < 12) return error.InvalidGdef;        const major = try readGdefU16(bytes, 0);        const minor = try readGdefU16(bytes, 2);        if (major != 1 or (minor != 0 and minor != 2 and minor != 3)) return error.InvalidGdef;        if (minor == 2 and bytes.len < 14) return error.InvalidGdef;        if (minor == 3 and bytes.len < 18) return error.InvalidGdef;        const glyph_class_def_relative = try readGdefU16(bytes, 4);        const glyph_class_def_offset = if (glyph_class_def_relative == 0)            null        else            try gdefChildOffset(bytes, 0, glyph_class_def_relative, 2);        if (glyph_class_def_offset) |offset| {            _ = layout.ClassDef.init(bytes, offset) catch return error.InvalidGdef;        }        const lig_caret_list_relative = try readGdefU16(bytes, 8);        const lig_caret_list_offset = if (lig_caret_list_relative == 0)            null        else            try gdefChildOffset(bytes, 0, lig_caret_list_relative, 4);        if (lig_caret_list_offset) |offset| try validateGdefLigCaretList(bytes, offset);        const mark_attach_class_def_relative = try readGdefU16(bytes, 10);        const mark_attach_class_def_offset = if (mark_attach_class_def_relative == 0)            null        else            try gdefChildOffset(bytes, 0, mark_attach_class_def_relative, 2);        if (mark_attach_class_def_offset) |offset| {            _ = layout.ClassDef.init(bytes, offset) catch return error.InvalidGdef;        }        const mark_glyph_sets_def_offset = if (minor >= 2) blk: {            const relative = try readGdefU16(bytes, 12);            if (relative == 0) break :blk null;            const offset = try gdefChildOffset(bytes, 0, relative, 4);            try validateGdefMarkGlyphSets(bytes, offset);            break :blk offset;        } else null;        const variation_store = if (minor >= 3) blk: {            const relative = try readGdefU32(bytes, 14);            if (relative == 0) break :blk null;            const offset = try gdefChildOffset32(bytes, 0, relative, 8);            const variation_axis_count = axis_count orelse break :blk null;            const store_table = Table{                .offset = gdef_table.offset + offset,                .len = gdef_table.len - offset,            };            break :blk ItemVariationStore.init(data, store_table, variation_axis_count) catch return error.InvalidGdef;        } else null;        return .{            .table = gdef_table,            .glyph_class_def_offset = glyph_class_def_offset,            .mark_attach_class_def_offset = mark_attach_class_def_offset,            .mark_glyph_sets_def_offset = mark_glyph_sets_def_offset,            .lig_caret_list_offset = lig_caret_list_offset,            .variation_store = variation_store,        };    }    pub fn glyphClass(self: Gdef, data: []const u8, glyph_id: u32) FontError!GlyphClass {        const glyph_class_def_offset = self.glyph_class_def_offset orelse return .unknown;        const bytes = data[self.table.offset..][0..self.table.len];        const class_def = layout.ClassDef.init(bytes, glyph_class_def_offset) catch return error.InvalidGdef;        return glyphClassFromValue(class_def.class(bytes, glyph_id) catch return error.InvalidGdef);    }    pub fn markAttachmentClass(self: Gdef, data: []const u8, glyph_id: u32) FontError!u16 {        const mark_attach_class_def_offset = self.mark_attach_class_def_offset orelse return 0;        const bytes = data[self.table.offset..][0..self.table.len];        const class_def = layout.ClassDef.init(bytes, mark_attach_class_def_offset) catch return error.InvalidGdef;        return class_def.class(bytes, glyph_id) catch return error.InvalidGdef;    }    pub fn markGlyphSetContains(self: Gdef, data: []const u8, set_index: u16, glyph_id: u32) FontError!bool {        const mark_glyph_sets_def_offset = self.mark_glyph_sets_def_offset orelse return false;        const bytes = data[self.table.offset..][0..self.table.len];        if (try readGdefU16(bytes, mark_glyph_sets_def_offset) != 1) return error.InvalidGdef;        const set_count = try readGdefU16(bytes, mark_glyph_sets_def_offset + 2);        if (set_index >= set_count) return error.InvalidGdef;        const coverage_offsets = mark_glyph_sets_def_offset + 4;        if (!hasGdefBytes(bytes, coverage_offsets, @as(usize, set_count) * 4)) return error.InvalidGdef;        const coverage_relative = try readGdefU32(bytes, coverage_offsets + @as(usize, set_index) * 4);        const coverage_offset = try gdefChildOffset32(bytes, mark_glyph_sets_def_offset, coverage_relative, 2);        const coverage = layout.Coverage.init(bytes, coverage_offset) catch return error.InvalidGdef;        return (coverage.index(bytes, glyph_id) catch return error.InvalidGdef) != null;    }    pub fn ligatureCaretCount(self: Gdef, data: []const u8, glyph_id: u32) FontError!u16 {        const lig_caret_list_offset = self.lig_caret_list_offset orelse return 0;        const bytes = data[self.table.offset..][0..self.table.len];        const lig_glyph_offset = (try gdefLigGlyphOffset(bytes, lig_caret_list_offset, glyph_id)) orelse return 0;        return try readGdefU16(bytes, lig_glyph_offset);    }    pub fn ligatureCaret(self: Gdef, data: []const u8, glyph_id: u32, caret_index: usize) FontError!?LigatureCaret {        const lig_caret_list_offset = self.lig_caret_list_offset orelse return null;        const bytes = data[self.table.offset..][0..self.table.len];        const lig_glyph_offset = (try gdefLigGlyphOffset(bytes, lig_caret_list_offset, glyph_id)) orelse return null;        const caret_count = try readGdefU16(bytes, lig_glyph_offset);        if (caret_index >= caret_count) return null;        const caret_offsets = lig_glyph_offset + 2;        if (!hasGdefBytes(bytes, caret_offsets, @as(usize, caret_count) * 2)) return error.InvalidGdef;        const caret_value_offset = try gdefChildOffset(            bytes,            lig_glyph_offset,            try readGdefU16(bytes, caret_offsets + caret_index * 2),            2,        );        return try readGdefCaretValue(bytes, caret_value_offset);    }    pub fn variationDelta(self: Gdef, data: []const u8, face: anytype, settings: []const VariationSetting, index: DeltaSetIndex) FontError!i32 {        const store = self.variation_store orelse return 0;        return try store.delta(data, face, settings, index);    }};fn glyphClassFromValue(value: u16) GlyphClass {    return switch (value) {        1 => .base,        2 => .ligature,        3 => .mark,        4 => .component,        else => .unknown,    };}fn validateGdefLigCaretList(data: []const u8, lig_caret_list_offset: usize) FontError!void {    if (!hasGdefBytes(data, lig_caret_list_offset, 4)) return error.InvalidGdef;    const coverage_offset = try gdefChildOffset(data, lig_caret_list_offset, try readGdefU16(data, lig_caret_list_offset), 2);    _ = layout.Coverage.init(data, coverage_offset) catch return error.InvalidGdef;    const lig_glyph_count = try readGdefU16(data, lig_caret_list_offset + 2);    const lig_glyph_offsets = lig_caret_list_offset + 4;    if (!hasGdefBytes(data, lig_glyph_offsets, @as(usize, lig_glyph_count) * 2)) return error.InvalidGdef;    for (0..lig_glyph_count) |lig_glyph_index| {        const lig_glyph_offset = try gdefChildOffset(            data,            lig_caret_list_offset,            try readGdefU16(data, lig_glyph_offsets + lig_glyph_index * 2),            2,        );        const caret_count = try readGdefU16(data, lig_glyph_offset);        const caret_offsets = lig_glyph_offset + 2;        if (!hasGdefBytes(data, caret_offsets, @as(usize, caret_count) * 2)) return error.InvalidGdef;        for (0..caret_count) |caret_index| {            const caret_value_offset = try gdefChildOffset(                data,                lig_glyph_offset,                try readGdefU16(data, caret_offsets + caret_index * 2),                2,            );            _ = try readGdefCaretValue(data, caret_value_offset);        }    }}fn validateGdefMarkGlyphSets(data: []const u8, mark_glyph_sets_offset: usize) FontError!void {    if (!hasGdefBytes(data, mark_glyph_sets_offset, 4)) return error.InvalidGdef;    if (try readGdefU16(data, mark_glyph_sets_offset) != 1) return error.InvalidGdef;    const set_count = try readGdefU16(data, mark_glyph_sets_offset + 2);    const coverage_offsets = mark_glyph_sets_offset + 4;    if (!hasGdefBytes(data, coverage_offsets, @as(usize, set_count) * 4)) return error.InvalidGdef;    for (0..set_count) |set_index| {        const coverage_offset = try gdefChildOffset32(            data,            mark_glyph_sets_offset,            try readGdefU32(data, coverage_offsets + set_index * 4),            2,        );        _ = layout.Coverage.init(data, coverage_offset) catch return error.InvalidGdef;    }}fn gdefLigGlyphOffset(data: []const u8, lig_caret_list_offset: usize, glyph_id: u32) FontError!?usize {    if (!hasGdefBytes(data, lig_caret_list_offset, 4)) return error.InvalidGdef;    const coverage_offset = try gdefChildOffset(data, lig_caret_list_offset, try readGdefU16(data, lig_caret_list_offset), 2);    const coverage = layout.Coverage.init(data, coverage_offset) catch return error.InvalidGdef;    const coverage_index = (coverage.index(data, glyph_id) catch return error.InvalidGdef) orelse return null;    const lig_glyph_count = try readGdefU16(data, lig_caret_list_offset + 2);    if (coverage_index >= lig_glyph_count) return error.InvalidGdef;    const lig_glyph_offsets = lig_caret_list_offset + 4;    if (!hasGdefBytes(data, lig_glyph_offsets, @as(usize, lig_glyph_count) * 2)) return error.InvalidGdef;    return try gdefChildOffset(        data,        lig_caret_list_offset,        try readGdefU16(data, lig_glyph_offsets + @as(usize, coverage_index) * 2),        2,    );}fn readGdefCaretValue(data: []const u8, caret_value_offset: usize) FontError!?LigatureCaret {    const format = try readGdefU16(data, caret_value_offset);    return switch (format) {        1 => blk: {            if (!hasGdefBytes(data, caret_value_offset, 4)) return error.InvalidGdef;            break :blk .{ .coordinate = try readGdefI16(data, caret_value_offset + 2) };        },        2 => blk: {            if (!hasGdefBytes(data, caret_value_offset, 4)) return error.InvalidGdef;            break :blk null;        },        3 => blk: {            if (!hasGdefBytes(data, caret_value_offset, 6)) return error.InvalidGdef;            const coordinate = try readGdefI16(data, caret_value_offset + 2);            const device_offset = try readGdefU16(data, caret_value_offset + 4);            if (device_offset != 0) _ = try gdefChildOffset(data, caret_value_offset, device_offset, 2);            break :blk .{ .coordinate = coordinate };        },        else => error.InvalidGdef,    };}fn gdefChildOffset(data: []const u8, base: usize, relative_offset: u16, min_len: usize) FontError!usize {    const relative: usize = relative_offset;    if (relative == 0 or base > data.len or relative > data.len - base) return error.InvalidGdef;    const offset = base + relative;    if (!hasGdefBytes(data, offset, min_len)) return error.InvalidGdef;    return offset;}fn gdefChildOffset32(data: []const u8, base: usize, relative_offset: u32, min_len: usize) FontError!usize {    if (relative_offset == 0 or relative_offset > std.math.maxInt(usize)) return error.InvalidGdef;    const relative: usize = @intCast(relative_offset);    if (base > data.len or relative > data.len - base) return error.InvalidGdef;    const offset = base + relative;    if (!hasGdefBytes(data, offset, min_len)) return error.InvalidGdef;    return offset;}fn hasGdefBytes(data: []const u8, offset: usize, len: usize) bool {    return offset <= data.len and len <= data.len - offset;}fn readGdefU16(data: []const u8, offset: usize) FontError!u16 {    if (!hasGdefBytes(data, offset, 2)) return error.InvalidGdef;    return std.mem.readInt(u16, data[offset..][0..2], .big);}fn readGdefI16(data: []const u8, offset: usize) FontError!i16 {    return @bitCast(try readGdefU16(data, offset));}fn readGdefU32(data: []const u8, offset: usize) FontError!u32 {    if (!hasGdefBytes(data, offset, 4)) return error.InvalidGdef;    return std.mem.readInt(u32, data[offset..][0..4], .big);}test "GDEF child offsets stay inside table data" {    const data = @as([10]u8, @splat(0));    try std.testing.expectEqual(@as(usize, 6), try gdefChildOffset(&data, 2, 4, 2));    try std.testing.expectError(error.InvalidGdef, gdefChildOffset(&data, 2, 0, 2));    try std.testing.expectError(error.InvalidGdef, gdefChildOffset(&data, 10, 1, 2));    try std.testing.expectError(error.InvalidGdef, gdefChildOffset(&data, 8, 1, 2));}test "GDEF glyph class values map to public classes" {    try std.testing.expectEqual(GlyphClass.unknown, glyphClassFromValue(0));    try std.testing.expectEqual(GlyphClass.base, glyphClassFromValue(1));    try std.testing.expectEqual(GlyphClass.ligature, glyphClassFromValue(2));    try std.testing.expectEqual(GlyphClass.mark, glyphClassFromValue(3));    try std.testing.expectEqual(GlyphClass.component, glyphClassFromValue(4));    try std.testing.expectEqual(GlyphClass.unknown, glyphClassFromValue(5));}test "GDEF caret values read supported coordinate formats" {    const format_1 = [_]u8{        0, 1,        0, 250,    };    const format_2 = [_]u8{        0, 2,        0, 7,    };    const format_3 = [_]u8{        0,    3,        0xff, 0x9c,        0,    0,    };    try std.testing.expectEqual(@as(i16, 250), (try readGdefCaretValue(&format_1, 0)).?.coordinate);    try std.testing.expect((try readGdefCaretValue(&format_2, 0)) == null);    try std.testing.expectEqual(@as(i16, -100), (try readGdefCaretValue(&format_3, 0)).?.coordinate);    try std.testing.expectError(error.InvalidGdef, readGdefCaretValue(&[_]u8{ 0, 4 }, 0));}

Source: lib/filigree/src/font/root.zig:7

zig
pub const gdef = @import("gdef.zig");

Complete call list for font.gdef.Gdef.init

7 direct calls.

Audit

Definitions9
Public names9
Members6
Version26.7.0
Revisiondaab053ee433