11use crate :: renderer:: { RenderParams , format_transform_matrix} ;
2+ use core_types:: table:: Table ;
23use core_types:: uuid:: generate_uuid;
3- use glam:: DAffine2 ;
4- use graphic_types:: vector_types:: gradient:: { Gradient , GradientType } ;
4+ use core_types:: { ATTR_GRADIENT_TYPE , ATTR_SPREAD_METHOD , ATTR_TRANSFORM , Color } ;
5+ use glam:: { DAffine2 , DVec2 } ;
6+ use graphic_types:: Graphic ;
7+ use graphic_types:: graphic:: fill_to_paint;
8+ use graphic_types:: vector_types:: gradient:: GradientType ;
59use graphic_types:: vector_types:: vector:: style:: { Fill , PaintOrder , PathStyle , Stroke , StrokeAlign , StrokeCap , StrokeJoin } ;
610use std:: fmt:: Write ;
11+ use vector_types:: GradientStops ;
712use vector_types:: gradient:: GradientSpreadMethod ;
813
914pub trait RenderExt {
1015 type Output ;
1116 fn render ( & self , svg_defs : & mut String , element_transform : DAffine2 , stroke_transform : DAffine2 , bounds : DAffine2 , transformed_bounds : DAffine2 , render_params : & RenderParams ) -> Self :: Output ;
1217}
1318
14- impl RenderExt for Gradient {
19+ impl RenderExt for Table < Color > {
20+ type Output = String ;
21+
22+ fn render (
23+ & self ,
24+ _svg_defs : & mut String ,
25+ _element_transform : DAffine2 ,
26+ _stroke_transform : DAffine2 ,
27+ _bounds : DAffine2 ,
28+ _transformed_bounds : DAffine2 ,
29+ _render_params : & RenderParams ,
30+ ) -> Self :: Output {
31+ let Some ( color) = self . element ( 0 ) else { return String :: new ( ) } ;
32+
33+ let mut result = format ! ( r##" fill="#{}""## , color. to_rgb_hex_srgb_from_gamma( ) ) ;
34+ if color. a ( ) < 1. {
35+ let _ = write ! ( result, r#" fill-opacity="{}""# , ( color. a( ) * 1000. ) . round( ) / 1000. ) ;
36+ }
37+
38+ result
39+ }
40+ }
41+
42+ impl RenderExt for Table < GradientStops > {
1543 type Output = u64 ;
1644
1745 /// Adds the gradient def through mutating the first argument, returning the gradient ID.
1846 fn render ( & self , svg_defs : & mut String , element_transform : DAffine2 , stroke_transform : DAffine2 , bounds : DAffine2 , transformed_bounds : DAffine2 , _render_params : & RenderParams ) -> Self :: Output {
1947 let mut stop = String :: new ( ) ;
20- for ( position, color, original_midpoint) in self . stops . interpolated_samples ( ) {
48+
49+ let Some ( stops) = self . element ( 0 ) else { return 0 } ;
50+ let gradient_type: GradientType = self . attribute_cloned_or_default ( ATTR_GRADIENT_TYPE , 0 ) ;
51+ let gradient_transform: DAffine2 = self . attribute_cloned_or_default ( ATTR_TRANSFORM , 0 ) ;
52+ let spread_method: GradientSpreadMethod = self . attribute_cloned_or_default ( ATTR_SPREAD_METHOD , 0 ) ;
53+
54+ for ( position, color, original_midpoint) in stops. interpolated_samples ( ) {
2155 stop. push_str ( "<stop" ) ;
2256 if position != 0. {
2357 let _ = write ! ( stop, r#" offset="{}""# , ( position * 1_000_000. ) . round( ) / 1_000_000. ) ;
@@ -32,9 +66,9 @@ impl RenderExt for Gradient {
3266 stop. push_str ( " />" )
3367 }
3468
35- let transform_points = element_transform * stroke_transform * bounds;
36- let start = transform_points. transform_point2 ( self . start ) ;
37- let end = transform_points. transform_point2 ( self . end ) ;
69+ let transform_points = element_transform * stroke_transform * bounds * gradient_transform ;
70+ let start = transform_points. transform_point2 ( DVec2 :: ZERO ) ;
71+ let end = transform_points. transform_point2 ( DVec2 :: X ) ;
3872
3973 let gradient_transform = if transformed_bounds. matrix2 . determinant ( ) != 0. {
4074 transformed_bounds. inverse ( )
@@ -48,15 +82,15 @@ impl RenderExt for Gradient {
4882 format ! ( r#" gradientTransform="{gradient_transform}""# )
4983 } ;
5084
51- let spread_method = if self . spread_method == GradientSpreadMethod :: Pad {
85+ let spread_method = if spread_method == GradientSpreadMethod :: Pad {
5286 String :: new ( )
5387 } else {
54- format ! ( r#" spreadMethod="{}""# , self . spread_method. svg_name( ) )
88+ format ! ( r#" spreadMethod="{}""# , spread_method. svg_name( ) )
5589 } ;
5690
5791 let gradient_id = generate_uuid ( ) ;
5892
59- match self . gradient_type {
93+ match gradient_type {
6094 GradientType :: Linear => {
6195 let _ = write ! (
6296 svg_defs,
@@ -83,19 +117,18 @@ impl RenderExt for Fill {
83117
84118 /// Renders the fill, adding necessary defs through mutating the first argument.
85119 fn render ( & self , svg_defs : & mut String , element_transform : DAffine2 , stroke_transform : DAffine2 , bounds : DAffine2 , transformed_bounds : DAffine2 , render_params : & RenderParams ) -> Self :: Output {
86- match self {
87- Self :: None => r#" fill="none""# . to_string ( ) ,
88- Self :: Solid ( color) => {
89- let mut result = format ! ( r##" fill="#{}""## , color. to_rgb_hex_srgb_from_gamma( ) ) ;
90- if color. a ( ) < 1. {
91- let _ = write ! ( result, r#" fill-opacity="{}""# , ( color. a( ) * 1000. ) . round( ) / 1000. ) ;
92- }
93- result
94- }
95- Self :: Gradient ( gradient) => {
96- let gradient_id = gradient. render ( svg_defs, element_transform, stroke_transform, bounds, transformed_bounds, render_params) ;
120+ let Some ( paint_table) = fill_to_paint ( self ) else { return r#" fill="none""# . to_string ( ) } ;
121+ let Some ( paint) = paint_table. element ( 0 ) else { return String :: new ( ) } ;
122+
123+ match paint {
124+ Graphic :: Color ( color_table) => color_table. render ( svg_defs, element_transform, stroke_transform, bounds, transformed_bounds, render_params) ,
125+ Graphic :: Gradient ( stops_table) => {
126+ let gradient_id = stops_table. render ( svg_defs, element_transform, stroke_transform, bounds, transformed_bounds, render_params) ;
97127 format ! ( r##" fill="url('#{gradient_id}')""## )
98128 }
129+ _ => {
130+ todo ! ( )
131+ }
99132 }
100133 }
101134}
0 commit comments