@@ -61,7 +61,7 @@ pub enum OverlaysType {
6161}
6262
6363#[ derive( PartialEq , Copy , Clone , Debug , serde:: Serialize , serde:: Deserialize , specta:: Type ) ]
64- #[ serde( default = "OverlaysVisibilitySettings::default" ) ]
64+ #[ serde( default ) ]
6565pub struct OverlaysVisibilitySettings {
6666 pub all : bool ,
6767 pub artboard_name : bool ,
@@ -910,7 +910,7 @@ impl OverlayContext {
910910
911911 pub fn draw_path_from_subpaths ( & mut self , subpaths : impl Iterator < Item = impl Borrow < Subpath < PointId > > > , stroke_transform : DAffine2 ) -> bool {
912912 // Subpaths on a layer is considered "closed" only if all subpaths are closed.
913- let mut is_closed = true ;
913+ let mut is_closed_on_all = true ;
914914 self . render_context . begin_path ( ) ;
915915 for subpath in subpaths {
916916 let subpath = subpath. borrow ( ) . clone ( ) ;
@@ -954,10 +954,10 @@ impl OverlayContext {
954954 if subpath. closed ( ) {
955955 self . render_context . close_path ( ) ;
956956 } else {
957- is_closed = false ;
957+ is_closed_on_all = false ;
958958 }
959959 }
960- return is_closed ;
960+ return is_closed_on_all ;
961961 }
962962
963963 /// Used by the Select tool to outline a path or a free point when selected or hovered.
@@ -1031,17 +1031,18 @@ impl OverlayContext {
10311031 return pattern;
10321032 }
10331033
1034- /// Fills the area inside the path (with an optional pattern). Assumes `color` is in gamma space.
1035- /// 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.
1034+ /// Used by the Pen tool to show the path being closed.
10361035 pub fn fill_path ( & mut self , subpaths : impl Iterator < Item = impl Borrow < Subpath < PointId > > > , transform : DAffine2 , color : & Color ) {
10371036 self . draw_path_from_subpaths ( subpaths, transform) ;
10381037
1039- let color_str = format ! ( "#{:? }" , color. to_rgba_hex_srgb( ) ) ;
1040- self . render_context . set_fill_style_str ( & color_str. as_str ( ) ) ;
1038+ let color_str = format ! ( "#{}" , color. to_rgba_hex_srgb( ) ) ;
1039+ self . render_context . set_fill_style_str ( & color_str) ;
10411040 self . render_context . fill ( ) ;
10421041 }
10431042
1044- pub fn fill_overlay ( & mut self , subpaths : impl Iterator < Item = impl Borrow < Subpath < PointId > > > , layer_to_viewport : DAffine2 , color : & Color , stroke : Option < Stroke > ) {
1043+ /// Fills the shape's fill region with a pattern of the given color. Assumes `color` is in gamma space.
1044+ /// https://www.w3schools.com/tags/canvas_globalcompositeoperation.asp
1045+ pub fn fill_overlay ( & mut self , subpaths : impl Iterator < Item = impl Borrow < Subpath < PointId > > > , transform : DAffine2 , color : & Color , stroke : Option < Stroke > ) {
10451046 // Render for elements with fill
10461047 // Render for elements with fill only
10471048 // Render for elements with fill and stroke
@@ -1053,13 +1054,15 @@ impl OverlayContext {
10531054
10541055 if let Some ( stroke) = stroke {
10551056 let has_real_stroke = stroke. weight ( ) > 0. && stroke. transform . matrix2 . determinant ( ) != 0. ;
1056- let applied_stroke_transform = if has_real_stroke { stroke. transform } else { layer_to_viewport } ;
1057- let element_transform = if has_real_stroke { layer_to_viewport * stroke. transform . inverse ( ) } else { DAffine2 :: IDENTITY } ;
1057+ let applied_stroke_transform = if has_real_stroke { stroke. transform } else { transform } ;
1058+ let element_transform = if has_real_stroke { transform * stroke. transform . inverse ( ) } else { DAffine2 :: IDENTITY } ;
10581059
10591060 let [ a, b, c, d, e, f] = element_transform. to_cols_array ( ) ;
10601061 self . render_context . transform ( a, b, c, d, e, f) . expect ( "element_transform should be set to render stroke properly" ) ;
10611062
1062- let is_closed = self . draw_path_from_subpaths ( subpaths, applied_stroke_transform) ;
1063+ // For layers with open subpaths, stroke align is ignored and set to default
1064+ let is_closed_on_all = self . draw_path_from_subpaths ( subpaths, applied_stroke_transform) ;
1065+ let stroke_align = if is_closed_on_all { stroke. align } else { StrokeAlign :: Center } ;
10631066
10641067 let do_fill = || {
10651068 self . render_context . set_fill_style_canvas_pattern ( & self . fill_canvas_pattern ( color) ) ;
@@ -1076,37 +1079,24 @@ impl OverlayContext {
10761079 . expect ( "Failed to set global composite operation" ) ;
10771080 } ;
10781081
1079- if is_closed {
1080- match ( stroke. align , stroke. paint_order ) {
1081- ( StrokeAlign :: Inside , PaintOrder :: StrokeAbove ) => {
1082- do_fill ( ) ;
1083- composite_mode ( "destination-out" ) ;
1084- do_stroke ( stroke. weight ( ) * 2. ) ;
1085- }
1086- ( StrokeAlign :: Inside , PaintOrder :: StrokeBelow ) => do_fill ( ) ,
1087- ( StrokeAlign :: Center , PaintOrder :: StrokeAbove ) => {
1088- do_fill ( ) ;
1089- composite_mode ( "destination-out" ) ;
1090- do_stroke ( stroke. weight ( ) ) ;
1091- }
1092- ( StrokeAlign :: Center , PaintOrder :: StrokeBelow ) => {
1093- do_fill ( ) ;
1094- }
1095- // Paint order does not affect this
1096- ( StrokeAlign :: Outside , _) => {
1097- do_fill ( ) ;
1098- }
1082+ match ( stroke_align, stroke. paint_order ) {
1083+ ( StrokeAlign :: Inside , PaintOrder :: StrokeAbove ) => {
1084+ do_fill ( ) ;
1085+ composite_mode ( "destination-out" ) ;
1086+ do_stroke ( stroke. weight ( ) * 2. ) ;
10991087 }
1100- } else {
1101- match stroke. paint_order {
1102- PaintOrder :: StrokeAbove => {
1103- do_fill ( ) ;
1104- composite_mode ( "destination-out" ) ;
1105- do_stroke ( stroke. weight ( ) ) ;
1106- }
1107- PaintOrder :: StrokeBelow => {
1108- do_fill ( ) ;
1109- }
1088+ ( StrokeAlign :: Inside , PaintOrder :: StrokeBelow ) => do_fill ( ) ,
1089+ ( StrokeAlign :: Center , PaintOrder :: StrokeAbove ) => {
1090+ do_fill ( ) ;
1091+ composite_mode ( "destination-out" ) ;
1092+ do_stroke ( stroke. weight ( ) ) ;
1093+ }
1094+ ( StrokeAlign :: Center , PaintOrder :: StrokeBelow ) => {
1095+ do_fill ( ) ;
1096+ }
1097+ // Paint order does not affect this
1098+ ( StrokeAlign :: Outside , _) => {
1099+ do_fill ( ) ;
11101100 }
11111101 }
11121102 } else {
@@ -1118,8 +1108,9 @@ impl OverlayContext {
11181108 self . render_context . restore ( ) ;
11191109 }
11201110
1121- // WARN: Don't use source-in, destination-atop, destination-in, copy
1122- // on the main canvas as it will erase the existing overlays
1111+ /// Fills the shape's stroke region with a pattern of the given color. Assumes `color` is in gamma space.
1112+ /// WARN: Don't use source-in, destination-atop, destination-in, copy
1113+ /// on the main canvas as it will erase the existing overlays
11231114 pub fn stroke_overlay ( & mut self , subpaths : impl Iterator < Item = impl Borrow < Subpath < PointId > > > , layer_to_viewport : DAffine2 , color : & Color , stroke : Option < Stroke > ) {
11241115 // Render for elements with stroke
11251116 //----StrokeAlign
@@ -1138,7 +1129,9 @@ impl OverlayContext {
11381129 let [ a, b, c, d, e, f] = element_transform. to_cols_array ( ) ;
11391130 self . render_context . transform ( a, b, c, d, e, f) . expect ( "element_transform should be set to render stroke properly" ) ;
11401131
1141- let is_closed = self . draw_path_from_subpaths ( subpaths, applied_stroke_transform) ;
1132+ // For layers with open subpaths, stroke align is ignored and set to default
1133+ let is_closed_on_all = self . draw_path_from_subpaths ( subpaths, applied_stroke_transform) ;
1134+ let stroke_align = if is_closed_on_all { stroke. align } else { StrokeAlign :: Center } ;
11421135
11431136 let do_stroke = |stroke_weight : f64 | {
11441137 self . render_context . set_stroke_style_canvas_pattern ( & self . fill_canvas_pattern ( color) ) ;
@@ -1158,39 +1151,26 @@ impl OverlayContext {
11581151 . expect ( "Failed to set global composite operation" ) ;
11591152 } ;
11601153
1161- if is_closed {
1162- match ( stroke. align , stroke. paint_order ) {
1163- ( StrokeAlign :: Inside , PaintOrder :: StrokeAbove ) => {
1164- // Clips away the stroke lying outside the path drawn from the subpaths
1165- self . render_context . clip ( ) ;
1166- do_stroke ( stroke. weight ( ) * 2. ) ;
1167- }
1168- ( StrokeAlign :: Inside , PaintOrder :: StrokeBelow ) => { }
1169- ( StrokeAlign :: Center , PaintOrder :: StrokeAbove ) => {
1170- do_stroke ( stroke. weight ( ) ) ;
1171- }
1172- ( StrokeAlign :: Center , PaintOrder :: StrokeBelow ) => {
1173- do_stroke ( stroke. weight ( ) ) ;
1174- composite_mode ( "destination-out" ) ;
1175- do_fill ( ) ;
1176- }
1177- // Paint order does not affect this
1178- ( StrokeAlign :: Outside , _) => {
1179- do_stroke ( stroke. weight ( ) * 2. ) ;
1180- composite_mode ( "destination-out" ) ;
1181- do_fill ( ) ;
1182- }
1154+ match ( stroke_align, stroke. paint_order ) {
1155+ ( StrokeAlign :: Inside , PaintOrder :: StrokeAbove ) => {
1156+ // Clips away the stroke lying outside the path drawn from the subpaths
1157+ self . render_context . clip ( ) ;
1158+ do_stroke ( stroke. weight ( ) * 2. ) ;
11831159 }
1184- } else {
1185- match stroke. paint_order {
1186- PaintOrder :: StrokeAbove => {
1187- do_stroke ( stroke. weight ( ) ) ;
1188- }
1189- PaintOrder :: StrokeBelow => {
1190- do_stroke ( stroke. weight ( ) ) ;
1191- composite_mode ( "destination-out" ) ;
1192- do_fill ( ) ;
1193- }
1160+ ( StrokeAlign :: Inside , PaintOrder :: StrokeBelow ) => { }
1161+ ( StrokeAlign :: Center , PaintOrder :: StrokeAbove ) => {
1162+ do_stroke ( stroke. weight ( ) ) ;
1163+ }
1164+ ( StrokeAlign :: Center , PaintOrder :: StrokeBelow ) => {
1165+ do_stroke ( stroke. weight ( ) ) ;
1166+ composite_mode ( "destination-out" ) ;
1167+ do_fill ( ) ;
1168+ }
1169+ // Paint order does not affect this
1170+ ( StrokeAlign :: Outside , _) => {
1171+ do_stroke ( stroke. weight ( ) * 2. ) ;
1172+ composite_mode ( "destination-out" ) ;
1173+ do_fill ( ) ;
11941174 }
11951175 }
11961176 }
0 commit comments