diff --git a/build.zig b/build.zig index 4d99a5f1..8426541d 100644 --- a/build.zig +++ b/build.zig @@ -40,7 +40,7 @@ pub fn build(b: *std.build.Builder) void { .{ .name = "instanced-cube", .packages = &[_]Pkg{Packages.zmath} }, .{ .name = "advanced-gen-texture-light", .packages = &[_]Pkg{Packages.zmath} }, .{ .name = "fractal-cube", .packages = &[_]Pkg{Packages.zmath} }, - .{ .name = "gkurve", .packages = &[_]Pkg{ Packages.zmath, Packages.zigimg, freetype.pkg }, .std_platform_only = true }, + .{ .name = "gkurve", .packages = &[_]Pkg{ Packages.zmath, Packages.zigimg, freetype.freetype_pkg }, .std_platform_only = true }, .{ .name = "textured-cube", .packages = &[_]Pkg{ Packages.zmath, Packages.zigimg } }, }) |example| { // FIXME: this is workaround for a problem that some examples (having the std_platform_only=true field) as @@ -62,7 +62,7 @@ pub fn build(b: *std.build.Builder) void { ); example_app.setBuildMode(mode); inline for (example.packages) |p| { - if (std.mem.eql(u8, p.name, freetype.pkg.name)) + if (std.mem.eql(u8, p.name, freetype.freetype_pkg.name)) freetype.link(example_app.b, example_app.step, .{}); } diff --git a/freetype/build.zig b/freetype/build.zig index dce77e2b..4617bced 100644 --- a/freetype/build.zig +++ b/freetype/build.zig @@ -3,25 +3,47 @@ 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"; + +pub const freetype_pkg = std.build.Pkg{ + .name = "freetype", + .source = .{ .path = thisDir() ++ "/src/freetype/main.zig" }, +}; +pub const harfbuzz_pkg = std.build.Pkg{ + .name = "harfbuzz", + .source = .{ .path = thisDir() ++ "/src/harfbuzz/main.zig" }, +}; + +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 { const mode = b.standardReleaseOptions(); const target = b.standardTargetOptions(.{}); - const dedicated_tests = b.addTest("src/main.zig"); - dedicated_tests.setBuildMode(mode); - dedicated_tests.setTarget(target); - dedicated_tests.addPackage(pkg); - link(b, dedicated_tests, .{}); + const freetype_tests = b.addTestSource(freetype_pkg.source); + freetype_tests.setBuildMode(mode); + freetype_tests.setTarget(target); + link(b, freetype_tests, .{}); const main_tests = b.addTest("test/main.zig"); main_tests.setBuildMode(mode); main_tests.setTarget(target); - main_tests.addPackage(pkg); - link(b, main_tests, .{ .custom_config_path = "./test/ft" }); + main_tests.addPackage(freetype_pkg); + link(b, main_tests, .{ .freetype = .{ .ft_config_path = "./test/ft" } }); const test_step = b.step("test", "Run library tests"); - test_step.dependOn(&dedicated_tests.step); + test_step.dependOn(&freetype_tests.step); test_step.dependOn(&main_tests.step); inline for ([_][]const u8{ @@ -31,7 +53,7 @@ pub fn build(b: *std.build.Builder) !void { const example_exe = b.addExecutable("example-" ++ example, "examples/" ++ example ++ ".zig"); example_exe.setBuildMode(mode); example_exe.setTarget(target); - example_exe.addPackage(pkg); + example_exe.addPackage(freetype_pkg); link(b, example_exe, .{}); example_exe.install(); @@ -49,39 +71,30 @@ pub fn build(b: *std.build.Builder) !void { } } -pub const Options = struct { - /// the path you specify freetype options - /// via `ftoptions.h` and `ftmodule.h` - /// e.g `test/ft/` - custom_config_path: ?[]const u8 = null, -}; - -pub const pkg = std.build.Pkg{ - .name = "freetype", - .source = .{ .path = thisDir() ++ "/src/main.zig" }, -}; - pub fn link(b: *Builder, step: *std.build.LibExeObjStep, options: Options) void { - const lib = buildLibrary(b, step, options); - step.linkLibrary(lib); - if (options.custom_config_path) |path| - step.addIncludePath(path); + const ft_lib = buildFreetype(b, step, options.freetype); + step.linkLibrary(ft_lib); step.addIncludePath(ft_include_path); + + if (options.harfbuzz) |hb_options| { + const hb_lib = buildHarfbuzz(b, step, hb_options); + hb_lib.linkLibrary(ft_lib); + step.linkLibrary(hb_lib); + } } -pub fn buildLibrary(b: *Builder, step: *std.build.LibExeObjStep, options: Options) *std.build.LibExeObjStep { - const main_abs = ft_root ++ "/src/base/ftbase.c"; - +pub fn buildFreetype(b: *Builder, step: *std.build.LibExeObjStep, options: FreetypeOptions) *std.build.LibExeObjStep { // TODO(build-system): https://github.com/hexops/mach/issues/229#issuecomment-1100958939 ensureDependencySubmodule(b.allocator, "upstream") catch unreachable; + const main_abs = ft_root ++ "/src/base/ftbase.c"; const lib = b.addStaticLibrary("freetype", main_abs); lib.defineCMacro("FT2_BUILD_LIBRARY", "1"); lib.setBuildMode(step.build_mode); lib.setTarget(step.target); lib.linkLibC(); lib.addIncludePath(ft_include_path); - if (options.custom_config_path) |path| + if (options.ft_config_path) |path| lib.addIncludePath(path); const target = (std.zig.system.NativeTargetInfo.detect(b.allocator, step.target) catch unreachable).target; @@ -107,6 +120,19 @@ pub fn buildLibrary(b: *Builder, step: *std.build.LibExeObjStep, options: Option return lib; } +pub fn buildHarfbuzz(b: *Builder, step: *std.build.LibExeObjStep, options: HarfbuzzOptions) *std.build.LibExeObjStep { + _ = options; + const main_abs = hb_root ++ "/src/harfbuzz.cc"; + const lib = b.addStaticLibrary("harfbuzz", main_abs); + lib.setBuildMode(step.build_mode); + lib.setTarget(step.target); + lib.linkLibCpp(); + lib.addIncludePath(hb_include_path); + lib.addCSourceFiles(harfbuzz_base_sources, &.{}); + lib.install(); + return lib; +} + fn thisDir() []const u8 { return std.fs.path.dirname(@src().file) orelse "."; } @@ -164,3 +190,56 @@ const freetype_base_sources = &[_][]const u8{ ft_root ++ "/src/type42/type42.c", ft_root ++ "/src/winfonts/winfnt.c", }; + +const harfbuzz_base_sources = &[_][]const u8{ + hb_root ++ "/src/hb-aat-layout.cc", + hb_root ++ "/src/hb-aat-map.cc", + hb_root ++ "/src/hb-blob.cc", + hb_root ++ "/src/hb-buffer-serialize.cc", + hb_root ++ "/src/hb-buffer-verify.cc", + hb_root ++ "/src/hb-buffer.cc", + hb_root ++ "/src/hb-common.cc", + hb_root ++ "/src/hb-draw.cc", + hb_root ++ "/src/hb-face.cc", + hb_root ++ "/src/hb-fallback-shape.cc", + hb_root ++ "/src/hb-font.cc", + hb_root ++ "/src/hb-map.cc", + hb_root ++ "/src/hb-number.cc", + hb_root ++ "/src/hb-ot-cff1-table.cc", + hb_root ++ "/src/hb-ot-cff2-table.cc", + hb_root ++ "/src/hb-ot-color.cc", + hb_root ++ "/src/hb-ot-face.cc", + hb_root ++ "/src/hb-ot-font.cc", + hb_root ++ "/src/hb-ot-layout.cc", + hb_root ++ "/src/hb-ot-map.cc", + hb_root ++ "/src/hb-ot-math.cc", + hb_root ++ "/src/hb-ot-meta.cc", + hb_root ++ "/src/hb-ot-metrics.cc", + hb_root ++ "/src/hb-ot-name.cc", + hb_root ++ "/src/hb-ot-shaper-arabic.cc", + hb_root ++ "/src/hb-ot-shaper-default.cc", + hb_root ++ "/src/hb-ot-shaper-hangul.cc", + hb_root ++ "/src/hb-ot-shaper-hebrew.cc", + hb_root ++ "/src/hb-ot-shaper-indic-table.cc", + hb_root ++ "/src/hb-ot-shaper-indic.cc", + hb_root ++ "/src/hb-ot-shaper-khmer.cc", + hb_root ++ "/src/hb-ot-shaper-myanmar.cc", + hb_root ++ "/src/hb-ot-shaper-syllabic.cc", + hb_root ++ "/src/hb-ot-shaper-thai.cc", + hb_root ++ "/src/hb-ot-shaper-use.cc", + hb_root ++ "/src/hb-ot-shaper-vowel-constraints.cc", + hb_root ++ "/src/hb-ot-shape-fallback.cc", + hb_root ++ "/src/hb-ot-shape-normalize.cc", + hb_root ++ "/src/hb-ot-shape.cc", + hb_root ++ "/src/hb-ot-tag.cc", + hb_root ++ "/src/hb-ot-var.cc", + hb_root ++ "/src/hb-set.cc", + hb_root ++ "/src/hb-shape-plan.cc", + hb_root ++ "/src/hb-shape.cc", + hb_root ++ "/src/hb-shaper.cc", + hb_root ++ "/src/hb-static.cc", + hb_root ++ "/src/hb-style.cc", + hb_root ++ "/src/hb-ucd.cc", + hb_root ++ "/src/hb-unicode.cc", + hb_root ++ "/src/hb-ft.cc", // freetype integration +}; diff --git a/freetype/src/Face.zig b/freetype/src/freetype/Face.zig similarity index 100% rename from freetype/src/Face.zig rename to freetype/src/freetype/Face.zig diff --git a/freetype/src/Glyph.zig b/freetype/src/freetype/Glyph.zig similarity index 100% rename from freetype/src/Glyph.zig rename to freetype/src/freetype/Glyph.zig diff --git a/freetype/src/GlyphSlot.zig b/freetype/src/freetype/GlyphSlot.zig similarity index 100% rename from freetype/src/GlyphSlot.zig rename to freetype/src/freetype/GlyphSlot.zig diff --git a/freetype/src/Library.zig b/freetype/src/freetype/Library.zig similarity index 100% rename from freetype/src/Library.zig rename to freetype/src/freetype/Library.zig diff --git a/freetype/src/Outline.zig b/freetype/src/freetype/Outline.zig similarity index 100% rename from freetype/src/Outline.zig rename to freetype/src/freetype/Outline.zig diff --git a/freetype/src/Stroker.zig b/freetype/src/freetype/Stroker.zig similarity index 100% rename from freetype/src/Stroker.zig rename to freetype/src/freetype/Stroker.zig diff --git a/freetype/src/c.zig b/freetype/src/freetype/c.zig similarity index 100% rename from freetype/src/c.zig rename to freetype/src/freetype/c.zig diff --git a/freetype/src/color.zig b/freetype/src/freetype/color.zig similarity index 100% rename from freetype/src/color.zig rename to freetype/src/freetype/color.zig diff --git a/freetype/src/error.zig b/freetype/src/freetype/error.zig similarity index 100% rename from freetype/src/error.zig rename to freetype/src/freetype/error.zig diff --git a/freetype/src/freetype.zig b/freetype/src/freetype/freetype.zig similarity index 100% rename from freetype/src/freetype.zig rename to freetype/src/freetype/freetype.zig diff --git a/freetype/src/image.zig b/freetype/src/freetype/image.zig similarity index 100% rename from freetype/src/image.zig rename to freetype/src/freetype/image.zig diff --git a/freetype/src/lcdfilter.zig b/freetype/src/freetype/lcdfilter.zig similarity index 100% rename from freetype/src/lcdfilter.zig rename to freetype/src/freetype/lcdfilter.zig diff --git a/freetype/src/main.zig b/freetype/src/freetype/main.zig similarity index 100% rename from freetype/src/main.zig rename to freetype/src/freetype/main.zig diff --git a/freetype/src/types.zig b/freetype/src/freetype/types.zig similarity index 100% rename from freetype/src/types.zig rename to freetype/src/freetype/types.zig diff --git a/freetype/src/utils.zig b/freetype/src/freetype/utils.zig similarity index 100% rename from freetype/src/utils.zig rename to freetype/src/freetype/utils.zig diff --git a/freetype/src/harfbuzz/main.zig b/freetype/src/harfbuzz/main.zig new file mode 100644 index 00000000..8337712e --- /dev/null +++ b/freetype/src/harfbuzz/main.zig @@ -0,0 +1 @@ +//