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);
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;
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;
57static inline float hsl_component(
float h,
float s,
float l,
float n)
59 const float k = fmodf(n + h / 30.f, 12.f);
67 if(h < 0.f) { h += 360.f; }
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);
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);
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);
93static inline uint8_t hex_digit(uint8_t c)
95 if(c >=
'0' && c <=
'9')
97 if(c >=
'a' && c <=
'f')
102static inline uint8_t hex_byte(uint8_t c1, uint8_t c2)
104 uint8_t h1 = hex_digit(c1);
105 uint8_t h2 = hex_digit(c2);
106 return (h1 << 4) | h2;
115static int color_entry_compare(
const void* a,
const void* b)
117 const char* name =
static_cast<const char*
>(a);
119 return strcmp(name, entry->
name);
122static bool parse_rgb_component(
const char** begin,
const char* end,
float* component)
129 *component = std::clamp(value, 0.f, 255.f) / 255.f;
133static bool parse_alpha_component(
const char** begin,
const char* end,
float* component)
140 *component = std::clamp(value, 0.f, 1.f);
147 length = strlen(data);
148 const char* it = data;
149 const char* end = it + length;
152 int r, g, b, a = 255;
153 const char* begin = it;
154 while(it < end && isxdigit(*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]);
162 a = hex_byte(begin[3], begin[3]);
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]);
169 a = hex_byte(begin[6], begin[7]);
179 while(it < end && name_length <
MAX_NAME && isalpha(*it))
180 name[name_length++] = tolower(*it++);
181 name[name_length] =
'\0';
183 if(strcmp(name,
"transparent") == 0) {
185 }
else if(strcmp(name,
"rgb") == 0 || strcmp(name,
"rgba") == 0) {
188 float r, g, b, a = 1.f;
189 if(!parse_rgb_component(&it, end, &r)
191 || !parse_rgb_component(&it, end, &g)
193 || !parse_rgb_component(&it, end, &b)) {
198 && !parse_alpha_component(&it, end, &a)) {
206 }
else if(strcmp(name,
"hsl") == 0 || strcmp(name,
"hsla") == 0) {
209 float h, s, l, a = 1.f;
212 || !parse_alpha_component(&it, end, &s)
214 || !parse_alpha_component(&it, end, &l)) {
219 && !parse_alpha_component(&it, end, &a)) {
229 {
"aliceblue", 0xF0F8FF},
230 {
"antiquewhite", 0xFAEBD7},
232 {
"aquamarine", 0x7FFFD4},
235 {
"bisque", 0xFFE4C4},
237 {
"blanchedalmond", 0xFFEBCD},
239 {
"blueviolet", 0x8A2BE2},
241 {
"burlywood", 0xDEB887},
242 {
"cadetblue", 0x5F9EA0},
243 {
"chartreuse", 0x7FFF00},
244 {
"chocolate", 0xD2691E},
246 {
"cornflowerblue", 0x6495ED},
247 {
"cornsilk", 0xFFF8DC},
248 {
"crimson", 0xDC143C},
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},
281 {
"goldenrod", 0xDAA520},
284 {
"greenyellow", 0xADFF2F},
286 {
"honeydew", 0xF0FFF0},
287 {
"hotpink", 0xFF69B4},
288 {
"indianred", 0xCD5C5C},
289 {
"indigo", 0x4B0082},
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},
312 {
"limegreen", 0x32CD32},
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},
331 {
"oldlace", 0xFDF5E6},
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},
346 {
"powderblue", 0xB0E0E6},
347 {
"purple", 0x800080},
348 {
"rebeccapurple", 0x663399},
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},
364 {
"springgreen", 0x00FF7F},
365 {
"steelblue", 0x4682B4},
368 {
"thistle", 0xD8BFD8},
369 {
"tomato", 0xFF6347},
370 {
"turquoise", 0x40E0D0},
371 {
"violet", 0xEE82EE},
374 {
"whitesmoke", 0xF5F5F5},
375 {
"yellow", 0xFFFF00},
376 {
"yellowgreen", 0x9ACD32}
396static void* paint_create(
paint_type_t type,
size_t size)
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);
433 gradient->
type = type;
434 gradient->
spread = spread;
437 gradient->
nstops = nstops;
439 float prev_offset = 0.f;
440 for(
int i = 0; i < nstops; ++i) {
460 return &gradient->
base;
472 return &gradient->
base;
481 texture->
type = type;
482 texture->
opacity = std::clamp(opacity, 0.f, 1.f);
485 return &texture->
base;
#define NOVASVG_MAX(a, b)
#define NOVASVG_MIN(a, b)
NOVASVG_INLINE void paint_destroy(paint_t *paint)
Decrements the reference count and destroys the paint if the count reaches zero.
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.
NOVASVG_INLINE bool parse_number(const char **begin, const char *end, float *number)
NOVASVG_INLINE void color_init_rgba32(color_t *color, unsigned int value)
Initializes a color from a 32-bit unsigned RGBA value.
texture_type_t
Defines the type of texture, either plain or tiled.
NOVASVG_INLINE bool skip_ws_and_delim(const char **begin, const char *end, char delim)
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.
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.
NOVASVG_INLINE unsigned int color_to_argb32(const color_t *color)
Converts a color to a 32-bit unsigned ARGB value.
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.
NOVASVG_INLINE paint_t * paint_reference(paint_t *paint)
Increments the reference count of a paint object.
NOVASVG_INLINE bool skip_ws_and_comma(const char **begin, const char *end)
void surface_destroy(surface_t *surface)
Decrements the reference count and destroys the surface if the count reaches zero.
NOVASVG_INLINE bool skip_delim(const char **begin, const char *end, const char delim)
NOVASVG_INLINE paint_t * paint_create_rgba(float r, float g, float b, float a)
Creates a solid RGBA paint.
NOVASVG_INLINE bool skip_ws(const char **begin, const char *end)
NOVASVG_INLINE unsigned int color_to_rgba32(const color_t *color)
Converts a color to a 32-bit unsigned RGBA value.
NOVASVG_INLINE paint_t * paint_create_color(const color_t *color)
Creates a solid color paint.
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.
NOVASVG_INLINE paint_t * paint_create_rgb(float r, float g, float b)
Creates a solid RGB paint.
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.
NOVASVG_INLINE int color_parse(color_t *color, const char *data, int length)
Parses a color from a string using CSS color syntax.
NOVASVG_INLINE void color_init_argb32(color_t *color, unsigned int value)
Initializes a color from a 32-bit unsigned ARGB value.
NOVASVG_INLINE int paint_get_reference_count(const paint_t *paint)
Retrieves the reference count of a paint object.
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.
spread_method_t
Defines the spread method for gradients.
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.
surface_t * surface_reference(surface_t *surface)
Increments the reference count for a surface.
@ NOVASVG_PAINT_TYPE_GRADIENT
@ NOVASVG_PAINT_TYPE_TEXTURE
@ NOVASVG_PAINT_TYPE_COLOR
@ NOVASVG_GRADIENT_TYPE_LINEAR
@ NOVASVG_GRADIENT_TYPE_RADIAL
NOVASVG_INLINE void color_init_hsl(color_t *color, float h, float s, float l)
Initializes a color with the specified HSL color values.
Main namespace for the NovaSVG library.
#define novasvg_get_reference_count(ob)
#define novasvg_destroy_reference(ob)
#define novasvg_init_reference(ob)
#define novasvg_increment_reference(ob)
#define NOVASVG_IDENTITY_MATRIX
Represents a color with red, green, blue, and alpha components.
float b
Blue component (0 to 1).
float g
Green component (0 to 1).
float a
Alpha (opacity) component (0 to 1).
float r
Red component (0 to 1).
Represents a gradient stop.
color_t color
The color of the gradient stop.
float offset
The offset of the gradient stop, as a value between 0 and 1.
A structure representing a 2D transformation matrix.