font: begin making Group work with wasm

This commit is contained in:
Mitchell Hashimoto
2022-12-05 16:08:20 -08:00
parent d2afddb7e2
commit 2a74330911
7 changed files with 86 additions and 37 deletions

View File

@ -121,6 +121,8 @@ pub fn build(b: *std.build.Builder) !void {
wasm.setBuildMode(mode);
wasm.setOutputDir("zig-out");
wasm.addOptions("build_options", exe_options);
// Wasm-specific deps
wasm.addPackage(js.pkg);
wasm.addPackage(tracylib.pkg);

View File

@ -24,8 +24,8 @@ fc: if (options.backend == .fontconfig_freetype) ?Fontconfig else void =
if (options.backend == .fontconfig_freetype) null else {},
/// CoreText
ct: if (options.backend == .coretext) ?CoreText else void =
if (options.backend == .coretext) null else {},
ct: if (font.Discover == font.discovery.CoreText) ?CoreText else void =
if (font.Discover == font.discovery.CoreText) null else {},
/// Fontconfig specific data. This is only present if building with fontconfig.
pub const Fontconfig = struct {
@ -66,7 +66,7 @@ pub fn deinit(self: *DeferredFace) void {
if (self.face) |*face| face.deinit();
switch (options.backend) {
.fontconfig_freetype => if (self.fc) |*fc| fc.deinit(),
.coretext => if (self.ct) |*ct| ct.deinit(),
.coretext, .coretext_freetype => if (self.ct) |*ct| ct.deinit(),
.freetype => {},
// TODO
.web_canvas => unreachable,
@ -86,7 +86,7 @@ pub fn name(self: DeferredFace) ![:0]const u8 {
.fontconfig_freetype => if (self.fc) |fc|
return (try fc.pattern.get(.fullname, 0)).string,
.coretext => if (self.ct) |ct| {
.coretext, .coretext_freetype => if (self.ct) |ct| {
const display_name = ct.font.copyDisplayName();
return display_name.cstringPtr(.utf8) orelse "<unsupported internal encoding>";
},
@ -116,14 +116,12 @@ pub fn load(
},
.coretext => {
// It is possible to use CoreText with Freetype so we support
// both here.
switch (font.Face) {
@import("face/freetype.zig").Face => try self.loadCoreTextFreetype(lib, size),
@import("face/coretext.zig").Face => try self.loadCoreText(lib, size),
else => unreachable,
}
try self.loadCoreText(lib, size);
return;
},
.coretext_freetype => {
try self.loadCoreTextFreetype(lib, size);
return;
},
@ -239,7 +237,7 @@ pub fn hasCodepoint(self: DeferredFace, cp: u32, p: ?Presentation) bool {
}
},
.coretext => {
.coretext, .coretext_freetype => {
// If we are using coretext, we check the loaded CT font.
if (self.ct) |ct| {
// Turn UTF-32 into UTF-16 for CT API

View File

@ -285,6 +285,26 @@ pub fn renderGlyph(
return try face.face.?.renderGlyph(alloc, atlas, glyph_index, max_height);
}
/// The wasm-compatible API.
pub const Wasm = struct {
const wasm = @import("../os/wasm.zig");
const alloc = wasm.alloc;
export fn group_new(pts: u16) ?*Group {
return group_new_(pts) catch null;
}
fn group_new_(pts: u16) !*Group {
var group = try Group.init(alloc, .{}, .{ .points = pts });
errdefer group.deinit();
var result = try alloc.create(Group);
errdefer alloc.destroy(result);
result.* = group;
return result;
}
};
test {
const testing = std.testing;
const alloc = testing.allocator;

View File

@ -1,19 +0,0 @@
//! A library represents the shared state that the underlying font
//! library implementation(s) require per-process.
//!
//! In the future, this will be abstracted so that the underlying text
//! engine might not be Freetype and may be something like Core Text,
//! but the API will remain the same.
const Library = @This();
const freetype = @import("freetype");
lib: freetype.Library,
pub fn init() freetype.Error!Library {
return Library{ .lib = try freetype.Library.init() };
}
pub fn deinit(self: *Library) void {
self.lib.deinit();
}

View File

@ -6,11 +6,13 @@ pub const web_canvas = @import("face/web_canvas.zig");
/// Face implementation for the compile options.
pub const Face = switch (options.backend) {
.fontconfig_freetype => freetype.Face,
.coretext => freetype.Face,
//.coretext => coretext.Face,
.freetype,
.fontconfig_freetype,
.coretext_freetype,
=> freetype.Face,
.coretext => coretext.Face,
.web_canvas => web_canvas.Face,
else => unreachable,
};
/// If a DPI can't be calculated, this DPI is used. This is probably

42
src/font/library.zig Normal file
View File

@ -0,0 +1,42 @@
//! A library represents the shared state that the underlying font
//! library implementation(s) require per-process.
const builtin = @import("builtin");
const options = @import("main.zig").options;
const freetype = @import("freetype");
const font = @import("main.zig");
/// Library implementation for the compile options.
pub const Library = switch (options.backend) {
// Freetype requires a state library
.freetype,
.fontconfig_freetype,
.coretext_freetype,
=> FreetypeLibrary,
// Some backends such as CT and Canvas don't have a "library"
.coretext,
.web_canvas,
=> NoopLibrary,
};
pub const FreetypeLibrary = struct {
lib: freetype.Library,
pub fn init() freetype.Error!Library {
return Library{ .lib = try freetype.Library.init() };
}
pub fn deinit(self: *Library) void {
self.lib.deinit();
}
};
pub const NoopLibrary = struct {
pub fn init() !Library {
return Library{};
}
pub fn deinit(self: *Library) void {
_ = self;
}
};

View File

@ -10,16 +10,17 @@ pub const Face = face.Face;
pub const Group = @import("Group.zig");
pub const GroupCache = @import("GroupCache.zig");
pub const Glyph = @import("Glyph.zig");
pub const Library = @import("Library.zig");
pub const Shaper = @import("Shaper.zig");
pub const sprite = @import("sprite.zig");
pub const Sprite = sprite.Sprite;
pub const Descriptor = discovery.Descriptor;
pub const Discover = discovery.Discover;
pub usingnamespace @import("library.zig");
/// If we're targeting wasm then we export some wasm APIs.
pub usingnamespace if (builtin.target.isWasm()) struct {
pub usingnamespace Atlas.Wasm;
pub usingnamespace Group.Wasm;
pub usingnamespace face.web_canvas.Wasm;
} else struct {};
@ -37,9 +38,12 @@ pub const Backend = enum {
/// Fontconfig for font discovery and FreeType for font rendering.
fontconfig_freetype,
/// CoreText for both font discovery and rendering (macOS).
/// CoreText for both font discovery for rendering (macOS).
coretext,
/// CoreText for font discovery and FreeType for rendering (macOS).
coretext_freetype,
/// Use the browser font system and the Canvas API (wasm). This limits
/// the available fonts to browser fonts (anything Canvas natively
/// supports).