Skip to documentation
SLOP

tiny.filigree.layout.class

Reference tiny.filigree layout class

Defined in layout.

API (3)

Types and contracts

Public types and contracts.

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

Source

Source: lib/filigree/src/layout/class.zig

zig
const std = @import("std");const binary = @import("binary.zig");const LayoutError = binary.LayoutError;const hasBytes = binary.hasBytes;const readU16 = binary.readU16;pub const ClassDef = union(enum) {    format_1: ClassDefFormat1,    format_2: ClassDefFormat2,    pub fn init(data: []const u8, offset: usize) LayoutError!ClassDef {        if (!hasBytes(data, offset, 2)) return error.InvalidLayout;        return switch (try readU16(data, offset)) {            1 => .{ .format_1 = try ClassDefFormat1.init(data, offset) },            2 => .{ .format_2 = try ClassDefFormat2.init(data, offset) },            else => error.UnsupportedClassDef,        };    }    pub fn class(self: ClassDef, data: []const u8, glyph_id: u32) LayoutError!u16 {        return switch (self) {            .format_1 => |format| format.class(data, glyph_id),            .format_2 => |format| format.class(data, glyph_id),        };    }};pub const ClassDefFormat1 = struct {    start_glyph_id: u16,    class_value_offset: usize,    glyph_count: u16,    fn init(data: []const u8, offset: usize) LayoutError!ClassDefFormat1 {        if (!hasBytes(data, offset, 6)) return error.InvalidLayout;        const glyph_count = try readU16(data, offset + 4);        const array_offset = offset + 6;        const array_len = @as(usize, glyph_count) * 2;        if (!hasBytes(data, array_offset, array_len)) return error.InvalidLayout;        return .{            .start_glyph_id = try readU16(data, offset + 2),            .class_value_offset = array_offset,            .glyph_count = glyph_count,        };    }    fn class(self: ClassDefFormat1, data: []const u8, glyph_id: u32) LayoutError!u16 {        if (glyph_id > std.math.maxInt(u16)) return 0;        const glyph: u16 = @intCast(glyph_id);        if (glyph < self.start_glyph_id) return 0;        const index = @as(usize, glyph - self.start_glyph_id);        if (index >= self.glyph_count) return 0;        return try readU16(data, self.class_value_offset + index * 2);    }};pub const ClassDefFormat2 = struct {    class_range_array_offset: usize,    class_range_count: u16,    fn init(data: []const u8, offset: usize) LayoutError!ClassDefFormat2 {        if (!hasBytes(data, offset, 4)) return error.InvalidLayout;        const range_count = try readU16(data, offset + 2);        const array_offset = offset + 4;        const array_len = @as(usize, range_count) * 6;        if (!hasBytes(data, array_offset, array_len)) return error.InvalidLayout;        var previous_end: ?u16 = null;        for (0..range_count) |i| {            const record = array_offset + i * 6;            const start = try readU16(data, record);            const end = try readU16(data, record + 2);            if (start > end) return error.InvalidLayout;            if (previous_end) |seen| {                if (start <= seen) return error.InvalidLayout;            }            previous_end = end;        }        return .{            .class_range_array_offset = array_offset,            .class_range_count = range_count,        };    }    fn class(self: ClassDefFormat2, data: []const u8, glyph_id: u32) LayoutError!u16 {        if (glyph_id > std.math.maxInt(u16)) return 0;        const glyph: u16 = @intCast(glyph_id);        var left: usize = 0;        var right: usize = self.class_range_count;        while (left < right) {            const mid = left + (right - left) / 2;            const record = self.class_range_array_offset + mid * 6;            const start = try readU16(data, record);            const end = try readU16(data, record + 2);            if (glyph < start) {                right = mid;            } else if (glyph > end) {                left = mid + 1;            } else {                return try readU16(data, record + 4);            }        }        return 0;    }};test "ClassDef format 1 maps consecutive glyph classes" {    const data = [_]u8{        0, 1,        0, 5,        0, 3,        0, 1,        0, 7,        0, 2,    };    const class_def = try ClassDef.init(&data, 0);    try std.testing.expectEqual(@as(u16, 0), try class_def.class(&data, 4));    try std.testing.expectEqual(@as(u16, 1), try class_def.class(&data, 5));    try std.testing.expectEqual(@as(u16, 7), try class_def.class(&data, 6));    try std.testing.expectEqual(@as(u16, 2), try class_def.class(&data, 7));    try std.testing.expectEqual(@as(u16, 0), try class_def.class(&data, 8));}test "ClassDef format 2 maps class ranges" {    const data = [_]u8{        0, 2,        0, 2,        0, 10,        0, 12,        0, 4,        0, 30,        0, 31,        0, 8,    };    const class_def = try ClassDef.init(&data, 0);    try std.testing.expectEqual(@as(u16, 4), try class_def.class(&data, 10));    try std.testing.expectEqual(@as(u16, 4), try class_def.class(&data, 12));    try std.testing.expectEqual(@as(u16, 8), try class_def.class(&data, 31));    try std.testing.expectEqual(@as(u16, 0), try class_def.class(&data, 13));    try std.testing.expectEqual(@as(u16, 0), try class_def.class(&data, 0x1_0000));}test "ClassDef honors nonzero table offsets" {    const data = [_]u8{        0xaa, 0xbb,        0,    1,        0,    7,        0,    1,        0,    5,    };    const class_def = try ClassDef.init(&data, 2);    try std.testing.expectEqual(@as(u16, 5), try class_def.class(&data, 7));}test "ClassDef rejects unsupported format" {    const data = [_]u8{ 0, 3 };    try std.testing.expectError(error.UnsupportedClassDef, ClassDef.init(&data, 0));}

Source: lib/filigree/src/layout/root.zig:2

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

Audit

Definitions3
Public names5
Members5
Version26.7.0
Revisiondaab053ee433