@@ -17,6 +17,7 @@ use core_types::{
1717use dyn_any:: DynAny ;
1818use glam:: { DAffine2 , DVec2 } ;
1919use graphene_hash:: CacheHashWrapper ;
20+ use graphic_types:: graphic:: fill_to_paint;
2021use graphic_types:: raster_types:: { BitmapMut , CPU , GPU , Image , Raster } ;
2122use graphic_types:: vector_types:: gradient:: { GradientStops , GradientType } ;
2223use graphic_types:: vector_types:: subpath:: Subpath ;
@@ -1186,70 +1187,86 @@ impl Render for Table<Vector> {
11861187 let use_layer = can_draw_aligned_stroke;
11871188 let wants_stroke_below = stroke. as_ref ( ) . is_some_and ( |s| s. paint_order == vector:: style:: PaintOrder :: StrokeBelow ) ;
11881189
1189- // Closures to avoid duplicated fill/stroke drawing logic
1190- let do_fill_path = |scene : & mut Scene , path : & kurbo:: BezPath , fill_rule : peniko:: Fill | match element. style . fill ( ) {
1191- Fill :: Solid ( color) => {
1192- let fill = peniko:: Brush :: Solid ( peniko:: Color :: new ( [ color. r ( ) , color. g ( ) , color. b ( ) , color. a ( ) ] ) ) ;
1193- scene. fill ( fill_rule, kurbo:: Affine :: new ( element_transform. to_cols_array ( ) ) , & fill, None , path) ;
1194- }
1195- Fill :: Gradient ( gradient) => {
1196- let mut stops = peniko:: ColorStops :: new ( ) ;
1197- for ( position, color, _) in gradient. stops . interpolated_samples ( ) {
1198- stops. push ( peniko:: ColorStop {
1199- offset : position as f32 ,
1200- color : peniko:: color:: DynamicColor :: from_alpha_color ( peniko:: Color :: new ( [ color. r ( ) , color. g ( ) , color. b ( ) , color. a ( ) ] ) ) ,
1201- } ) ;
1202- }
1203-
1204- let bounds = element. nonzero_bounding_box ( ) ;
1205- let bound_transform = DAffine2 :: from_scale_angle_translation ( bounds[ 1 ] - bounds[ 0 ] , 0. , bounds[ 0 ] ) ;
1206-
1207- let inverse_parent_transform = if parent_transform. matrix2 . determinant ( ) != 0. {
1208- parent_transform. inverse ( )
1209- } else {
1210- Default :: default ( )
1211- } ;
1212- let mod_points = inverse_parent_transform * multiplied_transform * bound_transform;
1190+ // TODO: This conversion is only necessary during the transition period from Fill to Table<Graphic>
1191+ let do_fill_path = |scene : & mut Scene , path : & kurbo:: BezPath , fill_rule : peniko:: Fill | {
1192+ let Some ( paint_table) = fill_to_paint ( element. style . fill ( ) ) else {
1193+ return ;
1194+ } ;
12131195
1214- let start = mod_points. transform_point2 ( gradient. start ) ;
1215- let end = mod_points. transform_point2 ( gradient. end ) ;
1196+ for paint_idx in 0 ..paint_table. len ( ) {
1197+ let Some ( paint) = paint_table. element ( paint_idx) else { continue } ;
1198+ match paint {
1199+ Graphic :: Color ( table) => {
1200+ let Some ( color) = table. element ( 0 ) else { continue } ;
12161201
1217- let fill = peniko:: Brush :: Gradient ( peniko:: Gradient {
1218- kind : match gradient. gradient_type {
1219- GradientType :: Linear => peniko:: LinearGradientPosition {
1220- start : to_point ( start) ,
1221- end : to_point ( end) ,
1222- }
1223- . into ( ) ,
1224- GradientType :: Radial => {
1225- let radius = start. distance ( end) ;
1226- peniko:: RadialGradientPosition {
1227- start_center : to_point ( start) ,
1228- start_radius : 0. ,
1229- end_center : to_point ( start) ,
1230- end_radius : radius as f32 ,
1231- }
1232- . into ( )
1202+ let fill = peniko:: Brush :: Solid ( peniko:: Color :: new ( [ color. r ( ) , color. g ( ) , color. b ( ) , color. a ( ) ] ) ) ;
1203+ scene. fill ( fill_rule, kurbo:: Affine :: new ( element_transform. to_cols_array ( ) ) , & fill, None , path) ;
1204+ }
1205+ Graphic :: Gradient ( stops_table) => {
1206+ let Some ( stops) = stops_table. element ( 0 ) else { continue } ;
1207+ let gradient_type: GradientType = stops_table. attribute_cloned_or_default ( ATTR_GRADIENT_TYPE , 0 ) ;
1208+ let gradient_transform: DAffine2 = stops_table. attribute_cloned_or_default ( ATTR_TRANSFORM , 0 ) ;
1209+ let spread_method: GradientSpreadMethod = stops_table. attribute_cloned_or_default ( ATTR_SPREAD_METHOD , 0 ) ;
1210+
1211+ let mut peniko_stops = peniko:: ColorStops :: new ( ) ;
1212+ for ( position, color, _) in stops. interpolated_samples ( ) {
1213+ peniko_stops. push ( peniko:: ColorStop {
1214+ offset : position as f32 ,
1215+ color : peniko:: color:: DynamicColor :: from_alpha_color ( peniko:: Color :: new ( [ color. r ( ) , color. g ( ) , color. b ( ) , color. a ( ) ] ) ) ,
1216+ } ) ;
12331217 }
1234- } ,
1235- extend : match gradient. spread_method {
1236- GradientSpreadMethod :: Pad => peniko:: Extend :: Pad ,
1237- GradientSpreadMethod :: Reflect => peniko:: Extend :: Reflect ,
1238- GradientSpreadMethod :: Repeat => peniko:: Extend :: Repeat ,
1239- } ,
1240- stops,
1241- interpolation_alpha_space : peniko:: InterpolationAlphaSpace :: Premultiplied ,
1242- ..Default :: default ( )
1243- } ) ;
1244- let inverse_element_transform = if element_transform. matrix2 . determinant ( ) != 0. {
1245- element_transform. inverse ( )
1246- } else {
1247- Default :: default ( )
1218+
1219+ let bounds = element. nonzero_bounding_box ( ) ;
1220+ let bound_transform = DAffine2 :: from_scale_angle_translation ( bounds[ 1 ] - bounds[ 0 ] , 0. , bounds[ 0 ] ) ;
1221+
1222+ let inverse_parent_transform = if parent_transform. matrix2 . determinant ( ) != 0. {
1223+ parent_transform. inverse ( )
1224+ } else {
1225+ Default :: default ( )
1226+ } ;
1227+ let mod_points = inverse_parent_transform * multiplied_transform * bound_transform * gradient_transform;
1228+
1229+ let start = mod_points. transform_point2 ( DVec2 :: ZERO ) ;
1230+ let end = mod_points. transform_point2 ( DVec2 :: X ) ;
1231+
1232+ let fill = peniko:: Brush :: Gradient ( peniko:: Gradient {
1233+ kind : match gradient_type {
1234+ GradientType :: Linear => peniko:: LinearGradientPosition {
1235+ start : to_point ( start) ,
1236+ end : to_point ( end) ,
1237+ }
1238+ . into ( ) ,
1239+ GradientType :: Radial => {
1240+ let radius = start. distance ( end) ;
1241+ peniko:: RadialGradientPosition {
1242+ start_center : to_point ( start) ,
1243+ start_radius : 0. ,
1244+ end_center : to_point ( start) ,
1245+ end_radius : radius as f32 ,
1246+ }
1247+ . into ( )
1248+ }
1249+ } ,
1250+ extend : match spread_method {
1251+ GradientSpreadMethod :: Pad => peniko:: Extend :: Pad ,
1252+ GradientSpreadMethod :: Reflect => peniko:: Extend :: Reflect ,
1253+ GradientSpreadMethod :: Repeat => peniko:: Extend :: Repeat ,
1254+ } ,
1255+ stops : peniko_stops,
1256+ interpolation_alpha_space : peniko:: InterpolationAlphaSpace :: Premultiplied ,
1257+ ..Default :: default ( )
1258+ } ) ;
1259+ let inverse_element_transform = if element_transform. matrix2 . determinant ( ) != 0. {
1260+ element_transform. inverse ( )
1261+ } else {
1262+ Default :: default ( )
1263+ } ;
1264+ let brush_transform = kurbo:: Affine :: new ( ( inverse_element_transform * parent_transform) . to_cols_array ( ) ) ;
1265+ scene. fill ( fill_rule, kurbo:: Affine :: new ( element_transform. to_cols_array ( ) ) , & fill, Some ( brush_transform) , path) ;
1266+ }
1267+ _ => todo ! ( ) ,
12481268 } ;
1249- let brush_transform = kurbo:: Affine :: new ( ( inverse_element_transform * parent_transform) . to_cols_array ( ) ) ;
1250- scene. fill ( fill_rule, kurbo:: Affine :: new ( element_transform. to_cols_array ( ) ) , & fill, Some ( brush_transform) , path) ;
12511269 }
1252- Fill :: None => { }
12531270 } ;
12541271
12551272 // Branching vectors without regions (e.g. mesh grids) need face-by-face fill rendering.
0 commit comments