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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
//! The application icon — the congeries as a circuit (DESIGN §11).
//!
//! Three circles sit **tangent** to a central one, 120° apart with one at
//! bottom dead centre. From each, an arm runs 60° of arc to a further circle;
//! the circles between ride that arc, joined by a trace of dim casing under a
//! bright phosphor conductor. The centre carries a slit pupil in the void's own
//! black. Two hues, both derived from one palette entry, on transparency.
//!
//! **Both ends of an arm are pinned, and the swell is the only knob.** A start
//! tangent to the middle circle, an end 60° away at [`END_R`] — which is what
//! puts the top-right arm's last circle directly over the main circle — and
//! between them an arc whose sagitta is [`SWELL`]. Everything else falls out of
//! that. The legs come out equal for nothing, because even spacing along a
//! circular arc gives equal chords. The circle seats are *sampled from* the arc
//! rather than placed against it, so the drawn curve passes through every one
//! of them by construction, not by agreement.
//!
//! **What this mark is not.** An earlier one wore purple, gold and green — the
//! carnival tricolour — and read as a jester's hat: bulging lobes ending fat at
//! the rim, with twelve beads scattered there like bells. Three fixes, each
//! load bearing: **two hues** (a third saturated colour was what paid the
//! carnival tax), **arms that terminate rather than bulge**, and **few, large
//! elements**, because 64 px is where a taskbar icon lives and anything smaller
//! than a node is noise there.
//!
//! **Everything is compass work.** No spline, no easing, no tuned curve: an arc
//! is named by two endpoints and the height of its apex above the chord
//! (`arc::arc`), which fixes one circle exactly. The pupil is a *lune*, the
//! sliver between two arcs sharing a pair of endpoints, so it comes to a true
//! point at each end because that is where the arcs meet.
//!
//! **The pupil is filled, not punched.** Cut as negative space it showed what
//! lay beneath — and the traces converge under the eye, so what it showed was
//! them. Filling it with [`VOID_DEEP`] also spares both renderers a
//! coverage-subtraction primitive neither has.
//!
//! **Three emissions, one walk.** [`rgba`] rasterizes it for the window icon,
//! [`svg`](vector::svg) emits the checked-in vector source, and [`paint`] draws
//! it live on an egui layer with one circle per agent (§11 live mark). All
//! three walk the same flat-filled `shape::Shape` list in the same order, so
//! they are the same picture rather than three approximations of one.
use ;
pub use paint;
pub use ;
pub use svg;
use ;
use Shape;
/// Arms, and the degrees between them — the triskele's three-fold turn.
const ARMS: u8 = 3;
const TURN: f32 = 120.0;
/// Points sampled along one arc. Divisible by `CIRCLES - 1`, so the seats fall
/// on sampled points exactly rather than between them.
const STEPS: u16 = 48;
/// Where the first arm's tangent circle sits, in degrees: bottom dead centre.
const BASE: f32 = 90.0;
/// The middle circle, and the radius of every other circle — all equal.
const MAIN_R: f32 = 0.132;
const NODE_R: f32 = 0.048;
/// An arm ends this far out, and this many degrees of arc from where it began.
/// The pair is what puts the top-right arm's last circle over the main circle:
/// its base sits at −30°, and 60° counter-clockwise of that is −90°, straight up.
const END_R: f32 = 0.398;
const SWEEP: f32 = 60.0;
/// Circles an arm, counting the tangent one it starts on and the one it ends on.
const CIRCLES: u8 = 3;
/// **The only free parameter.** The sagitta of an arm's arc, as a fraction of
/// the chord between its two pinned ends: flat near 0, bowed as it climbs.
///
/// At 0.448 the arm leaves its tangent circle at exactly 45° off the radial —
/// which was the ask — and the arc sweeps 167.4°. An arc is a *semicircle*
/// exactly when its sagitta equals the **half** chord, which is `SWELL` 0.5;
/// that sweeps a true 180° but drops the departure to 41.8°. The two cannot
/// both hold, so the swap is this one constant and nothing else.
const SWELL: f32 = 0.448;
/// The dim casing, and the bright conductor laid down its middle.
const CASING_W: f32 = 0.054;
const CONDUCTOR_W: f32 = 0.016;
/// The pupil's half-height and bulge, as fractions of the middle circle.
const PUPIL_LONG: f32 = 0.78;
const PUPIL_BULGE: f32 = 0.30;
/// How hard [`deep`] drives the one hue the mark is built from: the conductor
/// past the hue's own peak until it is phosphor, the casing well under it.
const PHOSPHOR: f32 = 1.15;
const CASING: f32 = 0.45;
/// How much of a palette hue's white component [`deep`] strips.
const WHITE_CUT: f32 = 0.85;
/// Antialiased edge width, in pixels, of any rasterized shape.
const EDGE_PX: f32 = 1.2;
/// The rasterized icon size in pixels. 64 is the window-manager sweet spot:
/// crisp in a 48 px dock, still sharp when a title bar shrinks it to 16.
pub const ICON_PX: u16 = 64;
/// A palette hue with its white component stripped and its value scaled. The
/// badge hues are tuned to read as *small marks on a dark panel*, which makes
/// them pastel; a logo wants them saturated, and driven past 1.0 the green goes
/// phosphor. Deriving them keeps the theme module the one home of every hue
/// (§11) — the icon restates no RGB triple of its own.
/// The unit-square point `radius` out from the centre at `degrees`.
/// One arm's two **pinned** points: a circle tangent to the middle one, and a
/// circle [`SWEEP`] degrees of arc counter-clockwise of it at [`END_R`].
/// The arc between them, bowed by [`SWELL`] of the chord.
/// Where an arm's circles sit: [`CIRCLES`] points spaced evenly along its arc.
/// Even spacing on a circular arc means equal chords, so the legs between them
/// come out equal without anyone asking.
/// The whole mark at rest — the identity, and what both artifact emissions
/// carry (a window icon states no agent's business).
/// The whole mark, back to front — **by layer, not by arm**. Every casing goes
/// down, then every conductor, then every circle, then the eye over the place
/// the arms converge. Drawing each arm complete in turn looks equivalent and is
/// not: the arms overlap near the middle, so a later one's casing would paint
/// over an earlier one's conductor.
///
/// The circles take their hues from `tints`; the traces never do. A trace is
/// the mark's own wiring, not an agent's business, and lighting it would leave
/// the reading of any one circle depending on which arm it sat on.
/// The window/taskbar icon for `ViewportBuilder::with_icon`. **On Wayland this
/// is never seen** — there is no protocol for a client to set its own window
/// icon there, and the compositor matches `app_id` to a desktop entry instead
/// (§11). It is the X11 path and the raster half of the parity story.
/// The mark rasterized `size`×`size` as straight-alpha RGBA8, row-major from
/// the top-left — winit's icon format.
/// The sizes emitted as PNG beside the scalable SVG. The small end is what a
/// fixed-size icon theme installs; the large end is for dropping the mark into
/// a README or a page, where an SVG is not always welcome. The *encoding* is a
/// build-time concern — see `examples/icon.rs` — so nothing here carries a
/// codec into the binary.
pub const PNG_SIZES: = ;