Skip to content

Commit

Permalink
move DrawContext to backend.zig
Browse files Browse the repository at this point in the history
  • Loading branch information
zenith391 committed Oct 22, 2024
1 parent 7a93109 commit eaab0e9
Show file tree
Hide file tree
Showing 15 changed files with 206 additions and 166 deletions.
17 changes: 0 additions & 17 deletions .vscode/tasks.json

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ For now, not every platform supports the same components. So here's a list of th
| |win32|macOS|GTK|Android|wasm|
|------------------|-----|-----|---|-----|-----|
|Button ||||||
|Canvas ||||||
|Canvas ||||||
|CheckBox ||||||
|Dropdown ||||||
|Image ||||||
Expand Down
6 changes: 3 additions & 3 deletions src/AnimationController.zig
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ var null_animation_controller_instance = AnimationController{
.listener = null,
};

/// This is an animation controller that is never triggered. It's used by components while they
/// don't have a proper animation controller.
/// This controller cannot be deinitialized.
/// This animation controller is never triggered. It is used by components that don't have a proper
/// animation controller.
/// It cannot be deinitialized.
pub var null_animation_controller = &null_animation_controller_instance;
95 changes: 93 additions & 2 deletions src/backend.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const std = @import("std");
const builtin = @import("builtin");
const capy = @import("capy.zig");
const shared = @import("backends/shared.zig");

const backend = //if (@hasDecl(@import("root"), "capyBackend"))
// @import("root").capyBackend
Expand All @@ -18,15 +20,104 @@ const backend = //if (@hasDecl(@import("root"), "capyBackend"))
if (builtin.cpu.arch == .wasm32 or builtin.cpu.arch == .wasm64) {
break :blk @import("backends/wasm/backend.zig");
} else {
@compileError("Unsupported OS: freestanding");
@compileError("Unsupported OS: wasi");
}
},
else => @compileError(std.fmt.comptimePrint("Unsupported OS: {}", .{builtin.os.tag})),
};
pub usingnamespace backend;

pub const DrawContext = struct {
impl: backend.Canvas.DrawContextImpl,

pub const TextLayout = backend.Canvas.DrawContextImpl.TextLayout;

/// Use the given sRGB color as a fill and stroke color.
pub fn setColorByte(self: *DrawContext, color: capy.Color) void {
self.setColorRGBA(
@as(f32, @floatFromInt(color.red)) / 255.0,
@as(f32, @floatFromInt(color.green)) / 255.0,
@as(f32, @floatFromInt(color.blue)) / 255.0,
@as(f32, @floatFromInt(color.alpha)) / 255.0,
);
}

/// Use the given color as a fill and stroke color.
/// The usual sRGB range corresponds to 0.0 - 1.0 for each component. Going beyond requires HDR.
pub fn setColor(self: *DrawContext, r: f32, g: f32, b: f32) void {
self.setColorRGBA(r, g, b, 1.0);
}

/// Use the given color as a fill and stroke color.
/// The usual sRGB range corresponds to 0.0 - 1.0 for each component. Going beyond requires HDR.
pub fn setColorRGBA(self: *DrawContext, r: f32, g: f32, b: f32, a: f32) void {
self.impl.setColorRGBA(r, g, b, a);
}

/// Use the given gradient for filling and stroking.
pub fn setLinearGradient(self: *DrawContext, gradient: shared.LinearGradient) void {
self.impl.setLinearGradient(gradient);
}

/// Add a rectangle to the current path
pub fn rectangle(self: *DrawContext, x: i32, y: i32, w: u32, h: u32) void {
self.impl.rectangle(x, y, w, h);
}

/// Add a rounded rectangle to the current path, with the same roundness on each corner.
pub fn roundedRectangle(self: *DrawContext, x: i32, y: i32, w: u32, h: u32, corner_radius: f32) void {
self.roundedRectangleEx(x, y, w, h, @splat(corner_radius));
}

/// Add a rounded rectangle to the current path, each corner size can be configured
/// individually. There are four corner sizes corresponding to the top-left, top-right,
/// bottom-left and bottom-right respectively.
pub fn roundedRectangleEx(self: *DrawContext, x: i32, y: i32, w: u32, h: u32, corner_radiuses: [4]f32) void {
self.impl.roundedRectangleEx(x, y, w, h, corner_radiuses);
}

/// Add an ellipse to the current path
pub fn ellipse(self: *DrawContext, x: i32, y: i32, w: u32, h: u32) void {
self.impl.ellipse(x, y, w, h);
}

/// Immediately draw the following text
pub fn text(self: *DrawContext, x: i32, y: i32, layout: TextLayout, str: []const u8) void {
self.impl.text(x, y, layout, str);
}

/// Immediately draw the given line
pub fn line(self: *DrawContext, x1: i32, y1: i32, x2: i32, y2: i32) void {
self.impl.line(x1, y1, x2, y2);
}

/// Immediately draw the given image. The image is stretched to fit the destination rectangle.
pub fn image(self: *DrawContext, x: i32, y: i32, w: u32, h: u32, data: capy.ImageData) void {
self.impl.image(x, y, w, h, data);
}

/// Clear the specified region and set it to the background color
pub fn clear(self: *DrawContext, x: u32, y: u32, w: u32, h: u32) void {
self.impl.clear(x, y, w, h);
}

pub fn setStrokeWidth(self: *DrawContext, width: f32) void {
self.impl.setStrokeWidth(width);
}

/// Stroke the current path and reset the path
pub fn stroke(self: *DrawContext) void {
self.impl.stroke();
}

/// Fill the current path and reset the path
pub fn fill(self: *DrawContext) void {
self.impl.fill();
}
};

test {
// ensure selected backend atleast compiles
// ensure the selected backend atleast compiles
std.testing.refAllDecls(backend);
}

Expand Down
42 changes: 17 additions & 25 deletions src/backends/android/backend.zig
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ pub const Canvas = struct {

pub usingnamespace Events(Canvas);

pub const DrawContext = struct {
pub const DrawContextImpl = struct {
canvas: android.jobject,
paint: android.jobject,
paintClass: android.JNI.Class,
Expand Down Expand Up @@ -470,30 +470,22 @@ pub const Canvas = struct {
}
};

pub fn setColorByte(self: *DrawContext, color: lib.Color) void {
self.paintClass.callVoidMethod(self.paint, "setARGB", "(IIII)V", .{
@as(android.jint, color.alpha),
@as(android.jint, color.red),
@as(android.jint, color.green),
@as(android.jint, color.blue),
}) catch unreachable;
}

pub fn setColor(self: *DrawContext, r: f32, g: f32, b: f32) void {
self.setColorRGBA(r, g, b, 1);
}

pub fn setColorRGBA(self: *DrawContext, r: f32, g: f32, b: f32, a: f32) void {
pub fn setColorRGBA(self: *DrawContextImpl, r: f32, g: f32, b: f32, a: f32) void {
const color = lib.Color{
.red = @as(u8, @intFromFloat(std.math.clamp(r, 0, 1) * 255)),
.green = @as(u8, @intFromFloat(std.math.clamp(g, 0, 1) * 255)),
.blue = @as(u8, @intFromFloat(std.math.clamp(b, 0, 1) * 255)),
.alpha = @as(u8, @intFromFloat(std.math.clamp(a, 0, 1) * 255)),
};
self.setColorByte(color);
self.paintClass.callVoidMethod(self.paint, "setARGB", "(IIII)V", .{
@as(android.jint, color.alpha),
@as(android.jint, color.red),
@as(android.jint, color.green),
@as(android.jint, color.blue),
}) catch unreachable;
}

pub fn rectangle(self: *DrawContext, x: i32, y: i32, w: u32, h: u32) void {
pub fn rectangle(self: *DrawContextImpl, x: i32, y: i32, w: u32, h: u32) void {
const PaintStyle = self.jni.findClass("android/graphics/Paint$Style") catch unreachable;
const FILL = PaintStyle.getStaticObjectField("FILL", "Landroid/graphics/Paint$Style;") catch unreachable;
self.paintClass.callVoidMethod(self.paint, "setStyle", "(Landroid/graphics/Paint$Style;)V", .{FILL}) catch unreachable;
Expand All @@ -506,7 +498,7 @@ pub const Canvas = struct {
}) catch unreachable;
}

pub fn text(self: *DrawContext, x: i32, y: i32, layout: TextLayout, str: []const u8) void {
pub fn text(self: *DrawContextImpl, x: i32, y: i32, layout: TextLayout, str: []const u8) void {
// TODO
_ = self;
_ = x;
Expand All @@ -515,7 +507,7 @@ pub const Canvas = struct {
_ = str;
}

pub fn image(self: *DrawContext, x: i32, y: i32, w: u32, h: u32, data: lib.ImageData) void {
pub fn image(self: *DrawContextImpl, x: i32, y: i32, w: u32, h: u32, data: lib.ImageData) void {
// TODO
_ = self;
_ = x;
Expand All @@ -525,7 +517,7 @@ pub const Canvas = struct {
_ = data;
}

pub fn line(self: *DrawContext, x1: i32, y1: i32, x2: i32, y2: i32) void {
pub fn line(self: *DrawContextImpl, x1: i32, y1: i32, x2: i32, y2: i32) void {
self.class.callVoidMethod(self.canvas, "drawLine", "(FFFFLandroid/graphics/Paint;)V", .{
@as(f32, @floatFromInt(x1)),
@as(f32, @floatFromInt(y1)),
Expand All @@ -535,7 +527,7 @@ pub const Canvas = struct {
}) catch unreachable;
}

pub fn ellipse(self: *DrawContext, x: i32, y: i32, w: u32, h: u32) void {
pub fn ellipse(self: *DrawContextImpl, x: i32, y: i32, w: u32, h: u32) void {
const PaintStyle = self.jni.findClass("android/graphics/Paint$Style") catch unreachable;
const FILL = PaintStyle.getStaticObjectField("FILL", "Landroid/graphics/Paint$Style;") catch unreachable;
self.paintClass.callVoidMethod(self.paint, "setStyle", "(Landroid/graphics/Paint$Style;)V", .{FILL}) catch unreachable;
Expand All @@ -549,7 +541,7 @@ pub const Canvas = struct {
}) catch unreachable;
}

pub fn clear(self: *DrawContext, x: u32, y: u32, w: u32, h: u32) void {
pub fn clear(self: *DrawContextImpl, x: u32, y: u32, w: u32, h: u32) void {
// TODO
_ = self;
_ = x;
Expand All @@ -558,12 +550,12 @@ pub const Canvas = struct {
_ = h;
}

pub fn stroke(self: *DrawContext) void {
pub fn stroke(self: *DrawContextImpl) void {
// TODO
_ = self;
}

pub fn fill(self: *DrawContext) void {
pub fn fill(self: *DrawContextImpl) void {
// TODO
_ = self;
}
Expand All @@ -574,7 +566,7 @@ pub const Canvas = struct {
const class = jni.findClass("android/graphics/Canvas") catch unreachable;
const paintClass = jni.findClass("android/graphics/Paint") catch unreachable;
const paint = paintClass.newObject("()V", .{}) catch unreachable;
var ctx = Canvas.DrawContext{ .canvas = canvas, .jni = jni, .class = class, .paintClass = paintClass, .paint = paint };
var ctx = Canvas.DrawContextImpl{ .canvas = canvas, .jni = jni, .class = class, .paintClass = paintClass, .paint = paint };
if (eventData.class.drawHandler) |handler| {
handler(&ctx, eventData.classUserdata);
}
Expand Down
Loading

0 comments on commit eaab0e9

Please sign in to comment.