diff --git a/freetype/build.zig b/freetype/build.zig index 577036b7..a7b93c92 100644 --- a/freetype/build.zig +++ b/freetype/build.zig @@ -4,27 +4,37 @@ const Builder = std.build.Builder; const ft_root = thisDir() ++ "/upstream/freetype"; const ft_include_path = ft_root ++ "/include"; const hb_root = thisDir() ++ "/upstream/harfbuzz"; -const hb_include_path = ft_root ++ "/src"; +const hb_include_path = hb_root ++ "/src"; + +const utils_pkg = std.build.Pkg{ + .name = "utils", + .source = .{ .path = thisDir() ++ "/src/utils.zig" }, +}; pub const pkg = std.build.Pkg{ .name = "freetype", .source = .{ .path = thisDir() ++ "/src/freetype/main.zig" }, + .dependencies = &.{utils_pkg}, }; + pub const harfbuzz_pkg = std.build.Pkg{ .name = "harfbuzz", .source = .{ .path = thisDir() ++ "/src/harfbuzz/main.zig" }, + .dependencies = &.{utils_pkg}, }; pub const Options = struct { harfbuzz: ?HarfbuzzOptions = null, freetype: FreetypeOptions = .{}, }; + pub const FreetypeOptions = struct { /// the path you specify freetype options /// via `ftoptions.h` and `ftmodule.h` /// e.g `test/ft/` ft_config_path: ?[]const u8 = null, }; + pub const HarfbuzzOptions = struct {}; pub fn build(b: *std.build.Builder) !void { @@ -34,8 +44,15 @@ pub fn build(b: *std.build.Builder) !void { const freetype_tests = b.addTestSource(pkg.source); freetype_tests.setBuildMode(mode); freetype_tests.setTarget(target); + freetype_tests.addPackage(utils_pkg); link(b, freetype_tests, .{}); + const harfbuzz_tests = b.addTestSource(harfbuzz_pkg.source); + harfbuzz_tests.setBuildMode(mode); + harfbuzz_tests.setTarget(target); + harfbuzz_tests.addPackage(utils_pkg); + link(b, harfbuzz_tests, .{ .harfbuzz = .{} }); + const main_tests = b.addTest("test/main.zig"); main_tests.setBuildMode(mode); main_tests.setTarget(target); @@ -44,6 +61,7 @@ pub fn build(b: *std.build.Builder) !void { const test_step = b.step("test", "Run library tests"); test_step.dependOn(&freetype_tests.step); + test_step.dependOn(&harfbuzz_tests.step); test_step.dependOn(&main_tests.step); inline for ([_][]const u8{ @@ -80,6 +98,7 @@ pub fn link(b: *Builder, step: *std.build.LibExeObjStep, options: Options) void const hb_lib = buildHarfbuzz(b, step, hb_options); hb_lib.linkLibrary(ft_lib); step.linkLibrary(hb_lib); + step.addIncludePath(hb_include_path); } } diff --git a/freetype/src/freetype/Face.zig b/freetype/src/freetype/Face.zig index 1f7d7b6f..04388b01 100644 --- a/freetype/src/freetype/Face.zig +++ b/freetype/src/freetype/Face.zig @@ -1,6 +1,6 @@ const std = @import("std"); +const utils = @import("utils"); const c = @import("c.zig"); -const utils = @import("utils.zig"); const intToError = @import("error.zig").intToError; const Error = @import("error.zig").Error; const GlyphSlot = @import("freetype.zig").GlyphSlot; diff --git a/freetype/src/freetype/color.zig b/freetype/src/freetype/color.zig index 86887666..dbd1ffd8 100644 --- a/freetype/src/freetype/color.zig +++ b/freetype/src/freetype/color.zig @@ -1,5 +1,5 @@ +const utils = @import("utils"); const c = @import("c.zig"); -const utils = @import("utils.zig"); const Face = @import("freetype.zig").Face; pub const Color = c.FT_Color; diff --git a/freetype/src/freetype/freetype.zig b/freetype/src/freetype/freetype.zig index fc777465..080e2d36 100644 --- a/freetype/src/freetype/freetype.zig +++ b/freetype/src/freetype/freetype.zig @@ -1,6 +1,6 @@ const std = @import("std"); +const utils = @import("utils"); const c = @import("c.zig"); -const utils = @import("utils.zig"); const intToError = @import("error.zig").intToError; const Error = @import("error.zig").Error; const Generic = @import("types.zig").Generic; diff --git a/freetype/src/freetype/main.zig b/freetype/src/freetype/main.zig index a6f3b65e..7fd74105 100644 --- a/freetype/src/freetype/main.zig +++ b/freetype/src/freetype/main.zig @@ -8,31 +8,17 @@ pub const Glyph = @import("Glyph.zig"); pub const Stroker = @import("Stroker.zig"); pub const Error = @import("error.zig").Error; -const std = @import("std"); - -fn refLiterallyAllDecls(comptime T: type) void { - switch (@typeInfo(T)) { - .Struct, .Union, .Opaque, .Enum => { - inline for (comptime std.meta.declarations(T)) |decl| { - if (decl.is_pub) { - refLiterallyAllDecls(@TypeOf(@field(T, decl.name))); - std.testing.refAllDecls(T); - } - } - }, - else => {}, - } -} +const utils = @import("utils"); test { - refLiterallyAllDecls(@This()); - refLiterallyAllDecls(@import("color.zig")); - refLiterallyAllDecls(@import("error.zig")); - refLiterallyAllDecls(@import("utils.zig")); - refLiterallyAllDecls(@import("Face.zig")); - refLiterallyAllDecls(@import("GlyphSlot.zig")); - refLiterallyAllDecls(@import("Library.zig")); - refLiterallyAllDecls(@import("Outline.zig")); - refLiterallyAllDecls(Glyph); - refLiterallyAllDecls(Stroker); + utils.refAllDecls(@This()); + utils.refAllDecls(@import("color.zig")); + utils.refAllDecls(@import("error.zig")); + utils.refAllDecls(@import("utils")); + utils.refAllDecls(@import("Face.zig")); + utils.refAllDecls(@import("GlyphSlot.zig")); + utils.refAllDecls(@import("Library.zig")); + utils.refAllDecls(@import("Outline.zig")); + utils.refAllDecls(Glyph); + utils.refAllDecls(Stroker); } diff --git a/freetype/src/harfbuzz/blob.zig b/freetype/src/harfbuzz/blob.zig new file mode 100644 index 00000000..daafc4ec --- /dev/null +++ b/freetype/src/harfbuzz/blob.zig @@ -0,0 +1,95 @@ +const std = @import("std"); +const c = @import("c.zig"); + +pub const MemoryMode = enum(u2) { + duplicate = c.HB_MEMORY_MODE_DUPLICATE, + readonly = c.HB_MEMORY_MODE_READONLY, + writable = c.HB_MEMORY_MODE_WRITABLE, + readonly_may_make_writable = c.HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE, +}; + +pub const Blob = struct { + handle: *c.hb_blob_t, + + pub fn init(data: []u8, mode: MemoryMode) ?Blob { + return Blob{ + .handle = c.hb_blob_create_or_fail(data.ptr, @intCast(c_uint, data.len), @enumToInt(mode), null, null) orelse return null, + }; + } + + pub fn initOrEmpty(data: []u8, mode: MemoryMode) Blob { + return .{ + .handle = c.hb_blob_create(data.ptr, @intCast(c_uint, data.len), @enumToInt(mode), null, null).?, + }; + } + + pub fn initFromFile(path: [*:0]const u8) ?Blob { + return Blob{ + .handle = c.hb_blob_create_from_file_or_fail(path) orelse return null, + }; + } + + pub fn initFromFileOrEmpty(path: [*:0]const u8) Blob { + return .{ + .handle = c.hb_blob_create_from_file(path).?, + }; + } + + pub fn getEmpty() Blob { + return .{ .handle = c.hb_blob_get_empty().? }; + } + + pub fn createSubBlobOrEmpty(self: Blob, offset: u32, len: u32) Blob { + return .{ + .handle = c.hb_blob_create_sub_blob(self.handle, offset, len).?, + }; + } + + pub fn copyWritable(self: Blob) ?Blob { + return Blob{ + .handle = c.hb_blob_copy_writable_or_fail(self.handle) orelse return null, + }; + } + + pub fn deinit(self: Blob) void { + c.hb_blob_destroy(self.handle); + } + + pub fn getData(self: Blob, len: ?u32) []const u8 { + var l = len; + const data = c.hb_blob_get_data(self.handle, if (l) |_| &l.? else null); + return if (l) |_| + data[0..l.?] + else + std.mem.sliceTo(data, 0); + } + + pub fn getDataWritable(self: Blob, len: ?u32) ?[]const u8 { + var l = len; + const data = c.hb_blob_get_data(self.handle, if (l) |_| &l.? else null); + return if (data == null) + null + else if (l) |_| + data[0..l.?] + else + std.mem.sliceTo(data, 0); + } + + pub fn getLength(self: Blob) u32 { + return c.hb_blob_get_length(self.handle); + } + + pub fn isImmutable(self: Blob) bool { + return c.hb_blob_is_immutable(self.handle) > 0; + } + + pub fn makeImmutable(self: Blob) void { + c.hb_blob_make_immutable(self.handle); + } + + pub fn reference(self: Blob) Blob { + return .{ + .handle = c.hb_blob_reference(self.handle).?, + }; + } +}; diff --git a/freetype/src/harfbuzz/buffer.zig b/freetype/src/harfbuzz/buffer.zig new file mode 100644 index 00000000..5d6a2f32 --- /dev/null +++ b/freetype/src/harfbuzz/buffer.zig @@ -0,0 +1,157 @@ +const std = @import("std"); +const utils = @import("utils"); +const c = @import("c.zig"); +const Direction = @import("common.zig").Direction; +const Script = @import("common.zig").Script; +const Language = @import("common.zig").Language; + +pub const ContentType = enum(u2) { + invalid = c.HB_BUFFER_CONTENT_TYPE_INVALID, + unicode = c.HB_BUFFER_CONTENT_TYPE_UNICODE, + glyphs = c.HB_BUFFER_CONTENT_TYPE_GLYPHS, +}; + +pub const Buffer = struct { + pub const Flags = packed struct { + bot: bool = false, + eot: bool = false, + preserve_default_ignorables: bool = false, + remove_default_ignorables: bool = false, + do_not_insert_dotted_circle: bool = false, + verify: bool = false, + produce_unsafe_to_concat: bool = false, + + pub const Flag = enum(u21) { + bot = c.HB_BUFFER_FLAG_BOT, + eot = c.HB_BUFFER_FLAG_EOT, + preserve_default_ignorables = c.HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES, + remove_default_ignorables = c.HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES, + do_not_insert_dotted_circle = c.HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE, + verify = c.HB_BUFFER_FLAG_VERIFY, + produce_unsafe_to_concat = c.HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT, + }; + + pub fn from(bits: u21) Flags { + return utils.bitFieldsToStruct(Flags, Flag, bits); + } + + pub fn cast(flags: Flags) u21 { + return utils.structToBitFields(u21, Flag, flags); + } + }; + + handle: *c.hb_buffer_t, + + pub fn init() ?Buffer { + var b = c.hb_buffer_create(); + if (c.hb_buffer_allocation_successful(b) < 1) + return null; + return Buffer{ .handle = b.? }; + } + + pub fn getEmpty() Buffer { + return .{ .handle = c.hb_buffer_get_empty().? }; + } + + pub fn initSimilar(self: Buffer) ?Buffer { + var b = c.hb_buffer_create_similar(self.handle); + if (c.hb_buffer_allocation_successful(b) < 1) + return null; + return Buffer{ .handle = b.? }; + } + + pub fn reference(self: Buffer) Buffer { + return .{ + .handle = c.hb_buffer_reference(self.handle).?, + }; + } + + pub fn deinit(self: Buffer) void { + c.hb_buffer_destroy(self.handle); + } + + pub fn reset(self: Buffer) void { + c.hb_buffer_reset(self.handle); + } + + pub fn clearContents(self: Buffer) void { + c.hb_buffer_clear_contents(self.handle); + } + + pub fn preAllocate(self: Buffer, size: u32) error{OutOfMemory}!void { + if (c.hb_buffer_pre_allocate(self.handle, size) < 1) + return error.OutOfMemory; + } + + pub fn allocationSuccessful(self: Buffer) bool { + return c.hb_buffer_allocation_successful(self.handle) > 0; + } + + pub fn add(self: Buffer, codepoint: u32, cluster: usize) void { + c.hb_buffer_add(self.handle, codepoint, @intCast(c_uint, cluster)); + } + + pub fn addCodepoints(self: Buffer, text: []const u32, item_offset: usize, item_length: usize) void { + c.hb_buffer_add_codepoints(self.handle, text.ptr, @intCast(c_int, text.len), @intCast(c_uint, item_offset), @intCast(c_int, item_length)); + } + + pub fn addUTF32(self: Buffer, text: []const u32, item_offset: usize, item_length: usize) void { + c.hb_buffer_add_utf32(self.handle, text.ptr, @intCast(c_int, text.len), @intCast(c_uint, item_offset), @intCast(c_int, item_length)); + } + + pub fn addUTF16(self: Buffer, text: []const u16, item_offset: usize, item_length: usize) void { + c.hb_buffer_add_utf16(self.handle, text.ptr, @intCast(c_int, text.len), @intCast(c_uint, item_offset), @intCast(c_int, item_length)); + } + + pub fn addUTF8(self: Buffer, text: []const u8, item_offset: usize, item_length: usize) void { + c.hb_buffer_add_utf8(self.handle, text.ptr, @intCast(c_int, text.len), @intCast(c_uint, item_offset), @intCast(c_int, item_length)); + } + + pub fn addLatin1(self: Buffer, text: []const u8, item_offset: usize, item_length: usize) void { + c.hb_buffer_add_latin1(self.handle, text.ptr, @intCast(c_int, text.len), @intCast(c_uint, item_offset), @intCast(c_int, item_length)); + } + + pub fn append(self: Buffer, source: Buffer, start: usize, end: usize) void { + c.hb_buffer_append(self.handle, source.handle, @intCast(c_uint, start), @intCast(c_uint, end)); + } + + pub fn setContentType(self: Buffer, content_type: ContentType) void { + c.hb_buffer_set_content_type(self.handle, @enumToInt(content_type)); + } + + pub fn getContentType(self: Buffer) ContentType { + return @intToEnum(ContentType, c.hb_buffer_get_content_type(self.handle)); + } + + pub fn setDirection(self: Buffer, direction: Direction) void { + c.hb_buffer_set_direction(self.handle, @enumToInt(direction)); + } + + pub fn getDirection(self: Buffer) Direction { + return @intToEnum(Direction, c.hb_buffer_get_direction(self.handle)); + } + + pub fn setScript(self: Buffer, script: Script) void { + c.hb_buffer_set_script(self.handle, @enumToInt(script)); + } + + pub fn getScript(self: Buffer) Script { + return @intToEnum(Script, c.hb_buffer_get_script(self.handle)); + } + + pub fn setLanguage(self: Buffer, lang: Language) void { + c.hb_buffer_set_language(self.handle, @enumToInt(lang)); + } + + pub fn getLanguage(self: Buffer) Language { + return @intToEnum(Language, c.hb_buffer_get_language(self.handle)); + } + + pub fn setFlags(self: Buffer, flags: Flags) void { + c.hb_buffer_set_flags(self.handle, flags.cast()); + } + + pub fn getFlags(self: Buffer) Flags { + return Flags.from(c.hb_buffer_get_flags(self.handle)); + } +}; diff --git a/freetype/src/harfbuzz/c.zig b/freetype/src/harfbuzz/c.zig new file mode 100644 index 00000000..246f4c3d --- /dev/null +++ b/freetype/src/harfbuzz/c.zig @@ -0,0 +1,3 @@ +pub usingnamespace @cImport({ + @cInclude("hb.h"); +}); diff --git a/freetype/src/harfbuzz/common.zig b/freetype/src/harfbuzz/common.zig new file mode 100644 index 00000000..896f824f --- /dev/null +++ b/freetype/src/harfbuzz/common.zig @@ -0,0 +1,191 @@ +const std = @import("std"); +const c = @import("c.zig"); + +pub const Direction = enum(u3) { + invalid = c.HB_DIRECTION_INVALID, + ltr = c.HB_DIRECTION_LTR, + rtl = c.HB_DIRECTION_RTL, + ttb = c.HB_DIRECTION_TTB, + bit = c.HB_DIRECTION_BTT, +}; + +pub const Script = enum(u31) { + common = c.HB_SCRIPT_COMMON, + inherited = c.HB_SCRIPT_INHERITED, + unknown = c.HB_SCRIPT_UNKNOWN, + arabic = c.HB_SCRIPT_ARABIC, + armenian = c.HB_SCRIPT_ARMENIAN, + bengali = c.HB_SCRIPT_BENGALI, + cyrillic = c.HB_SCRIPT_CYRILLIC, + devanagari = c.HB_SCRIPT_DEVANAGARI, + georgian = c.HB_SCRIPT_GEORGIAN, + greek = c.HB_SCRIPT_GREEK, + gujarati = c.HB_SCRIPT_GUJARATI, + gurmukhi = c.HB_SCRIPT_GURMUKHI, + hangul = c.HB_SCRIPT_HANGUL, + han = c.HB_SCRIPT_HAN, + hebrew = c.HB_SCRIPT_HEBREW, + hiragana = c.HB_SCRIPT_HIRAGANA, + kannada = c.HB_SCRIPT_KANNADA, + katakana = c.HB_SCRIPT_KATAKANA, + lao = c.HB_SCRIPT_LAO, + latin = c.HB_SCRIPT_LATIN, + malayalam = c.HB_SCRIPT_MALAYALAM, + oriya = c.HB_SCRIPT_ORIYA, + tamil = c.HB_SCRIPT_TAMIL, + telugu = c.HB_SCRIPT_TELUGU, + thai = c.HB_SCRIPT_THAI, + tibetan = c.HB_SCRIPT_TIBETAN, + bopomofo = c.HB_SCRIPT_BOPOMOFO, + braille = c.HB_SCRIPT_BRAILLE, + canadian_syllabics = c.HB_SCRIPT_CANADIAN_SYLLABICS, + cherokee = c.HB_SCRIPT_CHEROKEE, + ethiopic = c.HB_SCRIPT_ETHIOPIC, + khmer = c.HB_SCRIPT_KHMER, + mongolian = c.HB_SCRIPT_MONGOLIAN, + myanmar = c.HB_SCRIPT_MYANMAR, + ogham = c.HB_SCRIPT_OGHAM, + runic = c.HB_SCRIPT_RUNIC, + sinhala = c.HB_SCRIPT_SINHALA, + syriac = c.HB_SCRIPT_SYRIAC, + thaana = c.HB_SCRIPT_THAANA, + yi = c.HB_SCRIPT_YI, + deseret = c.HB_SCRIPT_DESERET, + gothic = c.HB_SCRIPT_GOTHIC, + old_italic = c.HB_SCRIPT_OLD_ITALIC, + buhid = c.HB_SCRIPT_BUHID, + hanunoo = c.HB_SCRIPT_HANUNOO, + tagalog = c.HB_SCRIPT_TAGALOG, + tagbanwa = c.HB_SCRIPT_TAGBANWA, + cypriot = c.HB_SCRIPT_CYPRIOT, + limbu = c.HB_SCRIPT_LIMBU, + linear_b = c.HB_SCRIPT_LINEAR_B, + osmanya = c.HB_SCRIPT_OSMANYA, + shavian = c.HB_SCRIPT_SHAVIAN, + tai_le = c.HB_SCRIPT_TAI_LE, + ugaritic = c.HB_SCRIPT_UGARITIC, + buginese = c.HB_SCRIPT_BUGINESE, + coptic = c.HB_SCRIPT_COPTIC, + glagolitic = c.HB_SCRIPT_GLAGOLITIC, + kharoshthi = c.HB_SCRIPT_KHAROSHTHI, + new_tai_lue = c.HB_SCRIPT_NEW_TAI_LUE, + old_persian = c.HB_SCRIPT_OLD_PERSIAN, + syloti_nagri = c.HB_SCRIPT_SYLOTI_NAGRI, + tifinagh = c.HB_SCRIPT_TIFINAGH, + balinese = c.HB_SCRIPT_BALINESE, + cuneiform = c.HB_SCRIPT_CUNEIFORM, + nko = c.HB_SCRIPT_NKO, + phags_pa = c.HB_SCRIPT_PHAGS_PA, + phoenician = c.HB_SCRIPT_PHOENICIAN, + carian = c.HB_SCRIPT_CARIAN, + cham = c.HB_SCRIPT_CHAM, + kayah_li = c.HB_SCRIPT_KAYAH_LI, + lepcha = c.HB_SCRIPT_LEPCHA, + lycian = c.HB_SCRIPT_LYCIAN, + lydian = c.HB_SCRIPT_LYDIAN, + ol_chiki = c.HB_SCRIPT_OL_CHIKI, + rejang = c.HB_SCRIPT_REJANG, + saurashtra = c.HB_SCRIPT_SAURASHTRA, + sundanese = c.HB_SCRIPT_SUNDANESE, + vai = c.HB_SCRIPT_VAI, + avestan = c.HB_SCRIPT_AVESTAN, + bamum = c.HB_SCRIPT_BAMUM, + egyptian_hieroglyphs = c.HB_SCRIPT_EGYPTIAN_HIEROGLYPHS, + imperial_aramaic = c.HB_SCRIPT_IMPERIAL_ARAMAIC, + inscriptional_pahlavi = c.HB_SCRIPT_INSCRIPTIONAL_PAHLAVI, + inscriptional_parthian = c.HB_SCRIPT_INSCRIPTIONAL_PARTHIAN, + javanese = c.HB_SCRIPT_JAVANESE, + kaithi = c.HB_SCRIPT_KAITHI, + lisu = c.HB_SCRIPT_LISU, + meetei_mayek = c.HB_SCRIPT_MEETEI_MAYEK, + old_south_arabian = c.HB_SCRIPT_OLD_SOUTH_ARABIAN, + old_turkic = c.HB_SCRIPT_OLD_TURKIC, + samaritan = c.HB_SCRIPT_SAMARITAN, + tai_tham = c.HB_SCRIPT_TAI_THAM, + tai_viet = c.HB_SCRIPT_TAI_VIET, + batak = c.HB_SCRIPT_BATAK, + brahmi = c.HB_SCRIPT_BRAHMI, + mandaic = c.HB_SCRIPT_MANDAIC, + chakma = c.HB_SCRIPT_CHAKMA, + meroitic_cursive = c.HB_SCRIPT_MEROITIC_CURSIVE, + meroitic_hieroglyphs = c.HB_SCRIPT_MEROITIC_HIEROGLYPHS, + miao = c.HB_SCRIPT_MIAO, + sharada = c.HB_SCRIPT_SHARADA, + sora_sompeng = c.HB_SCRIPT_SORA_SOMPENG, + takri = c.HB_SCRIPT_TAKRI, + bassa_vah = c.HB_SCRIPT_BASSA_VAH, + caucasian_albanian = c.HB_SCRIPT_CAUCASIAN_ALBANIAN, + duployan = c.HB_SCRIPT_DUPLOYAN, + elbasan = c.HB_SCRIPT_ELBASAN, + grantha = c.HB_SCRIPT_GRANTHA, + khojki = c.HB_SCRIPT_KHOJKI, + khudawadi = c.HB_SCRIPT_KHUDAWADI, + linear_a = c.HB_SCRIPT_LINEAR_A, + mahajani = c.HB_SCRIPT_MAHAJANI, + manichaean = c.HB_SCRIPT_MANICHAEAN, + mende_kikakui = c.HB_SCRIPT_MENDE_KIKAKUI, + modi = c.HB_SCRIPT_MODI, + mro = c.HB_SCRIPT_MRO, + nabataean = c.HB_SCRIPT_NABATAEAN, + old_north_arabian = c.HB_SCRIPT_OLD_NORTH_ARABIAN, + old_permic = c.HB_SCRIPT_OLD_PERMIC, + pahawh_hmong = c.HB_SCRIPT_PAHAWH_HMONG, + palmyrene = c.HB_SCRIPT_PALMYRENE, + pau_cin_hau = c.HB_SCRIPT_PAU_CIN_HAU, + psalter_pahlavi = c.HB_SCRIPT_PSALTER_PAHLAVI, + siddham = c.HB_SCRIPT_SIDDHAM, + tirhuta = c.HB_SCRIPT_TIRHUTA, + warang_citi = c.HB_SCRIPT_WARANG_CITI, + ahom = c.HB_SCRIPT_AHOM, + anatolian_hieroglyphs = c.HB_SCRIPT_ANATOLIAN_HIEROGLYPHS, + hatran = c.HB_SCRIPT_HATRAN, + multani = c.HB_SCRIPT_MULTANI, + old_hungarian = c.HB_SCRIPT_OLD_HUNGARIAN, + signwriting = c.HB_SCRIPT_SIGNWRITING, + adlam = c.HB_SCRIPT_ADLAM, + bhaiksuki = c.HB_SCRIPT_BHAIKSUKI, + marchen = c.HB_SCRIPT_MARCHEN, + osage = c.HB_SCRIPT_OSAGE, + tangut = c.HB_SCRIPT_TANGUT, + newa = c.HB_SCRIPT_NEWA, + masaram_gondi = c.HB_SCRIPT_MASARAM_GONDI, + nushu = c.HB_SCRIPT_NUSHU, + soyombo = c.HB_SCRIPT_SOYOMBO, + zanabazar_square = c.HB_SCRIPT_ZANABAZAR_SQUARE, + dogra = c.HB_SCRIPT_DOGRA, + gunjala_gondi = c.HB_SCRIPT_GUNJALA_GONDI, + hanifi_rohingya = c.HB_SCRIPT_HANIFI_ROHINGYA, + makasar = c.HB_SCRIPT_MAKASAR, + medefaidrin = c.HB_SCRIPT_MEDEFAIDRIN, + old_sogdian = c.HB_SCRIPT_OLD_SOGDIAN, + sogdian = c.HB_SCRIPT_SOGDIAN, + elymaic = c.HB_SCRIPT_ELYMAIC, + nandinagari = c.HB_SCRIPT_NANDINAGARI, + nyiakeng_puachue_hmong = c.HB_SCRIPT_NYIAKENG_PUACHUE_HMONG, + wancho = c.HB_SCRIPT_WANCHO, + chorasmian = c.HB_SCRIPT_CHORASMIAN, + dives_akuru = c.HB_SCRIPT_DIVES_AKURU, + khitan_small_script = c.HB_SCRIPT_KHITAN_SMALL_SCRIPT, + yezidi = c.HB_SCRIPT_YEZIDI, + cypro_minoan = c.HB_SCRIPT_CYPRO_MINOAN, + old_uyghur = c.HB_SCRIPT_OLD_UYGHUR, + tangsa = c.HB_SCRIPT_TANGSA, + toto = c.HB_SCRIPT_TOTO, + vithkuqi = c.HB_SCRIPT_VITHKUQI, + math = c.HB_SCRIPT_MATH, + invalid = c.HB_SCRIPT_INVALID, +}; + +pub const Language = struct { + handle: c.hb_language_t, + + pub fn init(name: []const u8) Language { + return .{ + .handle = c.hb_language_from_string(&name[0], name.len), + }; + } + + pub fn toString(self: Language) [:0]const u8 { + return std.mem.span(c.hb_language_to_string(self.handle)); + } +}; diff --git a/freetype/src/harfbuzz/main.zig b/freetype/src/harfbuzz/main.zig index 8337712e..6034b3c1 100644 --- a/freetype/src/harfbuzz/main.zig +++ b/freetype/src/harfbuzz/main.zig @@ -1 +1,10 @@ -// +pub usingnamespace @import("blob.zig"); +pub usingnamespace @import("buffer.zig"); +pub usingnamespace @import("common.zig"); +pub const c = @import("c.zig"); + +const utils = @import("utils"); + +test { + utils.refAllDecls(@This()); +} diff --git a/freetype/src/freetype/utils.zig b/freetype/src/utils.zig similarity index 51% rename from freetype/src/freetype/utils.zig rename to freetype/src/utils.zig index e377a72d..d161e1fe 100644 --- a/freetype/src/freetype/utils.zig +++ b/freetype/src/utils.zig @@ -20,26 +20,16 @@ pub fn bitFieldsToStruct(comptime StructType: type, comptime EnumDataType: type, return value; } -const TestEnum = enum(u16) { - filed_1 = (1 << 1), - filed_2 = (1 << 2), - filed_3 = (1 << 3), -}; - -const TestStruct = packed struct { - filed_1: bool = false, - filed_2: bool = false, - filed_3: bool = false, -}; - -test "struct fields to bit fields" { - try std.testing.expectEqual(@as(u16, (1 << 1) | (1 << 3)), structToBitFields(u16, TestEnum, TestStruct{ - .filed_1 = true, - .filed_3 = true, - })); - try std.testing.expectEqual(@as(u16, 0), structToBitFields(u16, TestEnum, TestStruct{})); -} - -test "bit fields to struct" { - try std.testing.expectEqual(TestStruct{ .filed_1 = true, .filed_2 = true, .filed_3 = false }, bitFieldsToStruct(TestStruct, TestEnum, (1 << 1) | (1 << 2))); +pub fn refAllDecls(comptime T: type) void { + switch (@typeInfo(T)) { + .Struct, .Union, .Opaque, .Enum => { + inline for (comptime std.meta.declarations(T)) |decl| { + if (decl.is_pub) { + refAllDecls(@TypeOf(@field(T, decl.name))); + std.testing.refAllDecls(T); + } + } + }, + else => {}, + } }