@@ -17,7 +17,7 @@ use graphene_std::subpath::Subpath;
1717use graphene_std:: vector:: click_target:: ClickTargetType ;
1818use graphene_std:: vector:: misc:: { dvec2_to_point, point_to_dvec2} ;
1919use graphene_std:: vector:: stroke:: DashLengthsInput ;
20- use graphene_std:: vector:: style:: Stroke ;
20+ use graphene_std:: vector:: style:: { PaintOrder , Stroke } ;
2121use graphene_std:: vector:: { PointId , SegmentId , Vector } ;
2222use kurbo:: { self , Affine , CubicBez , ParamCurve , PathSeg } ;
2323use std:: collections:: HashMap ;
@@ -1031,69 +1031,97 @@ impl OverlayContext {
10311031
10321032 /// Fills the area inside the path (with an optional pattern). Assumes `color` is in gamma space.
10331033 /// 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- pub fn fill_path (
1035- & mut self ,
1036- subpaths : impl Iterator < Item = impl Borrow < Subpath < PointId > > > ,
1037- transform : DAffine2 ,
1038- stroke_transform : DAffine2 ,
1039- color : & Color ,
1040- with_pattern : bool ,
1041- clear_stroke_part : bool ,
1042- stroke_width : Option < f64 > ,
1043- ) {
1034+ pub fn fill_path ( & mut self , subpaths : impl Iterator < Item = impl Borrow < Subpath < PointId > > > , transform : DAffine2 , color : & Color ) {
1035+ self . draw_path_from_subpaths ( subpaths, transform) ;
1036+
1037+ let color_str = format ! ( "#{:?}" , color. to_rgba_hex_srgb( ) ) ;
1038+ self . render_context . set_fill_style_str ( & color_str. as_str ( ) ) ;
1039+ self . render_context . fill ( ) ;
1040+ }
1041+
1042+ pub fn fill_overlay ( & mut self , subpaths : impl Iterator < Item = impl Borrow < Subpath < PointId > > > , layer_to_viewport : DAffine2 , color : & Color , stroke : Option < Stroke > ) {
1043+ // Render for elements with fill
1044+ // Render for elements with fill only
1045+ // Render for elements with fill and stroke
1046+ //----PaintOrder
1047+ //----StrokeAlign
1048+
10441049 self . render_context . save ( ) ;
10451050 self . start_dpi_aware_transform ( ) ;
10461051
1047- if with_pattern {
1048- self . render_context . set_fill_style_canvas_pattern ( & self . fill_canvas_pattern ( color) ) ;
1049- } else {
1050- let color_str = format ! ( "#{:?}" , color. to_rgba_hex_srgb( ) ) ;
1051- self . render_context . set_fill_style_str ( & color_str. as_str ( ) ) ;
1052- }
1053- // let stroke_transform = Some(stroke_transform).filter(|transform| transform.matrix2.determinant() != 0.).unwrap_or(DAffine2::IDENTITY);
1054- let a = transform. matrix2 . x_axis . x ;
1055- let b = transform. matrix2 . y_axis . x ;
1056- let c = transform. matrix2 . x_axis . y ;
1057- let d = transform. matrix2 . y_axis . y ;
1058- let e = transform. translation . x ;
1059- let f = transform. translation . y ;
1060- self . render_context . transform ( a, b, c, d, e, f) ;
1061- self . draw_path_from_subpaths ( subpaths, stroke_transform) ;
1062- self . render_context . fill ( ) ;
1052+ if let Some ( stroke) = stroke {
1053+ let has_real_stroke = stroke. weight ( ) > 0. && stroke. transform . matrix2 . determinant ( ) != 0. ;
1054+ let applied_stroke_transform = if has_real_stroke { stroke. transform } else { layer_to_viewport } ;
1055+ let element_transform = if has_real_stroke { layer_to_viewport * stroke. transform . inverse ( ) } else { DAffine2 :: IDENTITY } ;
10631056
1064- // Make the stroke transparent and erase the fill area overlapping the stroke.
1065- if clear_stroke_part {
1066- self . render_context . set_line_width ( stroke_width. unwrap_or ( 1. ) ) ;
1067- self . render_context . set_global_composite_operation ( "destination-out" ) . expect ( "Failed to set global composite operation" ) ;
1068- self . render_context . set_stroke_style_str ( & "#000000" ) ;
1069- self . render_context . stroke ( ) ;
1057+ let [ a, b, c, d, e, f] = element_transform. to_cols_array ( ) ;
1058+ self . render_context . transform ( a, b, c, d, e, f) ;
1059+
1060+ self . draw_path_from_subpaths ( subpaths, applied_stroke_transform) ;
1061+
1062+ match stroke. paint_order {
1063+ PaintOrder :: StrokeAbove => {
1064+ self . render_context . set_fill_style_canvas_pattern ( & self . fill_canvas_pattern ( color) ) ;
1065+ self . render_context . fill ( ) ;
1066+
1067+ // Make the stroke transparent and erase the fill area overlapping the stroke.
1068+ self . render_context . set_stroke_style_str ( & "#000000" ) ;
1069+ self . render_context . set_line_width ( stroke. weight ( ) ) ;
1070+ self . render_context . set_global_composite_operation ( "destination-out" ) . expect ( "Failed to set global composite operation" ) ;
1071+ self . render_context . stroke ( ) ;
1072+ }
1073+ PaintOrder :: StrokeBelow => {
1074+ self . render_context . set_fill_style_canvas_pattern ( & self . fill_canvas_pattern ( color) ) ;
1075+ self . render_context . fill ( ) ;
1076+ }
1077+ }
1078+ } else {
1079+ self . render_context . set_fill_style_canvas_pattern ( & self . fill_canvas_pattern ( color) ) ;
1080+ self . render_context . fill ( ) ;
10701081 }
10711082
10721083 self . end_dpi_aware_transform ( ) ;
10731084 self . render_context . restore ( ) ;
10741085 }
10751086
1076- pub fn fill_stroke ( & mut self , subpaths : impl Iterator < Item = impl Borrow < Subpath < PointId > > > , transform : DAffine2 , overlay_stroke : & Stroke ) {
1087+ pub fn stroke_overlay ( & mut self , subpaths : impl Iterator < Item = impl Borrow < Subpath < PointId > > > , layer_to_viewport : DAffine2 , color : & Color , stroke : Option < Stroke > ) {
1088+ // Render for elements with stroke
1089+ //----StrokeAlign
1090+ // Render for elements with stroke only
1091+ // Render for elements with stroke and fill
1092+ //----PaintOrder
1093+
10771094 self . render_context . save ( ) ;
10781095 self . start_dpi_aware_transform ( ) ;
10791096
1080- self . render_context
1081- . set_stroke_style_canvas_pattern ( & self . fill_canvas_pattern ( & overlay_stroke. color . expect ( "Color should be set for fill_stroke()" ) ) ) ;
1082- self . render_context . set_line_width ( overlay_stroke. weight ) ;
1083- self . render_context . set_line_cap ( overlay_stroke. cap . html_canvas_name ( ) . as_str ( ) ) ;
1084- self . render_context . set_line_join ( overlay_stroke. join . html_canvas_name ( ) . as_str ( ) ) ;
1085- self . render_context . set_miter_limit ( overlay_stroke. join_miter_limit ) ;
1086- // let stroke_transform = Some(overlay_stroke.transform).filter(|transform| transform.matrix2.determinant() != 0.).unwrap_or(DAffine2::IDENTITY);
1087- // let stroke_transform = overlay_stroke.transform;
1088- let a = transform. matrix2 . x_axis . x ;
1089- let b = transform. matrix2 . y_axis . x ;
1090- let c = transform. matrix2 . x_axis . y ;
1091- let d = transform. matrix2 . y_axis . y ;
1092- let e = transform. translation . x ;
1093- let f = transform. translation . y ;
1094- self . render_context . transform ( a, b, c, d, e, f) ;
1095- self . draw_path_from_subpaths ( subpaths, overlay_stroke. transform ) ;
1096- self . render_context . stroke ( ) ;
1097+ if let Some ( stroke) = stroke {
1098+ let has_real_stroke = stroke. weight ( ) > 0. && stroke. transform . matrix2 . determinant ( ) != 0. ;
1099+ let applied_stroke_transform = if has_real_stroke { stroke. transform } else { layer_to_viewport } ;
1100+ let element_transform = if has_real_stroke { layer_to_viewport * stroke. transform . inverse ( ) } else { DAffine2 :: IDENTITY } ;
1101+
1102+ let [ a, b, c, d, e, f] = element_transform. to_cols_array ( ) ;
1103+ self . render_context . transform ( a, b, c, d, e, f) ;
1104+
1105+ self . draw_path_from_subpaths ( subpaths, applied_stroke_transform) ;
1106+
1107+ self . render_context . set_stroke_style_canvas_pattern ( & self . fill_canvas_pattern ( color) ) ;
1108+ self . render_context . set_line_width ( stroke. weight ) ;
1109+ self . render_context . set_line_cap ( stroke. cap . html_canvas_name ( ) . as_str ( ) ) ;
1110+ self . render_context . set_line_join ( stroke. join . html_canvas_name ( ) . as_str ( ) ) ;
1111+ self . render_context . set_miter_limit ( stroke. join_miter_limit ) ;
1112+ match stroke. paint_order {
1113+ PaintOrder :: StrokeAbove => {
1114+ self . render_context . stroke ( ) ;
1115+ }
1116+ PaintOrder :: StrokeBelow => {
1117+ self . render_context . stroke ( ) ;
1118+
1119+ self . render_context . set_fill_style_str ( & "#000000" ) ;
1120+ self . render_context . set_global_composite_operation ( "destination-out" ) . expect ( "Failed to set global composite operation" ) ;
1121+ self . render_context . fill ( ) ;
1122+ }
1123+ }
1124+ }
10971125
10981126 self . end_dpi_aware_transform ( ) ;
10991127 self . render_context . restore ( ) ;
0 commit comments