NovaSVG 0.10.0
A header-only SVG library
Loading...
Searching...
No Matches
paint.h
Go to the documentation of this file.
1#pragma once
2
3#include "private.h"
4#include "utils.h"
5
6#include <ctype.h>
7
8namespace novasvg {
9namespace render {
10
11NOVASVG_INLINE void color_init_rgb(color_t* color, float r, float g, float b)
12{
13 color_init_rgba(color, r, g, b, 1.f);
14}
15
16NOVASVG_INLINE void color_init_rgba(color_t* color, float r, float g, float b, float a)
17{
18 color->r = std::clamp(r, 0.f, 1.f);
19 color->g = std::clamp(g, 0.f, 1.f);
20 color->b = std::clamp(b, 0.f, 1.f);
21 color->a = std::clamp(a, 0.f, 1.f);
22}
23
24NOVASVG_INLINE void color_init_rgb8(color_t* color, int r, int g, int b)
25{
26 color_init_rgba8(color, r, g, b, 255);
27}
28
29NOVASVG_INLINE void color_init_rgba8(color_t* color, int r, int g, int b, int a)
30{
31 color_init_rgba(color, r / 255.f, g / 255.f, b / 255.f, a / 255.f);
32}
33
35{
36 uint8_t r = (value >> 24) & 0xFF;
37 uint8_t g = (value >> 16) & 0xFF;
38 uint8_t b = (value >> 8) & 0xFF;
39 uint8_t a = (value >> 0) & 0xFF;
40 color_init_rgba8(color, r, g, b, a);
41}
42
44{
45 uint8_t a = (value >> 24) & 0xFF;
46 uint8_t r = (value >> 16) & 0xFF;
47 uint8_t g = (value >> 8) & 0xFF;
48 uint8_t b = (value >> 0) & 0xFF;
49 color_init_rgba8(color, r, g, b, a);
50}
51
52NOVASVG_INLINE void color_init_hsl(color_t* color, float h, float s, float l)
53{
54 color_init_hsla(color, h, s, l, 1.f);
55}
56
57static inline float hsl_component(float h, float s, float l, float n)
58{
59 const float k = fmodf(n + h / 30.f, 12.f);
60 const float a = s * NOVASVG_MIN(l, 1.f - l);
61 return l - a * NOVASVG_MAX(-1.f, NOVASVG_MIN(1.f, NOVASVG_MIN(k - 3.f, 9.f - k)));
62}
63
64NOVASVG_INLINE void color_init_hsla(color_t* color, float h, float s, float l, float a)
65{
66 h = fmodf(h, 360.f);
67 if(h < 0.f) { h += 360.f; }
68
69 float r = hsl_component(h, s, l, 0);
70 float g = hsl_component(h, s, l, 8);
71 float b = hsl_component(h, s, l, 4);
72 color_init_rgba(color, r, g, b, a);
73}
74
76{
77 uint32_t r = lroundf(color->r * 255);
78 uint32_t g = lroundf(color->g * 255);
79 uint32_t b = lroundf(color->b * 255);
80 uint32_t a = lroundf(color->a * 255);
81 return (r << 24) | (g << 16) | (b << 8) | (a);
82}
83
85{
86 uint32_t a = lroundf(color->a * 255);
87 uint32_t r = lroundf(color->r * 255);
88 uint32_t g = lroundf(color->g * 255);
89 uint32_t b = lroundf(color->b * 255);
90 return (a << 24) | (r << 16) | (g << 8) | (b);
91}
92
93static inline uint8_t hex_digit(uint8_t c)
94{
95 if(c >= '0' && c <= '9')
96 return c - '0';
97 if(c >= 'a' && c <= 'f')
98 return 10 + c - 'a';
99 return 10 + c - 'A';
100}
101
102static inline uint8_t hex_byte(uint8_t c1, uint8_t c2)
103{
104 uint8_t h1 = hex_digit(c1);
105 uint8_t h2 = hex_digit(c2);
106 return (h1 << 4) | h2;
107}
108
109#define MAX_NAME 20
110typedef struct {
111 const char* name;
112 uint32_t value;
114
115static int color_entry_compare(const void* a, const void* b)
116{
117 const char* name = static_cast<const char*>(a);
118 const color_entry_t* entry = static_cast<const color_entry_t*>(b);
119 return strcmp(name, entry->name);
120}
121
122static bool parse_rgb_component(const char** begin, const char* end, float* component)
123{
124 float value = 0;
125 if(!parse_number(begin, end, &value))
126 return false;
127 if(skip_delim(begin, end, '%'))
128 value *= 2.55f;
129 *component = std::clamp(value, 0.f, 255.f) / 255.f;
130 return true;
131}
132
133static bool parse_alpha_component(const char** begin, const char* end, float* component)
134{
135 float value = 0;
136 if(!parse_number(begin, end, &value))
137 return false;
138 if(skip_delim(begin, end, '%'))
139 value /= 100.f;
140 *component = std::clamp(value, 0.f, 1.f);
141 return true;
142}
143
144NOVASVG_INLINE int color_parse(color_t* color, const char* data, int length)
145{
146 if(length == -1)
147 length = strlen(data);
148 const char* it = data;
149 const char* end = it + length;
150 skip_ws(&it, end);
151 if(skip_delim(&it, end, '#')) {
152 int r, g, b, a = 255;
153 const char* begin = it;
154 while(it < end && isxdigit(*it))
155 ++it;
156 int count = it - begin;
157 if(count == 3 || count == 4) {
158 r = hex_byte(begin[0], begin[0]);
159 g = hex_byte(begin[1], begin[1]);
160 b = hex_byte(begin[2], begin[2]);
161 if(count == 4) {
162 a = hex_byte(begin[3], begin[3]);
163 }
164 } else if(count == 6 || count == 8) {
165 r = hex_byte(begin[0], begin[1]);
166 g = hex_byte(begin[2], begin[3]);
167 b = hex_byte(begin[4], begin[5]);
168 if(count == 8) {
169 a = hex_byte(begin[6], begin[7]);
170 }
171 } else {
172 return 0;
173 }
174
175 color_init_rgba8(color, r, g, b, a);
176 } else {
177 int name_length = 0;
178 char name[MAX_NAME + 1];
179 while(it < end && name_length < MAX_NAME && isalpha(*it))
180 name[name_length++] = tolower(*it++);
181 name[name_length] = '\0';
182
183 if(strcmp(name, "transparent") == 0) {
184 color_init_rgba(color, 0, 0, 0, 0);
185 } else if(strcmp(name, "rgb") == 0 || strcmp(name, "rgba") == 0) {
186 if(!skip_ws_and_delim(&it, end, '('))
187 return 0;
188 float r, g, b, a = 1.f;
189 if(!parse_rgb_component(&it, end, &r)
190 || !skip_ws_and_comma(&it, end)
191 || !parse_rgb_component(&it, end, &g)
192 || !skip_ws_and_comma(&it, end)
193 || !parse_rgb_component(&it, end, &b)) {
194 return 0;
195 }
196
197 if(skip_ws_and_comma(&it, end)
198 && !parse_alpha_component(&it, end, &a)) {
199 return 0;
200 }
201
202 skip_ws(&it, end);
203 if(!skip_delim(&it, end, ')'))
204 return 0;
205 color_init_rgba(color, r, g, b, a);
206 } else if(strcmp(name, "hsl") == 0 || strcmp(name, "hsla") == 0) {
207 if(!skip_ws_and_delim(&it, end, '('))
208 return 0;
209 float h, s, l, a = 1.f;
210 if(!parse_number(&it, end, &h)
211 || !skip_ws_and_comma(&it, end)
212 || !parse_alpha_component(&it, end, &s)
213 || !skip_ws_and_comma(&it, end)
214 || !parse_alpha_component(&it, end, &l)) {
215 return 0;
216 }
217
218 if(skip_ws_and_comma(&it, end)
219 && !parse_alpha_component(&it, end, &a)) {
220 return 0;
221 }
222
223 skip_ws(&it, end);
224 if(!skip_delim(&it, end, ')'))
225 return 0;
226 color_init_hsla(color, h, s, l, a);
227 } else {
228 static const color_entry_t colormap[] = {
229 {"aliceblue", 0xF0F8FF},
230 {"antiquewhite", 0xFAEBD7},
231 {"aqua", 0x00FFFF},
232 {"aquamarine", 0x7FFFD4},
233 {"azure", 0xF0FFFF},
234 {"beige", 0xF5F5DC},
235 {"bisque", 0xFFE4C4},
236 {"black", 0x000000},
237 {"blanchedalmond", 0xFFEBCD},
238 {"blue", 0x0000FF},
239 {"blueviolet", 0x8A2BE2},
240 {"brown", 0xA52A2A},
241 {"burlywood", 0xDEB887},
242 {"cadetblue", 0x5F9EA0},
243 {"chartreuse", 0x7FFF00},
244 {"chocolate", 0xD2691E},
245 {"coral", 0xFF7F50},
246 {"cornflowerblue", 0x6495ED},
247 {"cornsilk", 0xFFF8DC},
248 {"crimson", 0xDC143C},
249 {"cyan", 0x00FFFF},
250 {"darkblue", 0x00008B},
251 {"darkcyan", 0x008B8B},
252 {"darkgoldenrod", 0xB8860B},
253 {"darkgray", 0xA9A9A9},
254 {"darkgreen", 0x006400},
255 {"darkgrey", 0xA9A9A9},
256 {"darkkhaki", 0xBDB76B},
257 {"darkmagenta", 0x8B008B},
258 {"darkolivegreen", 0x556B2F},
259 {"darkorange", 0xFF8C00},
260 {"darkorchid", 0x9932CC},
261 {"darkred", 0x8B0000},
262 {"darksalmon", 0xE9967A},
263 {"darkseagreen", 0x8FBC8F},
264 {"darkslateblue", 0x483D8B},
265 {"darkslategray", 0x2F4F4F},
266 {"darkslategrey", 0x2F4F4F},
267 {"darkturquoise", 0x00CED1},
268 {"darkviolet", 0x9400D3},
269 {"deeppink", 0xFF1493},
270 {"deepskyblue", 0x00BFFF},
271 {"dimgray", 0x696969},
272 {"dimgrey", 0x696969},
273 {"dodgerblue", 0x1E90FF},
274 {"firebrick", 0xB22222},
275 {"floralwhite", 0xFFFAF0},
276 {"forestgreen", 0x228B22},
277 {"fuchsia", 0xFF00FF},
278 {"gainsboro", 0xDCDCDC},
279 {"ghostwhite", 0xF8F8FF},
280 {"gold", 0xFFD700},
281 {"goldenrod", 0xDAA520},
282 {"gray", 0x808080},
283 {"green", 0x008000},
284 {"greenyellow", 0xADFF2F},
285 {"grey", 0x808080},
286 {"honeydew", 0xF0FFF0},
287 {"hotpink", 0xFF69B4},
288 {"indianred", 0xCD5C5C},
289 {"indigo", 0x4B0082},
290 {"ivory", 0xFFFFF0},
291 {"khaki", 0xF0E68C},
292 {"lavender", 0xE6E6FA},
293 {"lavenderblush", 0xFFF0F5},
294 {"lawngreen", 0x7CFC00},
295 {"lemonchiffon", 0xFFFACD},
296 {"lightblue", 0xADD8E6},
297 {"lightcoral", 0xF08080},
298 {"lightcyan", 0xE0FFFF},
299 {"lightgoldenrodyellow", 0xFAFAD2},
300 {"lightgray", 0xD3D3D3},
301 {"lightgreen", 0x90EE90},
302 {"lightgrey", 0xD3D3D3},
303 {"lightpink", 0xFFB6C1},
304 {"lightsalmon", 0xFFA07A},
305 {"lightseagreen", 0x20B2AA},
306 {"lightskyblue", 0x87CEFA},
307 {"lightslategray", 0x778899},
308 {"lightslategrey", 0x778899},
309 {"lightsteelblue", 0xB0C4DE},
310 {"lightyellow", 0xFFFFE0},
311 {"lime", 0x00FF00},
312 {"limegreen", 0x32CD32},
313 {"linen", 0xFAF0E6},
314 {"magenta", 0xFF00FF},
315 {"maroon", 0x800000},
316 {"mediumaquamarine", 0x66CDAA},
317 {"mediumblue", 0x0000CD},
318 {"mediumorchid", 0xBA55D3},
319 {"mediumpurple", 0x9370DB},
320 {"mediumseagreen", 0x3CB371},
321 {"mediumslateblue", 0x7B68EE},
322 {"mediumspringgreen", 0x00FA9A},
323 {"mediumturquoise", 0x48D1CC},
324 {"mediumvioletred", 0xC71585},
325 {"midnightblue", 0x191970},
326 {"mintcream", 0xF5FFFA},
327 {"mistyrose", 0xFFE4E1},
328 {"moccasin", 0xFFE4B5},
329 {"navajowhite", 0xFFDEAD},
330 {"navy", 0x000080},
331 {"oldlace", 0xFDF5E6},
332 {"olive", 0x808000},
333 {"olivedrab", 0x6B8E23},
334 {"orange", 0xFFA500},
335 {"orangered", 0xFF4500},
336 {"orchid", 0xDA70D6},
337 {"palegoldenrod", 0xEEE8AA},
338 {"palegreen", 0x98FB98},
339 {"paleturquoise", 0xAFEEEE},
340 {"palevioletred", 0xDB7093},
341 {"papayawhip", 0xFFEFD5},
342 {"peachpuff", 0xFFDAB9},
343 {"peru", 0xCD853F},
344 {"pink", 0xFFC0CB},
345 {"plum", 0xDDA0DD},
346 {"powderblue", 0xB0E0E6},
347 {"purple", 0x800080},
348 {"rebeccapurple", 0x663399},
349 {"red", 0xFF0000},
350 {"rosybrown", 0xBC8F8F},
351 {"royalblue", 0x4169E1},
352 {"saddlebrown", 0x8B4513},
353 {"salmon", 0xFA8072},
354 {"sandybrown", 0xF4A460},
355 {"seagreen", 0x2E8B57},
356 {"seashell", 0xFFF5EE},
357 {"sienna", 0xA0522D},
358 {"silver", 0xC0C0C0},
359 {"skyblue", 0x87CEEB},
360 {"slateblue", 0x6A5ACD},
361 {"slategray", 0x708090},
362 {"slategrey", 0x708090},
363 {"snow", 0xFFFAFA},
364 {"springgreen", 0x00FF7F},
365 {"steelblue", 0x4682B4},
366 {"tan", 0xD2B48C},
367 {"teal", 0x008080},
368 {"thistle", 0xD8BFD8},
369 {"tomato", 0xFF6347},
370 {"turquoise", 0x40E0D0},
371 {"violet", 0xEE82EE},
372 {"wheat", 0xF5DEB3},
373 {"white", 0xFFFFFF},
374 {"whitesmoke", 0xF5F5F5},
375 {"yellow", 0xFFFF00},
376 {"yellowgreen", 0x9ACD32}
377 };
378
379 const color_entry_t* entry = static_cast<const color_entry_t*>(bsearch(
380 name,
381 colormap,
382 sizeof(colormap) / sizeof(color_entry_t),
383 sizeof(color_entry_t),
384 color_entry_compare
385 ));
386 if(entry == NULL)
387 return 0;
388 color_init_argb32(color, 0xFF000000 | entry->value);
389 }
390 }
391
392 skip_ws(&it, end);
393 return it - data;
394}
395
396static void* paint_create(paint_type_t type, size_t size)
397{
398 paint_t* paint = static_cast<paint_t*>(malloc(size));
400 paint->type = type;
401 return paint;
402}
403
404NOVASVG_INLINE paint_t* paint_create_rgb(float r, float g, float b)
405{
406 return paint_create_rgba(r, g, b, 1.f);
407}
408
409NOVASVG_INLINE paint_t* paint_create_rgba(float r, float g, float b, float a)
410{
411 solid_paint_t* solid = static_cast<solid_paint_t*>(paint_create(
413 sizeof(solid_paint_t)
414 ));
415 solid->color.r = std::clamp(r, 0.f, 1.f);
416 solid->color.g = std::clamp(g, 0.f, 1.f);
417 solid->color.b = std::clamp(b, 0.f, 1.f);
418 solid->color.a = std::clamp(a, 0.f, 1.f);
419 return &solid->base;
420}
421
426
427static gradient_paint_t* gradient_create(gradient_type_t type, spread_method_t spread, const gradient_stop_t* stops, int nstops, const matrix_t* matrix)
428{
429 gradient_paint_t* gradient = static_cast<gradient_paint_t*>(paint_create(
431 sizeof(gradient_paint_t) + nstops * sizeof(gradient_stop_t)
432 ));
433 gradient->type = type;
434 gradient->spread = spread;
436 gradient->stops = (gradient_stop_t*)(gradient + 1);
437 gradient->nstops = nstops;
438
439 float prev_offset = 0.f;
440 for(int i = 0; i < nstops; ++i) {
441 const gradient_stop_t* stop = stops + i;
442 gradient->stops[i].offset = NOVASVG_MAX(prev_offset, std::clamp(stop->offset, 0.f, 1.f));
443 gradient->stops[i].color.r = std::clamp(stop->color.r, 0.f, 1.f);
444 gradient->stops[i].color.g = std::clamp(stop->color.g, 0.f, 1.f);
445 gradient->stops[i].color.b = std::clamp(stop->color.b, 0.f, 1.f);
446 gradient->stops[i].color.a = std::clamp(stop->color.a, 0.f, 1.f);
447 prev_offset = gradient->stops[i].offset;
448 }
449
450 return gradient;
451}
452
453NOVASVG_INLINE paint_t* paint_create_linear_gradient(float x1, float y1, float x2, float y2, spread_method_t spread, const gradient_stop_t* stops, int nstops, const matrix_t* matrix)
454{
455 gradient_paint_t* gradient = gradient_create(NOVASVG_GRADIENT_TYPE_LINEAR, spread, stops, nstops, matrix);
456 gradient->values[0] = x1;
457 gradient->values[1] = y1;
458 gradient->values[2] = x2;
459 gradient->values[3] = y2;
460 return &gradient->base;
461}
462
463NOVASVG_INLINE paint_t* paint_create_radial_gradient(float cx, float cy, float cr, float fx, float fy, float fr, spread_method_t spread, const gradient_stop_t* stops, int nstops, const matrix_t* matrix)
464{
465 gradient_paint_t* gradient = gradient_create(NOVASVG_GRADIENT_TYPE_RADIAL, spread, stops, nstops, matrix);
466 gradient->values[0] = cx;
467 gradient->values[1] = cy;
468 gradient->values[2] = cr;
469 gradient->values[3] = fx;
470 gradient->values[4] = fy;
471 gradient->values[5] = fr;
472 return &gradient->base;
473}
474
476{
477 texture_paint_t* texture = static_cast<texture_paint_t*>(paint_create(
479 sizeof(texture_paint_t)
480 ));
481 texture->type = type;
482 texture->opacity = std::clamp(opacity, 0.f, 1.f);
485 return &texture->base;
486}
487
493
495{
499 surface_destroy(texture->surface);
500 }
501
502 free(paint);
503 }
504}
505
510
511
512} // namespace render
513} // namespace novasvg
#define NOVASVG_MAX(a, b)
Definition color.h:11
#define NOVASVG_MIN(a, b)
Definition color.h:14
NOVASVG_INLINE void paint_destroy(paint_t *paint)
Decrements the reference count and destroys the paint if the count reaches zero.
Definition paint.h:494
NOVASVG_INLINE void color_init_rgb(color_t *color, float r, float g, float b)
Initializes a color using RGB components in the 0-1 range.
Definition paint.h:11
NOVASVG_INLINE bool parse_number(const char **begin, const char *end, float *number)
Definition utils.h:88
NOVASVG_INLINE void color_init_rgba32(color_t *color, unsigned int value)
Initializes a color from a 32-bit unsigned RGBA value.
Definition paint.h:34
texture_type_t
Defines the type of texture, either plain or tiled.
Definition render.h:1294
NOVASVG_INLINE bool skip_ws_and_delim(const char **begin, const char *end, char delim)
Definition utils.h:183
NOVASVG_INLINE void color_init_hsla(color_t *color, float h, float s, float l, float a)
Initializes a color with the specified HSLA color values.
Definition paint.h:64
NOVASVG_INLINE void color_init_rgba(color_t *color, float r, float g, float b, float a)
Initializes a color using RGBA components in the 0-1 range.
Definition paint.h:16
NOVASVG_INLINE unsigned int color_to_argb32(const color_t *color)
Converts a color to a 32-bit unsigned ARGB value.
Definition paint.h:84
NOVASVG_INLINE void color_init_rgba8(color_t *color, int r, int g, int b, int a)
Initializes a color using RGBA components in the 0-255 range.
Definition paint.h:29
NOVASVG_INLINE paint_t * paint_reference(paint_t *paint)
Increments the reference count of a paint object.
Definition paint.h:488
NOVASVG_INLINE bool skip_ws_and_comma(const char **begin, const char *end)
Definition utils.h:198
void surface_destroy(surface_t *surface)
Decrements the reference count and destroys the surface if the count reaches zero.
Definition surface.h:7926
NOVASVG_INLINE bool skip_delim(const char **begin, const char *end, const char delim)
Definition utils.h:147
NOVASVG_INLINE paint_t * paint_create_rgba(float r, float g, float b, float a)
Creates a solid RGBA paint.
Definition paint.h:409
NOVASVG_INLINE bool skip_ws(const char **begin, const char *end)
Definition utils.h:174
NOVASVG_INLINE unsigned int color_to_rgba32(const color_t *color)
Converts a color to a 32-bit unsigned RGBA value.
Definition paint.h:75
NOVASVG_INLINE paint_t * paint_create_color(const color_t *color)
Creates a solid color paint.
Definition paint.h:422
NOVASVG_INLINE paint_t * paint_create_linear_gradient(float x1, float y1, float x2, float y2, spread_method_t spread, const gradient_stop_t *stops, int nstops, const matrix_t *matrix)
Creates a linear gradient paint.
Definition paint.h:453
NOVASVG_INLINE paint_t * paint_create_rgb(float r, float g, float b)
Creates a solid RGB paint.
Definition paint.h:404
NOVASVG_INLINE paint_t * paint_create_texture(surface_t *surface, texture_type_t type, float opacity, const matrix_t *matrix)
Creates a texture paint from a surface.
Definition paint.h:475
NOVASVG_INLINE int color_parse(color_t *color, const char *data, int length)
Parses a color from a string using CSS color syntax.
Definition paint.h:144
NOVASVG_INLINE void color_init_argb32(color_t *color, unsigned int value)
Initializes a color from a 32-bit unsigned ARGB value.
Definition paint.h:43
NOVASVG_INLINE int paint_get_reference_count(const paint_t *paint)
Retrieves the reference count of a paint object.
Definition paint.h:506
NOVASVG_INLINE paint_t * paint_create_radial_gradient(float cx, float cy, float cr, float fx, float fy, float fr, spread_method_t spread, const gradient_stop_t *stops, int nstops, const matrix_t *matrix)
Creates a radial gradient paint.
Definition paint.h:463
spread_method_t
Defines the spread method for gradients.
Definition render.h:1302
NOVASVG_INLINE void color_init_rgb8(color_t *color, int r, int g, int b)
Initializes a color using RGB components in the 0-255 range.
Definition paint.h:24
surface_t * surface_reference(surface_t *surface)
Increments the reference count for a surface.
Definition surface.h:7920
@ NOVASVG_PAINT_TYPE_GRADIENT
Definition private.h:75
@ NOVASVG_PAINT_TYPE_TEXTURE
Definition private.h:76
@ NOVASVG_PAINT_TYPE_COLOR
Definition private.h:74
@ NOVASVG_GRADIENT_TYPE_LINEAR
Definition private.h:90
@ NOVASVG_GRADIENT_TYPE_RADIAL
Definition private.h:91
NOVASVG_INLINE void color_init_hsl(color_t *color, float h, float s, float l)
Initializes a color with the specified HSL color values.
Definition paint.h:52
Main namespace for the NovaSVG library.
Definition bitmap.h:23
#define NOVASVG_INLINE
Definition novasvg.h:42
#define MAX_NAME
Definition paint.h:109
#define novasvg_get_reference_count(ob)
Definition private.h:48
#define novasvg_destroy_reference(ob)
Definition private.h:47
#define novasvg_init_reference(ob)
Definition private.h:45
#define novasvg_increment_reference(ob)
Definition private.h:46
#define NOVASVG_IDENTITY_MATRIX
Definition render.h:150
Definition paint.h:110
const char * name
Definition paint.h:111
uint32_t value
Definition paint.h:112
Represents a color with red, green, blue, and alpha components.
Definition render.h:1019
float b
Blue component (0 to 1).
Definition render.h:1022
float g
Green component (0 to 1).
Definition render.h:1021
float a
Alpha (opacity) component (0 to 1).
Definition render.h:1023
float r
Red component (0 to 1).
Definition render.h:1020
Represents a gradient stop.
Definition render.h:1311
color_t color
The color of the gradient stop.
Definition render.h:1313
float offset
The offset of the gradient stop, as a value between 0 and 1.
Definition render.h:1312
A structure representing a 2D transformation matrix.
Definition render.h:138
paint_type_t type
Definition private.h:81