Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
canvas_widget.hpp
Go to the documentation of this file.
1#pragma once
2
7
8#include <pulp/view/view.hpp>
10#include <algorithm>
11#include <cmath>
12#include <functional>
13#include <memory>
14#include <optional>
15#include <string>
16#include <unordered_map>
17#include <vector>
18
19namespace pulp::view {
20
29
36public:
37 virtual ~NativeCanvasPainter() = default;
38 virtual void paint(const NativeCanvasPaintContext& context) = 0;
39};
40
48
52 enum class Type {
53 // Shapes
57 // Text
59 // Canvas2D `strokeText(text, x, y, maxWidth)` recorded
60 // as a distinct cmd so the paint loop can route it through the
61 // dedicated `Canvas::stroke_text` (true outlined glyphs) instead
62 // of the older fillText-with-stroke-color approximation.
63 // Layout: text in `text`, (x,y) in `x`/`y`, maxWidth in `w`
64 // (0 = no limit), font size in `extra`, color in `color`.
66 // Canvas2D `ctx.font` full CSS font shorthand. The
67 // legacy `set_font` only carries family + size; the JS shim now
68 // parses `[<style>] [<variant>] [<weight>] <size>[/<lineHeight>]
69 // <family>`. `set_font_full` carries the parsed weight / slant
70 // through to `Canvas::set_font_full`, which Skia honours via
71 // `make_font(family, size, weight, slant)`. CG falls back to
72 // family+size (no slant override) — same as the base
73 // `set_font_full` default. Layout in CanvasDrawCmd:
74 // text = family
75 // extra = size (px)
76 // x = weight (100..900, cast to int)
77 // y = slant (0=upright, 1=italic/oblique)
78 // x2 = letter_spacing in px (0 when derived from `font`)
80 // Style
84 // Gradient
92 // Canvas2D ctx.createConicGradient.
93 // cx/cy in (x, y), start_angle in `extra`, stops in
94 // gradient_colors / gradient_positions (same shape as the
95 // linear / radial entries above).
97 // Canvas2D `ctx.strokeStyle =
98 // createLinearGradient(...) | createRadialGradient(...) |
99 // createConicGradient(...)`. Field layout matches the fill
100 // counterparts:
101 // set_stroke_gradient_linear: x/y/x2/y2 = (x0,y0,x1,y1)
102 // set_stroke_gradient_radial: x/y/extra = (cx,cy,radius)
103 // set_stroke_gradient_radial_two_circles:
104 // x/y/extra = (x0,y0,r0)
105 // x2/y2/w = (x1,y1,r1)
106 // set_stroke_gradient_conic: x/y/extra = (cx,cy,startAngle)
107 // Stops live in gradient_colors / gradient_positions.
113 // Canvas2D ctx.createPattern.
114 // Image source path / data URI in `text`, tile modes packed into
115 // `int_val` (bit 0 = x, bit 1 = y; 0 = repeat, 1 = no-repeat).
116 // Fill patterns route through the backend pattern implementation;
117 // stroke patterns fall back to solid stroke color on backends that
118 // do not support stroke-pattern shaders.
120 // Path
123 // Native arc subpaths.
124 // Layout in CanvasDrawCmd:
125 // path_arc: x=cx, y=cy, extra=radius,
126 // x2=startAngle, y2=endAngle,
127 // int_val=anticlockwise (0/1)
128 // path_arc_to: x=x1, y=y1, x2=x2, y2=y2, extra=radius
129 // path_ellipse: x=cx, y=cy, w=rx, h=ry, extra=rotation,
130 // x2=startAngle, y2=endAngle,
131 // int_val=anticlockwise (0/1)
132 // path_round_rect: x=x, y=y, w=w, h=h,
133 // gradient_positions packed [tl_x,tl_y,
134 // tr_x,tr_y, br_x,br_y, bl_x,bl_y]
139 // State
141 // Transform
143 set_transform, // replace transform with affine matrix
144 clip, // intersect clip with current path
145 // Image
147 // SDF shader draw. `text` stores the geometry JSON and
148 // `shader_sksl` stores optional structured SkSL.
150 // Canvas2D API coverage
153 // Canvas2D shadow* sticky state setters
158 // ctx.miterLimit and
159 // ctx.imageSmoothingEnabled / Quality. Sticky state pushed by
160 // the JS shim before the next stroke / drawImage.
163 // Canvas2D ctx.direction / ctx.filter sticky state.
164 // direction enum (0=ltr, 1=rtl, 2=inherit) in `int_val`; filter
165 // raw CSS <filter-function-list> string in `text`. Pushed by
166 // the JS shim before fillText / strokeText / fill / stroke /
167 // drawImage so the backend can wrap the next paint.
170 // Clear
172 // Cached group: replays the commands stored under the key in `text`
173 // inside an implicit save/restore, under the transform in effect at
174 // this point of the stream (see CanvasWidget::end_group).
176 };
178 float x = 0, y = 0, w = 0, h = 0;
179 float x2 = 0, y2 = 0; // extra coords (line end, control point 1)
180 float x3 = 0, y3 = 0; // cubic control point 2
181 canvas::Color color{255, 255, 255, 255};
182 float extra = 0; // radius, line width, font size, angle
183 std::string text; // for fill_text, set_font family
184 std::string shader_sksl;
185 std::vector<canvas::Canvas::NamedUniform> shader_uniforms;
186 std::optional<canvas::Canvas::ShaderGeometry> shader_geometry;
187 int int_val = 0; // for enum values (text align, baseline, blend mode, cap, join)
188 std::vector<canvas::Color> gradient_colors; // for gradient stops
189 std::vector<float> gradient_positions; // gradient stop positions
198 bool use_active_style = false;
199
206 bool has_source_rect = false;
207};
208
212class CanvasWidget : public View {
213private:
214 struct RecordedCommands;
215 struct RepaintObserver {
216 CanvasWidget* owner = nullptr;
217 RecordedCommands* stream = nullptr;
218 };
219
220public:
223 void* texture_handle = nullptr;
224 uint32_t width = 0;
225 uint32_t height = 0;
226 std::string format = "bgra8unorm";
227 bool available = false;
228 };
230
232 : repaint_observer_(std::make_shared<RepaintObserver>()) {
233 repaint_observer_->owner = this;
234 observe_recorded_commands();
235 }
236 ~CanvasWidget() override {
237 repaint_observer_->owner = nullptr;
238 repaint_observer_->stream = nullptr;
239 }
240
242 std::shared_ptr<NativeCanvasPainter> painter,
245 native_painter_ = std::move(painter);
246 native_backend_requirement_ = requirement;
247 content_mode_ = native_painter_ ? ContentMode::native_painter
250 }
252 native_painter_.reset();
253 native_backend_requirement_ = NativeCanvasBackendRequirement::any;
254 content_mode_ = ContentMode::recorded_commands;
256 }
257 ContentMode content_mode() const noexcept { return content_mode_; }
258 bool last_native_paint_succeeded() const noexcept {
259 return last_native_paint_succeeded_;
260 }
262 return last_native_paint_backend_;
263 }
264
266 recorded_commands_->commands.clear();
267 recorded_commands_->needs_backdrop_isolation = false;
268 recorded_commands_->has_group_replays = false;
269 // A recording still open at a frame clear was abandoned (its script
270 // was interrupted before end_group); keep it from swallowing the
271 // new frame.
272 abort_group_recording();
273 notify_recorded_command_consumers();
274 }
275
289 auto& stream = *recorded_commands_;
290 cmd.x = sanitize_finite(cmd.x);
291 cmd.y = sanitize_finite(cmd.y);
292 cmd.w = sanitize_finite(cmd.w);
293 cmd.h = sanitize_finite(cmd.h);
294 cmd.x2 = sanitize_finite(cmd.x2);
295 cmd.y2 = sanitize_finite(cmd.y2);
296 cmd.x3 = sanitize_finite(cmd.x3);
297 cmd.y3 = sanitize_finite(cmd.y3);
298 cmd.extra = sanitize_finite(cmd.extra);
299 for (auto& p : cmd.gradient_positions) p = sanitize_finite(p);
300 if (stream.recording_group) {
301 if (reads_backdrop(cmd)) stream.recording.reads_backdrop = true;
302 stream.recording.commands.push_back(std::move(cmd));
303 return;
304 }
305 if (reads_backdrop(cmd)) stream.needs_backdrop_isolation = true;
306 stream.commands.push_back(std::move(cmd));
307 }
308
309 // ── Cached groups ──────────────────────────────────────────────────
310 //
311 // A cached group is a keyed command list recorded once and replayed by
312 // reference, so static content (grids, scales, labels) costs one bridge
313 // call per frame instead of one per draw. Groups live beside the frame's
314 // command stream, not in it: clear_commands() does not drop them, and a
315 // canvas sharing this stream (share_recorded_commands_from) shares them.
316 //
317 // A replay runs the stored commands in place, inside an implicit
318 // save/restore and under whatever transform the stream holds at that
319 // point, so its pixels and blend order are exactly those of drawing the
320 // same commands directly. State set inside a group never leaks out, and
321 // a restore() inside a group cannot pop state saved outside it.
322
326 bool begin_group(std::string key) {
327 auto& stream = *recorded_commands_;
328 if (stream.recording_group) return false;
329 stream.recording_group = true;
330 stream.recording_key = std::move(key);
331 stream.recording = CachedGroup{};
332 return true;
333 }
334
336 bool end_group() {
337 auto& stream = *recorded_commands_;
338 if (!stream.recording_group) return false;
339 stream.recording_group = false;
340 auto key = std::move(stream.recording_key);
341 stream.groups[key] = std::move(stream.recording);
342 stream.recording = CachedGroup{};
343 return replay_group(key);
344 }
345
348 bool replay_group(const std::string& key) {
349 auto& stream = *recorded_commands_;
350 if (stream.recording_group) return false;
351 const auto it = stream.groups.find(key);
352 if (it == stream.groups.end()) return false;
353 if (it->second.reads_backdrop) stream.needs_backdrop_isolation = true;
354 stream.has_group_replays = true;
355 CanvasDrawCmd cmd;
357 cmd.text = key;
358 stream.commands.push_back(std::move(cmd));
359 return true;
360 }
361
363 void invalidate_group(const std::string& key) {
364 recorded_commands_->groups.erase(key);
365 }
367 recorded_commands_->groups.clear();
368 abort_group_recording();
369 }
370 size_t group_count() const { return recorded_commands_->groups.size(); }
373 const std::vector<CanvasDrawCmd>* group_commands(const std::string& key) const {
374 const auto it = recorded_commands_->groups.find(key);
375 return it == recorded_commands_->groups.end() ? nullptr : &it->second.commands;
376 }
377 size_t command_count() const { return recorded_commands_->commands.size(); }
378
388 return recorded_commands_->needs_backdrop_isolation;
389 }
390
392 static bool reads_backdrop(const CanvasDrawCmd& cmd) {
393 using T = CanvasDrawCmd::Type;
394 if (cmd.type == T::clear_rect || cmd.type == T::put_image_data) return true;
395 if (cmd.type != T::set_blend_mode) return false;
396 const auto mode = static_cast<canvas::Canvas::BlendMode>(cmd.int_val);
397 return mode != canvas::Canvas::BlendMode::normal &&
399 }
400
407 std::vector<const CanvasDrawCmd*> replay_sequence() const;
412 const std::vector<CanvasDrawCmd>& commands() const {
413 return recorded_commands_->commands;
414 }
415
420 if (recorded_commands_ == source.recorded_commands_) return;
421 recorded_commands_ = source.recorded_commands_;
422 observe_recorded_commands();
424 }
425 bool last_native_gpu_texture_draw_succeeded() const { return last_native_gpu_texture_draw_succeeded_; }
427 native_gpu_texture_provider_ = std::move(provider);
428 }
429
442 void set_shader_effect(std::string name, float intensity = 1.0f) {
443 shader_effect_name_ = std::move(name);
444 shader_effect_intensity_ = std::clamp(intensity, 0.0f, 1.0f);
445 }
446
448 const std::string& shader_effect() const { return shader_effect_name_; }
449 float shader_effect_intensity() const { return shader_effect_intensity_; }
450
451 void paint(canvas::Canvas& canvas) override;
452
453private:
458 static float sanitize_finite(float v) noexcept {
459 return std::isfinite(v) ? v : 0.0f;
460 }
461
462 struct CachedGroup {
463 std::vector<CanvasDrawCmd> commands;
464 bool reads_backdrop = false;
465 };
466 struct RecordedCommands {
467 std::vector<CanvasDrawCmd> commands;
468 bool needs_backdrop_isolation = false;
469 bool has_group_replays = false;
470 std::unordered_map<std::string, CachedGroup> groups;
471 bool recording_group = false;
472 std::string recording_key;
473 CachedGroup recording;
474 std::vector<std::weak_ptr<RepaintObserver>> observers;
475 };
476 void abort_group_recording() {
477 auto& stream = *recorded_commands_;
478 stream.recording_group = false;
479 stream.recording_key.clear();
480 stream.recording = CachedGroup{};
481 }
482 static void append_replay_sequence(const RecordedCommands& stream,
483 std::vector<const CanvasDrawCmd*>& out);
484 void observe_recorded_commands() {
485 repaint_observer_->stream = recorded_commands_.get();
486 recorded_commands_->observers.emplace_back(repaint_observer_);
487 }
488 void notify_recorded_command_consumers() {
489 auto& observers = recorded_commands_->observers;
490 observers.erase(std::remove_if(observers.begin(), observers.end(),
491 [this](const std::weak_ptr<RepaintObserver>& weak) {
492 auto observer = weak.lock();
493 if (!observer) return true;
494 // Bounded to the canvas's own box: paint() clips every
495 // replay to the widget bounds (or a layer of the same size),
496 // so a redrawn canvas cannot touch a pixel outside them. A
497 // whole-surface request here made every animating canvas --
498 // an analyzer, a modulated plot -- repaint the editor's
499 // static chrome each frame on a partial-repaint host.
500 if (observer->owner && observer->stream == recorded_commands_.get())
501 observer->owner->request_repaint_self(1.0f);
502 return false;
503 }), observers.end());
504 }
505 std::shared_ptr<RecordedCommands> recorded_commands_ =
506 std::make_shared<RecordedCommands>();
507 std::shared_ptr<RepaintObserver> repaint_observer_;
508 std::shared_ptr<NativeCanvasPainter> native_painter_;
509 NativeCanvasBackendRequirement native_backend_requirement_ =
512 std::uint64_t native_frame_id_ = 0;
513 bool last_native_paint_succeeded_ = false;
514 canvas::RendererBackend last_native_paint_backend_ =
516 NativeGpuTextureProvider native_gpu_texture_provider_;
517 bool last_native_gpu_texture_draw_succeeded_ = false;
518 // Curated named GPU post-effect state (see set_shader_effect). Sticky
519 // across command-list rebuilds; "none"/"" means no effect.
520 std::string shader_effect_name_ = "none";
521 float shader_effect_intensity_ = 1.0f;
522};
523
524} // namespace pulp::view
Definition canvas.hpp:240
BlendMode
Indices 0..15 match the existing W3C "advanced" composite ops and must stay stable — set_blend_mode i...
Definition canvas.hpp:527
@ source_over
Definition canvas.hpp:533
@ normal
Definition canvas.hpp:529
void set_native_painter(std::shared_ptr< NativeCanvasPainter > painter, NativeCanvasBackendRequirement requirement=NativeCanvasBackendRequirement::any)
Definition canvas_widget.hpp:241
void clear_commands()
Definition canvas_widget.hpp:265
const std::vector< CanvasDrawCmd > * group_commands(const std::string &key) const
Stored commands of group key, or nullptr.
Definition canvas_widget.hpp:373
void set_native_gpu_texture_provider(NativeGpuTextureProvider provider)
Definition canvas_widget.hpp:426
CanvasWidget()
Definition canvas_widget.hpp:231
void invalidate_all_groups()
Definition canvas_widget.hpp:366
size_t group_count() const
Definition canvas_widget.hpp:370
void add_command(CanvasDrawCmd cmd)
NaN / ±Infinity defense at the recording boundary.
Definition canvas_widget.hpp:288
bool last_native_paint_succeeded() const noexcept
Definition canvas_widget.hpp:258
canvas::RendererBackend last_native_paint_backend() const noexcept
Definition canvas_widget.hpp:261
void invalidate_group(const std::string &key)
Drop the stored group key, so the next replay_group() reports it missing and the script records it ag...
Definition canvas_widget.hpp:363
const std::string & shader_effect() const
Active curated effect name ("none" / "" when disabled).
Definition canvas_widget.hpp:448
bool replay_group(const std::string &key)
Append a replay of the stored group key to the frame.
Definition canvas_widget.hpp:348
~CanvasWidget() override
Definition canvas_widget.hpp:236
bool begin_group(std::string key)
Start recording the group key: every add_command until end_group() goes into the group instead of the...
Definition canvas_widget.hpp:326
size_t command_count() const
Definition canvas_widget.hpp:377
std::function< NativeGpuTextureFrame()> NativeGpuTextureProvider
Definition canvas_widget.hpp:229
ContentMode
Definition canvas_widget.hpp:221
@ native_painter
Definition canvas_widget.hpp:221
@ recorded_commands
Definition canvas_widget.hpp:221
bool end_group()
Seal the recording group under its key, replacing any previous content, and append a replay of it to ...
Definition canvas_widget.hpp:336
void paint(canvas::Canvas &canvas) override
void share_recorded_commands_from(CanvasWidget &source)
Make this canvas replay the same retained command stream as source.
Definition canvas_widget.hpp:419
bool last_native_gpu_texture_draw_succeeded() const
Definition canvas_widget.hpp:425
bool needs_backdrop_isolation() const
Whether the recorded stream contains a command whose result depends on the pixels already under it: c...
Definition canvas_widget.hpp:387
static bool reads_backdrop(const CanvasDrawCmd &cmd)
Whether cmd depends on the pixels already under it (see needs_backdrop_isolation()).
Definition canvas_widget.hpp:392
ContentMode content_mode() const noexcept
Definition canvas_widget.hpp:257
void set_shader_effect(std::string name, float intensity=1.0f)
Request a curated, named GPU post-effect over the whole canvas.
Definition canvas_widget.hpp:442
float shader_effect_intensity() const
Definition canvas_widget.hpp:449
void reset_native_painter()
Definition canvas_widget.hpp:251
std::vector< const CanvasDrawCmd * > replay_sequence() const
The commands paint() replays, in order: the recorded stream with each cached-group replay expanded in...
const std::vector< CanvasDrawCmd > & commands() const
Accessor for tests asserting on the recorded JS command stream.
Definition canvas_widget.hpp:412
Retained native painter installed on a CanvasWidget.
Definition canvas_widget.hpp:35
virtual void paint(const NativeCanvasPaintContext &context)=0
virtual ~NativeCanvasPainter()=default
void request_repaint()
Request that this view's host invalidate and schedule a repaint.
const std::shared_ptr< WidgetPainter > & painter() const
Definition view.hpp:235
Definition affine_transform.hpp:24
RendererBackend
Runtime identity of the concrete renderer receiving draw calls.
Definition canvas.hpp:29
@ unknown
Definition canvas.hpp:30
Hover-cursor tracking for platform window hosts.
Definition fwd.hpp:27
@ p
Definition input_events.hpp:40
@ v
Definition input_events.hpp:41
NativeCanvasBackendRequirement
Definition canvas_widget.hpp:41
@ skia_dawn
Definition canvas_widget.hpp:46
@ any
Definition canvas_widget.hpp:42
@ skia_dawn_allow_recording
Production paints require Graphite-on-Dawn; RecordingCanvas remains accepted so deterministic command...
Definition canvas_widget.hpp:45
STL namespace.
Definition canvas.hpp:52
A draw command recorded from JS for replay in paint().
Definition canvas_widget.hpp:51
bool has_source_rect
When true on a draw_image cmd, x2/y2/x3/y3 carry the source rect (sx, sy, sw, sh) for the 9-arg ctx....
Definition canvas_widget.hpp:206
float x3
Definition canvas_widget.hpp:180
Type type
Definition canvas_widget.hpp:177
float y
Definition canvas_widget.hpp:178
std::string shader_sksl
Definition canvas_widget.hpp:184
canvas::Color color
Definition canvas_widget.hpp:181
Type
Definition canvas_widget.hpp:52
@ clear
Definition canvas_widget.hpp:171
@ stroke_circle
Definition canvas_widget.hpp:55
@ stroke_path
Definition canvas_widget.hpp:122
@ scale
Definition canvas_widget.hpp:142
@ set_shadow_blur
blur (px) in extra
Definition canvas_widget.hpp:155
@ set_stroke_gradient_radial
Definition canvas_widget.hpp:109
@ cubic_to
Definition canvas_widget.hpp:121
@ set_stroke_gradient_linear
Definition canvas_widget.hpp:108
@ set_stroke_pattern
Definition canvas_widget.hpp:119
@ path_arc_to
Definition canvas_widget.hpp:136
@ set_fill_gradient_radial
Definition canvas_widget.hpp:85
@ stroke_arc
Definition canvas_widget.hpp:56
@ set_fill_color
Definition canvas_widget.hpp:81
@ replay_group
Definition canvas_widget.hpp:175
@ set_direction
Definition canvas_widget.hpp:168
@ path_arc
Definition canvas_widget.hpp:135
@ fill_rect
Definition canvas_widget.hpp:54
@ clear_stroke_gradient
Definition canvas_widget.hpp:112
@ fill_text
Definition canvas_widget.hpp:58
@ set_line_cap
Definition canvas_widget.hpp:82
@ stroke_line
Definition canvas_widget.hpp:56
@ stroke_rounded_rect
Definition canvas_widget.hpp:54
@ set_text_align
Definition canvas_widget.hpp:58
@ set_miter_limit
limit in extra
Definition canvas_widget.hpp:161
@ save
Definition canvas_widget.hpp:140
@ clip_path
Definition canvas_widget.hpp:122
@ set_line_join
Definition canvas_widget.hpp:82
@ set_blend_mode
Definition canvas_widget.hpp:83
@ set_shadow_color
color in color
Definition canvas_widget.hpp:154
@ set_fill_pattern
Definition canvas_widget.hpp:119
@ rotate
Definition canvas_widget.hpp:142
@ put_image_data
RGBA pixels in text (binary), int_val=width, x2=height (as int).
Definition canvas_widget.hpp:152
@ set_filter
Definition canvas_widget.hpp:169
@ clip_rect
Definition canvas_widget.hpp:142
@ fill_path
Definition canvas_widget.hpp:122
@ set_global_alpha
Definition canvas_widget.hpp:83
@ draw_sdf
Definition canvas_widget.hpp:149
@ line_to
Definition canvas_widget.hpp:121
@ set_stroke_color
Definition canvas_widget.hpp:81
@ set_font
Definition canvas_widget.hpp:58
@ clear_rect
Definition canvas_widget.hpp:171
@ stroke_text
Definition canvas_widget.hpp:65
@ set_fill_gradient_radial_two_circles
Canvas2D ctx.createRadialGradient(x0,y0,r0,x1,y1,r1) two-circle form.
Definition canvas_widget.hpp:91
@ path_ellipse
Definition canvas_widget.hpp:137
@ begin_path
Definition canvas_widget.hpp:121
@ draw_image
Definition canvas_widget.hpp:146
@ set_shadow_offset_x
dx (px) in extra
Definition canvas_widget.hpp:156
@ set_transform
Definition canvas_widget.hpp:143
@ clear_fill_gradient
Definition canvas_widget.hpp:85
@ fill_rounded_rect
Definition canvas_widget.hpp:54
@ restore
Definition canvas_widget.hpp:140
@ set_font_full
Definition canvas_widget.hpp:79
@ set_shadow_offset_y
dy (px) in extra
Definition canvas_widget.hpp:157
@ path_round_rect
Definition canvas_widget.hpp:138
@ set_stroke_gradient_conic
Definition canvas_widget.hpp:111
@ move_to
Definition canvas_widget.hpp:121
@ set_fill_gradient_linear
Definition canvas_widget.hpp:85
@ close_path
Definition canvas_widget.hpp:121
@ set_fill_gradient_conic
Definition canvas_widget.hpp:96
@ quad_to
Definition canvas_widget.hpp:121
@ set_line_width
Definition canvas_widget.hpp:81
@ clip
Definition canvas_widget.hpp:144
@ fill_circle
Definition canvas_widget.hpp:55
@ set_image_smoothing
enabled in int_val (0/1), quality in extra (0=low,1=med,2=high)
Definition canvas_widget.hpp:162
@ set_line_dash
pattern in gradient_positions, phase in extra
Definition canvas_widget.hpp:151
@ translate
Definition canvas_widget.hpp:142
@ set_text_baseline
Definition canvas_widget.hpp:58
@ set_stroke_gradient_radial_two_circles
Definition canvas_widget.hpp:110
@ stroke_rect
Definition canvas_widget.hpp:54
float w
Definition canvas_widget.hpp:178
float extra
Definition canvas_widget.hpp:182
std::optional< canvas::Canvas::ShaderGeometry > shader_geometry
Definition canvas_widget.hpp:186
float x
Definition canvas_widget.hpp:178
int int_val
Definition canvas_widget.hpp:187
std::vector< canvas::Color > gradient_colors
Definition canvas_widget.hpp:188
std::vector< float > gradient_positions
Definition canvas_widget.hpp:189
float x2
Definition canvas_widget.hpp:179
bool use_active_style
When true on a fill_rect / stroke_rect cmd, the paint loop must NOT call set_fill_color / set_stroke_...
Definition canvas_widget.hpp:198
float y2
Definition canvas_widget.hpp:179
float y3
Definition canvas_widget.hpp:180
std::vector< canvas::Canvas::NamedUniform > shader_uniforms
Definition canvas_widget.hpp:185
std::string text
Definition canvas_widget.hpp:183
float h
Definition canvas_widget.hpp:178
Definition canvas_widget.hpp:222
uint32_t width
Definition canvas_widget.hpp:224
bool available
Definition canvas_widget.hpp:227
uint32_t height
Definition canvas_widget.hpp:225
std::string format
Definition canvas_widget.hpp:226
void * texture_handle
Definition canvas_widget.hpp:223
Per-paint metadata for native, retained CanvasWidget content.
Definition canvas_widget.hpp:22
Rect local_bounds
Definition canvas_widget.hpp:24
float backing_scale
Definition canvas_widget.hpp:25
std::uint64_t frame_id
Definition canvas_widget.hpp:26
canvas::RendererBackend backend
Definition canvas_widget.hpp:27
canvas::Canvas & canvas
Definition canvas_widget.hpp:23
Axis-aligned rectangle in continuous (float) coordinates.
Definition geometry.hpp:52