1     let draw_rectangle (canvas : Canvas) (rectangle : Rectangle) =
2         let pos = rectangle.global_position
3         let rect = Rect
4             left = pos.x
5             top = pos.y
6             right = pos.x + rectangle.width.as<f32>
7             bottom = pos.y + rectangle.height.as<f32>
8     
9         canvas.draw_rect rect@ref rectangle.paint
10    
11    let draw_border (canvas : Canvas) (border : Border) =
12        let pos = border.global_position
13        for rect in border.rectangles do
14            let r = Rect left = rect.left + pos.x
15                         top = rect.top + pos.y
16                         right = rect.right + pos.x
17                         bottom = rect.bottom + pos.y
18            canvas.draw_rect r@ref border.paint
19    
20    let draw_figure (canvas : Canvas) (figure : Figure) =
21        assert figure.kind == FigureKind/Cross
22        let pos = figure.global_position
23        let offset_x = figure.width as f32 * 0.15
24        let offset_y = figure.height as f32 * 0.15
25        do
26            let x0 = pos.x + offset_x
27            let y0 = pos.y + offset_y
28            let x1 = pos.x + figure.width as f32 - offset_x
29            let y1 = pos.y + figure.height as f32 - offset_y
30            canvas.draw_line x0 y0 x1 y1 figure.paint
31    
32        do
33            let x0 = pos.x + figure.width as f32 - offset_x
34            let y0 = pos.y + offset_y
35            let x1 = pos.x + offset_x
36            let y1 = pos.y + figure.height as f32 - offset_y
37            canvas.draw_line x0 y0 x1 y1 figure.paint
38    
39    let draw_text_block (canvas : Canvas) (text_block : TextBlock) =
40        let pos = text_block.global_position
41        let x = pos.x + text_block.offset_x.as<f32>
42        let y = pos.y + text_block.offset_y.as<f32>
43        let skia_font = text_block.font as Font
44        canvas.draw_simple_text text_block.text.ptr
45                                text_block.text.size.as<usize> TextEncoding/UTF8
46                                x y skia_font.font text_block.paint
47    
48    let draw_text_display (canvas : Canvas) (text_display : TextDisplay) =
49        let font = text_display.font as Font
50        let first = if text_display.visible_up < text_display.margin.up
51                    then 0
52                    else (text_display.visible_up - text_display.margin.up)
53                         / font.line_height
54        let last = (text_display.visible_down - text_display.margin.up)
55                   / font.line_height + 2 |> min text_display.text.size
56    
57        let pos = text_display.global_position
58        let x = pos.x + text_display.margin.left.as<f32>
59        let mut y = first * font.line_height + text_display.margin.up
60                    |> as<f32> + pos.y - font.offset_y
61    
62        let align_to_width =
63            if text_display.should_align
64            then text_display.text[text_display.text.size - 1].size - 1
65            else 0
66    
67        for i = first until last do
68            let line = text_display.text[i]
69            if line.has_background then
70                let start = TextPos i 1
71                let bounds = text_display.bounds start
72                let rect_y = pos.y + bounds.up as f32 - text_display.offset_y as f32
73                let rect = Rect
74                    left = pos.x
75                    top = rect_y
76                    right = pos.x + text_display.parent.unwrap.width as f32
77                    bottom = rect_y + bounds.down as f32 - bounds.up as f32
78    
79                let skia_color = vector_to_skia_color line.background
80                text_display.paint.set_color skia_color
81                canvas.draw_rect rect@ref text_display.paint
82    
83            let text = line.as_string.drop_last 1
84            if text.is_not_empty then
85                let mut first_char = 0
86                let mut j = 1
87                let mut word_x = x
88                if align_to_width then
89                    word_x += align_to_width - text.size |> as<f32> * font.advance
90    
91                repeat
92                    while j < text.size && line[first_char].color == line[j].color do
93                        j += 1
94    
95                    let ptr = text.ptr + first_char
96                    let size = j - first_char
97                    let color_index = line[first_char].color
98                    let color = FontColor.palette[color_index as u32]
99                    let skia_color = vector_to_skia_color color
100                   text_display.paint.set_color skia_color
101                   canvas.draw_simple_text ptr size.as<usize>
102                                           TextEncoding/UTF8 word_x y
103                                           font.font text_display.paint
104                   word_x += size as f32 * font.advance
105                   first_char = j
106               until j == text.size
107           y += font.line_height.as<f32>
108   
109   let draw_quad_control (canvas : Canvas) (quad_control : QuadControl) =
110       let pos = quad_control.global_position
111       let rect = Rect
112           left = pos.x
113           top = pos.y
114           right = pos.x + quad_control.size.width.as<f32>
115           bottom = pos.y + quad_control.size.height.as<f32>
116   
117       canvas.draw_rect rect@ref quad_control.paint
118   
119   let draw_triangle_control (canvas : Canvas) (control : TriangleControl) =
120       let pos = control.global_position
121       canvas.save
122              translate pos.x pos.y
123              draw_path control.path control.paint
124              restore
125   
126   def draw (canvas : Canvas) (control : Control) : Unit =
127       let maybe_clip = control/try_get_clip_rect control
128       if maybe_clip ? Some rect then
129           let skia_rect = Rect
130               left = rect.x as f32
131               top = rect.y as f32
132               right = rect.x + rect.width.as<i32> |> as<f32>
133               bottom = rect.y + rect.height.as<i32> |> as<f32>
134           canvas.save
135           canvas.clip_rect skia_rect@ref ClipOp/Intersect
136   
137       case control of
138           is Rectangle -> draw_rectangle canvas control
139           is Border -> draw_border canvas control
140           is Figure -> draw_figure canvas control
141           is TextBlock -> draw_text_block canvas control
142           is TextDisplay -> draw_text_display canvas control
143           is QuadControl -> draw_quad_control canvas control
144           is TriangleControl -> draw_triangle_control canvas control
145           else -> ()
146   
147       if control is Container then
148           let items = control.get_slice
149           for item in items do
150               if item.is_visible && not item.is_popup then
151                   draw canvas item
152   
153       if maybe_clip.is_some then
154           canvas.restore
155