From c391d0f3dee5098b1bff638cf3e0085291460542 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 13 Dec 2022 22:17:27 -0800 Subject: [PATCH] font: web canvas sprite font can composite --- example/app.ts | 19 +++++++++++++++-- src/font/sprite/Box.zig | 2 +- src/font/sprite/canvas.zig | 42 ++++++++++++++++++++++++++++++-------- 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/example/app.ts b/example/app.ts index 8e0778188..f66771371 100644 --- a/example/app.ts +++ b/example/app.ts @@ -82,7 +82,7 @@ fetch(url.href).then(response => //free(font_ptr); // Create our group - const group = group_new(72 /* size */); + const group = group_new(32 /* size */); group_add_face(group, 0 /* regular */, deferred_face_new(font_name.ptr, font_name.len, 0 /* text */)); group_add_face(group, 0 /* regular */, deferred_face_new(font_name.ptr, font_name.len, 1 /* emoji */)); @@ -109,7 +109,22 @@ fetch(url.href).then(response => for (let i = 0x2500; i <= 0x257F; i++) { const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1); group_cache_render_glyph(group_cache, font_idx, i, 0); - //face_render_glyph(face, atlas, i); + } + for (let i = 0x2580; i <= 0x259f; i++) { + const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1); + group_cache_render_glyph(group_cache, font_idx, i, 0); + } + for (let i = 0x2800; i <= 0x28FF; i++) { + const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1); + group_cache_render_glyph(group_cache, font_idx, i, 0); + } + for (let i = 0x1FB00; i <= 0x1FB3B; i++) { + const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1); + group_cache_render_glyph(group_cache, font_idx, i, 0); + } + for (let i = 0x1FB3C; i <= 0x1FB6B; i++) { + const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1); + group_cache_render_glyph(group_cache, font_idx, i, 0); } //face_render_glyph(face, atlas, "橋".codePointAt(0)); diff --git a/src/font/sprite/Box.zig b/src/font/sprite/Box.zig index e99d8fa53..db9add6f6 100644 --- a/src/font/sprite/Box.zig +++ b/src/font/sprite/Box.zig @@ -2125,7 +2125,7 @@ fn draw_wedge_triangle_inverted( src.rect(.{ .x = 0, .y = 0, .width = self.width, .height = self.height }, .on); defer src.deinit(alloc); canvas.composite( - .destination_out, + .source_out, &src, .{ .x = 0, .y = 0, .width = self.width, .height = self.height }, ); diff --git a/src/font/sprite/canvas.zig b/src/font/sprite/canvas.zig index 932f8e4dc..68c08e709 100644 --- a/src/font/sprite/canvas.zig +++ b/src/font/sprite/canvas.zig @@ -86,11 +86,17 @@ pub const Color = enum(u8) { pub const CompositionOp = enum { // Note: more can be added here as needed. - destination_out, + source_out, fn pixmanOp(self: CompositionOp) pixman.Op { return switch (self) { - .destination_out => .out, + .source_out => .out, + }; + } + + fn jsOp(self: CompositionOp) js.String { + return switch (self) { + .source_out => js.string("source-out"), }; } }; @@ -151,9 +157,14 @@ const WebCanvasImpl = struct { } pub fn triangle(self: *WebCanvasImpl, t: Triangle, color: Color) void { - _ = self; - _ = t; - _ = color; + const ctx = self.context(color) catch return; + defer ctx.deinit(); + + ctx.call(void, "beginPath", .{}) catch return; + ctx.call(void, "moveTo", .{ t.p1.x, t.p1.y }) catch return; + ctx.call(void, "lineTo", .{ t.p2.x, t.p2.y }) catch return; + ctx.call(void, "lineTo", .{ t.p3.x, t.p3.y }) catch return; + ctx.call(void, "fill", .{}) catch return; } pub fn composite( @@ -162,16 +173,29 @@ const WebCanvasImpl = struct { src: *const WebCanvasImpl, dest: Rect, ) void { - _ = self; - _ = op; - _ = src; - _ = dest; + const ctx = self.context(Color.on) catch return; + defer ctx.deinit(); + + // Set our compositing operation + ctx.set("globalCompositeOperation", op.jsOp()) catch return; + + // Composite + ctx.call(void, "drawImage", .{ + src.canvas, + dest.x, + dest.y, + dest.width, + dest.height, + }) catch return; } fn context(self: WebCanvasImpl, fill: ?Color) !js.Object { const ctx = try self.canvas.call(js.Object, "getContext", .{js.string("2d")}); errdefer ctx.deinit(); + // Reset our composite operation + try ctx.set("globalCompositeOperation", js.string("source-over")); + // Set our fill color if (fill) |c| { var buf: [Color.CSS_BUF_MAX]u8 = undefined;