@@ -597,7 +597,7 @@ impl OverlayContext {
597
597
self . end_dpi_aware_transform ( ) ;
598
598
}
599
599
600
- pub fn push_path ( & mut self , subpaths : impl Iterator < Item = impl Borrow < Subpath < PointId > > > , transform : DAffine2 ) {
600
+ pub fn draw_path ( & mut self , subpaths : impl Iterator < Item = impl Borrow < Subpath < PointId > > > , transform : DAffine2 ) {
601
601
self . start_dpi_aware_transform ( ) ;
602
602
603
603
self . render_context . begin_path ( ) ;
@@ -611,28 +611,29 @@ impl OverlayContext {
611
611
612
612
self . render_context . move_to ( transform. transform_point2 ( first. start ( ) ) . x , transform. transform_point2 ( first. start ( ) ) . y ) ;
613
613
for curve in curves {
614
+ let splat_value = 0.5 ;
614
615
match curve. handles {
615
616
bezier_rs:: BezierHandles :: Linear => {
616
617
let a = transform. transform_point2 ( curve. end ( ) ) ;
617
- let a = a. round ( ) - DVec2 :: splat ( 0.5 ) ;
618
+ let a = a. round ( ) - DVec2 :: splat ( splat_value ) ;
618
619
619
620
self . render_context . line_to ( a. x , a. y )
620
621
}
621
622
bezier_rs:: BezierHandles :: Quadratic { handle } => {
622
623
let a = transform. transform_point2 ( handle) ;
623
624
let b = transform. transform_point2 ( curve. end ( ) ) ;
624
- let a = a. round ( ) - DVec2 :: splat ( 0.5 ) ;
625
- let b = b. round ( ) - DVec2 :: splat ( 0.5 ) ;
625
+ let a = a. round ( ) - DVec2 :: splat ( splat_value ) ;
626
+ let b = b. round ( ) - DVec2 :: splat ( splat_value ) ;
626
627
627
628
self . render_context . quadratic_curve_to ( a. x , a. y , b. x , b. y )
628
629
}
629
630
bezier_rs:: BezierHandles :: Cubic { handle_start, handle_end } => {
630
631
let a = transform. transform_point2 ( handle_start) ;
631
632
let b = transform. transform_point2 ( handle_end) ;
632
633
let c = transform. transform_point2 ( curve. end ( ) ) ;
633
- let a = a. round ( ) - DVec2 :: splat ( 0.5 ) ;
634
- let b = b. round ( ) - DVec2 :: splat ( 0.5 ) ;
635
- let c = c. round ( ) - DVec2 :: splat ( 0.5 ) ;
634
+ let a = a. round ( ) - DVec2 :: splat ( splat_value ) ;
635
+ let b = b. round ( ) - DVec2 :: splat ( splat_value ) ;
636
+ let c = c. round ( ) - DVec2 :: splat ( splat_value ) ;
636
637
637
638
self . render_context . bezier_curve_to ( a. x , a. y , b. x , b. y , c. x , c. y )
638
639
}
@@ -649,60 +650,64 @@ impl OverlayContext {
649
650
650
651
/// Used by the Select tool to outline a path selected or hovered.
651
652
pub fn outline ( & mut self , subpaths : impl Iterator < Item = impl Borrow < Subpath < PointId > > > , transform : DAffine2 , color : Option < & str > ) {
652
- self . push_path ( subpaths, transform) ;
653
+ self . draw_path ( subpaths, transform) ;
653
654
654
655
let color = color. unwrap_or ( COLOR_OVERLAY_BLUE ) ;
655
656
self . render_context . set_stroke_style_str ( color) ;
656
657
self . render_context . stroke ( ) ;
657
658
}
658
659
659
- /// Fills the area inside the path. Assumes `color` is in gamma space.
660
- /// Used by the Pen tool to show the path being closed.
661
- pub fn fill_path ( & mut self , subpaths : impl Iterator < Item = impl Borrow < Subpath < PointId > > > , transform : DAffine2 , color : & str ) {
662
- self . push_path ( subpaths, transform) ;
663
-
664
- self . render_context . set_fill_style_str ( color) ;
665
- self . render_context . fill ( ) ;
666
- }
667
-
668
- /// Fills the area inside the path with a pattern. Assumes `color` is in gamma space.
669
- /// Used by the fill tool to show the area to be filled.
670
- pub fn fill_path_pattern ( & mut self , color : & Color ) {
671
- const PATTERN_WIDTH : usize = 4 ;
672
- const PATTERN_HEIGHT : usize = 4 ;
673
-
674
- let pattern_canvas = OffscreenCanvas :: new ( PATTERN_WIDTH as u32 , PATTERN_HEIGHT as u32 ) . unwrap ( ) ;
675
- let pattern_context: OffscreenCanvasRenderingContext2d = pattern_canvas
676
- . get_context ( "2d" )
677
- . ok ( )
678
- . flatten ( )
679
- . expect ( "Failed to get canvas context" )
680
- . dyn_into ( )
681
- . expect ( "Context should be a canvas 2d context" ) ;
660
+ /// Fills the area inside the path (with an optional pattern). Assumes `color` is in gamma space.
661
+ /// Used by the Pen tool to show the path being closed and by the Fill tool to show the area to be filled with a pattern.
662
+ pub fn fill_path ( & mut self , subpaths : impl Iterator < Item = impl Borrow < Subpath < PointId > > > , transform : DAffine2 , color : & str , with_pattern : bool , width_for_inner_boundary : Option < f64 > ) {
663
+ self . render_context . set_line_width ( width_for_inner_boundary. unwrap_or ( 1. ) * self . device_pixel_ratio ) ;
664
+ self . draw_path ( subpaths, transform) ;
665
+
666
+ if with_pattern {
667
+ const PATTERN_WIDTH : usize = 4 ;
668
+ const PATTERN_HEIGHT : usize = 4 ;
669
+
670
+ let pattern_canvas = OffscreenCanvas :: new ( PATTERN_WIDTH as u32 , PATTERN_HEIGHT as u32 ) . unwrap ( ) ;
671
+ let pattern_context: OffscreenCanvasRenderingContext2d = pattern_canvas
672
+ . get_context ( "2d" )
673
+ . ok ( )
674
+ . flatten ( )
675
+ . expect ( "Failed to get canvas context" )
676
+ . dyn_into ( )
677
+ . expect ( "Context should be a canvas 2d context" ) ;
678
+
679
+ // 4x4 pixels, 4 components (RGBA) per pixel
680
+ let mut data = [ 0_u8 ; 4 * PATTERN_WIDTH * PATTERN_HEIGHT ] ;
681
+
682
+ // ┌▄▄┬──┬──┬──┐
683
+ // ├▀▀┼──┼──┼──┤
684
+ // ├──┼──┼▄▄┼──┤
685
+ // ├──┼──┼▀▀┼──┤
686
+ // └──┴──┴──┴──┘
687
+ let pixels = [ ( 0 , 0 ) , ( 2 , 2 ) ] ;
688
+ for & ( x, y) in & pixels {
689
+ let index = ( x + y * PATTERN_WIDTH as usize ) * 4 ;
690
+ data[ index..index + 4 ] . copy_from_slice ( & Color :: from_rgba_str ( color) . unwrap ( ) . to_rgba8_srgb ( ) ) ;
691
+ }
682
692
683
- // 4x4 pixels, 4 components (RGBA) per pixel
684
- let mut data = [ 0_u8 ; 4 * PATTERN_WIDTH * PATTERN_HEIGHT ] ;
693
+ let image_data = web_sys:: ImageData :: new_with_u8_clamped_array_and_sh ( wasm_bindgen:: Clamped ( & mut data) , PATTERN_WIDTH as u32 , PATTERN_HEIGHT as u32 ) . unwrap ( ) ;
694
+ pattern_context. put_image_data ( & image_data, 0. , 0. ) . unwrap ( ) ;
695
+ let pattern = self . render_context . create_pattern_with_offscreen_canvas ( & pattern_canvas, "repeat" ) . unwrap ( ) . unwrap ( ) ;
685
696
686
- // ┌▄▄┬──┬──┬──┐
687
- // ├▀▀┼──┼──┼──┤
688
- // ├──┼──┼▄▄┼──┤
689
- // ├──┼──┼▀▀┼──┤
690
- // └──┴──┴──┴──┘
691
- let pixels = [ ( 0 , 0 ) , ( 2 , 2 ) ] ;
692
- for & ( x, y) in & pixels {
693
- let index = ( x + y * PATTERN_WIDTH as usize ) * 4 ;
694
- data[ index..index + 4 ] . copy_from_slice ( & color. to_rgba8_srgb ( ) ) ;
697
+ self . render_context . set_fill_style_canvas_pattern ( & pattern) ;
698
+ self . render_context . fill ( ) ;
699
+ } else {
700
+ self . render_context . set_fill_style_str ( color) ;
701
+ self . render_context . fill ( ) ;
695
702
}
696
703
697
- let image_data = web_sys:: ImageData :: new_with_u8_clamped_array_and_sh ( wasm_bindgen:: Clamped ( & mut data) , PATTERN_WIDTH as u32 , PATTERN_HEIGHT as u32 ) . unwrap ( ) ;
698
- pattern_context. put_image_data ( & image_data, 0. , 0. ) . unwrap ( ) ;
699
- let pattern = self . render_context . create_pattern_with_offscreen_canvas ( & pattern_canvas, "repeat" ) . unwrap ( ) . unwrap ( ) ;
700
-
701
- self . render_context . set_fill_style_canvas_pattern ( & pattern) ;
702
- self . render_context . fill ( ) ;
704
+ self . render_context . set_line_width ( 1. ) ;
703
705
}
704
706
705
- pub fn fill_stroke_pattern ( & mut self , color : & Color ) {
707
+ pub fn fill_stroke ( & mut self , subpaths : impl Iterator < Item = impl Borrow < Subpath < PointId > > > , transform : DAffine2 , color : & Color , width : Option < f64 > ) {
708
+ self . render_context . set_line_width ( width. unwrap_or ( 1. ) * self . device_pixel_ratio ) ;
709
+ self . draw_path ( subpaths, transform) ;
710
+
706
711
const PATTERN_WIDTH : usize = 4 ;
707
712
const PATTERN_HEIGHT : usize = 4 ;
708
713
@@ -735,6 +740,8 @@ impl OverlayContext {
735
740
736
741
self . render_context . set_stroke_style_canvas_pattern ( & pattern) ;
737
742
self . render_context . stroke ( ) ;
743
+
744
+ self . render_context . set_line_width ( 1. ) ;
738
745
}
739
746
740
747
pub fn get_width ( & self , text : & str ) -> f64 {
0 commit comments