@@ -378,7 +378,8 @@ impl OverlayContext {
378378 }
379379
380380 pub fn text ( & self , text : & str , font_color : & str , background_color : Option < & str > , transform : DAffine2 , padding : f64 , pivot : [ Pivot ; 2 ] ) {
381- self . internal ( ) . text ( text, font_color, background_color, transform, padding, pivot) ;
381+ let mut internal = self . internal ( ) ;
382+ internal. text ( text, font_color, background_color, transform, padding, pivot) ;
382383 }
383384
384385 pub fn translation_box ( & mut self , translation : DVec2 , quad : Quad , typed_string : Option < String > ) {
@@ -972,34 +973,104 @@ impl OverlayContextInternal {
972973 /// Fills the area inside the path with a pattern. Assumes `color` is in gamma space.
973974 /// Used by the fill tool to show the area to be filled.
974975 fn fill_path_pattern ( & mut self , subpaths : impl Iterator < Item = impl Borrow < Subpath < PointId > > > , transform : DAffine2 , color : & Color ) {
975- // TODO: Implement pattern fill in Vello
976- // For now, just fill with a semi-transparent version of the color
976+ const PATTERN_WIDTH : u32 = 4 ;
977+ const PATTERN_HEIGHT : u32 = 4 ;
978+
979+ // Create a 4x4 pixel pattern with colored pixels at (0,0) and (2,2)
980+ // This matches the Canvas2D checkerboard pattern
981+ let mut data = vec ! [ 0u8 ; ( PATTERN_WIDTH * PATTERN_HEIGHT * 4 ) as usize ] ;
982+ let rgba = color. to_rgba8_srgb ( ) ;
983+
984+ // Set pixels at (0,0) and (2,2) to the specified color
985+ let pixels = [ ( 0 , 0 ) , ( 2 , 2 ) ] ;
986+ for & ( x, y) in & pixels {
987+ let index = ( ( y * PATTERN_WIDTH + x) * 4 ) as usize ;
988+ data[ index..index + 4 ] . copy_from_slice ( & rgba) ;
989+ }
990+
991+ let image = peniko:: Image {
992+ data : data. into ( ) ,
993+ format : peniko:: ImageFormat :: Rgba8 ,
994+ width : PATTERN_WIDTH ,
995+ height : PATTERN_HEIGHT ,
996+ x_extend : peniko:: Extend :: Repeat ,
997+ y_extend : peniko:: Extend :: Repeat ,
998+ alpha : 1.0 ,
999+ quality : peniko:: ImageQuality :: default ( ) ,
1000+ } ;
1001+
9771002 let path = self . push_path ( subpaths, transform) ;
978- let semi_transparent_color = color. with_alpha ( 0.5 ) ;
979-
980- self . scene . fill (
981- peniko:: Fill :: NonZero ,
982- self . get_transform ( ) ,
983- peniko:: Color :: from_rgba8 (
984- ( semi_transparent_color. r ( ) * 255. ) as u8 ,
985- ( semi_transparent_color. g ( ) * 255. ) as u8 ,
986- ( semi_transparent_color. b ( ) * 255. ) as u8 ,
987- ( semi_transparent_color. a ( ) * 255. ) as u8 ,
988- ) ,
1003+ let brush = peniko:: Brush :: Image ( image) ;
1004+
1005+ self . scene . fill ( peniko:: Fill :: NonZero , self . get_transform ( ) , & brush, None , & path) ;
1006+ }
1007+
1008+ fn get_width ( & self , text : & str ) -> f64 {
1009+ // Basic text width estimation that matches the text() function implementation
1010+ // This uses the same character width estimation for consistency
1011+ // Note: This is primarily used for manual positioning calculations, but ideally
1012+ // the pivot system in text() should handle centering automatically
1013+ const CHAR_WIDTH : f64 = 7.0 ; // Approximate character width at 12px font size
1014+ text. len ( ) as f64 * CHAR_WIDTH
1015+ }
1016+
1017+ fn text ( & mut self , text : & str , font_color : & str , background_color : Option < & str > , transform : DAffine2 , padding : f64 , pivot : [ Pivot ; 2 ] ) {
1018+ // For now, implement a basic text rendering approach
1019+ // This is a simplified version that can be enhanced later with full font support
1020+
1021+ // Calculate approximate text dimensions (basic estimation)
1022+ let char_width = 7.0 ; // Approximate character width at 12px font size
1023+ let char_height = 12.0 ; // Font size
1024+ let text_width = text. len ( ) as f64 * char_width;
1025+ let text_height = char_height;
1026+
1027+ // Calculate position based on pivot
1028+ let mut position = DVec2 :: ZERO ;
1029+ match pivot[ 0 ] {
1030+ Pivot :: Start => position. x = padding,
1031+ Pivot :: Middle => position. x = -text_width / 2.0 ,
1032+ Pivot :: End => position. x = -padding - text_width,
1033+ }
1034+ match pivot[ 1 ] {
1035+ Pivot :: Start => position. y = padding + text_height,
1036+ Pivot :: Middle => position. y = text_height / 2.0 ,
1037+ Pivot :: End => position. y = -padding,
1038+ }
1039+
1040+ let text_transform = transform * DAffine2 :: from_translation ( position) ;
1041+ let device_transform = self . get_transform ( ) ;
1042+ let combined_transform = kurbo:: Affine :: new ( text_transform. to_cols_array ( ) ) ;
1043+ let vello_transform = device_transform * combined_transform;
1044+
1045+ // Draw background if specified
1046+ if let Some ( bg_color) = background_color {
1047+ let bg_rect = kurbo:: Rect :: new (
1048+ -padding,
1049+ -padding,
1050+ text_width + padding,
1051+ text_height + padding
1052+ ) ;
1053+ self . scene . fill (
1054+ peniko:: Fill :: NonZero ,
1055+ vello_transform,
1056+ Self :: parse_color ( bg_color) ,
1057+ None ,
1058+ & bg_rect,
1059+ ) ;
1060+ }
1061+
1062+ // For now, draw a simple rectangle to represent text
1063+ // TODO: Implement proper font rendering using vello's text capabilities
1064+ let text_rect = kurbo:: Rect :: new ( 0.0 , 0.0 , text_width, text_height) ;
1065+ self . scene . stroke (
1066+ & kurbo:: Stroke :: new ( 1.0 ) ,
1067+ vello_transform,
1068+ Self :: parse_color ( font_color) ,
9891069 None ,
990- & path ,
1070+ & text_rect ,
9911071 ) ;
9921072 }
9931073
994- fn get_width ( & self , _text : & str ) -> f64 {
995- // TODO: Implement proper text measurement in Vello
996- 0.
997- }
998-
999- fn text ( & self , _text : & str , _font_color : & str , _background_color : Option < & str > , _transform : DAffine2 , _padding : f64 , _pivot : [ Pivot ; 2 ] ) {
1000- // TODO: Implement text rendering in Vello
1001- }
1002-
10031074 fn translation_box ( & mut self , translation : DVec2 , quad : Quad , typed_string : Option < String > ) {
10041075 if translation. x . abs ( ) > 1e-3 {
10051076 self . dashed_line ( quad. top_left ( ) , quad. top_right ( ) , None , None , Some ( 2. ) , Some ( 2. ) , Some ( 0.5 ) ) ;
0 commit comments