Skip to content

Commit

Permalink
Merge pull request #155 from doodlewind/misc
Browse files Browse the repository at this point in the history
feat: support getContextAttributes
  • Loading branch information
doodlewind committed Feb 3, 2021
2 parents b83adf8 + 929bdc0 commit 58e8e3e
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 8 deletions.
21 changes: 19 additions & 2 deletions __test__/draw.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ test.beforeEach((t) => {
t.context.ctx = canvas.getContext('2d')!
})

test('alpha-false', async (t) => {
const canvas = createCanvas(512, 512)
const ctx = canvas.getContext('2d', { alpha: false })
await snapshotImage(t, { canvas, ctx })
})

test('arc', async (t) => {
const { ctx } = t.context
ctx.beginPath()
Expand Down Expand Up @@ -284,7 +290,18 @@ test('fillRect', async (t) => {

test.todo('fillText')

test.todo('getContextAttributes')
test('getContextAttributes', (t) => {
const defaultCtx = t.context.ctx
const defaultAttrs = defaultCtx.getContextAttributes()
t.is(defaultAttrs.alpha, true)
t.is(defaultAttrs.desynchronized, false)

const canvas = createCanvas(512, 512)
const ctx = canvas.getContext('2d', { alpha: false })
const customAttrs = ctx.getContextAttributes()
t.is(customAttrs.alpha, false)
t.is(customAttrs.desynchronized, false)
})

test('getImageData', async (t) => {
const { ctx } = t.context
Expand Down Expand Up @@ -314,7 +331,7 @@ test('isPointInPath', (t) => {
t.is(ctx.isPointInPath(path, 50, 1), true)

path.rect(40, 40, 20, 20)
t.is(ctx.isPointInPath(50, 50), true)
t.is(ctx.isPointInPath(path, 50, 50), true)
t.is(ctx.isPointInPath(path, 50, 50, 'nonzero'), true)
t.is(ctx.isPointInPath(path, 50, 50, 'evenodd'), false)
})
Expand Down
4 changes: 2 additions & 2 deletions __test__/image-snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { ExecutionContext } from 'ava'

const png = PNG()

export async function snapshotImage<C>(t: ExecutionContext<C>) {
export async function snapshotImage<C>(t: ExecutionContext<C>, context = t.context) {
// @ts-expect-error
const { canvas } = t.context
const { canvas } = context
const image = await canvas.png()
const p = join(__dirname, 'snapshots', `${t.title}.png`)

Expand Down
Binary file added __test__/snapshots/alpha-false.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,11 @@ export interface SKRSContext2D extends Omit<CanvasRenderingContext2D, 'drawImage
dw: number,
dh: number,
): void
getContextAttributes(): { alpha: boolean; desynchronized: boolean }
}

export interface Canvas extends Omit<HTMLCanvasElement, 'getContext'> {
getContext(contextId: '2d'): SKRSContext2D
getContext(contextType: '2d', contextAttributes?: { alpha: boolean }): SKRSContext2D
png(): Promise<Buffer>
}

Expand Down
15 changes: 14 additions & 1 deletion src/ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ impl From<SkError> for Error {
pub struct Context {
pub(crate) surface: Surface,
path: Path,
pub alpha: bool,
pub(crate) states: Vec<Context2dRenderingState>,
}

Expand Down Expand Up @@ -101,6 +102,7 @@ impl Context {
Property::new(&env, "createLinearGradient")?.with_method(create_linear_gradient),
Property::new(&env, "createRadialGradient")?.with_method(create_radial_gradient),
Property::new(&env, "drawImage")?.with_method(draw_image),
Property::new(&env, "getContextAttributes")?.with_method(get_context_attributes),
Property::new(&env, "isPointInPath")?.with_method(is_point_in_path),
Property::new(&env, "isPointInStroke")?.with_method(is_point_in_stroke),
Property::new(&env, "ellipse")?.with_method(ellipse),
Expand Down Expand Up @@ -138,6 +140,7 @@ impl Context {
states.push(Context2dRenderingState::default());
Ok(Context {
surface,
alpha: true,
path: Path::new(),
states,
})
Expand Down Expand Up @@ -262,7 +265,7 @@ impl Context {
}

#[inline(always)]
fn fill_paint(&self) -> result::Result<Paint, SkError> {
pub fn fill_paint(&self) -> result::Result<Paint, SkError> {
let current_paint = &self.states.last().unwrap().paint;
let mut paint = current_paint.clone();
paint.set_style(PaintStyle::Fill);
Expand Down Expand Up @@ -695,6 +698,16 @@ fn draw_image(ctx: CallContext) -> Result<JsUndefined> {
ctx.env.get_undefined()
}

#[js_function]
fn get_context_attributes(ctx: CallContext) -> Result<JsObject> {
let this = ctx.this_unchecked::<JsObject>();
let context_2d = ctx.env.unwrap::<Context>(&this)?;
let mut obj = ctx.env.create_object()?;
obj.set_named_property("alpha", ctx.env.get_boolean(context_2d.alpha)?)?;
obj.set_named_property("desynchronized", ctx.env.get_boolean(false)?)?;
Ok(obj)
}

#[js_function(4)]
fn is_point_in_path(ctx: CallContext) -> Result<JsBoolean> {
let this = ctx.this_unchecked::<JsObject>();
Expand Down
26 changes: 24 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
extern crate napi_derive;

use napi::*;
use std::convert::TryInto;

use ctx::{Context, ContextData};
use font::{init_font_regexp, FONT_REGEXP};
Expand Down Expand Up @@ -74,7 +75,7 @@ fn canvas_element_constructor(ctx: CallContext) -> Result<JsUndefined> {
ctx.env.get_undefined()
}

#[js_function(1)]
#[js_function(2)]
fn get_context(ctx: CallContext) -> Result<JsObject> {
let context_type = ctx.get::<JsString>(0)?.into_utf8()?;
if context_type.as_str()? != "2d" {
Expand All @@ -83,8 +84,29 @@ fn get_context(ctx: CallContext) -> Result<JsObject> {
"Only supports 2d context".to_owned(),
));
}

let this = ctx.this_unchecked::<JsObject>();
this.get_named_property("ctx")
let ctx_js = this.get_named_property::<JsObject>("ctx")?;
let context_2d = ctx.env.unwrap::<Context>(&ctx_js)?;

if ctx.length == 2 {
let attrs = ctx.get::<JsObject>(1)?;
let alpha = attrs
.get_named_property::<JsBoolean>("alpha")?
.get_value()?;
if !alpha {
let mut fill_paint = context_2d.fill_paint()?;
fill_paint.set_color(255, 255, 255, 255);
let w: f64 = this.get_named_property::<JsNumber>("width")?.try_into()?;
let h: f64 = this.get_named_property::<JsNumber>("height")?.try_into()?;
context_2d.alpha = false;
context_2d
.surface
.draw_rect(0f32, 0f32, w as f32, h as f32, &fill_paint);
}
}

Ok(ctx_js)
}

#[js_function]
Expand Down

0 comments on commit 58e8e3e

Please sign in to comment.