Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
scene_path.hpp
Go to the documentation of this file.
1// ScenePath — a scene-graph NODE that draws a path.
2//
3// The geometry itself lives in `pulp::canvas::Path` (see
4// <pulp/canvas/path.hpp>) — the retained path VALUE type. ScenePath adds what
5// a scene node needs on top of that value: paint style (fill / stroke colors,
6// widths, fill rule), dirty tracking, and a place in the node hierarchy.
7//
8// Path and ScenePath are deliberately not the same thing, and the split matters:
9// a Path is a value you can copy, transform, compare, and hand around freely,
10// with no identity and no parent. Before this split, ScenePath carried its own
11// private command buffer, which meant `pulp::canvas` had two incompatible
12// representations of "a path" and no way to move geometry between them.
13#pragma once
14
15#include <pulp/canvas/path.hpp>
17
18#include <utility>
19#include <vector>
20
21namespace pulp::canvas {
22
23class ScenePath : public SceneNode {
24public:
26
28 bool fill_enabled() const { return fill_enabled_; }
29 void set_fill_enabled(bool v) {
30 if (fill_enabled_ == v) return;
31 fill_enabled_ = v;
32 mark_dirty();
33 }
34
36 bool stroke_enabled() const { return stroke_enabled_; }
37 void set_stroke_enabled(bool v) {
38 if (stroke_enabled_ == v) return;
39 stroke_enabled_ = v;
40 mark_dirty();
41 }
42
43 Color fill_color() const { return fill_color_; }
45 if (fill_color_ == c) return;
46 fill_color_ = c;
47 mark_dirty();
48 }
49
50 Color stroke_color() const { return stroke_color_; }
52 if (stroke_color_ == c) return;
53 stroke_color_ = c;
54 mark_dirty();
55 }
56
57 float stroke_width() const { return stroke_width_; }
58 void set_stroke_width(float w) {
59 if (stroke_width_ == w) return;
60 stroke_width_ = w;
61 mark_dirty();
62 }
63
64 FillRule fill_rule() const { return fill_rule_; }
66 if (fill_rule_ == r) return;
67 fill_rule_ = r;
68 mark_dirty();
69 }
70
71 // ── Path building ────────────────────────────────────────────────────
72 // These forward to the underlying Path value. Kept as members (rather than
73 // making callers reach through `path()`) so existing call sites and the
74 // SVG importer keep working unchanged.
75 void clear() {
76 path_.clear();
77 bounds_dirty_ = true;
78 bounds_cache_ = SceneRect{};
79 mark_dirty();
80 }
81
82 void move_to(float x, float y) {
83 path_.move_to(x, y);
84 bounds_dirty_ = true;
85 mark_dirty();
86 }
87
88 void line_to(float x, float y) {
89 path_.line_to(x, y);
90 bounds_dirty_ = true;
91 mark_dirty();
92 }
93
94 void quad_to(float cpx, float cpy, float x, float y) {
95 path_.quad_to(cpx, cpy, x, y);
96 bounds_dirty_ = true;
97 mark_dirty();
98 }
99
100 void cubic_to(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y) {
101 path_.cubic_to(cp1x, cp1y, cp2x, cp2y, x, y);
102 bounds_dirty_ = true;
103 mark_dirty();
104 }
105
106 void close_path() {
107 path_.close();
108 // close doesn't add new geometry; no bounds invalidation needed.
109 mark_dirty();
110 }
111
113 const Path& path() const { return path_; }
114
117 void set_path(Path p) {
118 path_ = std::move(p);
119 bounds_dirty_ = true;
120 mark_dirty();
121 }
122
123 // ── SceneNode overrides ──────────────────────────────────────────────
124 SceneRect local_bounds() const override;
125 void paint_geometry(Canvas& canvas) const override;
126
127private:
128 Path path_;
129 Color fill_color_ = Color::rgba(0, 0, 0, 1);
130 Color stroke_color_ = Color::rgba(0, 0, 0, 1);
131 float stroke_width_ = 1.0f;
132 FillRule fill_rule_ = FillRule::nonzero;
133 bool fill_enabled_ = true;
134 bool stroke_enabled_ = false;
135
136 mutable bool bounds_dirty_ = true;
137 mutable SceneRect bounds_cache_{};
138};
139
140} // namespace pulp::canvas
Definition canvas.hpp:240
Definition path.hpp:87
void mark_dirty()
Mark this node and (recursively) every ancestor dirty.
SceneNode(SceneNodeKind kind)
Definition scene_node.hpp:108
float stroke_width() const
Definition scene_path.hpp:57
bool fill_enabled() const
Whether this path should be filled (default true).
Definition scene_path.hpp:28
void set_stroke_color(Color c)
Definition scene_path.hpp:51
Color stroke_color() const
Definition scene_path.hpp:50
void set_fill_color(Color c)
Definition scene_path.hpp:44
void cubic_to(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y)
Definition scene_path.hpp:100
void set_path(Path p)
Replace the geometry wholesale — the drop-in for callers that built a Path elsewhere (an SVG parse,...
Definition scene_path.hpp:117
void clear()
Definition scene_path.hpp:75
void paint_geometry(Canvas &canvas) const override
Paint this node (and its sub-tree) into canvas.
Color fill_color() const
Definition scene_path.hpp:43
void line_to(float x, float y)
Definition scene_path.hpp:88
ScenePath()
Definition scene_path.hpp:25
void set_fill_rule(FillRule r)
Definition scene_path.hpp:65
const Path & path() const
The node's geometry, as a value. Copying it out is O(1) (see Path).
Definition scene_path.hpp:113
void set_fill_enabled(bool v)
Definition scene_path.hpp:29
FillRule fill_rule() const
Definition scene_path.hpp:64
bool stroke_enabled() const
Whether this path should be stroked (default false).
Definition scene_path.hpp:36
void move_to(float x, float y)
Definition scene_path.hpp:82
void close_path()
Definition scene_path.hpp:106
SceneRect local_bounds() const override
Local-coordinate bounding box (pre-transform, pre-opacity).
void quad_to(float cpx, float cpy, float x, float y)
Definition scene_path.hpp:94
void set_stroke_enabled(bool v)
Definition scene_path.hpp:37
void set_stroke_width(float w)
Definition scene_path.hpp:58
Definition affine_transform.hpp:24
FillRule
Winding rule used to decide what counts as "inside" a path.
Definition path.hpp:54
@ nonzero
Definition path.hpp:54
SceneNodeKind
Kind discriminator — keeps dynamic_cast off the hot path.
Definition scene_node.hpp:91
Definition canvas.hpp:52
static constexpr Color rgba(float r, float g, float b, float a=1.0f)
Construct from float channels [0,1] (>1.0 allowed for HDR).
Definition canvas.hpp:56
Axis-aligned bounding box used for repaint-rect math.
Definition scene_node.hpp:27