Skip to content

Commit

Permalink
feat: scale and rotate
Browse files Browse the repository at this point in the history
  • Loading branch information
Brooooooklyn committed Jan 9, 2021
1 parent cd324ea commit f6c761f
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 2 deletions.
39 changes: 37 additions & 2 deletions __test__/draw.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -408,9 +408,44 @@ test('save-restore', async (t) => {
await snapshotImage(t)
})

test.todo('rotate')
test('rotate', async (t) => {
const { ctx } = t.context
// Point of transform origin
ctx.arc(0, 0, 5, 0, 2 * Math.PI)
ctx.fillStyle = 'blue'
ctx.fill()

test.todo('scale')
// Non-rotated rectangle
ctx.fillStyle = 'gray'
ctx.fillRect(100, 0, 80, 20)

// Rotated rectangle
ctx.rotate((45 * Math.PI) / 180)
ctx.fillStyle = 'red'
ctx.fillRect(100, 0, 80, 20)
// Reset transformation matrix to the identity matrix
ctx.setTransform(1, 0, 0, 1, 0, 0)

ctx.fillStyle = 'hotpink'
ctx.fillRect(100, 50, 80, 20)
await snapshotImage(t)
})

test('scale', async (t) => {
const { ctx } = t.context
// Scaled rectangle
ctx.scale(9, 3)
ctx.fillStyle = 'red'
ctx.fillRect(10, 10, 8, 20)

// Reset current transformation matrix to the identity matrix
ctx.setTransform(1, 0, 0, 1, 0, 0)

// Non-scaled rectangle
ctx.fillStyle = 'gray'
ctx.fillRect(10, 10, 8, 20)
await snapshotImage(t)
})

test('setLineDash', async (t) => {
const { ctx } = t.context
Expand Down
Binary file added __test__/snapshots/rotate.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added __test__/snapshots/scale.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions skia-c/skia_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,11 @@ extern "C"
CANVAS_CAST->translate(dx, dy);
}

void skiac_canvas_rotate(skiac_canvas *c_canvas, float degrees)
{
CANVAS_CAST->rotate(degrees);
}

skiac_matrix *skiac_canvas_get_total_transform_matrix(skiac_canvas *c_canvas)
{
auto martix = CANVAS_CAST->getTotalMatrix();
Expand Down
1 change: 1 addition & 0 deletions skia-c/skia_c.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ extern "C"
void skiac_canvas_concat(skiac_canvas *c_canvas, skiac_transform c_ts);
void skiac_canvas_scale(skiac_canvas *c_canvas, float sx, float sy);
void skiac_canvas_translate(skiac_canvas *c_canvas, float dx, float dy);
void skiac_canvas_rotate(skiac_canvas *c_canvas, float degrees);
skiac_transform skiac_canvas_get_total_transform(skiac_canvas *c_canvas);
skiac_matrix *skiac_canvas_get_total_transform_matrix(skiac_canvas *c_canvas);
void skiac_canvas_draw_color(skiac_canvas *c_canvas, float r, float g, float b, float a);
Expand Down
13 changes: 13 additions & 0 deletions src/ctx.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::convert::TryInto;
use std::f32::consts::PI;
use std::mem;
use std::result;
use std::str::FromStr;
Expand Down Expand Up @@ -101,6 +102,7 @@ impl Context {
Property::new(&env, "rect")?.with_method(rect),
Property::new(&env, "resetTransform")?.with_method(reset_transform),
Property::new(&env, "restore")?.with_method(restore),
Property::new(&env, "rotate")?.with_method(rotate),
Property::new(&env, "save")?.with_method(save),
Property::new(&env, "scale")?.with_method(scale),
Property::new(&env, "setLineDash")?.with_method(set_line_dash),
Expand Down Expand Up @@ -558,6 +560,17 @@ fn restore(ctx: CallContext) -> Result<JsUndefined> {
ctx.env.get_undefined()
}

#[js_function(1)]
fn rotate(ctx: CallContext) -> Result<JsUndefined> {
let this = ctx.this_unchecked::<JsObject>();
let context_2d = ctx.env.unwrap::<Context>(&this)?;

let angle: f64 = ctx.get::<JsNumber>(0)?.try_into()?;
context_2d.path.transform(&Transform::rotate(-angle as f32));
context_2d.surface.canvas.rotate(angle as f32 / PI * 180f32);
ctx.env.get_undefined()
}

#[js_function(4)]
fn clear_rect(ctx: CallContext) -> Result<JsUndefined> {
let this = ctx.this_unchecked::<JsObject>();
Expand Down
25 changes: 25 additions & 0 deletions src/sk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ mod ffi {

pub fn skiac_canvas_translate(canvas: *mut skiac_canvas, dx: f32, dy: f32);

pub fn skiac_canvas_rotate(canvas: *mut skiac_canvas, degrees: f32);

pub fn skiac_canvas_get_total_transform(canvas: *mut skiac_canvas) -> skiac_transform;

pub fn skiac_canvas_get_total_transform_matrix(canvas: *mut skiac_canvas) -> *mut skiac_matrix;
Expand Down Expand Up @@ -1131,6 +1133,13 @@ impl Canvas {
}
}

#[inline]
pub fn rotate(&mut self, degrees: f32) {
unsafe {
ffi::skiac_canvas_rotate(self.0, degrees);
}
}

#[inline]
pub fn get_transform(&self) -> Transform {
unsafe { ffi::skiac_canvas_get_total_transform(self.0).into() }
Expand Down Expand Up @@ -1873,10 +1882,26 @@ pub struct Transform {
}

impl Transform {
#[inline]
pub fn new(a: f32, b: f32, c: f32, d: f32, e: f32, f: f32) -> Self {
Transform { a, b, c, d, e, f }
}

#[inline]
pub fn rotate(radians: f32) -> Self {
let sin_v = radians.sin();
let cos_v = radians.cos();

Self {
a: cos_v,
b: -sin_v,
c: 0f32,
d: sin_v,
e: cos_v,
f: 0f32,
}
}

#[inline]
/// | A B C | | A/X B/X C/X |
/// | D E F | -> | D/X E/X F/X | for X != 0
Expand Down

1 comment on commit f6c761f

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: f6c761f Previous: cd324ea Ratio
Draw house#@napi-rs/skia 23 ops/sec (±1.21%) 28 ops/sec (±0.11%) 1.22
Draw house#node-canvas 22 ops/sec (±1.25%) 24 ops/sec (±0.36%) 1.09
Draw gradient#@napi-rs/skia 23 ops/sec (±1.72%) 27 ops/sec (±0.05%) 1.17
Draw gradient#node-canvas 22 ops/sec (±1.44%) 23 ops/sec (±0.28%) 1.05

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.