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.length.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        for i = first until last do
62            let line = text_display.text[i]
63            if line.is_highlighted then
64                let start = TextPos i 1
65                let bounds = text_display.bounds start
66                let rect_y = pos.y + bounds.up as f32 - text_display.offset_y as f32
67                let rect = Rect
68                    left = pos.x
69                    top = rect_y
70                    right = pos.x + text_display.parent.unwrap.width as f32
71                    bottom = rect_y + bounds.down as f32 - bounds.up as f32
72    
73                let skia_color = vector_to_skia_color line.highlight_color
74                text_display.paint.set_color skia_color
75                canvas.draw_rect rect@ref text_display.paint
76    
77            let text = line.as_string.drop_last 1
78            if text.is_not_empty then
79                let mut first_char = 0
80                let mut j = 1
81                let mut word_x = x
82                repeat
83                    while j < text.length && line[first_char].color == line[j].color do
84                        j += 1
85    
86                    let ptr = text.ptr + first_char
87                    let length = j - first_char
88                    let color_index = line[first_char].color
89                    let color = FontColor.palette[color_index as u32]
90                    let skia_color = vector_to_skia_color color
91                    text_display.paint.set_color skia_color
92                    canvas.draw_simple_text ptr length.as<usize>
93                                            TextEncoding/UTF8 word_x y
94                                            font.font text_display.paint
95                    word_x += length as f32 * font.advance
96                    first_char = j
97                until j == text.length
98            y += font.line_height.as<f32>
99    
100   let draw_quad_control (canvas : Canvas) (quad_control : QuadControl) =
101       let pos = quad_control.global_position
102       let rect = Rect
103           left = pos.x
104           top = pos.y
105           right = pos.x + quad_control.size.width.as<f32>
106           bottom = pos.y + quad_control.size.height.as<f32>
107   
108       canvas.draw_rect rect@ref quad_control.paint
109   
110   let draw_triangle_control (canvas : Canvas) (control : TriangleControl) =
111       let pos = control.global_position
112       canvas.save
113              translate pos.x pos.y
114              draw_path control.path control.paint
115              restore
116   
117   def draw (canvas : Canvas) (control : Control) : Unit =
118       let maybe_clip = control/try_get_clip_rect control
119       if maybe_clip ? Some rect then
120           let skia_rect = Rect
121               left = rect.x as f32
122               top = rect.y as f32
123               right = rect.x + rect.width.as<i32> |> as<f32>
124               bottom = rect.y + rect.height.as<i32> |> as<f32>
125           canvas.save
126           canvas.clip_rect skia_rect@ref ClipOp/Intersect
127   
128       case control of
129           is Rectangle -> draw_rectangle canvas control
130           is Border -> draw_border canvas control
131           is Figure -> draw_figure canvas control
132           is TextBlock -> draw_text_block canvas control
133           is TextDisplay -> draw_text_display canvas control
134           is QuadControl -> draw_quad_control canvas control
135           is TriangleControl -> draw_triangle_control canvas control
136           else -> ()
137   
138       if control is Container then
139           let items = control.get_slice
140           for item in items do
141               if item.is_visible then
142                   draw canvas item
143   
144       if maybe_clip.is_some then
145           canvas.restore
146