1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
//! Shared `U+2800`-block braille dot packing, used by every TUI
//! rasteriser that needs sub-cell resolution: [`super::chart`]'s line
//! charts and [`super::minimap`]'s density view (#382).
//!
//! Lifted out of `tui/chart.rs` rather than duplicated: getting the bit
//! order wrong transposes the whole image in a way that still looks
//! plausible, so there must be exactly one copy of it (#382 review note).
/// Braille dot offsets: `(row_in_cell, col_in_cell) -> bit index`.
/// Standard Unicode braille ordering — a terminal cell is 2 dots wide
/// (`col_in_cell` in `0..2`) by 4 dots tall (`row_in_cell` in `0..4`).
pub const BRAILLE_OFFSETS: = ;
/// Pack one 2x4 dot cell into its `U+2800`-block braille codepoint.
/// `dot_at(row, col)` is queried for every one of the 8 dots
/// (`row` in `0..4`, `col` in `0..2`) and should return whether that dot
/// is set. An all-`false` cell packs to `U+2800` itself (blank braille),
/// not a space — callers that want to skip painting an empty cell decide
/// that themselves by comparing the result to `'\u{2800}'`.
pub
/// Threshold a dot's coverage (`covered` non-whitespace source columns out
/// of `bucket_width` total) against a 4x4 ordered-dither (Bayer) matrix,
/// indexed by the dot's own `(row, col)` position within the whole
/// rendered grid (not just within its cell) so that the dither pattern
/// tiles consistently across the entire minimap strip rather than
/// repeating identically inside every cell.
///
/// [`super::minimap`]'s density view decides "is this dot set?" with a
/// boolean OR over the dot's source-column bucket (`any(|c|
/// !c.is_whitespace())`), which saturates every dot from the end of a
/// line's indent onward as soon as the bucket widens past one column —
/// every row of real code runs to the strip's right edge with no
/// line-length signal at all. An ordered dither spreads that "is there
/// *any* code here" boolean across many dots' worth of threshold instead:
/// a sparsely-covered bucket only lights up the small subset of dot
/// positions whose threshold value happens to be low, while a
/// fully-covered bucket lights up every position — which is what produces
/// a raggedy, VS-Code-like right edge instead of a solid wall.
///
/// Pure integer arithmetic — one multiply and one compare, no floating
/// point, no lookahead, no per-call allocation. A fully-covered bucket
/// (`covered == bucket_width`) always returns `true` and an
/// all-whitespace bucket (`covered == 0`) always returns `false` —
/// dithering only has any effect strictly *between* those two extremes.
///
/// Re-exported from [`crate::primitives::minimap`] rather than defined
/// here: that module's `sample_blocks` uses the exact same matrix and
/// threshold formula to make an analogous decision one granularity
/// coarser — whether a *block*'s per-column coverage (several real
/// buffer lines folded into one output row) reads back non-blank. A
/// single shared definition makes both compositions provably the same
/// dither policy applied twice, not two that happen to agree today.
pub use cratedither_threshold_met;
/// Set every dot on the straight line between `(x0, y0)` and `(x1, y1)`
/// in `grid` (indexed `grid[row][col]`, i.e. `grid[y][x]`), including
/// both endpoints. Shared by every rasteriser in this crate that needs to
/// connect two dot-grid coordinates with a solid stroke — [`super::chart`]'s
/// line charts and [`super::canvas`]'s `DrawOp::Line`/`DrawOp::Path`
/// degrade both call this rather than keeping their own,
/// independently-tuned copy of a line-rasterisation loop, which is
/// exactly the kind of drift this module's own doc comment already warns
/// about for the bit-packing table above.
///
/// Out-of-bounds coordinates (`iy >= grid.len()` or `ix >= grid[0].len()`)
/// are silently skipped rather than panicking — a caller that clamps its
/// own endpoints to the grid never hits this, but the interpolated path
/// between two in-bounds endpoints cannot itself leave the grid (each
/// step is a convex combination of two in-bounds points), so this guard
/// is defensive rather than load-bearing.
///
/// **`(x0, y0) == (x1, y1)` is a no-op** — every caller already sets a
/// coincident single point's own dot itself before calling this for the
/// *connecting* segment, so a caller that wants a lone point rendered
/// when both endpoints coincide must set it separately; see
/// [`super::canvas`]'s `DrawOp::Line` handling for an example.
pub