Render everything in terms of RsvgPathBuilder, not cairo_path_t

We used to pass a cairo_path_t to ctx->render->render_path().  Now that
is called render_path_builder(), and we pass it an RsvgPathBuilder.

This should let us port rsvg-path.[ch] entirely to Rust.
parent 00baf53c
......@@ -2150,10 +2150,10 @@ rsvg_release_node (RsvgDrawingCtx * ctx, RsvgNode *node)
}
void
rsvg_render_path (RsvgDrawingCtx * ctx, const cairo_path_t *path)
rsvg_render_path_builder (RsvgDrawingCtx * ctx, RsvgPathBuilder *builder)
{
ctx->render->render_path (ctx, path);
rsvg_render_markers (ctx, path);
ctx->render->render_path_builder (ctx, builder);
rsvg_render_markers (ctx, builder);
}
void
......
......@@ -61,7 +61,7 @@ rsvg_cairo_clip_apply_affine (RsvgCairoClipRender *render, cairo_matrix_t *affin
}
static void
rsvg_cairo_clip_render_path (RsvgDrawingCtx * ctx, const cairo_path_t *path)
rsvg_cairo_clip_render_path_builder (RsvgDrawingCtx * ctx, RsvgPathBuilder *builder)
{
RsvgCairoClipRender *render = RSVG_CAIRO_CLIP_RENDER (ctx->render);
RsvgCairoRender *cairo_render = &render->super;
......@@ -74,7 +74,7 @@ rsvg_cairo_clip_render_path (RsvgDrawingCtx * ctx, const cairo_path_t *path)
cairo_set_fill_rule (cr, rsvg_current_state (ctx)->clip_rule);
cairo_append_path (cr, path);
rsvg_path_builder_add_to_cairo_context (builder, cr);
}
static void
......@@ -125,7 +125,7 @@ rsvg_cairo_clip_render_new (cairo_t * cr, RsvgCairoRender *parent)
render->create_pango_context = rsvg_cairo_create_pango_context;
render->render_pango_layout = rsvg_cairo_render_pango_layout;
render->render_surface = rsvg_cairo_clip_render_surface;
render->render_path = rsvg_cairo_clip_render_path;
render->render_path_builder = rsvg_cairo_clip_render_path_builder;
render->pop_discrete_layer = rsvg_cairo_clip_pop_discrete_layer;
render->push_discrete_layer = rsvg_cairo_clip_push_discrete_layer;
render->add_clipping_rect = rsvg_cairo_clip_add_clipping_rect;
......
......@@ -454,7 +454,7 @@ rsvg_cairo_render_pango_layout (RsvgDrawingCtx * ctx, PangoLayout * layout, doub
}
void
rsvg_cairo_render_path (RsvgDrawingCtx * ctx, const cairo_path_t *path)
rsvg_cairo_render_path_builder (RsvgDrawingCtx * ctx, RsvgPathBuilder *builder)
{
RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render);
RsvgState *state = rsvg_current_state (ctx);
......@@ -477,7 +477,7 @@ rsvg_cairo_render_path (RsvgDrawingCtx * ctx, const cairo_path_t *path)
cairo_set_dash (cr, state->dash.dash, state->dash.n_dash,
_rsvg_css_normalize_length (&state->dash.offset, ctx, 'o'));
cairo_append_path (cr, path);
rsvg_path_builder_add_to_cairo_context (builder, cr);
rsvg_bbox_init (&bbox, &state->affine);
......
......@@ -38,8 +38,8 @@ G_GNUC_INTERNAL
void rsvg_cairo_render_pango_layout (RsvgDrawingCtx *ctx, PangoLayout *layout,
double x, double y);
G_GNUC_INTERNAL
void rsvg_cairo_render_path (RsvgDrawingCtx *ctx,
const cairo_path_t *path);
void rsvg_cairo_render_path_builder (RsvgDrawingCtx *ctx,
RsvgPathBuilder *builder);
G_GNUC_INTERNAL
void rsvg_cairo_render_surface (RsvgDrawingCtx *ctx, cairo_surface_t *surface,
double x, double y, double w, double h);
......
......@@ -59,7 +59,7 @@ rsvg_cairo_render_new (cairo_t * cr, double width, double height)
cairo_render->super.create_pango_context = rsvg_cairo_create_pango_context;
cairo_render->super.render_pango_layout = rsvg_cairo_render_pango_layout;
cairo_render->super.render_surface = rsvg_cairo_render_surface;
cairo_render->super.render_path = rsvg_cairo_render_path;
cairo_render->super.render_path_builder = rsvg_cairo_render_path_builder;
cairo_render->super.pop_discrete_layer = rsvg_cairo_pop_discrete_layer;
cairo_render->super.push_discrete_layer = rsvg_cairo_push_discrete_layer;
cairo_render->super.add_clipping_rect = rsvg_cairo_add_clipping_rect;
......
......@@ -541,14 +541,15 @@ typedef enum {
} SubpathState;
void
rsvg_render_markers (RsvgDrawingCtx * ctx,
const cairo_path_t *path)
rsvg_render_markers (RsvgDrawingCtx *ctx,
RsvgPathBuilder *builder)
{
RsvgState *state;
double linewidth;
const char *startmarker;
const char *middlemarker;
const char *endmarker;
cairo_path_t *path;
int i;
double incoming_vx, incoming_vy;
......@@ -559,6 +560,7 @@ rsvg_render_markers (RsvgDrawingCtx * ctx,
SubpathState subpath_state;
state = rsvg_current_state (ctx);
linewidth = _rsvg_css_normalize_length (&state->stroke_width, ctx, 'o');
......@@ -572,8 +574,12 @@ rsvg_render_markers (RsvgDrawingCtx * ctx,
if (!startmarker && !middlemarker && !endmarker)
return;
if (path->num_data <= 0)
path = rsvg_path_builder_copy_path (builder);
if (path->num_data <= 0) {
rsvg_cairo_path_destroy (path);
return;
}
/* Convert the path to a list of segments and bare points (i.e. degenerate segments) */
path_to_segments (path, &segments, &num_segments);
......@@ -648,4 +654,6 @@ rsvg_render_markers (RsvgDrawingCtx * ctx,
}
g_free (segments);
rsvg_cairo_path_destroy (path);
}
......@@ -33,7 +33,7 @@ G_BEGIN_DECLS
G_GNUC_INTERNAL
RsvgNode *rsvg_new_marker (void);
G_GNUC_INTERNAL
void rsvg_render_markers (RsvgDrawingCtx *ctx, const cairo_path_t *path);
void rsvg_render_markers (RsvgDrawingCtx *ctx, RsvgPathBuilder *builder);
G_END_DECLS
......
......@@ -773,11 +773,10 @@ rsvg_parse_path_data (RSVGParsePathCtx * ctx, const char *data)
}
}
cairo_path_t *
rsvg_parse_path (const char *path_str)
RsvgPathBuilder *
rsvg_path_builder_parse_path (const char *path_str)
{
RSVGParsePathCtx ctx;
cairo_path_t *path;
ctx.builder = rsvg_path_builder_new ();
......@@ -793,11 +792,7 @@ rsvg_parse_path (const char *path_str)
if (ctx.param)
rsvg_parse_path_do_cmd (&ctx, TRUE);
path = rsvg_path_builder_copy_path (ctx.builder);
rsvg_path_builder_destroy (ctx.builder);
return path;
return ctx.builder;
}
void
......
......@@ -78,7 +78,8 @@ G_GNUC_INTERNAL
void rsvg_path_builder_add_to_cairo_context (RsvgPathBuilder *builder, cairo_t *cr);
G_GNUC_INTERNAL
cairo_path_t *rsvg_parse_path (const char *path_str);
RsvgPathBuilder *rsvg_path_builder_parse_path (const char *path_str);
G_GNUC_INTERNAL
void rsvg_cairo_path_destroy (cairo_path_t *path);
......
......@@ -30,6 +30,7 @@
#include <cairo.h>
#include "rsvg.h"
#include "rsvg-path.h"
#include <libxml/SAX.h>
#include <libxml/xmlmemory.h>
......@@ -220,7 +221,7 @@ struct RsvgRender {
PangoContext *(*create_pango_context) (RsvgDrawingCtx * ctx);
void (*render_pango_layout) (RsvgDrawingCtx * ctx, PangoLayout *layout,
double x, double y);
void (*render_path) (RsvgDrawingCtx * ctx, const cairo_path_t *path);
void (*render_path_builder) (RsvgDrawingCtx * ctx, RsvgPathBuilder *builder);
void (*render_surface) (RsvgDrawingCtx * ctx, cairo_surface_t *surface,
double x, double y, double w, double h);
void (*pop_discrete_layer) (RsvgDrawingCtx * ctx);
......@@ -365,7 +366,7 @@ RsvgNode *rsvg_acquire_node_of_type (RsvgDrawingCtx * ctx, const char *url, Rsvg
G_GNUC_INTERNAL
void rsvg_release_node (RsvgDrawingCtx * ctx, RsvgNode *node);
G_GNUC_INTERNAL
void rsvg_render_path (RsvgDrawingCtx * ctx, const cairo_path_t *path);
void rsvg_render_path_builder (RsvgDrawingCtx * ctx, RsvgPathBuilder *builder);
G_GNUC_INTERNAL
void rsvg_render_surface (RsvgDrawingCtx * ctx, cairo_surface_t *surface,
double x, double y, double w, double h);
......
......@@ -44,6 +44,7 @@ typedef struct _RsvgNodePath RsvgNodePath;
struct _RsvgNodePath {
RsvgNode super;
RsvgPathBuilder *builder;
cairo_path_t *path;
};
......@@ -51,8 +52,8 @@ static void
rsvg_node_path_free (RsvgNode * self)
{
RsvgNodePath *path = (RsvgNodePath *) self;
if (path->path)
rsvg_cairo_path_destroy (path->path);
if (path->builder)
rsvg_path_builder_destroy (path->builder);
_rsvg_node_finalize (&path->super);
g_free (path);
}
......@@ -62,12 +63,12 @@ rsvg_node_path_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
{
RsvgNodePath *path = (RsvgNodePath *) self;
if (!path->path)
if (!path->builder)
return;
rsvg_state_reinherit_top (ctx, self->state, dominate);
rsvg_render_path (ctx, path->path);
rsvg_render_path_builder (ctx, path->builder);
}
static void
......@@ -78,9 +79,9 @@ rsvg_node_path_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * at
if (rsvg_property_bag_size (atts)) {
if ((value = rsvg_property_bag_lookup (atts, "d"))) {
if (path->path)
rsvg_cairo_path_destroy (path->path);
path->path = rsvg_parse_path (value);
if (path->builder)
rsvg_path_builder_destroy (path->builder);
path->builder = rsvg_path_builder_parse_path (value);
}
if ((value = rsvg_property_bag_lookup (atts, "class")))
klazz = value;
......@@ -99,7 +100,7 @@ rsvg_new_path (void)
RsvgNodePath *path;
path = g_new (RsvgNodePath, 1);
_rsvg_node_init (&path->super, RSVG_NODE_TYPE_PATH);
path->path = NULL;
path->builder = NULL;
path->super.free = rsvg_node_path_free;
path->super.draw = rsvg_node_path_draw;
path->super.set_atts = rsvg_node_path_set_atts;
......@@ -109,14 +110,14 @@ rsvg_new_path (void)
struct _RsvgNodePoly {
RsvgNode super;
cairo_path_t *path;
RsvgPathBuilder *builder;
};
typedef struct _RsvgNodePoly RsvgNodePoly;
static cairo_path_t *
_rsvg_node_poly_build_path (const char *value,
gboolean close_path);
static RsvgPathBuilder *
_rsvg_node_poly_create_builder (const char *value,
gboolean close_path);
static void
_rsvg_node_poly_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * atts)
......@@ -128,10 +129,10 @@ _rsvg_node_poly_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
/* support for svg < 1.0 which used verts */
if ((value = rsvg_property_bag_lookup (atts, "verts"))
|| (value = rsvg_property_bag_lookup (atts, "points"))) {
if (poly->path)
rsvg_cairo_path_destroy (poly->path);
poly->path = _rsvg_node_poly_build_path (value,
RSVG_NODE_TYPE (self) == RSVG_NODE_TYPE_POLYGON);
if (poly->builder)
rsvg_path_builder_destroy (poly->builder);
poly->builder = _rsvg_node_poly_create_builder (value,
RSVG_NODE_TYPE (self) == RSVG_NODE_TYPE_POLYGON);
}
if ((value = rsvg_property_bag_lookup (atts, "class")))
klazz = value;
......@@ -147,14 +148,13 @@ _rsvg_node_poly_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
}
static cairo_path_t *
_rsvg_node_poly_build_path (const char *value,
gboolean close_path)
static RsvgPathBuilder *
_rsvg_node_poly_create_builder (const char *value,
gboolean close_path)
{
double *pointlist;
guint pointlist_len, i;
RsvgPathBuilder *builder;
cairo_path_t *path;
pointlist = rsvg_css_parse_number_list (value, &pointlist_len);
if (pointlist == NULL)
......@@ -189,12 +189,9 @@ _rsvg_node_poly_build_path (const char *value,
if (close_path)
rsvg_path_builder_close_path (builder);
path = rsvg_path_builder_copy_path (builder);
g_free (pointlist);
rsvg_path_builder_destroy (builder);
return path;
return builder;
}
static void
......@@ -202,20 +199,20 @@ _rsvg_node_poly_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
{
RsvgNodePoly *poly = (RsvgNodePoly *) self;
if (poly->path == NULL)
if (poly->builder == NULL)
return;
rsvg_state_reinherit_top (ctx, self->state, dominate);
rsvg_render_path (ctx, poly->path);
rsvg_render_path_builder (ctx, poly->builder);
}
static void
_rsvg_node_poly_free (RsvgNode * self)
{
RsvgNodePoly *poly = (RsvgNodePoly *) self;
if (poly->path)
rsvg_cairo_path_destroy (poly->path);
if (poly->builder)
rsvg_path_builder_destroy (poly->builder);
_rsvg_node_finalize (&poly->super);
g_free (poly);
}
......@@ -229,7 +226,7 @@ rsvg_new_any_poly (RsvgNodeType type)
poly->super.free = _rsvg_node_poly_free;
poly->super.draw = _rsvg_node_poly_draw;
poly->super.set_atts = _rsvg_node_poly_set_atts;
poly->path = NULL;
poly->builder = NULL;
return &poly->super;
}
......@@ -282,7 +279,6 @@ _rsvg_node_line_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag * a
static void
_rsvg_node_line_draw (RsvgNode * overself, RsvgDrawingCtx * ctx, int dominate)
{
cairo_path_t *path;
RsvgPathBuilder *builder;
RsvgNodeLine *self = (RsvgNodeLine *) overself;
double x1, y1, x2, y2;
......@@ -297,14 +293,11 @@ _rsvg_node_line_draw (RsvgNode * overself, RsvgDrawingCtx * ctx, int dominate)
rsvg_path_builder_move_to (builder, x1, y1);
rsvg_path_builder_line_to (builder, x2, y2);
path = rsvg_path_builder_copy_path (builder);
rsvg_path_builder_destroy (builder);
rsvg_state_reinherit_top (ctx, overself->state, dominate);
rsvg_render_path (ctx, path);
rsvg_cairo_path_destroy (path);
rsvg_render_path_builder (ctx, builder);
rsvg_path_builder_destroy (builder);
}
RsvgNode *
......@@ -368,7 +361,6 @@ _rsvg_node_rect_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
double x, y, w, h, rx, ry;
double half_w, half_h;
RsvgPathBuilder *builder;
cairo_path_t *path;
RsvgNodeRect *rect = (RsvgNodeRect *) self;
x = _rsvg_css_normalize_length (&rect->x, ctx, 'h');
......@@ -495,13 +487,11 @@ _rsvg_node_rect_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
rsvg_path_builder_close_path (builder);
}
path = rsvg_path_builder_copy_path (builder);
rsvg_state_reinherit_top (ctx, self->state, dominate);
rsvg_path_builder_destroy (builder);
rsvg_render_path_builder (ctx, builder);
rsvg_state_reinherit_top (ctx, self->state, dominate);
rsvg_render_path (ctx, path);
rsvg_cairo_path_destroy (path);
rsvg_path_builder_destroy (builder);
}
RsvgNode *
......@@ -551,7 +541,6 @@ _rsvg_node_circle_set_atts (RsvgNode * self, RsvgHandle * ctx, RsvgPropertyBag *
static void
_rsvg_node_circle_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
{
cairo_path_t *path;
RsvgNodeCircle *circle = (RsvgNodeCircle *) self;
double cx, cy, r;
RsvgPathBuilder *builder;
......@@ -591,13 +580,11 @@ _rsvg_node_circle_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
rsvg_path_builder_close_path (builder);
path = rsvg_path_builder_copy_path (builder);
rsvg_state_reinherit_top (ctx, self->state, dominate);
rsvg_path_builder_destroy (builder);
rsvg_render_path_builder (ctx, builder);
rsvg_state_reinherit_top (ctx, self->state, dominate);
rsvg_render_path (ctx, path);
rsvg_cairo_path_destroy (path);
rsvg_path_builder_destroy (builder);
}
RsvgNode *
......@@ -649,7 +636,6 @@ static void
_rsvg_node_ellipse_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
{
RsvgNodeEllipse *ellipse = (RsvgNodeEllipse *) self;
cairo_path_t *path;
double cx, cy, rx, ry;
RsvgPathBuilder *builder;
......@@ -689,13 +675,11 @@ _rsvg_node_ellipse_draw (RsvgNode * self, RsvgDrawingCtx * ctx, int dominate)
rsvg_path_builder_close_path (builder);
path = rsvg_path_builder_copy_path (builder);
rsvg_state_reinherit_top (ctx, self->state, dominate);
rsvg_render_path_builder (ctx, builder);
rsvg_path_builder_destroy (builder);
rsvg_state_reinherit_top (ctx, self->state, dominate);
rsvg_render_path (ctx, path);
rsvg_cairo_path_destroy (path);
}
RsvgNode *
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment