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
//! Pixel-alignment policy for widget bounds and draw-time translation.
//!
//! # Port of MatterCAD / agg-sharp
//!
//! `GuiWidget.DefaultEnforceIntegerBounds` (static) controls whether widgets
//! round their bounds / padding / margin to the physical pixel grid, and is
//! then mirrored on each widget as `EnforceIntegerBounds` so individual
//! widgets can opt out (e.g. a smooth-scrolling marker or a zoomed canvas
//! that genuinely wants sub-pixel positioning).
//!
//! We default to **true** because the vast majority of UI widgets want crisp
//! text and strokes — fractional bounds are the exception, not the rule.
//!
//! # Read site
//!
//! `paint_subtree` reads the effective flag (widget's override, falling back
//! to the global default) and rounds the child-translation to the nearest
//! integer pixel before calling the child's `paint`. That single snap kills
//! fractional CTM accumulated by cumulative-heights flex layout (e.g. Label
//! `line_h = font_size × 1.5` is fractional for most font sizes), which is
//! what caused the Y-axis pixel fringe on crisp rectangle fills downstream.
//!
//! # Opt-out
//!
//! ```ignore
//! // Globally disable (rare — only for fully sub-pixel render targets):
//! agg_gui::pixel_bounds::set_default_enforce_integer_bounds(false);
//!
//! // Per-widget:
//! my_widget.widget_base_mut().enforce_integer_bounds = false;
//! ```
use ;
/// Storage for the process-wide default. Reads use `Relaxed` — the flag is
/// consulted once per paint; there are no cross-thread ordering requirements
/// beyond "eventually sees the latest write".
static DEFAULT_ENFORCE_INTEGER_BOUNDS: AtomicBool = new;
/// Current process-wide default used to initialise each new widget's
/// `enforce_integer_bounds` field.
/// Change the process-wide default. Only affects widgets constructed
/// *after* this call; existing widgets keep whichever value they captured
/// when they were built. Match MatterCAD semantics (`DefaultEnforceIntegerBounds`
/// setter) exactly.