@@ -2,6 +2,7 @@ use crate::math::{BoundingBox, Dimensions};
22use  crate :: render_commands:: { Custom ,  RenderCommand ,  RenderCommandConfig } ; 
33use  crate :: text:: TextConfig ; 
44use  crate :: { ClayLayoutScope ,  Color  as  ClayColor } ; 
5+ 
56use  skia_safe:: { 
67    Canvas ,  ClipOp ,  Color ,  Font ,  Image ,  Paint ,  PaintCap ,  Point ,  RRect ,  Rect ,  SamplingOptions ,  Typeface 
78} ; 
@@ -348,305 +349,3 @@ pub fn create_measure_text_function(
348349        ( width,  font. metrics ( ) . 1 . bottom  - font. metrics ( ) . 1 . top ) . into ( ) 
349350    } 
350351} 
351- 
352- use  skia_safe:: { 
353-     Canvas ,  ClipOp ,  Color ,  Font ,  Image ,  Paint ,  Point ,  RRect ,  Rect ,  SamplingOptions ,  Typeface , 
354- } ; 
355- 
356- pub  fn  clay_to_skia_color ( color :  ClayColor )  -> Color  { 
357-     Color :: from_argb ( 
358-         ( color. a ) . round ( )  as  u8 , 
359-         ( color. r ) . round ( )  as  u8 , 
360-         ( color. g ) . round ( )  as  u8 , 
361-         ( color. b ) . round ( )  as  u8 , 
362-     ) 
363- } 
364- 
365- fn  clay_to_skia_rect ( rect :  BoundingBox )  -> Rect  { 
366-     Rect :: from_xywh ( rect. x ,  rect. y ,  rect. width ,  rect. height ) 
367- } 
368- /// This is a direct* port of Clay's raylib renderer using skia_safe as the drawing API. 
369- pub  fn  clay_skia_render < ' a ,  CustomElementData :  ' a > ( 
370-     canvas :  & Canvas , 
371-     render_commands :  impl  Iterator < Item  = RenderCommand < ' a ,  Image ,  CustomElementData > > , 
372-     mut  render_custom_element :  impl  FnMut ( 
373-         & RenderCommand < ' a ,  Image ,  CustomElementData > , 
374-         & Custom < ' a ,  CustomElementData > , 
375-         & Canvas , 
376-     ) , 
377-     fonts :  & [ & Typeface ] , 
378- )  { 
379-     for  command in  render_commands { 
380-         match  command. config  { 
381-             RenderCommandConfig :: Text ( text)  => { 
382-                 let  text_data = text. text ; 
383-                 let  mut  paint = Paint :: default ( ) ; 
384-                 paint. set_color ( clay_to_skia_color ( text. color ) ) ; 
385-                 let  font = Font :: new ( fonts[ text. font_id  as  usize ] . clone ( ) ,  text. font_size  as  f32 ) ; 
386-                 let  pos = Point :: new ( 
387-                     command. bounding_box . x , 
388-                     command. bounding_box . y  + text. font_size  as  f32 , 
389-                 ) ; 
390-                 canvas. draw_str ( & text_data,  pos,  & font,  & paint) ; 
391-             } 
392- 
393-             RenderCommandConfig :: Image ( image)  => { 
394-                 let  skia_image = image. data ; 
395-                 let  mut  paint = Paint :: default ( ) ; 
396-                 paint. set_color ( Color :: WHITE ) ; 
397-                 paint. set_anti_alias ( true ) ; 
398- 
399-                 let  bounds = clay_to_skia_rect ( command. bounding_box ) ; 
400-                 let  has_border_radius = image. corner_radii . top_left  > 0. 
401-                     || image. corner_radii . top_right  > 0. 
402-                     || image. corner_radii . bottom_left  > 0. 
403-                     || image. corner_radii . bottom_right  > 0. ; 
404-                 if  has_border_radius { 
405-                     canvas. save ( ) ; 
406-                     let  rrect = RRect :: new_rect_radii ( 
407-                         bounds, 
408-                         & [ 
409-                             Point :: new ( image. corner_radii . top_left ,  image. corner_radii . top_left ) , 
410-                             Point :: new ( image. corner_radii . top_right ,  image. corner_radii . top_right ) , 
411-                             Point :: new ( 
412-                                 image. corner_radii . bottom_left , 
413-                                 image. corner_radii . bottom_left , 
414-                             ) , 
415-                             Point :: new ( 
416-                                 image. corner_radii . bottom_right , 
417-                                 image. corner_radii . bottom_right , 
418-                             ) , 
419-                         ] , 
420-                     ) ; 
421-                     canvas. clip_rrect ( rrect,  ClipOp :: Intersect ,  true ) ; 
422-                 } 
423- 
424-                 canvas. draw_image_rect_with_sampling_options ( 
425-                     skia_image, 
426-                     None , 
427-                     bounds, 
428-                     SamplingOptions :: new ( 
429-                         skia_safe:: FilterMode :: Linear , 
430-                         skia_safe:: MipmapMode :: Linear , 
431-                     ) , 
432-                     & paint, 
433-                 ) ; 
434- 
435-                 // Restore canvas state if we applied a clip 
436-                 if  has_border_radius { 
437-                     canvas. restore ( ) ; 
438-                 } 
439-             } 
440- 
441-             RenderCommandConfig :: ScissorStart ( )  => { 
442-                 // Save the current state then clip to the bounding box. 
443-                 canvas. save ( ) ; 
444-                 let  clip_rect = clay_to_skia_rect ( command. bounding_box ) ; 
445-                 canvas. clip_rect ( clip_rect,  ClipOp :: Intersect ,  false ) ; 
446-             } 
447- 
448-             RenderCommandConfig :: ScissorEnd ( )  => { 
449-                 // Restore the previous state 
450-                 canvas. restore ( ) ; 
451-             } 
452- 
453-             RenderCommandConfig :: Rectangle ( rect)  => { 
454-                 let  paint = { 
455-                     let  mut  p = Paint :: default ( ) ; 
456-                     p. set_color ( clay_to_skia_color ( rect. color ) ) ; 
457-                     p. set_anti_alias ( true ) ; 
458-                     p. set_style ( skia_safe:: PaintStyle :: Fill ) ; 
459-                     p
460-                 } ; 
461-                 let  bounds = clay_to_skia_rect ( command. bounding_box ) ; 
462-                 if  rect. corner_radii . top_left  > 0. 
463-                     || rect. corner_radii . top_right  > 0. 
464-                     || rect. corner_radii . bottom_left  > 0. 
465-                     || rect. corner_radii . bottom_right  > 0. 
466-                 { 
467-                     let  rrect = RRect :: new_rect_radii ( 
468-                         bounds, 
469-                         & [ 
470-                             Point :: new ( rect. corner_radii . top_left ,  rect. corner_radii . top_left ) , 
471-                             Point :: new ( rect. corner_radii . top_right ,  rect. corner_radii . top_right ) , 
472-                             Point :: new ( 
473-                                 rect. corner_radii . bottom_left , 
474-                                 rect. corner_radii . bottom_left , 
475-                             ) , 
476-                             Point :: new ( 
477-                                 rect. corner_radii . bottom_right , 
478-                                 rect. corner_radii . bottom_right , 
479-                             ) , 
480-                         ] , 
481-                     ) ; 
482-                     canvas. draw_rrect ( rrect,  & paint) ; 
483-                 }  else  { 
484-                     canvas. draw_rect ( bounds,  & paint) ; 
485-                 } 
486-             } 
487- 
488-             RenderCommandConfig :: Border ( border)  => { 
489-                 // Draw each border side using fill rectangles. 
490-                 let  paint = { 
491-                     let  mut  p = Paint :: default ( ) ; 
492-                     p. set_color ( clay_to_skia_color ( border. color ) ) ; 
493-                     p. set_anti_alias ( true ) ; 
494-                     p
495-                 } ; 
496- 
497-                 let  bb = & command. bounding_box ; 
498- 
499-                 // Left border. 
500-                 if  border. width . left  > 0  { 
501-                     let  rect = Rect :: from_xywh ( 
502-                         bb. x , 
503-                         bb. y  + border. corner_radii . top_left , 
504-                         border. width . left  as  f32 , 
505-                         bb. height  - border. corner_radii . top_left  - border. corner_radii . bottom_left , 
506-                     ) ; 
507-                     canvas. draw_rect ( rect,  & paint) ; 
508-                 } 
509- 
510-                 // Right border. 
511-                 if  border. width . right  > 0  { 
512-                     let  rect = Rect :: from_xywh ( 
513-                         bb. x  + bb. width  - border. width . right  as  f32 , 
514-                         bb. y  + border. corner_radii . top_right , 
515-                         border. width . right  as  f32 , 
516-                         bb. height 
517-                             - border. corner_radii . top_right 
518-                             - border. corner_radii . bottom_right , 
519-                     ) ; 
520-                     canvas. draw_rect ( rect,  & paint) ; 
521-                 } 
522- 
523-                 // Top border. 
524-                 if  border. width . top  > 0  { 
525-                     let  rect = Rect :: from_xywh ( 
526-                         bb. x  + border. corner_radii . top_left , 
527-                         bb. y , 
528-                         bb. width  - border. corner_radii . top_left  - border. corner_radii . top_right , 
529-                         border. width . top  as  f32 , 
530-                     ) ; 
531-                     canvas. draw_rect ( rect,  & paint) ; 
532-                 } 
533- 
534-                 // Bottom border. 
535-                 if  border. width . bottom  > 0  { 
536-                     let  rect = Rect :: from_xywh ( 
537-                         bb. x  + border. corner_radii . bottom_left , 
538-                         bb. y  + bb. height  - border. width . bottom  as  f32 , 
539-                         bb. width 
540-                             - border. corner_radii . bottom_left 
541-                             - border. corner_radii . bottom_right , 
542-                         border. width . bottom  as  f32 , 
543-                     ) ; 
544-                     canvas. draw_rect ( rect,  & paint) ; 
545-                 } 
546- 
547-                 // For corner arcs, we draw strokes. 
548-                 let  mut  stroke = Paint :: default ( ) ; 
549-                 stroke. set_color ( clay_to_skia_color ( border. color ) ) ; 
550-                 stroke. set_stroke_width ( 1.0 ) ; 
551-                 stroke. set_style ( skia_safe:: paint:: Style :: Stroke ) ; 
552-                 stroke. set_anti_alias ( true ) ; 
553- 
554-                 // Helper to draw an arc. 
555-                 let  draw_corner_arc = |canvas :  & Canvas , 
556-                                        center_x :  f32 , 
557-                                        center_y :  f32 , 
558-                                        radius :  f32 , 
559-                                        start_angle :  f32 , 
560-                                        sweep_angle :  f32 | { 
561-                     let  arc_rect = Rect :: from_xywh ( 
562-                         center_x - radius, 
563-                         center_y - radius, 
564-                         radius *  2.0 , 
565-                         radius *  2.0 , 
566-                     ) ; 
567-                     canvas. draw_arc ( arc_rect,  start_angle,  sweep_angle,  false ,  & stroke) ; 
568-                 } ; 
569- 
570-                 if  border. corner_radii . top_left  > 0.  { 
571-                     // top-left: arc from 180 to 270 degrees. 
572-                     let  center_x = bb. x  + border. corner_radii . top_left ; 
573-                     let  center_y = bb. y  + border. corner_radii . top_left ; 
574-                     draw_corner_arc ( 
575-                         canvas, 
576-                         center_x, 
577-                         center_y, 
578-                         border. corner_radii . top_left , 
579-                         180.0 , 
580-                         90.0 , 
581-                     ) ; 
582-                 } 
583- 
584-                 if  border. corner_radii . top_right  > 0.  { 
585-                     // top-right: arc from 270 to 360 degrees. 
586-                     let  center_x = bb. x  + bb. width  - border. corner_radii . top_right ; 
587-                     let  center_y = bb. y  + border. corner_radii . top_right ; 
588-                     draw_corner_arc ( 
589-                         canvas, 
590-                         center_x, 
591-                         center_y, 
592-                         border. corner_radii . top_right , 
593-                         270.0 , 
594-                         90.0 , 
595-                     ) ; 
596-                 } 
597- 
598-                 if  border. corner_radii . bottom_left  > 0.  { 
599-                     // bottom-left: arc from 90 to 180 degrees. 
600-                     let  center_x = bb. x  + border. corner_radii . bottom_left ; 
601-                     let  center_y = bb. y  + bb. height  - border. corner_radii . bottom_left ; 
602-                     draw_corner_arc ( 
603-                         canvas, 
604-                         center_x, 
605-                         center_y, 
606-                         border. corner_radii . bottom_left , 
607-                         90.0 , 
608-                         90.0 , 
609-                     ) ; 
610-                 } 
611- 
612-                 if  border. corner_radii . bottom_right  > 0.  { 
613-                     // bottom-right: arc from 0 to 90 degrees. 
614-                     let  center_x = bb. x  + bb. width  - border. corner_radii . bottom_right ; 
615-                     let  center_y = bb. y  + bb. height  - border. corner_radii . bottom_right ; 
616-                     draw_corner_arc ( 
617-                         canvas, 
618-                         center_x, 
619-                         center_y, 
620-                         border. corner_radii . bottom_right , 
621-                         0.0 , 
622-                         90.0 , 
623-                     ) ; 
624-                 } 
625-             } 
626-             RenderCommandConfig :: Custom ( ref  custom)  => { 
627-                 render_custom_element ( & command,  custom,  canvas) 
628-             } 
629-             RenderCommandConfig :: None ( )  => { } 
630-         } 
631-     } 
632- } 
633- 
634- pub  type  SkiaClayScope < ' clay ,  ' render ,  CustomElements >  =
635-     ClayLayoutScope < ' clay ,  ' render ,  Image ,  CustomElements > ; 
636- 
637- pub  fn  get_source_dimensions_from_skia_image ( image :  & Image )  -> Dimensions  { 
638-     ( image. width ( )  as  f32 ,  image. height ( )  as  f32 ) . into ( ) 
639- } 
640- 
641- pub  fn  create_measure_text_function ( 
642-     fonts :  & ' static  [ & Typeface ] , 
643- )  -> impl  Fn ( & str ,  & TextConfig )  -> Dimensions  + ' static  { 
644-     |text,  text_config| { 
645-         let  font = Font :: new ( 
646-             fonts[ text_config. font_id  as  usize ] , 
647-             text_config. font_size  as  f32 , 
648-         ) ; 
649-         let  width = font. measure_str ( text,  None ) . 0 ; 
650-         ( width,  font. metrics ( ) . 1 . bottom  - font. metrics ( ) . 1 . top ) . into ( ) 
651-     } 
652- } 
0 commit comments