18#define NOVASVG_IS_NUM(c) ((c) >= '0' && (c) <= '9')
19#define NOVASVG_IS_ALPHA(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
20#define NOVASVG_IS_ALNUM(c) (NOVASVG_IS_ALPHA(c) || NOVASVG_IS_NUM(c))
21#define NOVASVG_IS_WS(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r')
31#define novasvg_alpha(c) (((c) >> 24) & 0xff)
32#define novasvg_red(c) (((c) >> 16) & 0xff)
33#define novasvg_green(c) (((c) >> 8) & 0xff)
34#define novasvg_blue(c) (((c) >> 0) & 0xff)
36#define novasvg_array_init(array) \
38 (array).data = NULL; \
40 (array).capacity = 0; \
44#define NOVASVG_ARRAY_CAST(array, value) static_cast<decltype((array).data)>(value)
46#define NOVASVG_ARRAY_CAST(array, value) (value)
49#define novasvg_array_ensure(array, count) \
51 if((array).size + (count) > (array).capacity) { \
52 int capacity = (array).size + (count); \
53 int newcapacity = (array).capacity == 0 ? 8 : (array).capacity; \
54 while(newcapacity < capacity) { newcapacity *= 2; } \
55 (array).data = NOVASVG_ARRAY_CAST(array, realloc((array).data, newcapacity * sizeof((array).data[0]))); \
56 (array).capacity = newcapacity; \
60#define novasvg_array_append_data(array, newdata, count) \
62 if(newdata && count > 0) { \
63 novasvg_array_ensure(array, count); \
64 memcpy((array).data + (array).size, newdata, (count) * sizeof((newdata)[0])); \
65 (array).size += count; \
69#define novasvg_array_append(array, other) novasvg_array_append_data(array, (other).data, (other).size)
70#define novasvg_array_clear(array) ((array).size = 0)
71#define novasvg_array_destroy(array) free((array).data)
85 return (a << 24) | (r << 16) | (g << 8) | (b);
90 const char* it = *begin;
97 if(it < end && *it ==
'+') {
99 }
else if(it < end && *it ==
'-') {
108 integer = 10.f * integer + (*it++ -
'0');
112 if(it < end && *it ==
'.') {
118 fraction = 10.f * fraction + (*it++ -
'0');
124 if(it < end && (*it ==
'e' || *it ==
'E')) {
126 if(it < end && *it ==
'+') {
128 }
else if(it < end && *it ==
'-') {
136 exponent = 10 * exponent + (*it++ -
'0');
141 *number = sign * (integer + fraction);
143 *number *= powf(10.f, expsign * exponent);
144 return *number >= -FLT_MAX && *number <= FLT_MAX;
149 const char* it = *begin;
150 if(it < end && *it == delim) {
160 const char* it = *begin;
161 while(it < end && *data && *it == *data) {
176 const char* it = *begin;
185 const char* it = *begin;
205 const char* it = *begin;
238 const char* it = *begin;
239 const char* unitStart = it;
240 while(it < end && ((*it >=
'a' && *it <=
'z') || (*it >=
'A' && *it <=
'Z') || *it ==
'%'))
245 auto length = size_t(it - unitStart);
246 auto matches = [&](
const char* unit) {
247 auto unitLength = strlen(unit);
248 return length == unitLength && strncmp(unitStart, unit, unitLength) == 0;
252 *number *= 180.f / 3.14159265f;
253 else if(matches(
"grad"))
255 else if(matches(
"turn"))
NOVASVG_INLINE bool parse_number(const char **begin, const char *end, float *number)
NOVASVG_INLINE bool skip_ws_or_comma(const char **begin, const char *end, bool *has_comma)
NOVASVG_INLINE bool skip_ws_and_delim(const char **begin, const char *end, char delim)
NOVASVG_INLINE uint32_t premultiply_argb(uint32_t color)
NOVASVG_INLINE bool skip_ws_and_comma(const char **begin, const char *end)
NOVASVG_INLINE bool skip_delim(const char **begin, const char *end, const char delim)
NOVASVG_INLINE bool skip_string(const char **begin, const char *end, const char *data)
NOVASVG_INLINE bool skip_ws(const char **begin, const char *end)
NOVASVG_INLINE void skip_css_unit(const char **begin, const char *end, float *number)
NOVASVG_INLINE bool skip_ws_or_delim(const char **begin, const char *end, char delim, bool *has_delim)
Main namespace for the NovaSVG library.
Represents a color with red, green, blue, and alpha components.
#define NOVASVG_IS_NUM(c)