Skip to content

Commit 6d60739

Browse files
committed
chore: updates
1 parent 1b760f5 commit 6d60739

62 files changed

Lines changed: 6984 additions & 6121 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/demo/src/plugin-demos/canvas-chartjs.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export function navigatingTo(args: EventData) {
1111
export class DemoModel extends DemoSharedCanvasChartjs {
1212
ready(event) {
1313
const canvas = event.object;
14-
new Chart(canvas, {
14+
const chart = new Chart(canvas, {
1515
platform: NativeScriptPlatform,
1616
type: 'bar',
1717
data: {
@@ -25,7 +25,7 @@ export class DemoModel extends DemoSharedCanvasChartjs {
2525
],
2626
},
2727
options: {
28-
responsive: false,
28+
responsive: true,
2929
scales: {
3030
y: {
3131
beginAtZero: true,

apps/demo/src/plugin-demos/canvas-chartjs.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<ActionBar title="canvas-chartjs" icon="" class="action-bar">
44
</ActionBar>
55
</Page.actionBar>
6-
<GridLayout class="p-20">
6+
<GridLayout height="100%" width="100%">
77
<canvas:Canvas style="width:100%;height:100%;" ready="{{ ready }}"/>
88
</GridLayout>
99
</Page>

crates/canvas-2d/src/context/drawing_images/mod.rs

Lines changed: 106 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ use canvas_core::image_asset::ImageAsset;
66
use crate::context::Context;
77

88
impl Context {
9+
#[cfg(feature = "2d")]
10+
fn promote_to_gpu(&mut self, img: Image) -> Image {
11+
if let Some(ctx) = self.direct_context.as_mut() {
12+
img.new_texture_image(ctx, skia_safe::gpu::Mipmapped::No)
13+
.unwrap_or(img)
14+
} else {
15+
img
16+
}
17+
}
18+
919
pub fn draw_image_asset_src_xywh_dst_xywh(
1020
&mut self,
1121
image: &ImageAsset,
@@ -18,24 +28,33 @@ impl Context {
1828
dst_width: f32,
1929
dst_height: f32,
2030
) {
31+
#[cfg(feature = "2d")]
32+
if let Some(img) = image.raster_image() {
33+
let img = self.promote_to_gpu(img);
34+
self.draw_image_src_xywh_dst_xywh(
35+
&img, src_x, src_y, src_width, src_height,
36+
dst_x, dst_y, dst_width, dst_height,
37+
);
38+
return;
39+
}
40+
2141
image.with_skia_image_bytes(|image, bytes| {
2242
if let Some(image) = image {
2343
self.draw_image_src_xywh_dst_xywh(
24-
&image, src_x, src_y, src_width, src_height, dst_x, dst_y, dst_width, dst_height,
44+
image, src_x, src_y, src_width, src_height,
45+
dst_x, dst_y, dst_width, dst_height,
2546
)
26-
} else {
27-
if let Some((dimensions, bytes)) = bytes {
28-
let (width, height) = dimensions;
29-
if let Some(image) = crate::utils::image::from_image_slice_no_copy(
30-
bytes,
31-
width as i32,
32-
height as i32,
33-
) {
34-
self.draw_image_src_xywh_dst_xywh(
35-
&image, src_x, src_y, src_width, src_height, dst_x, dst_y, dst_width,
36-
dst_height,
37-
)
38-
}
47+
} else if let Some((dimensions, bytes)) = bytes {
48+
let (width, height) = dimensions;
49+
if let Some(image) = crate::utils::image::from_image_slice_no_copy(
50+
bytes,
51+
width as i32,
52+
height as i32,
53+
) {
54+
self.draw_image_src_xywh_dst_xywh(
55+
&image, src_x, src_y, src_width, src_height,
56+
dst_x, dst_y, dst_width, dst_height,
57+
)
3958
}
4059
}
4160
});
@@ -47,38 +66,51 @@ impl Context {
4766
src_rect: impl Into<Rect>,
4867
dst_rect: impl Into<Rect>,
4968
) {
69+
let src_rect = src_rect.into();
70+
let dst_rect = dst_rect.into();
71+
72+
#[cfg(feature = "2d")]
73+
if let Some(img) = image.raster_image() {
74+
let img = self.promote_to_gpu(img);
75+
self.draw_image(&img, src_rect, dst_rect);
76+
return;
77+
}
78+
5079
image.with_skia_image_bytes(|image, bytes| {
5180
if let Some(image) = image {
52-
self.draw_image(&image, src_rect, dst_rect)
53-
} else {
54-
if let Some((dimensions, bytes)) = bytes {
55-
let (width, height) = dimensions;
56-
if let Some(image) = crate::utils::image::from_image_slice_no_copy(
57-
bytes,
58-
width as i32,
59-
height as i32,
60-
) {
61-
self.draw_image(&image, src_rect, dst_rect)
62-
}
81+
self.draw_image(image, src_rect, dst_rect)
82+
} else if let Some((dimensions, bytes)) = bytes {
83+
let (width, height) = dimensions;
84+
if let Some(image) = crate::utils::image::from_image_slice_no_copy(
85+
bytes,
86+
width as i32,
87+
height as i32,
88+
) {
89+
self.draw_image(&image, src_rect, dst_rect)
6390
}
6491
}
6592
});
6693
}
6794

6895
pub fn draw_image_asset_dx_dy(&mut self, image: &ImageAsset, x: f32, y: f32) {
96+
#[cfg(feature = "2d")]
97+
if let Some(img) = image.raster_image() {
98+
let img = self.promote_to_gpu(img);
99+
self.draw_image_dx_dy(&img, x, y);
100+
return;
101+
}
102+
69103
image.with_skia_image_bytes(|image, bytes| {
70104
if let Some(image) = image {
71-
self.draw_image_dx_dy(&image, x, y)
72-
} else {
73-
if let Some((dimensions, bytes)) = bytes {
74-
let (width, height) = dimensions;
75-
if let Some(image) = crate::utils::image::from_image_slice_no_copy(
76-
bytes,
77-
width as i32,
78-
height as i32,
79-
) {
80-
self.draw_image_dx_dy(&image, x, y)
81-
}
105+
self.draw_image_dx_dy(image, x, y)
106+
} else if let Some((dimensions, bytes)) = bytes {
107+
let (width, height) = dimensions;
108+
if let Some(image) = crate::utils::image::from_image_slice_no_copy(
109+
bytes,
110+
width as i32,
111+
height as i32,
112+
) {
113+
self.draw_image_dx_dy(&image, x, y)
82114
}
83115
}
84116
});
@@ -92,36 +124,48 @@ impl Context {
92124
width: f32,
93125
height: f32,
94126
) {
127+
#[cfg(feature = "2d")]
128+
if let Some(img) = image.raster_image() {
129+
let img = self.promote_to_gpu(img);
130+
self.draw_image_dx_dy_dw_dh(&img, x, y, width, height);
131+
return;
132+
}
133+
95134
image.with_skia_image_bytes(|image, bytes| {
96135
if let Some(image) = image {
97-
self.draw_image_dx_dy_dw_dh(&image, x, y, width, height)
98-
} else {
99-
if let Some((dimensions, bytes)) = bytes {
100-
let (w, h) = dimensions;
101-
if let Some(image) =
102-
crate::utils::image::from_image_slice_no_copy(bytes, w as i32, h as i32)
103-
{
104-
self.draw_image_dx_dy_dw_dh(&image, x, y, width, height)
105-
}
136+
self.draw_image_dx_dy_dw_dh(image, x, y, width, height)
137+
} else if let Some((dimensions, bytes)) = bytes {
138+
let (w, h) = dimensions;
139+
if let Some(image) =
140+
crate::utils::image::from_image_slice_no_copy(bytes, w as i32, h as i32)
141+
{
142+
self.draw_image_dx_dy_dw_dh(&image, x, y, width, height)
106143
}
107144
}
108145
});
109146
}
110147

111148
pub fn draw_image_asset_with_rect(&mut self, image: &ImageAsset, dst_rect: impl Into<Rect>) {
149+
let dst_rect = dst_rect.into();
150+
151+
#[cfg(feature = "2d")]
152+
if let Some(img) = image.raster_image() {
153+
let img = self.promote_to_gpu(img);
154+
self.draw_image_with_rect(&img, dst_rect);
155+
return;
156+
}
157+
112158
image.with_skia_image_bytes(|image, bytes| {
113159
if let Some(image) = image {
114-
self.draw_image_with_rect(&image, dst_rect)
115-
} else {
116-
if let Some((dimensions, bytes)) = bytes {
117-
let (width, height) = dimensions;
118-
if let Some(image) = crate::utils::image::from_image_slice_no_copy(
119-
bytes,
120-
width as i32,
121-
height as i32,
122-
) {
123-
self.draw_image_with_rect(&image, dst_rect)
124-
}
160+
self.draw_image_with_rect(image, dst_rect)
161+
} else if let Some((dimensions, bytes)) = bytes {
162+
let (width, height) = dimensions;
163+
if let Some(image) = crate::utils::image::from_image_slice_no_copy(
164+
bytes,
165+
width as i32,
166+
height as i32,
167+
) {
168+
self.draw_image_with_rect(&image, dst_rect)
125169
}
126170
}
127171
});
@@ -149,7 +193,8 @@ impl Context {
149193
pub fn draw_image_dx_dy(&mut self, image: &Image, x: f32, y: f32) {
150194
#[cfg(any(target_os = "macos", target_os = "ios"))]
151195
let _ = unsafe { objc2_foundation::NSAutoreleasePool::new() };
152-
#[cfg(feature = "gl")]{
196+
#[cfg(feature = "gl")]
197+
{
153198
if let Some(ref context) = self.gl_context {
154199
context.make_current();
155200
}
@@ -178,7 +223,8 @@ impl Context {
178223
fn draw_image(&mut self, image: &Image, src_rect: impl Into<Rect>, dst_rect: impl Into<Rect>) {
179224
#[cfg(any(target_os = "macos", target_os = "ios"))]
180225
let _ = unsafe { objc2_foundation::NSAutoreleasePool::new() };
181-
#[cfg(feature = "gl")]{
226+
#[cfg(feature = "gl")]
227+
{
182228
if let Some(ref context) = self.gl_context {
183229
context.make_current();
184230
}
@@ -215,14 +261,14 @@ impl Context {
215261
fn draw_image_with_rect(&mut self, image: &Image, dst_rect: impl Into<Rect>) {
216262
#[cfg(any(target_os = "macos", target_os = "ios"))]
217263
let _ = unsafe { objc2_foundation::NSAutoreleasePool::new() };
218-
#[cfg(feature = "gl")]{
264+
#[cfg(feature = "gl")]
265+
{
219266
if let Some(ref context) = self.gl_context {
220267
context.make_current();
221268
}
222269
}
223270

224271
let dimensions = image.dimensions();
225-
226272
let src_rect = Rect::from_xywh(0., 0., dimensions.width as f32, dimensions.height as f32);
227273
let dst_rect = dst_rect.into();
228274

crates/canvas-2d/src/context/fill_and_stroke_styles/paint.rs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ impl PaintStyle {
5757

5858
#[inline]
5959
pub fn new_color_str(color: &str) -> Option<Self> {
60-
// Fast path for common named colors and hex patterns to avoid csscolorparser overhead
6160
match color {
6261
"black" | "#000" | "#000000" => return Some(Self::Color(Color::BLACK)),
6362
"white" | "#fff" | "#FFF" | "#ffffff" | "#FFFFFF" => return Some(Self::Color(Color::WHITE)),
@@ -67,7 +66,6 @@ impl PaintStyle {
6766
"transparent" => return Some(Self::Color(Color::TRANSPARENT)),
6867
_ => {}
6968
}
70-
// Fast path for #RRGGBB hex (most common programmatic format)
7169
if color.len() == 7 && color.as_bytes()[0] == b'#' {
7270
if let (Ok(r), Ok(g), Ok(b_val)) = (
7371
u8::from_str_radix(&color[1..3], 16),
@@ -77,7 +75,6 @@ impl PaintStyle {
7775
return Some(Self::Color(Color::from_argb(255, r, g, b_val)));
7876
}
7977
}
80-
// Fast path for rgb(r,g,b) and rgba(r,g,b,a) — the most common programmatic formats
8178
if let Some(parsed) = Self::parse_rgb_rgba_fast(color) {
8279
return Some(parsed);
8380
}
@@ -93,13 +90,11 @@ impl PaintStyle {
9390
.ok()
9491
}
9592

96-
/// Fast inline parser for `rgb(r,g,b)` and `rgba(r,g,b,a)` strings.
97-
/// Avoids the full csscolorparser overhead for the most common programmatic color format.
93+
9894
#[inline]
9995
fn parse_rgb_rgba_fast(color: &str) -> Option<Self> {
10096
let bytes = color.as_bytes();
10197
let len = bytes.len();
102-
// Minimum: "rgb(0,0,0)" = 10 chars
10398
if len < 10 {
10499
return None;
105100
}
@@ -108,7 +103,6 @@ impl PaintStyle {
108103
if !is_rgba && !is_rgb {
109104
return None;
110105
}
111-
// Must end with ')'
112106
if bytes[len - 1] != b')' {
113107
return None;
114108
}
@@ -351,6 +345,15 @@ impl Default for Paint {
351345
}
352346

353347
pub fn paint_style_set_color_with_string(context: &mut Context, is_fill: bool, color: &str) {
348+
if let Some(style) = PaintStyle::new_color_str(color) {
349+
if is_fill {
350+
context.set_fill_style(style);
351+
} else {
352+
context.set_stroke_style(style);
353+
}
354+
return;
355+
}
356+
354357
if let Ok(color) = color.parse::<csscolorparser::Color>() {
355358
let color = color.to_rgba8();
356359
let style = PaintStyle::Color(Color::from_argb(color[3], color[0], color[1], color[2]));
@@ -393,3 +396,23 @@ pub fn paint_style_set_color_with_rgba_4f(
393396
context.set_stroke_style(style);
394397
}
395398
}
399+
400+
#[cfg(test)]
401+
mod tests {
402+
use super::*;
403+
404+
#[test]
405+
fn new_color_str_basic() {
406+
// hex
407+
let style = PaintStyle::new_color_str("#ff0000").expect("parse hex");
408+
assert_eq!(style.get_parsed_color().unwrap(), "#ff0000");
409+
410+
// rgb
411+
let style = PaintStyle::new_color_str("rgb(255,0,0)").expect("parse rgb");
412+
assert_eq!(style.get_parsed_color().unwrap(), "#ff0000");
413+
414+
// rgba with 0.5 alpha
415+
let style = PaintStyle::new_color_str("rgba(255,0,0,0.5)").expect("parse rgba");
416+
assert_eq!(style.get_parsed_color().unwrap(), "rgba(255, 0, 0, 0.5)");
417+
}
418+
}

0 commit comments

Comments
 (0)