From e5b9b5300696c02f872dc8f124fc96402e4570b4 Mon Sep 17 00:00:00 2001 From: Leon Styhre Date: Wed, 26 Oct 2022 20:03:31 +0200 Subject: [PATCH] Squashed 'external/lunasvg/' changes from ead790126..be5d0977b be5d0977b Fix possible memory leaks 62e0e4b31 Optimize plutovg memory allocations 587539885 Support graphical empty files #109 git-subtree-dir: external/lunasvg git-subtree-split: be5d0977b393055f89be70323ac9b020ef3ab657 --- 3rdparty/plutovg/plutovg-blend.c | 24 ++- 3rdparty/plutovg/plutovg-geometry.c | 9 +- 3rdparty/plutovg/plutovg-paint.c | 287 +++++++++------------------- 3rdparty/plutovg/plutovg-private.h | 69 +++++-- 3rdparty/plutovg/plutovg-rle.c | 93 +++++---- 3rdparty/plutovg/plutovg.c | 82 ++++---- 3rdparty/plutovg/plutovg.h | 54 ++---- source/canvas.cpp | 29 ++- source/lunasvg.cpp | 2 +- 9 files changed, 263 insertions(+), 386 deletions(-) diff --git a/3rdparty/plutovg/plutovg-blend.c b/3rdparty/plutovg/plutovg-blend.c index 8b018363c..6cbe76e7f 100644 --- a/3rdparty/plutovg/plutovg-blend.c +++ b/3rdparty/plutovg/plutovg-blend.c @@ -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) diff --git a/3rdparty/plutovg/plutovg-geometry.c b/3rdparty/plutovg/plutovg-geometry.c index ec0cd2e63..6bc748982 100644 --- a/3rdparty/plutovg/plutovg-geometry.c +++ b/3rdparty/plutovg/plutovg-geometry.c @@ -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); diff --git a/3rdparty/plutovg/plutovg-paint.c b/3rdparty/plutovg/plutovg-paint.c index afae6e2b7..247231312 100644 --- a/3rdparty/plutovg/plutovg-paint.c +++ b/3rdparty/plutovg/plutovg-paint.c @@ -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); } diff --git a/3rdparty/plutovg/plutovg-private.h b/3rdparty/plutovg/plutovg-private.h index c31a4bf73..a644fca26 100644 --- a/3rdparty/plutovg/plutovg-private.h +++ b/3rdparty/plutovg/plutovg-private.h @@ -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,27 +159,41 @@ 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 { \ - if(array.size + count > array.capacity) { \ - 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.capacity = newcapacity; \ + if(array.size + count > array.capacity) { \ + int capacity = array.size + count; \ + int newcapacity = array.capacity == 0 ? 8 : array.capacity; \ + while(newcapacity < capacity) { newcapacity *= 2; } \ + 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 diff --git a/3rdparty/plutovg/plutovg-rle.c b/3rdparty/plutovg/plutovg-rle.c index 69345fc61..783ee8354 100644 --- a/3rdparty/plutovg/plutovg-rle.c +++ b/3rdparty/plutovg/plutovg-rle.c @@ -6,25 +6,26 @@ #include #include -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(¶ms); - 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(¶ms); - 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; } diff --git a/3rdparty/plutovg/plutovg.c b/3rdparty/plutovg/plutovg.c index 28e751952..a5ee85c73 100644 --- a/3rdparty/plutovg/plutovg.c +++ b/3rdparty/plutovg/plutovg.c @@ -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); } } diff --git a/3rdparty/plutovg/plutovg.h b/3rdparty/plutovg/plutovg.h index 3daf75b17..e9da860e7 100644 --- a/3rdparty/plutovg/plutovg.h +++ b/3rdparty/plutovg/plutovg.h @@ -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); diff --git a/source/canvas.cpp b/source/canvas.cpp index 32db99abe..80e05a38f 100644 --- a/source/canvas.cpp +++ b/source/canvas.cpp @@ -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) diff --git a/source/lunasvg.cpp b/source/lunasvg.cpp index a77cfefb9..4da130422 100644 --- a/source/lunasvg.cpp +++ b/source/lunasvg.cpp @@ -297,7 +297,7 @@ std::unique_ptr 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(new Document);