Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: macOS NAPI #133

Draft
wants to merge 16 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"files.associations": {
"new": "cpp"
}
}
934 changes: 934 additions & 0 deletions .yarn/releases/yarn-4.5.2.cjs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
yarnPath: .yarn/releases/yarn-4.5.2.cjs
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ members = [
"crates/canvas-ios",
"crates/playground",
"crates/canvas-c",
"crates/canvas-svg"]
"crates/canvas-svg",
"napi/canvas-napi",
]

[profile.release]
panic = "abort"
Expand All @@ -37,7 +39,7 @@ canvas-core = { path = "./crates/canvas-core" }
canvas-webgl = { path = "./crates/canvas-webgl" }
gl-bindings = { path = "./crates/gl-bindings" }
canvas-c = { path = "./crates/canvas-c" }
skia-safe = { version = "0.78.2", features = ["textlayout"] }
skia-safe = { version = "0.80.0", features = ["textlayout"] }
itertools = "0.13.0"
wgpu-core = { git = "https://github.com/triniwiz/wgpu", rev = "48f663f70d5b6e99a5b8a708876ce9642d78fbde", features = ["wgsl", "vulkan", "metal", "raw-window-handle"] }
wgpu-types = { git = "https://github.com/triniwiz/wgpu", rev = "48f663f70d5b6e99a5b8a708876ce9642d78fbde" }
Expand Down
4 changes: 2 additions & 2 deletions crates/canvas-2d/src/context/fill_and_stroke_styles/paint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ impl Paint {
color: Color,
blur: c_float,
) -> Option<skia_safe::Paint> {
if !(color != Color::TRANSPARENT && blur > 0.0) {
if color == Color::TRANSPARENT && blur > 0.0 {
return None;
}
let mut paint = self.fill_paint().clone();
Expand All @@ -215,7 +215,7 @@ impl Paint {
color: Color,
blur: c_float,
) -> Option<skia_safe::Paint> {
if !(color != Color::TRANSPARENT && blur > 0.0) {
if color == Color::TRANSPARENT && blur > 0.0 {
return None;
}
let mut paint = self.stroke_paint().clone();
Expand Down
8 changes: 8 additions & 0 deletions crates/canvas-2d/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,14 @@ impl Context {
};
}

pub fn reset(&mut self) {
self.reset_state();
self.reset_transform();
self.with_canvas_dirty(|canvas| {
canvas.clear(Color::TRANSPARENT);
});
}

pub fn reset_state(&mut self) {
let direction = self.state.direction;
self.state = State::default();
Expand Down
7 changes: 7 additions & 0 deletions crates/canvas-2d/src/context/shadows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::os::raw::c_float;
use skia_safe::Color;

use crate::context::Context;
use crate::utils::color::parse_color;

impl Context {
pub fn set_shadow_blur(&mut self, blur: c_float) {
Expand Down Expand Up @@ -34,6 +35,12 @@ impl Context {
self.state.shadow_color = color;
}

pub fn set_shadow_color_str(&mut self, color: &str) {
if let Some(color) = parse_color(color) {
self.state.shadow_color = color;
}
}

pub fn set_shadow_color_rgba(&mut self, r: u8, g: u8, b: u8, a: u8) {
self.state.shadow_color = Color::from_argb(a, r, g, b);
}
Expand Down
2 changes: 1 addition & 1 deletion crates/canvas-2d/src/context/text_styles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,6 @@ impl Context {
}

pub fn get_letter_spacing(&self) -> &str {
return self.state.letter_spacing_value.as_str();
self.state.letter_spacing_value.as_str()
}
}
16 changes: 16 additions & 0 deletions crates/canvas-c/src/buffers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ impl U16Buffer {
pub fn length(&self) -> usize {
self.0.len()
}

pub fn into_vec(self) -> Vec<u16> {
self.0
}
}

impl Default for U16Buffer {
Expand Down Expand Up @@ -133,6 +137,10 @@ impl F32Buffer {
pub fn length(&self) -> usize {
self.0.len()
}

pub fn into_vec(self) -> Vec<f32> {
self.0
}
}

impl Default for F32Buffer {
Expand Down Expand Up @@ -164,6 +172,10 @@ impl I32Buffer {
pub fn length(&self) -> usize {
self.0.len()
}

pub fn into_vec(self) -> Vec<i32> {
self.0
}
}

impl Default for I32Buffer {
Expand Down Expand Up @@ -196,6 +208,10 @@ impl U32Buffer {
pub fn length(&self) -> usize {
self.0.len()
}

pub fn into_vec(self) -> Vec<u32> {
self.0
}
}

impl Default for U32Buffer {
Expand Down
82 changes: 75 additions & 7 deletions crates/canvas-c/src/c2d/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2211,10 +2211,11 @@ pub extern "C" fn canvas_native_context_fill(context: *mut CanvasRenderingContex
#[no_mangle]
pub extern "C" fn canvas_native_context_fill_with_path(
context: *mut CanvasRenderingContext2D,
path: &mut Path,
path: *mut Path,
rule: CanvasFillRule,
) {
let context = unsafe { &mut *context };
let path = unsafe { &mut *path };
context.context.fill_rule(Some(&mut path.0), rule.into());
}

Expand Down Expand Up @@ -2312,12 +2313,13 @@ pub extern "C" fn canvas_native_context_is_point_in_path_str(
#[no_mangle]
pub extern "C" fn canvas_native_context_is_point_in_path_with_path_str(
context: *mut CanvasRenderingContext2D,
path: &mut Path,
path: *mut Path,
x: f32,
y: f32,
rule: CanvasFillRule,
) -> bool {
let context = unsafe { &*context };
let path = unsafe { &*path };
context
.context
.point_in_path(Some(&path.0), x, y, rule.into())
Expand All @@ -2337,12 +2339,13 @@ pub extern "C" fn canvas_native_context_is_point_in_path(
#[no_mangle]
pub extern "C" fn canvas_native_context_is_point_in_path_with_path(
context: *mut CanvasRenderingContext2D,
path: &mut Path,
path: *mut Path,
x: f32,
y: f32,
rule: CanvasFillRule,
) -> bool {
let context = unsafe { &*context };
let path = unsafe { &*path };
context
.context
.point_in_path(Some(&path.0), x, y, rule.into())
Expand All @@ -2361,11 +2364,12 @@ pub extern "C" fn canvas_native_context_is_point_in_stroke(
#[no_mangle]
pub extern "C" fn canvas_native_context_is_point_in_stroke_with_path(
context: *mut CanvasRenderingContext2D,
path: &mut Path,
path: *mut Path,
x: f32,
y: f32,
) -> bool {
let context = unsafe { &*context };
let path = unsafe { &*path };
context.context.point_in_stroke(Some(&path.0), x, y)
}

Expand Down Expand Up @@ -2453,6 +2457,14 @@ pub extern "C" fn canvas_native_context_rect(
context.context.rect(x, y, width, height)
}

#[no_mangle]
pub extern "C" fn canvas_native_context_reset(
context: *mut CanvasRenderingContext2D
) {
let context = unsafe { &mut *context };
context.context.reset()
}

#[no_mangle]
pub extern "C" fn canvas_native_context_round_rect(
context: *mut CanvasRenderingContext2D,
Expand All @@ -2465,8 +2477,63 @@ pub extern "C" fn canvas_native_context_round_rect(
) {
let radii = unsafe { std::slice::from_raw_parts(radii, size) };
let context = unsafe { &mut *context };
if radii.len() == 8 {
context.context.round_rect(x, y, width, height, radii)


let size = radii.len();
if size == 0 {
return;
}
/*
[all-corners]
[top-left-and-bottom-right, top-right-and-bottom-left]
[top-left, top-right-and-bottom-left, bottom-right]
[top-left, top-right, bottom-right, bottom-left]
*/
let mut top_left = 0.;
let mut top_right = 0.;
let mut bottom_right = 0.;
let mut bottom_left = 0.;

match size {
1 => {
top_left = radii[0];
top_right = top_left;
bottom_right = top_left;
bottom_left = top_left;
}
2 => {
top_left = radii[0];
top_right = radii[1];
bottom_right = top_left;
bottom_left = top_right;
}

3 => {
top_left = radii[0];
top_right = radii[1];
bottom_right = radii[2];
bottom_left = top_right
}
4 => {
top_left = radii[0];
top_right = radii[1];
bottom_right = radii[2];
bottom_left = radii[3];
}
_ => {}
}

if size > 0 && size <= 4 {
context.context.round_rect(x, y, width, height, &[
top_left,
top_left,
top_right,
top_right,
bottom_right,
bottom_right,
bottom_left,
bottom_left,
]);
}
}

Expand Down Expand Up @@ -2565,9 +2632,10 @@ pub extern "C" fn canvas_native_context_stroke(context: *mut CanvasRenderingCont
#[no_mangle]
pub extern "C" fn canvas_native_context_stroke_with_path(
context: *mut CanvasRenderingContext2D,
path: &mut Path,
path: *mut Path,
) {
let context = unsafe { &mut *context };
let path = unsafe { &mut *path };
context.context.stroke(Some(&mut path.0));
}

Expand Down
15 changes: 14 additions & 1 deletion crates/canvas-c/src/c2d/paint/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
use std::ffi::CStr;
use std::os::raw::c_char;
use std::os::raw::{c_char, c_float};
use std::ptr;

use canvas_2d::utils::image::from_image_slice;

use crate::c2d::context::CanvasRenderingContext2D;

mod gradient;
pub use gradient::*;
mod pattern;

pub use pattern::*;

#[derive(Clone)]
pub struct PaintStyle(pub(crate) canvas_2d::context::fill_and_stroke_styles::paint::PaintStyle);

Expand Down Expand Up @@ -38,6 +41,16 @@ impl PaintStyle {
}
}
}


pub fn add_color_stop(&mut self, offset: c_float, color: &str) {
match &mut self.0 {
canvas_2d::context::fill_and_stroke_styles::paint::PaintStyle::Gradient(gradient) => {
gradient.add_color_stop_str(offset, color.as_ref())
}
_ => {}
}
}
}

#[no_mangle]
Expand Down
6 changes: 6 additions & 0 deletions crates/canvas-c/src/c2d/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ use std::os::raw::c_char;
#[derive(Clone)]
pub struct Path(pub(crate) canvas_2d::context::paths::path::Path);

impl Path {
pub fn with_d(d: &str) -> Self {
Path(canvas_2d::context::paths::path::Path::from_str(d))
}
}

impl Default for Path {
fn default() -> Self {
Self(Default::default())
Expand Down
4 changes: 3 additions & 1 deletion crates/canvas-c/src/image_asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use std::sync::Arc;
#[derive(Clone)]
pub struct ImageAsset(pub(crate) canvas_core::image_asset::ImageAsset);

unsafe impl Send for ImageAsset {}

impl ImageAsset {
pub fn new(asset: canvas_core::image_asset::ImageAsset) -> Self {
Self(asset)
Expand Down Expand Up @@ -227,7 +229,7 @@ pub extern "C" fn canvas_native_image_asset_load_from_raw(
) -> bool {
let array = unsafe { std::slice::from_raw_parts(array, size) };
let asset = unsafe { &*asset };
asset.load_from_raw_bytes(width, height,4, array.to_vec())
asset.load_from_raw_bytes(width, height, 4, array.to_vec())
}

#[no_mangle]
Expand Down
11 changes: 11 additions & 0 deletions crates/canvas-c/src/text_decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ use crate::c2d::CCow;
#[derive(Clone)]
pub struct TextDecoder(canvas_2d::context::text_decoder::TextDecoder);

impl TextDecoder {
pub fn encoding(&self) -> &str {
self.0.encoding()
}

pub fn decode(&self, data: &[u8]) -> String {
self.0.decode_to_string(data)
}
}


#[no_mangle]
pub extern "C" fn canvas_native_text_decoder_release(value: *mut TextDecoder) {
if value.is_null() {
Expand Down
9 changes: 9 additions & 0 deletions crates/canvas-c/src/text_encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ use crate::buffers::U8Buffer;

#[derive(Clone)]
pub struct TextEncoder(canvas_2d::context::text_encoder::TextEncoder);
impl TextEncoder {
pub fn encoding(&self) -> &str {
self.0.encoding()
}

pub fn encode(&self, value: &str) -> Vec<u8> {
self.0.encode(value)
}
}

#[no_mangle]
pub extern "C" fn canvas_native_text_encoder_release(value: *mut TextEncoder) {
Expand Down
Loading
Loading