You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/guide/styling.md
+23Lines changed: 23 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,6 +6,27 @@ Rezi styling is designed to be:
6
6
-**deterministic**: the same inputs produce the same frames
7
7
-**composable**: styles inherit through containers
8
8
9
+
## Text attributes
10
+
11
+
`TextStyle` supports these boolean text attributes:
12
+
13
+
-`bold`
14
+
-`dim`
15
+
-`italic`
16
+
-`underline`
17
+
-`inverse`
18
+
-`strikethrough`
19
+
-`overline`
20
+
-`blink`
21
+
22
+
New attribute SGR target mappings:
23
+
24
+
-`strikethrough` -> SGR `9`
25
+
-`overline` -> SGR `53`
26
+
-`blink` -> SGR `5`
27
+
28
+
These codes are the terminal mapping used by the backend emitter. Drawlist encoding carries all three attrs, and backend emission now supports `strikethrough`, `overline`, and `blink` end-to-end (terminal rendering still depends on terminal support).
29
+
9
30
## Inline styles
10
31
11
32
Most visual widgets accept a `style` prop:
@@ -57,6 +78,7 @@ Style is merged from parent → child:
57
78
58
79
- containers pass their resolved style to children
Drawlist style encoding packs boolean attrs into the low 8 bits of `style.attrs` (`u32`):
20
+
21
+
- bit `0`: `bold`
22
+
- bit `1`: `italic`
23
+
- bit `2`: `underline`
24
+
- bit `3`: `inverse`
25
+
- bit `4`: `dim`
26
+
- bit `5`: `strikethrough`
27
+
- bit `6`: `overline`
28
+
- bit `7`: `blink`
29
+
30
+
Equivalent mask expression:
31
+
32
+
```text
33
+
attrs =
34
+
(bold ? 1<<0 : 0) |
35
+
(italic ? 1<<1 : 0) |
36
+
(underline ? 1<<2 : 0) |
37
+
(inverse ? 1<<3 : 0) |
38
+
(dim ? 1<<4 : 0) |
39
+
(strikethrough ? 1<<5 : 0) |
40
+
(overline ? 1<<6 : 0) |
41
+
(blink ? 1<<7 : 0)
42
+
```
43
+
44
+
The mapping is identical for `drawText(...)` and `drawTextRun(...)` segment styles.
45
+
46
+
## Terminal SGR Mapping
47
+
48
+
Terminal target SGR codes for the new attrs are:
49
+
50
+
-`strikethrough` -> `9`
51
+
-`overline` -> `53`
52
+
-`blink` -> `5`
53
+
54
+
Drawlist encoding carries these bits in `style.attrs`, and backend emission supports all three attrs (`strikethrough`, `overline`, `blink`) end-to-end. Terminal-visible behavior still depends on terminal support.
55
+
56
+
## Renderer Merge Cache (Fast Path)
57
+
58
+
`mergeTextStyle(base, override)` has a fast path when:
59
+
60
+
-`base === DEFAULT_BASE_STYLE`
61
+
-`override.fg` and `override.bg` are both `undefined`
62
+
63
+
In that case, the renderer computes a compact key from per-attr tri-state values and uses direct array indexing into `BASE_BOOL_STYLE_CACHE`.
64
+
65
+
Tri-state encoding per attr:
66
+
67
+
-`0` = `undefined` (inherit)
68
+
-`1` = `false`
69
+
-`2` = `true`
70
+
71
+
Key layout (2 bits per attr, 8 attrs total):
72
+
73
+
```text
74
+
key =
75
+
b
76
+
| (d << 2)
77
+
| (i << 4)
78
+
| (u << 6)
79
+
| (inv<< 8)
80
+
| (s << 10)
81
+
| (o << 12)
82
+
| (bl << 14)
83
+
```
84
+
85
+
Cache sizing rationale:
86
+
87
+
- 8 attrs * 2 bits = 16-bit key space
88
+
- cache length is `65536` (`2^16`), so every possible key index is valid
89
+
- tri-state value set uses only `0..2` per 2-bit slot, so current reachable combinations are a subset (`3^8 = 6561`), with room for full direct addressing
90
+
91
+
Why this is used:
92
+
93
+
- avoids per-merge object churn for common default-base boolean-only style merges
94
+
- avoids hash-map overhead by using a fixed-size array lookup
95
+
- keeps object identity stable for repeated equivalent style inputs on the hot path
0 commit comments