Merge commit 'e5b9b5300696c02f872dc8f124fc96402e4570b4' into new-svg-renderer

This commit is contained in:
Leon Styhre 2022-10-26 20:03:32 +02:00
commit 3e9ddde2f3
9 changed files with 263 additions and 386 deletions

View file

@ -418,7 +418,6 @@ static void blend_solid(plutovg_surface_t* surface, plutovg_operator_t op, const
}
}
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define BUFFER_SIZE 1024
static void blend_linear_gradient(plutovg_surface_t* surface, plutovg_operator_t op, const plutovg_rle_t* rle, const gradient_data_t* gradient)
{
@ -445,7 +444,7 @@ static void blend_linear_gradient(plutovg_surface_t* surface, plutovg_operator_t
int x = spans->x;
while(length)
{
int l = MIN(length, BUFFER_SIZE);
int l = plutovg_min(length, BUFFER_SIZE);
fetch_linear_gradient(buffer, &v, gradient, spans->y, x, l);
uint32_t* target = (uint32_t*)(surface->data + spans->y * surface->stride) + x;
func(target, l, buffer, spans->coverage);
@ -479,7 +478,7 @@ static void blend_radial_gradient(plutovg_surface_t* surface, plutovg_operator_t
int x = spans->x;
while(length)
{
int l = MIN(length, BUFFER_SIZE);
int l = plutovg_min(length, BUFFER_SIZE);
fetch_radial_gradient(buffer, &v, gradient, spans->y, x, l);
uint32_t* target = (uint32_t*)(surface->data + spans->y * surface->stride) + x;
func(target, l, buffer, spans->coverage);
@ -491,7 +490,6 @@ static void blend_radial_gradient(plutovg_surface_t* surface, plutovg_operator_t
}
}
#define CLAMP(v, lo, hi) ((v) < (lo) ? (lo) : (hi) < (v) ? (hi) : (v))
#define FIXED_SCALE (1 << 16)
static void blend_transformed_argb(plutovg_surface_t* surface, plutovg_operator_t op, const plutovg_rle_t* rle, const texture_data_t* texture)
{
@ -520,13 +518,13 @@ static void blend_transformed_argb(plutovg_surface_t* surface, plutovg_operator_
const int coverage = (spans->coverage * texture->const_alpha) >> 8;
while(length)
{
int l = MIN(length, BUFFER_SIZE);
int l = plutovg_min(length, BUFFER_SIZE);
const uint32_t* end = buffer + l;
uint32_t* b = buffer;
while(b < end)
{
int px = CLAMP(x >> 16, 0, image_width - 1);
int py = CLAMP(y >> 16, 0, image_height - 1);
int px = plutovg_clamp(x >> 16, 0, image_width - 1);
int py = plutovg_clamp(y >> 16, 0, image_height - 1);
*b = ((const uint32_t*)(texture->data + py * texture->stride))[px];
x += fdx;
@ -614,7 +612,7 @@ static void blend_untransformed_tiled_argb(plutovg_surface_t* surface, plutovg_o
const int coverage = (spans->coverage * texture->const_alpha) >> 8;
while(length)
{
int l = MIN(image_width - sx, length);
int l = plutovg_min(image_width - sx, length);
if(BUFFER_SIZE < l)
l = BUFFER_SIZE;
const uint32_t* src = (const uint32_t*)(texture->data + sy * texture->stride) + sx;
@ -658,7 +656,7 @@ static void blend_transformed_tiled_argb(plutovg_surface_t* surface, plutovg_ope
int length = spans->len;
while(length)
{
int l = MIN(length, BUFFER_SIZE);
int l = plutovg_min(length, BUFFER_SIZE);
const uint32_t* end = buffer + l;
uint32_t* b = buffer;
int px16 = x % (image_width << 16);
@ -696,13 +694,13 @@ static void blend_transformed_tiled_argb(plutovg_surface_t* surface, plutovg_ope
void plutovg_blend(plutovg_t* pluto, const plutovg_rle_t* rle)
{
plutovg_paint_t* source = pluto->state->source;
plutovg_paint_t* source = &pluto->state->paint;
if(source->type == plutovg_paint_type_color)
plutovg_blend_color(pluto, rle, source->color);
plutovg_blend_color(pluto, rle, &source->color);
else if(source->type == plutovg_paint_type_gradient)
plutovg_blend_gradient(pluto, rle, source->gradient);
plutovg_blend_gradient(pluto, rle, &source->gradient);
else
plutovg_blend_texture(pluto, rle, source->texture);
plutovg_blend_texture(pluto, rle, &source->texture);
}
void plutovg_blend_color(plutovg_t* pluto, const plutovg_rle_t* rle, const plutovg_color_t* color)

View file

@ -327,14 +327,13 @@ void plutovg_path_add_rect(plutovg_path_t* path, double x, double y, double w, d
plutovg_path_close(path);
}
#define KAPPA 0.5522847498
void plutovg_path_add_round_rect(plutovg_path_t* path, double x, double y, double w, double h, double rx, double ry)
{
double right = x + w;
double bottom = y + h;
double cpx = rx * KAPPA;
double cpy = ry * KAPPA;
double cpx = rx * plutovg_kappa;
double cpy = ry * plutovg_kappa;
plutovg_path_move_to(path, x, y+ry);
plutovg_path_cubic_to(path, x, y+ry-cpy, x+rx-cpx, y, x+rx, y);
@ -355,8 +354,8 @@ void plutovg_path_add_ellipse(plutovg_path_t* path, double cx, double cy, double
double right = cx + rx;
double bottom = cy + ry;
double cpx = rx * KAPPA;
double cpy = ry * KAPPA;
double cpx = rx * plutovg_kappa;
double cpy = ry * plutovg_kappa;
plutovg_path_move_to(path, cx, top);
plutovg_path_cubic_to(path, cx+cpx, top, right, cy-cpy, right, cy);

View file

@ -7,69 +7,30 @@ void plutovg_color_init_rgb(plutovg_color_t* color, double r, double g, double b
void plutovg_color_init_rgba(plutovg_color_t* color, double r, double g, double b, double a)
{
color->r = r;
color->g = g;
color->b = b;
color->a = a;
color->r = plutovg_clamp(r, 0.0, 1.0);
color->g = plutovg_clamp(g, 0.0, 1.0);
color->b = plutovg_clamp(b, 0.0, 1.0);
color->a = plutovg_clamp(a, 0.0, 1.0);
}
plutovg_gradient_t* plutovg_gradient_create_linear(double x1, double y1, double x2, double y2)
void plutovg_gradient_init_linear(plutovg_gradient_t* gradient, double x1, double y1, double x2, double y2)
{
plutovg_gradient_t* gradient = malloc(sizeof(plutovg_gradient_t));
gradient->ref = 1;
gradient->type = plutovg_gradient_type_linear;
gradient->spread = plutovg_spread_method_pad;
gradient->opacity = 1.0;
plutovg_array_init(gradient->stops);
plutovg_array_clear(gradient->stops);
plutovg_matrix_init_identity(&gradient->matrix);
plutovg_gradient_set_values_linear(gradient, x1, y1, x2, y2);
return gradient;
}
plutovg_gradient_t* plutovg_gradient_create_radial(double cx, double cy, double cr, double fx, double fy, double fr)
void plutovg_gradient_init_radial(plutovg_gradient_t* gradient, double cx, double cy, double cr, double fx, double fy, double fr)
{
plutovg_gradient_t* gradient = malloc(sizeof(plutovg_gradient_t));
gradient->ref = 1;
gradient->type = plutovg_gradient_type_radial;
gradient->spread = plutovg_spread_method_pad;
gradient->opacity = 1.0;
plutovg_array_init(gradient->stops);
plutovg_array_clear(gradient->stops);
plutovg_matrix_init_identity(&gradient->matrix);
plutovg_gradient_set_values_radial(gradient, cx, cy, cr, fx, fy, fr);
return gradient;
}
plutovg_gradient_t* plutovg_gradient_reference(plutovg_gradient_t* gradient)
{
++gradient->ref;
return gradient;
}
void plutovg_gradient_destroy(plutovg_gradient_t* gradient)
{
if(gradient==NULL)
return;
if(--gradient->ref==0)
{
free(gradient->stops.data);
free(gradient);
}
}
int plutovg_gradient_get_reference_count(const plutovg_gradient_t* gradient)
{
return gradient->ref;
}
void plutovg_gradient_set_type(plutovg_gradient_t* gradient, plutovg_gradient_type_t type)
{
gradient->type = type;
}
plutovg_gradient_type_t plutovg_gradient_get_type(const plutovg_gradient_t* gradient)
{
return gradient->type;
}
void plutovg_gradient_set_spread(plutovg_gradient_t* gradient, plutovg_spread_method_t spread)
@ -87,7 +48,7 @@ void plutovg_gradient_set_matrix(plutovg_gradient_t* gradient, const plutovg_mat
gradient->matrix = *matrix;
}
void plutovg_gradient_get_matrix(const plutovg_gradient_t* gradient, plutovg_matrix_t* matrix)
void plutovg_gradient_get_matrix(const plutovg_gradient_t* gradient, plutovg_matrix_t *matrix)
{
*matrix = gradient->matrix;
}
@ -99,26 +60,29 @@ void plutovg_gradient_add_stop_rgb(plutovg_gradient_t* gradient, double offset,
void plutovg_gradient_add_stop_rgba(plutovg_gradient_t* gradient, double offset, double r, double g, double b, double a)
{
if(offset < 0.0) offset = 0.0;
if(offset > 1.0) offset = 1.0;
plutovg_array_ensure(gradient->stops, 1);
plutovg_gradient_stop_t* stops = gradient->stops.data;
int nstops = gradient->stops.size;
int i;
for(i = 0;i < nstops;i++)
{
if(offset < stops[i].offset)
{
int i = 0;
for(; i < nstops; i++) {
if(offset < stops[i].offset) {
memmove(&stops[i+1], &stops[i], (size_t)(nstops - i) * sizeof(plutovg_gradient_stop_t));
break;
}
}
stops[i].offset = offset;
stops[i].color.r = r;
stops[i].color.g = g;
stops[i].color.b = b;
stops[i].color.a = a;
plutovg_gradient_stop_t* stop = &stops[i];
stop->offset = offset;
plutovg_color_init_rgba(&stop->color, r, g, b, a);
gradient->stops.size += 1;
}
gradient->stops.size++;
void plutovg_gradient_add_stop_color(plutovg_gradient_t* gradient, double offset, const plutovg_color_t* color)
{
plutovg_gradient_add_stop_rgba(gradient, offset, color->r, color->g, color->b, color->a);
}
void plutovg_gradient_add_stop(plutovg_gradient_t* gradient, const plutovg_gradient_stop_t* stop)
@ -141,22 +105,27 @@ plutovg_gradient_stop_t* plutovg_gradient_get_stops(const plutovg_gradient_t* gr
return gradient->stops.data;
}
plutovg_gradient_type_t plutovg_gradient_get_type(const plutovg_gradient_t* gradient)
{
return gradient->type;
}
void plutovg_gradient_get_values_linear(const plutovg_gradient_t* gradient, double* x1, double* y1, double* x2, double* y2)
{
*x1 = gradient->values[0];
*y1 = gradient->values[1];
*x2 = gradient->values[2];
*y2 = gradient->values[3];
if(x1) *x1 = gradient->values[0];
if(y1) *y1 = gradient->values[1];
if(x2) *x2 = gradient->values[2];
if(y2) *y2 = gradient->values[3];
}
void plutovg_gradient_get_values_radial(const plutovg_gradient_t* gradient, double* cx, double* cy, double* cr, double* fx, double* fy, double* fr)
{
*cx = gradient->values[0];
*cy = gradient->values[1];
*cr = gradient->values[2];
*fx = gradient->values[3];
*fy = gradient->values[4];
*fr = gradient->values[5];
if(cx) *cx = gradient->values[0];
if(cy) *cy = gradient->values[1];
if(cr) *cr = gradient->values[2];
if(fx) *fx = gradient->values[3];
if(fy) *fy = gradient->values[4];
if(fr) *fr = gradient->values[5];
}
void plutovg_gradient_set_values_linear(plutovg_gradient_t* gradient, double x1, double y1, double x2, double y2)
@ -179,7 +148,7 @@ void plutovg_gradient_set_values_radial(plutovg_gradient_t* gradient, double cx,
void plutovg_gradient_set_opacity(plutovg_gradient_t* gradient, double opacity)
{
gradient->opacity = opacity;
gradient->opacity = plutovg_clamp(opacity, 0.0, 1.0);
}
double plutovg_gradient_get_opacity(const plutovg_gradient_t* gradient)
@ -187,38 +156,30 @@ double plutovg_gradient_get_opacity(const plutovg_gradient_t* gradient)
return gradient->opacity;
}
plutovg_texture_t* plutovg_texture_create(plutovg_surface_t* surface)
void plutovg_gradient_copy(plutovg_gradient_t* gradient, const plutovg_gradient_t* source)
{
plutovg_texture_t* texture = malloc(sizeof(plutovg_texture_t));
texture->ref = 1;
texture->type = plutovg_texture_type_plain;
texture->surface = plutovg_surface_reference(surface);
gradient->type = source->type;
gradient->spread = source->spread;
gradient->matrix = source->matrix;
gradient->opacity = source->opacity;
plutovg_array_ensure(gradient->stops, source->stops.size);
memcpy(gradient->values, source->values, sizeof(source->values));
memcpy(gradient->stops.data, source->stops.data, source->stops.size * sizeof(plutovg_gradient_stop_t));
}
void plutovg_gradient_destroy(plutovg_gradient_t* gradient)
{
plutovg_array_destroy(gradient->stops);
}
void plutovg_texture_init(plutovg_texture_t* texture, plutovg_surface_t* surface, plutovg_texture_type_t type)
{
surface = plutovg_surface_reference(surface);
plutovg_surface_destroy(texture->surface);
texture->type = type;
texture->surface = surface;
texture->opacity = 1.0;
plutovg_matrix_init_identity(&texture->matrix);
return texture;
}
plutovg_texture_t* plutovg_texture_reference(plutovg_texture_t* texture)
{
++texture->ref;
return texture;
}
void plutovg_texture_destroy(plutovg_texture_t* texture)
{
if(texture==NULL)
return;
if(--texture->ref==0)
{
plutovg_surface_destroy(texture->surface);
free(texture);
}
}
int plutovg_texture_get_reference_count(const plutovg_texture_t* texture)
{
return texture->ref;
}
void plutovg_texture_set_type(plutovg_texture_t* texture, plutovg_texture_type_t type)
@ -233,12 +194,12 @@ plutovg_texture_type_t plutovg_texture_get_type(const plutovg_texture_t* texture
void plutovg_texture_set_matrix(plutovg_texture_t* texture, const plutovg_matrix_t* matrix)
{
memcpy(&texture->matrix, matrix, sizeof(plutovg_matrix_t));
texture->matrix = *matrix;
}
void plutovg_texture_get_matrix(const plutovg_texture_t* texture, plutovg_matrix_t* matrix)
{
memcpy(matrix, &texture->matrix, sizeof(plutovg_matrix_t));
*matrix = texture->matrix;
}
void plutovg_texture_set_surface(plutovg_texture_t* texture, plutovg_surface_t* surface)
@ -255,7 +216,7 @@ plutovg_surface_t* plutovg_texture_get_surface(const plutovg_texture_t* texture)
void plutovg_texture_set_opacity(plutovg_texture_t* texture, double opacity)
{
texture->opacity = opacity;
texture->opacity = plutovg_clamp(opacity, 0.0, 1.0);
}
double plutovg_texture_get_opacity(const plutovg_texture_t* texture)
@ -263,112 +224,42 @@ double plutovg_texture_get_opacity(const plutovg_texture_t* texture)
return texture->opacity;
}
plutovg_paint_t* plutovg_paint_create_rgb(double r, double g, double b)
void plutovg_texture_copy(plutovg_texture_t* texture, const plutovg_texture_t* source)
{
return plutovg_paint_create_rgba(r, g, b, 1.0);
plutovg_surface_t* surface = plutovg_surface_reference(source->surface);
plutovg_surface_destroy(texture->surface);
texture->type = source->type;
texture->surface = surface;
texture->opacity = source->opacity;
texture->matrix = source->matrix;
}
plutovg_paint_t* plutovg_paint_create_rgba(double r, double g, double b, double a)
void plutovg_texture_destroy(plutovg_texture_t* texture)
{
plutovg_surface_destroy(texture->surface);
}
void plutovg_paint_init(plutovg_paint_t* paint)
{
plutovg_paint_t* paint = malloc(sizeof(plutovg_paint_t));
paint->ref = 1;
paint->type = plutovg_paint_type_color;
paint->color = malloc(sizeof(plutovg_color_t));
plutovg_color_init_rgba(paint->color, r, g, b, a);
return paint;
}
plutovg_paint_t* plutovg_paint_create_linear(double x1, double y1, double x2, double y2)
{
plutovg_gradient_t* gradient = plutovg_gradient_create_linear(x1, y1, x2, y2);
plutovg_paint_t* paint = plutovg_paint_create_gradient(gradient);
plutovg_gradient_destroy(gradient);
return paint;
}
plutovg_paint_t* plutovg_paint_create_radial(double cx, double cy, double cr, double fx, double fy, double fr)
{
plutovg_gradient_t* gradient = plutovg_gradient_create_radial(cx, cy, cr, fx, fy, fr);
plutovg_paint_t* paint = plutovg_paint_create_gradient(gradient);
plutovg_gradient_destroy(gradient);
return paint;
}
plutovg_paint_t* plutovg_paint_create_for_surface(plutovg_surface_t* surface)
{
plutovg_texture_t* texture = plutovg_texture_create(surface);
plutovg_paint_t* paint = plutovg_paint_create_texture(texture);
plutovg_texture_destroy(texture);
return paint;
}
plutovg_paint_t* plutovg_paint_create_color(const plutovg_color_t* color)
{
return plutovg_paint_create_rgba(color->r, color->g, color->b, color->a);
}
plutovg_paint_t* plutovg_paint_create_gradient(plutovg_gradient_t* gradient)
{
plutovg_paint_t* paint = malloc(sizeof(plutovg_paint_t));
paint->ref = 1;
paint->type = plutovg_paint_type_gradient;
paint->gradient = plutovg_gradient_reference(gradient);
return paint;
}
plutovg_paint_t* plutovg_paint_create_texture(plutovg_texture_t* texture)
{
plutovg_paint_t* paint = malloc(sizeof(plutovg_paint_t));
paint->ref = 1;
paint->type = plutovg_paint_type_texture;
paint->texture = plutovg_texture_reference(texture);
return paint;
}
plutovg_paint_t* plutovg_paint_reference(plutovg_paint_t* paint)
{
++paint->ref;
return paint;
paint->texture.surface = NULL;
plutovg_array_init(paint->gradient.stops);
plutovg_color_init_rgb(&paint->color, 0, 0, 0);
}
void plutovg_paint_destroy(plutovg_paint_t* paint)
{
if(paint==NULL)
return;
if(--paint->ref==0)
{
if(paint->type==plutovg_paint_type_color)
free(paint->color);
if(paint->type==plutovg_paint_type_gradient)
plutovg_gradient_destroy(paint->gradient);
if(paint->type==plutovg_paint_type_texture)
plutovg_texture_destroy(paint->texture);
free(paint);
}
plutovg_texture_destroy(&paint->texture);
plutovg_gradient_destroy(&paint->gradient);
}
int plutovg_paint_get_reference_count(const plutovg_paint_t* paint)
void plutovg_paint_copy(plutovg_paint_t* paint, const plutovg_paint_t* source)
{
return paint->ref;
}
plutovg_paint_type_t plutovg_paint_get_type(const plutovg_paint_t* paint)
{
return paint->type;
}
plutovg_color_t* plutovg_paint_get_color(const plutovg_paint_t* paint)
{
return paint->type==plutovg_paint_type_color?paint->color:NULL;
}
plutovg_gradient_t* plutovg_paint_get_gradient(const plutovg_paint_t* paint)
{
return paint->type==plutovg_paint_type_gradient?paint->gradient:NULL;
}
plutovg_texture_t* plutovg_paint_get_texture(const plutovg_paint_t* paint)
{
return paint->type==plutovg_paint_type_texture?paint->texture:NULL;
paint->type = source->type;
if(source->type == plutovg_paint_type_color)
paint->color = source->color;
else if(source->type == plutovg_paint_type_color)
plutovg_gradient_copy(&paint->gradient, &paint->gradient);
else
plutovg_texture_copy(&paint->texture, &paint->texture);
}

View file

@ -55,16 +55,21 @@ struct plutovg_texture {
double opacity;
};
struct plutovg_paint {
int ref;
plutovg_paint_type_t type;
union {
plutovg_color_t* color;
plutovg_gradient_t* gradient;
plutovg_texture_t* texture;
};
typedef int plutovg_paint_type_t;
enum {
plutovg_paint_type_color,
plutovg_paint_type_gradient,
plutovg_paint_type_texture
};
typedef struct {
plutovg_paint_type_t type;
plutovg_color_t color;
plutovg_gradient_t gradient;
plutovg_texture_t texture;
} plutovg_paint_t;
typedef struct {
int x;
int len;
@ -101,7 +106,7 @@ typedef struct {
typedef struct plutovg_state {
plutovg_rle_t* clippath;
plutovg_paint_t* source;
plutovg_paint_t paint;
plutovg_matrix_t matrix;
plutovg_fill_rule_t winding;
plutovg_stroke_data_t stroke;
@ -118,11 +123,23 @@ struct plutovg {
plutovg_rle_t* rle;
plutovg_rle_t* clippath;
plutovg_rect_t clip;
void* outline_data;
size_t outline_size;
};
void plutovg_paint_init(plutovg_paint_t* paint);
void plutovg_paint_destroy(plutovg_paint_t* paint);
void plutovg_paint_copy(plutovg_paint_t* paint, const plutovg_paint_t* source);
void plutovg_gradient_copy(plutovg_gradient_t* gradient, const plutovg_gradient_t* source);
void plutovg_gradient_destroy(plutovg_gradient_t* gradient);
void plutovg_texture_copy(plutovg_texture_t* texture, const plutovg_texture_t* source);
void plutovg_texture_destroy(plutovg_texture_t* texture);
plutovg_rle_t* plutovg_rle_create(void);
void plutovg_rle_destroy(plutovg_rle_t* rle);
void plutovg_rle_rasterize(plutovg_rle_t* rle, const plutovg_path_t* path, const plutovg_matrix_t* matrix, const plutovg_rect_t* clip, const plutovg_stroke_data_t* stroke, plutovg_fill_rule_t winding);
void plutovg_rle_rasterize(plutovg_t* pluto, plutovg_rle_t* rle, const plutovg_path_t* path, const plutovg_matrix_t* matrix, const plutovg_rect_t* clip, const plutovg_stroke_data_t* stroke, plutovg_fill_rule_t winding);
plutovg_rle_t* plutovg_rle_intersection(const plutovg_rle_t* a, const plutovg_rle_t* b);
void plutovg_rle_clip_path(plutovg_rle_t* rle, const plutovg_rle_t* clip);
plutovg_rle_t* plutovg_rle_clone(const plutovg_rle_t* rle);
@ -142,17 +159,28 @@ void plutovg_blend_color(plutovg_t* pluto, const plutovg_rle_t* rle, const pluto
void plutovg_blend_gradient(plutovg_t* pluto, const plutovg_rle_t* rle, const plutovg_gradient_t* gradient);
void plutovg_blend_texture(plutovg_t* pluto, const plutovg_rle_t* rle, const plutovg_texture_t* texture);
#define plutovg_sqrt2 1.41421356237309504880
#define plutovg_pi 3.14159265358979323846
#define plutovg_two_pi 6.28318530717958647693
#define plutovg_half_pi 1.57079632679489661923
#define plutovg_kappa 0.55228474983079339840
#define plutovg_min(a, b) ((a) < (b) ? (a) : (b))
#define plutovg_max(a, b) ((a) > (b) ? (a) : (b))
#define plutovg_clamp(v, lo, hi) ((v) < (lo) ? (lo) : (hi) < (v) ? (hi) : (v))
#define plutovg_div255(x) (((x) + ((x) >> 8) + 0x80) >> 8)
#define plutovg_alpha(c) ((c) >> 24)
#define plutovg_red(c) (((c) >> 16) & 0xff)
#define plutovg_green(c) (((c) >> 8) & 0xff)
#define plutovg_blue(c) (((c) >> 0) & 0xff)
#define plutovg_array_init(array) \
do { \
do { \
array.data = NULL; \
array.size = 0; \
array.capacity = 0; \
} while(0)
} while(0)
#define plutovg_array_ensure(array, count) \
do { \
@ -160,9 +188,12 @@ void plutovg_blend_texture(plutovg_t* pluto, const plutovg_rle_t* rle, const plu
int capacity = array.size + count; \
int newcapacity = array.capacity == 0 ? 8 : array.capacity; \
while(newcapacity < capacity) { newcapacity *= 2; } \
array.data = realloc(array.data, (size_t)newcapacity * sizeof(array.data[0])); \
array.data = realloc(array.data, newcapacity * sizeof(array.data[0])); \
array.capacity = newcapacity; \
} \
} while(0)
} while(0)
#define plutovg_array_clear(array) (array.size = 0)
#define plutovg_array_destroy(array) free(array.data)
#endif // PLUTOVG_PRIVATE_H

View file

@ -6,25 +6,26 @@
#include <math.h>
#include <limits.h>
static PVG_FT_Outline* ft_outline_create(size_t points, size_t contours)
static void ft_outline_init(PVG_FT_Outline* outline, plutovg_t* pluto, int points, int contours)
{
PVG_FT_Outline* ft = malloc(sizeof(PVG_FT_Outline));
ft->points = malloc((points + contours) * sizeof(PVG_FT_Vector));
ft->tags = malloc((points + contours) * sizeof(char));
ft->contours = malloc(contours * sizeof(int));
ft->contours_flag = malloc(contours * sizeof(char));
ft->n_points = ft->n_contours = 0;
ft->flags = 0x0;
return ft;
}
size_t size_a = (points + contours) * sizeof(PVG_FT_Vector);
size_t size_b = (points + contours) * sizeof(char);
size_t size_c = contours * sizeof(int);
size_t size_d = contours * sizeof(char);
size_t size_n = size_a + size_b + size_c + size_d;
if(size_n > pluto->outline_size) {
pluto->outline_data = realloc(pluto->outline_data, size_n);
pluto->outline_size = size_n;
}
static void ft_outline_destroy(PVG_FT_Outline* ft)
{
free(ft->points);
free(ft->tags);
free(ft->contours);
free(ft->contours_flag);
free(ft);
PVG_FT_Byte* data = pluto->outline_data;
outline->points = (PVG_FT_Vector*)(data);
outline->tags = (char*)(data + size_a);
outline->contours = (int*)(data + size_a + size_b);
outline->contours_flag = (char*)(data + size_a + size_b + size_c);
outline->n_points = 0;
outline->n_contours = 0;
outline->flags = 0x0;
}
#define FT_COORD(x) (PVG_FT_Pos)((x) * 64)
@ -89,9 +90,9 @@ static void ft_outline_end(PVG_FT_Outline* ft)
}
}
static PVG_FT_Outline* ft_outline_convert(const plutovg_path_t* path, const plutovg_matrix_t* matrix)
static void ft_outline_convert(PVG_FT_Outline* outline, plutovg_t* pluto, const plutovg_path_t* path, const plutovg_matrix_t* matrix)
{
PVG_FT_Outline* outline = ft_outline_create(path->points.size, path->contours);
ft_outline_init(outline, pluto, path->points.size, path->contours);
plutovg_path_element_t* elements = path->elements.data;
plutovg_point_t* points = path->points.data;
plutovg_point_t p[3];
@ -122,15 +123,13 @@ static PVG_FT_Outline* ft_outline_convert(const plutovg_path_t* path, const plut
}
ft_outline_end(outline);
return outline;
}
static PVG_FT_Outline* ft_outline_convert_dash(const plutovg_path_t* path, const plutovg_matrix_t* matrix, const plutovg_dash_t* dash)
static void ft_outline_convert_dash(PVG_FT_Outline* outline, plutovg_t* pluto, const plutovg_path_t* path, const plutovg_matrix_t* matrix, const plutovg_dash_t* dash)
{
plutovg_path_t* dashed = plutovg_dash_path(dash, path);
PVG_FT_Outline* outline = ft_outline_convert(dashed, matrix);
ft_outline_convert(outline, pluto, dashed, matrix);
plutovg_path_destroy(dashed);
return outline;
}
static void generation_callback(int count, const PVG_FT_Span* spans, void* user)
@ -162,8 +161,7 @@ void plutovg_rle_destroy(plutovg_rle_t* rle)
free(rle);
}
#define SQRT2 1.41421356237309504880
void plutovg_rle_rasterize(plutovg_rle_t* rle, const plutovg_path_t* path, const plutovg_matrix_t* matrix, const plutovg_rect_t* clip, const plutovg_stroke_data_t* stroke, plutovg_fill_rule_t winding)
void plutovg_rle_rasterize(plutovg_t* pluto, plutovg_rle_t* rle, const plutovg_path_t* path, const plutovg_matrix_t* matrix, const plutovg_rect_t* clip, const plutovg_stroke_data_t* stroke, plutovg_fill_rule_t winding)
{
PVG_FT_Raster_Params params;
params.flags = PVG_FT_RASTER_FLAG_DIRECT | PVG_FT_RASTER_FLAG_AA;
@ -171,25 +169,25 @@ void plutovg_rle_rasterize(plutovg_rle_t* rle, const plutovg_path_t* path, const
params.user = rle;
if(clip) {
params.flags |= PVG_FT_RASTER_FLAG_CLIP;
params.clip_box.xMin = (PVG_FT_Pos)clip->x;
params.clip_box.yMin = (PVG_FT_Pos)clip->y;
params.clip_box.xMin = (PVG_FT_Pos)(clip->x);
params.clip_box.yMin = (PVG_FT_Pos)(clip->y);
params.clip_box.xMax = (PVG_FT_Pos)(clip->x + clip->w);
params.clip_box.yMax = (PVG_FT_Pos)(clip->y + clip->h);
}
if(stroke) {
PVG_FT_Outline* outline;
PVG_FT_Outline outline;
if(stroke->dash == NULL)
outline = ft_outline_convert(path, matrix);
ft_outline_convert(&outline, pluto, path, matrix);
else
outline = ft_outline_convert_dash(path, matrix, stroke->dash);
ft_outline_convert_dash(&outline, pluto, path, matrix, stroke->dash);
PVG_FT_Stroker_LineCap ftCap;
PVG_FT_Stroker_LineJoin ftJoin;
PVG_FT_Fixed ftWidth;
PVG_FT_Fixed ftMiterLimit;
plutovg_point_t p1 = {0, 0};
plutovg_point_t p2 = {SQRT2, SQRT2};
plutovg_point_t p2 = {plutovg_sqrt2, plutovg_sqrt2};
plutovg_point_t p3;
plutovg_matrix_map_point(matrix, &p1, &p1);
@ -230,35 +228,33 @@ void plutovg_rle_rasterize(plutovg_rle_t* rle, const plutovg_path_t* path, const
PVG_FT_Stroker stroker;
PVG_FT_Stroker_New(&stroker);
PVG_FT_Stroker_Set(stroker, ftWidth, ftCap, ftJoin, ftMiterLimit);
PVG_FT_Stroker_ParseOutline(stroker, outline);
PVG_FT_Stroker_ParseOutline(stroker, &outline);
PVG_FT_UInt points;
PVG_FT_UInt contours;
PVG_FT_Stroker_GetCounts(stroker, &points, &contours);
PVG_FT_Outline* strokeOutline = ft_outline_create(points, contours);
PVG_FT_Stroker_Export(stroker, strokeOutline);
ft_outline_init(&outline, pluto, points, contours);
PVG_FT_Stroker_Export(stroker, &outline);
PVG_FT_Stroker_Done(stroker);
strokeOutline->flags = PVG_FT_OUTLINE_NONE;
params.source = strokeOutline;
outline.flags = PVG_FT_OUTLINE_NONE;
params.source = &outline;
PVG_FT_Raster_Render(&params);
ft_outline_destroy(outline);
ft_outline_destroy(strokeOutline);
} else {
PVG_FT_Outline* outline = ft_outline_convert(path, matrix);
PVG_FT_Outline outline;
ft_outline_convert(&outline, pluto, path, matrix);
switch(winding) {
case plutovg_fill_rule_even_odd:
outline->flags = PVG_FT_OUTLINE_EVEN_ODD_FILL;
outline.flags = PVG_FT_OUTLINE_EVEN_ODD_FILL;
break;
default:
outline->flags = PVG_FT_OUTLINE_NONE;
outline.flags = PVG_FT_OUTLINE_NONE;
break;
}
params.source = outline;
params.source = &outline;
PVG_FT_Raster_Render(&params);
ft_outline_destroy(outline);
}
if(rle->spans.size == 0) {
@ -286,12 +282,9 @@ void plutovg_rle_rasterize(plutovg_rle_t* rle, const plutovg_path_t* path, const
rle->h = y2 - y1 + 1;
}
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define DIV255(x) (((x) + ((x) >> 8) + 0x80) >> 8)
plutovg_rle_t* plutovg_rle_intersection(const plutovg_rle_t* a, const plutovg_rle_t* b)
{
int count = MAX(a->spans.size, b->spans.size);
int count = plutovg_max(a->spans.size, b->spans.size);
plutovg_rle_t* result = malloc(sizeof(plutovg_rle_t));
plutovg_array_init(result->spans);
plutovg_array_ensure(result->spans, count);
@ -332,15 +325,15 @@ plutovg_rle_t* plutovg_rle_intersection(const plutovg_rle_t* a, const plutovg_rl
continue;
}
int x = MAX(ax1, bx1);
int len = MIN(ax2, bx2) - x;
int x = plutovg_max(ax1, bx1);
int len = plutovg_min(ax2, bx2) - x;
if(len)
{
plutovg_span_t* span = result->spans.data + result->spans.size;
span->x = (short)x;
span->len = (unsigned short)len;
span->y = a_spans->y;
span->coverage = DIV255(a_spans->coverage * b_spans->coverage);
span->coverage = plutovg_div255(a_spans->coverage * b_spans->coverage);
++result->spans.size;
--count;
}

View file

@ -72,7 +72,7 @@ plutovg_state_t* plutovg_state_create(void)
{
plutovg_state_t* state = malloc(sizeof(plutovg_state_t));
state->clippath = NULL;
state->source = plutovg_paint_create_rgb(0, 0, 0);
plutovg_paint_init(&state->paint);
plutovg_matrix_init_identity(&state->matrix);
state->winding = plutovg_fill_rule_non_zero;
state->stroke.width = 1.0;
@ -88,9 +88,9 @@ plutovg_state_t* plutovg_state_create(void)
plutovg_state_t* plutovg_state_clone(const plutovg_state_t* state)
{
plutovg_state_t* newstate = malloc(sizeof(plutovg_state_t));
plutovg_state_t* newstate = plutovg_state_create();
newstate->clippath = plutovg_rle_clone(state->clippath);
newstate->source = plutovg_paint_reference(state->source); /** FIXME: **/
plutovg_paint_copy(&newstate->paint, &state->paint);
newstate->matrix = state->matrix;
newstate->winding = state->winding;
newstate->stroke.width = state->stroke.width;
@ -107,7 +107,7 @@ plutovg_state_t* plutovg_state_clone(const plutovg_state_t* state)
void plutovg_state_destroy(plutovg_state_t* state)
{
plutovg_rle_destroy(state->clippath);
plutovg_paint_destroy(state->source);
plutovg_paint_destroy(&state->paint);
plutovg_dash_destroy(state->stroke.dash);
free(state);
}
@ -125,6 +125,8 @@ plutovg_t* plutovg_create(plutovg_surface_t* surface)
pluto->clip.y = 0.0;
pluto->clip.w = surface->width;
pluto->clip.h = surface->height;
pluto->outline_data = NULL;
pluto->outline_size = 0;
return pluto;
}
@ -152,6 +154,7 @@ void plutovg_destroy(plutovg_t* pluto)
plutovg_path_destroy(pluto->path);
plutovg_rle_destroy(pluto->rle);
plutovg_rle_destroy(pluto->clippath);
free(pluto->outline_data);
free(pluto);
}
}
@ -175,58 +178,53 @@ void plutovg_restore(plutovg_t* pluto)
plutovg_state_destroy(oldstate);
}
void plutovg_set_source_rgb(plutovg_t* pluto, double r, double g, double b)
plutovg_color_t* plutovg_set_rgb(plutovg_t* pluto, double r, double g, double b)
{
plutovg_set_source_rgba(pluto, r, g, b, 1.0);
return plutovg_set_rgba(pluto, r, g, b, 1.0);
}
void plutovg_set_source_rgba(plutovg_t* pluto, double r, double g, double b, double a)
plutovg_color_t* plutovg_set_rgba(plutovg_t* pluto, double r, double g, double b, double a)
{
plutovg_paint_t* source = plutovg_paint_create_rgba(r, g, b, a);
plutovg_set_source(pluto, source);
plutovg_paint_destroy(source);
plutovg_paint_t* paint = &pluto->state->paint;
paint->type = plutovg_paint_type_color;
plutovg_color_init_rgba(&paint->color, r, g, b, a);
return &paint->color;
}
void plutovg_set_source_surface(plutovg_t* pluto, plutovg_surface_t* surface, double x, double y)
plutovg_color_t* plutovg_set_color(plutovg_t* pluto, const plutovg_color_t* color)
{
plutovg_paint_t* source = plutovg_paint_create_for_surface(surface);
plutovg_texture_t* texture = plutovg_paint_get_texture(source);
plutovg_matrix_t matrix;
plutovg_matrix_init_translate(&matrix, x, y);
plutovg_texture_set_matrix(texture, &matrix);
plutovg_set_source(pluto, source);
plutovg_paint_destroy(source);
return plutovg_set_rgba(pluto, color->r, color->g, color->b, color->a);
}
void plutovg_set_source_color(plutovg_t* pluto, const plutovg_color_t* color)
plutovg_gradient_t* plutovg_set_linear_gradient(plutovg_t* pluto, double x1, double y1, double x2, double y2)
{
plutovg_set_source_rgba(pluto, color->r, color->g, color->b, color->a);
plutovg_paint_t* paint = &pluto->state->paint;
paint->type = plutovg_paint_type_gradient;
plutovg_gradient_init_linear(&paint->gradient, x1, y1, x2, y2);
return &paint->gradient;
}
void plutovg_set_source_gradient(plutovg_t* pluto, plutovg_gradient_t* gradient)
plutovg_gradient_t* plutovg_set_radial_gradient(plutovg_t* pluto, double cx, double cy, double cr, double fx, double fy, double fr)
{
plutovg_paint_t* source = plutovg_paint_create_gradient(gradient);
plutovg_set_source(pluto, source);
plutovg_paint_destroy(source);
plutovg_paint_t* paint = &pluto->state->paint;
paint->type = plutovg_paint_type_gradient;
plutovg_gradient_init_radial(&paint->gradient, cx, cy, cr, fx, fy, fr);
return &paint->gradient;
}
void plutovg_set_source_texture(plutovg_t* pluto, plutovg_texture_t* texture)
plutovg_texture_t* plutovg_set_texture_surface(plutovg_t* pluto, plutovg_surface_t* surface, double x, double y)
{
plutovg_paint_t* source = plutovg_paint_create_texture(texture);
plutovg_set_source(pluto, source);
plutovg_paint_destroy(source);
plutovg_texture_t* texture = plutovg_set_texture(pluto, surface, plutovg_texture_type_plain);
plutovg_matrix_init_translate(&texture->matrix, x, y);
return texture;
}
void plutovg_set_source(plutovg_t* pluto, plutovg_paint_t* source)
plutovg_texture_t* plutovg_set_texture(plutovg_t* pluto, plutovg_surface_t* surface, plutovg_texture_type_t type)
{
source = plutovg_paint_reference(source);
plutovg_paint_destroy(pluto->state->source);
pluto->state->source = source;
}
plutovg_paint_t* plutovg_get_source(const plutovg_t* pluto)
{
return pluto->state->source;
plutovg_paint_t* paint = &pluto->state->paint;
paint->type = plutovg_paint_type_texture;
plutovg_texture_init(&paint->texture, surface, plutovg_texture_type_plain);
return &paint->texture;
}
void plutovg_set_operator(plutovg_t* pluto, plutovg_operator_t op)
@ -448,7 +446,7 @@ void plutovg_paint(plutovg_t* pluto)
plutovg_matrix_t matrix;
plutovg_matrix_init_identity(&matrix);
pluto->clippath = plutovg_rle_create();
plutovg_rle_rasterize(pluto->clippath, path, &matrix, &pluto->clip, NULL, plutovg_fill_rule_non_zero);
plutovg_rle_rasterize(pluto, pluto->clippath, path, &matrix, &pluto->clip, NULL, plutovg_fill_rule_non_zero);
plutovg_path_destroy(path);
}
@ -460,7 +458,7 @@ void plutovg_fill_preserve(plutovg_t* pluto)
{
plutovg_state_t* state = pluto->state;
plutovg_rle_clear(pluto->rle);
plutovg_rle_rasterize(pluto->rle, pluto->path, &state->matrix, &pluto->clip, NULL, state->winding);
plutovg_rle_rasterize(pluto, pluto->rle, pluto->path, &state->matrix, &pluto->clip, NULL, state->winding);
plutovg_rle_clip_path(pluto->rle, state->clippath);
plutovg_blend(pluto, pluto->rle);
}
@ -469,7 +467,7 @@ void plutovg_stroke_preserve(plutovg_t* pluto)
{
plutovg_state_t* state = pluto->state;
plutovg_rle_clear(pluto->rle);
plutovg_rle_rasterize(pluto->rle, pluto->path, &state->matrix, &pluto->clip, &state->stroke, plutovg_fill_rule_non_zero);
plutovg_rle_rasterize(pluto, pluto->rle, pluto->path, &state->matrix, &pluto->clip, &state->stroke, plutovg_fill_rule_non_zero);
plutovg_rle_clip_path(pluto->rle, state->clippath);
plutovg_blend(pluto, pluto->rle);
}
@ -480,13 +478,13 @@ void plutovg_clip_preserve(plutovg_t* pluto)
if(state->clippath)
{
plutovg_rle_clear(pluto->rle);
plutovg_rle_rasterize(pluto->rle, pluto->path, &state->matrix, &pluto->clip, NULL, state->winding);
plutovg_rle_rasterize(pluto, pluto->rle, pluto->path, &state->matrix, &pluto->clip, NULL, state->winding);
plutovg_rle_clip_path(state->clippath, pluto->rle);
}
else
{
state->clippath = plutovg_rle_create();
plutovg_rle_rasterize(state->clippath, pluto->path, &state->matrix, &pluto->clip, NULL, state->winding);
plutovg_rle_rasterize(pluto, state->clippath, pluto->path, &state->matrix, &pluto->clip, NULL, state->winding);
}
}

View file

@ -120,11 +120,8 @@ typedef struct {
plutovg_color_t color;
} plutovg_gradient_stop_t;
plutovg_gradient_t* plutovg_gradient_create_linear(double x1, double y1, double x2, double y2);
plutovg_gradient_t* plutovg_gradient_create_radial(double cx, double cy, double cr, double fx, double fy, double fr);
plutovg_gradient_t* plutovg_gradient_reference(plutovg_gradient_t* gradient);
void plutovg_gradient_destroy(plutovg_gradient_t* gradient);
int plutovg_gradient_get_reference_count(const plutovg_gradient_t* gradient);
void plutovg_gradient_init_linear(plutovg_gradient_t* gradient, double x1, double y1, double x2, double y2);
void plutovg_gradient_init_radial(plutovg_gradient_t* gradient, double cx, double cy, double cr, double fx, double fy, double fr);
void plutovg_gradient_set_type(plutovg_gradient_t* gradient, plutovg_gradient_type_t type);
plutovg_gradient_type_t plutovg_gradient_get_type(const plutovg_gradient_t* gradient);
void plutovg_gradient_set_spread(plutovg_gradient_t* gradient, plutovg_spread_method_t spread);
@ -151,10 +148,7 @@ typedef enum {
plutovg_texture_type_tiled
} plutovg_texture_type_t;
plutovg_texture_t* plutovg_texture_create(plutovg_surface_t* surface);
plutovg_texture_t* plutovg_texture_reference(plutovg_texture_t* texture);
void plutovg_texture_destroy(plutovg_texture_t* texture);
int plutovg_texture_get_reference_count(const plutovg_texture_t* texture);
void plutovg_texture_init(plutovg_texture_t* texture, plutovg_surface_t* surface, plutovg_texture_type_t type);
void plutovg_texture_set_type(plutovg_texture_t* texture, plutovg_texture_type_t type);
plutovg_texture_type_t plutovg_texture_get_type(const plutovg_texture_t* texture);
void plutovg_texture_set_matrix(plutovg_texture_t* texture, const plutovg_matrix_t* matrix);
@ -164,30 +158,6 @@ plutovg_surface_t* plutovg_texture_get_surface(const plutovg_texture_t* texture)
void plutovg_texture_set_opacity(plutovg_texture_t* texture, double opacity);
double plutovg_texture_get_opacity(const plutovg_texture_t* texture);
typedef struct plutovg_paint plutovg_paint_t;
typedef enum {
plutovg_paint_type_color,
plutovg_paint_type_gradient,
plutovg_paint_type_texture
} plutovg_paint_type_t;
plutovg_paint_t* plutovg_paint_create_rgb(double r, double g, double b);
plutovg_paint_t* plutovg_paint_create_rgba(double r, double g, double b, double a);
plutovg_paint_t* plutovg_paint_create_linear(double x1, double y1, double x2, double y2);
plutovg_paint_t* plutovg_paint_create_radial(double cx, double cy, double cr, double fx, double fy, double fr);
plutovg_paint_t* plutovg_paint_create_for_surface(plutovg_surface_t* surface);
plutovg_paint_t* plutovg_paint_create_color(const plutovg_color_t* color);
plutovg_paint_t* plutovg_paint_create_gradient(plutovg_gradient_t* gradient);
plutovg_paint_t* plutovg_paint_create_texture(plutovg_texture_t* texture);
plutovg_paint_t* plutovg_paint_reference(plutovg_paint_t* paint);
void plutovg_paint_destroy(plutovg_paint_t* paint);
int plutovg_paint_get_reference_count(const plutovg_paint_t* paint);
plutovg_paint_type_t plutovg_paint_get_type(const plutovg_paint_t* paint);
plutovg_color_t* plutovg_paint_get_color(const plutovg_paint_t* paint);
plutovg_gradient_t* plutovg_paint_get_gradient(const plutovg_paint_t* paint);
plutovg_texture_t* plutovg_paint_get_texture(const plutovg_paint_t* paint);
typedef enum {
plutovg_line_cap_butt,
plutovg_line_cap_round,
@ -220,14 +190,16 @@ void plutovg_destroy(plutovg_t* pluto);
int plutovg_get_reference_count(const plutovg_t* pluto);
void plutovg_save(plutovg_t* pluto);
void plutovg_restore(plutovg_t* pluto);
void plutovg_set_source_rgb(plutovg_t* pluto, double r, double g, double b);
void plutovg_set_source_rgba(plutovg_t* pluto, double r, double g, double b, double a);
void plutovg_set_source_surface(plutovg_t* pluto, plutovg_surface_t* surface, double x, double y);
void plutovg_set_source_color(plutovg_t* pluto, const plutovg_color_t* color);
void plutovg_set_source_gradient(plutovg_t* pluto, plutovg_gradient_t* gradient);
void plutovg_set_source_texture(plutovg_t* pluto, plutovg_texture_t* texture);
void plutovg_set_source(plutovg_t* pluto, plutovg_paint_t* source);
plutovg_paint_t* plutovg_get_source(const plutovg_t* pluto);
plutovg_color_t* plutovg_set_rgb(plutovg_t* pluto, double r, double g, double b);
plutovg_color_t* plutovg_set_rgba(plutovg_t* pluto, double r, double g, double b, double a);
plutovg_color_t* plutovg_set_color(plutovg_t* pluto, const plutovg_color_t* color);
plutovg_gradient_t* plutovg_set_linear_gradient(plutovg_t* pluto, double x1, double y1, double x2, double y2);
plutovg_gradient_t* plutovg_set_radial_gradient(plutovg_t* pluto, double cx, double cy, double cr, double fx, double fy, double fr);
plutovg_texture_t* plutovg_set_texture_surface(plutovg_t* pluto, plutovg_surface_t* surface, double x, double y);
plutovg_texture_t* plutovg_set_texture(plutovg_t* pluto, plutovg_surface_t* surface, plutovg_texture_type_t type);
void plutovg_set_operator(plutovg_t* pluto, plutovg_operator_t op);
void plutovg_set_opacity(plutovg_t* pluto, double opacity);

View file

@ -10,6 +10,7 @@ static plutovg_operator_t to_plutovg_operator(BlendMode mode);
static plutovg_line_cap_t to_plutovg_line_cap(LineCap cap);
static plutovg_line_join_t to_plutovg_line_join(LineJoin join);
static plutovg_spread_method_t to_plutovg_spread_method(SpreadMethod spread);
static plutovg_texture_type_t to_plutovg_texture_type(TextureType type);
static void to_plutovg_stops(plutovg_gradient_t* gradient, const GradientStops& stops);
static void to_plutovg_path(plutovg_t* pluto, const Path& path);
@ -59,43 +60,32 @@ Canvas::~Canvas()
void Canvas::setColor(const Color& color)
{
plutovg_set_source_rgba(pluto, color.red() / 255.0, color.green() / 255.0, color.blue() / 255.0, color.alpha() / 255.0);
plutovg_set_rgba(pluto, color.red() / 255.0, color.green() / 255.0, color.blue() / 255.0, color.alpha() / 255.0);
}
void Canvas::setLinearGradient(double x1, double y1, double x2, double y2, const GradientStops& stops, SpreadMethod spread, const Transform& transform)
{
auto gradient = plutovg_gradient_create_linear(x1, y1, x2, y2);
auto gradient = plutovg_set_linear_gradient(pluto, x1, y1, x2, y2);
auto matrix = to_plutovg_matrix(transform);
to_plutovg_stops(gradient, stops);
plutovg_gradient_set_spread(gradient, to_plutovg_spread_method(spread));
plutovg_gradient_set_matrix(gradient, &matrix);
plutovg_set_source_gradient(pluto, gradient);
plutovg_gradient_destroy(gradient);
}
void Canvas::setRadialGradient(double cx, double cy, double r, double fx, double fy, const GradientStops& stops, SpreadMethod spread, const Transform& transform)
{
auto gradient = plutovg_gradient_create_radial(cx, cy, r, fx, fy, 0);
auto gradient = plutovg_set_radial_gradient(pluto, cx, cy, r, fx, fy, 0);
auto matrix = to_plutovg_matrix(transform);
to_plutovg_stops(gradient, stops);
plutovg_gradient_set_spread(gradient, to_plutovg_spread_method(spread));
plutovg_gradient_set_matrix(gradient, &matrix);
plutovg_set_source_gradient(pluto, gradient);
plutovg_gradient_destroy(gradient);
}
void Canvas::setTexture(const Canvas* source, TextureType type, const Transform& transform)
{
auto texture = plutovg_texture_create(source->surface);
auto texture = plutovg_set_texture(pluto, source->surface, to_plutovg_texture_type(type));
auto matrix = to_plutovg_matrix(transform);
if(type == TextureType::Plain)
plutovg_texture_set_type(texture, plutovg_texture_type_plain);
else
plutovg_texture_set_type(texture, plutovg_texture_type_tiled);
plutovg_texture_set_matrix(texture, &matrix);
plutovg_set_source_texture(pluto, texture);
plutovg_texture_destroy(texture);
}
void Canvas::fill(const Path& path, const Transform& transform, WindRule winding, BlendMode mode, double opacity)
@ -128,7 +118,7 @@ void Canvas::stroke(const Path& path, const Transform& transform, double width,
void Canvas::blend(const Canvas* source, BlendMode mode, double opacity)
{
plutovg_set_source_surface(pluto, source->surface, source->rect.x, source->rect.y);
plutovg_set_texture_surface(pluto, source->surface, source->rect.x, source->rect.y);
plutovg_set_operator(pluto, to_plutovg_operator(mode));
plutovg_set_opacity(pluto, opacity);
plutovg_set_matrix(pluto, &translation);
@ -145,7 +135,7 @@ void Canvas::mask(const Rect& clip, const Transform& transform)
plutovg_add_path(pluto, path);
plutovg_path_destroy(path);
plutovg_set_source_rgba(pluto, 0, 0, 0, 0);
plutovg_set_rgba(pluto, 0, 0, 0, 0);
plutovg_set_fill_rule(pluto, plutovg_fill_rule_even_odd);
plutovg_set_operator(pluto, plutovg_operator_src);
plutovg_set_opacity(pluto, 0.0);
@ -232,6 +222,11 @@ static plutovg_spread_method_t to_plutovg_spread_method(SpreadMethod spread)
return spread == SpreadMethod::Pad ? plutovg_spread_method_pad : spread == SpreadMethod::Reflect ? plutovg_spread_method_reflect : plutovg_spread_method_repeat;
}
static plutovg_texture_type_t to_plutovg_texture_type(TextureType type)
{
return type == TextureType::Plain ? plutovg_texture_type_plain : plutovg_texture_type_tiled;
}
static void to_plutovg_stops(plutovg_gradient_t* gradient, const GradientStops& stops)
{
for(const auto& stop : stops)

View file

@ -297,7 +297,7 @@ std::unique_ptr<Document> Document::loadFromData(const char* data, std::size_t s
return nullptr;
auto root = builder.build();
if(!root || root->children.empty())
if(root == nullptr)
return nullptr;
std::unique_ptr<Document> document(new Document);