diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-24 12:56:04 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:14 -0300 |
| commit | 7fdf5ed9d1dd433e4657b670b7831cec6e3d41ca (patch) | |
| tree | a0a8f2631e54647cdb88ef876189ff175f4b9a58 | |
| parent | 8de5bf6fecc19cf2be6093b4338691fe4af84815 (diff) | |
| download | pardes-7fdf5ed9d1dd433e4657b670b7831cec6e3d41ca.tar.gz pardes-7fdf5ed9d1dd433e4657b670b7831cec6e3d41ca.zip | |
Build MuPDF against the FreeType the gui links, not the slim one it bundles
MuPDF compiled its own FreeType 2.13.3 (FREETYPE_SRC, trimmed by
scripts/freetype's slimftmodules.h and slimftoptions.h) into libmupdf.a, and
the gui also links the freetype package, 2.14.3 in its full configuration.
The two define the same 312 symbols, and a linker handed both keeps one of
each: the gui's MuPDF ran the package's FreeType compiled against the slim
headers, while the tty ran the slim one. Now there is one. mupdf.zig takes
the build's freetype artifact, links it (its headers come with it) and no
longer compiles FREETYPE_SRC or puts the slim headers on the include path.
The shared artifact is built at c_optimize, as MuPDF is, so a Debug gui's
glyph atlas now uses a ReleaseFast FreeType too; one artifact cannot be both.
The tty gains the full FreeType's extra modules, which FT_Add_Default_Modules
registers whether or not a PDF needs them. MuPDF asks nothing of FreeType the
full configuration lacks: every page of docs/design.pdf, docs/9p.pdf and
docs/registry.pdf renders bit for bit as before, at 144 and at 300 dpi.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
| -rw-r--r-- | build.zig | 19 | ||||
| -rw-r--r-- | mupdf.zig | 22 |
2 files changed, 22 insertions, 19 deletions
@@ -418,12 +418,22 @@ pub fn build(b: *std.Build) void { .root_source_file = b.path("src/c_heap.zig"), }); + // One FreeType in a binary: the gui's glyph atlas links it and MuPDF is + // built against it (see mupdf.zig). At c_optimize with the rest of the + // vendored C, since MuPDF rasterizes a PDF's text through it. + const freetype: ?*std.Build.Step.Compile = if (freestanding_core) null else b.dependency("freetype", .{ + .target = target, + .optimize = c_optimize, + .@"enable-libpng" = false, + }).artifact("freetype"); + if (enable_mupdf) { if (b.lazyDependency("mupdf", .{})) |mupdf_dep| { const mupdf = mupdf_build.add(b, io, mupdf_dep, .{ .target = target, .optimize = c_optimize, .jpx = enable_jpx, + .freetype = freetype.?, }); const mupdf_mod = b.createModule(.{ .target = target, @@ -647,12 +657,7 @@ pub fn build(b: *std.Build) void { gm.linkLibrary(sdl_lib); gm.addIncludePath(dep.path("include")); } - const freetype_dep = b.dependency("freetype", .{ - .target = target, - .optimize = optimize, - .@"enable-libpng" = false, - }); - gm.linkLibrary(freetype_dep.artifact("freetype")); + gm.linkLibrary(freetype.?); // HarfBuzz from source, like FreeType: its FreeType integration // (HAVE_FREETYPE, hb-ft) links the freetype artifact above, so the two // share one FreeType. The flags are the ones Ghostty builds it with, @@ -669,7 +674,7 @@ pub fn build(b: *std.Build) void { .link_libcpp = true, }), }); - harfbuzz.root_module.linkLibrary(freetype_dep.artifact("freetype")); + harfbuzz.root_module.linkLibrary(freetype.?); harfbuzz.root_module.addIncludePath(upstream.path("src")); harfbuzz.root_module.addCSourceFile(.{ .file = upstream.path("src/harfbuzz.cc"), @@ -33,6 +33,14 @@ pub fn add(b: *std.Build, io: std.Io, dependency: *std.Build.Dependency, options /// Compile openjpeg and let MuPDF decode JPEG 2000. See the OPENJPEG /// block below for why this is a switch rather than always-on. jpx: bool = true, + /// The FreeType the rest of the build links, which MuPDF is compiled + /// against and links instead of the slim one it bundles (FREETYPE_SRC, + /// configured by scripts/freetype). Both define the same symbols and a + /// linker handed two keeps one of each, so the gui's MuPDF ran the full + /// FreeType's code compiled against the slim one's headers, while the tty + /// ran the slim one. MuPDF asks nothing of FreeType the full + /// configuration lacks. + freetype: *std.Build.Step.Compile, }) Result { const module = b.createModule(.{ .target = options.target, @@ -45,6 +53,8 @@ pub fn add(b: *std.Build, io: std.Io, dependency: *std.Build.Dependency, options // debug-locking/assertion paths. linkTo applies the same public-header // contract to consumers; keeping it here also covers every archive source. module.addCMacro("NDEBUG", "1"); + // The build's own FreeType, headers and all; see `freetype` above. + module.linkLibrary(options.freetype); // MuPDF itself uses wildcards for these two directories. The dependency // is immutable and content-addressed, so discovering the flat C lists at @@ -82,16 +92,6 @@ pub fn add(b: *std.Build, io: std.Io, dependency: *std.Build.Dependency, options const makelists = readMakelists(b, io, dependency); module.addCSourceFiles(.{ .root = dependency.path(""), - .files = makeSources(b, makelists, "FREETYPE_SRC"), - .flags = &.{ - "-std=gnu11", - "-DFT_CONFIG_MODULES_H=\"slimftmodules.h\"", - "-DFT_CONFIG_OPTIONS_H=\"slimftoptions.h\"", - "-DFT2_BUILD_LIBRARY", - }, - }); - module.addCSourceFiles(.{ - .root = dependency.path(""), .files = makeSources(b, makelists, "LIBJPEG_SRC"), .flags = &.{"-std=gnu11"}, }); @@ -250,8 +250,6 @@ fn configureModule(module: *std.Build.Module, dependency: *std.Build.Dependency, module.addIncludePath(dependency.path("include")); module.addIncludePath(dependency.path("source/fitz")); module.addIncludePath(dependency.path("source/pdf")); - module.addIncludePath(dependency.path("thirdparty/freetype/include")); - module.addIncludePath(dependency.path("scripts/freetype")); module.addIncludePath(dependency.path("thirdparty/libjpeg")); module.addIncludePath(dependency.path("scripts/libjpeg")); module.addIncludePath(dependency.path("thirdparty/zlib")); |
