1    type TextBlock
2        val paint = Paint.new
3    
4        color@atom.bind { v ->
5            let skia_color = vector_to_skia_color v
6            paint.set_color skia_color } |> push_token
7    
8        var size = Size.new
9        var offset_x = 0
10       var offset_y = 0
11       local update = Stream<()>.new
12   
13       (text@atom, font@atom)
14       |> to_atom
15       |> bind { self (text, font) ->
16           let mut bounds = Rect.new
17           let skia_font = font as Font
18           skia_font.font.measure_text text.ptr text.length.as<usize>
19                                       TextEncoding/UTF8 bounds@mut_ptr null
20           let margin_x = font.height.as<f32> * 0.4 |> as<u32>
21           let (margin_up, margin_down) =
22               let margin_y = font.height.as<f32> * 0.25
23               (margin_y * 1.15 |> round |> as<u32>
24                margin_y * 0.85 |> round |> as<u32>)
25   
26           let width = bounds.right - bounds.left |> as<u32> + margin_x * 2
27           let height = font.height + margin_up + margin_down
28           self.size = Size width height
29           self.char_margins_height = height
30           self.offset_x = margin_x.as<f32> - bounds.left |> as<u32>
31           self.offset_y = margin_up.as<f32> - font.offset_y |> as<u32>
32           self.update.push }
33       |> push_token
34   
35       def Control.measure w h =
36           assert (w == 0 || size.width <= w) && size.height <= h
37           measure_width = size.width
38           measure_height = size.height
39