static int _rsvg_node_text_length_children (RsvgNode * self, RsvgDrawingCtx * ctx, gdouble * x, gboolean * lastwasspace) { guint i; int out = FALSE; for (i = 0; i < self->children->len; i++) { RsvgNode *node = g_ptr_array_index (self->children, i); rsvg_state_push (ctx); rsvg_state_reinherit_top (ctx, node->state, 0); if (!strcmp (node->type->str, "RSVG_NODE_CHARS")) { RsvgNodeChars *chars = (RsvgNodeChars *) node; GString *str = _rsvg_text_chomp (rsvg_current_state (ctx), chars->contents, lastwasspace); *x += rsvg_text_length_text_as_string (ctx, str->str); g_string_free (str, TRUE); } else if (!strcmp (node->type->str, "tspan")) { RsvgNodeText *tspan = (RsvgNodeText *) node; out = _rsvg_node_text_length_tspan (tspan, ctx, x, lastwasspace); } else if (!strcmp (node->type->str, "tref")) { RsvgNodeTref *tref = (RsvgNodeTref *) node; out = _rsvg_node_text_length_tref (tref, ctx, x, lastwasspace); } rsvg_state_pop (ctx); if (out) break; } return out; }
static void _rsvg_node_text_type_children (RsvgNode * self, RsvgDrawingCtx * ctx, gdouble * x, gdouble * y, gboolean * lastwasspace) { guint i; rsvg_push_discrete_layer (ctx); for (i = 0; i < self->children->len; i++) { RsvgNode *node = g_ptr_array_index (self->children, i); if (!strcmp (node->type->str, "RSVG_NODE_CHARS")) { RsvgNodeChars *chars = (RsvgNodeChars *) node; GString *str = _rsvg_text_chomp (rsvg_current_state (ctx), chars->contents, lastwasspace); rsvg_text_render_text (ctx, str->str, x, y); g_string_free (str, TRUE); } else if (!strcmp (node->type->str, "tspan")) { RsvgNodeText *tspan = (RsvgNodeText *) node; rsvg_state_push (ctx); _rsvg_node_text_type_tspan (tspan, ctx, x, y, lastwasspace); rsvg_state_pop (ctx); } else if (!strcmp (node->type->str, "tref")) { RsvgNodeTref *tref = (RsvgNodeTref *) node; _rsvg_node_text_type_tref (tref, ctx, x, y, lastwasspace); } } rsvg_pop_discrete_layer (ctx); }
static void _rsvg_node_text_type_text_path (RsvgNodeTextPath * self, RsvgDrawingCtx * ctx, gdouble * x, gdouble * y, gboolean * lastwasspace, gboolean usetextonly) { if (self->link && self->link->type == RSVG_NODE_TYPE_PATH) { guint i; // Resolve the xlink:href id and get its cairo path object cairo_path_t *path = ((RsvgNodePath *)self->link)->path; // Get the cairo_t context RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render); cairo_t *cr = render->cr; // Flatten path cairo_save(cr); cairo_new_path(cr); cairo_append_path(cr, path); path = cairo_copy_path_flat (cr); cairo_restore(cr); // TODO recursively draw children rsvg_push_discrete_layer (ctx); for (i = 0; i < self->super.children->len; i++) { RsvgNode *node = g_ptr_array_index (self->super.children, i); RsvgNodeType type = RSVG_NODE_TYPE (node); if (type == RSVG_NODE_TYPE_CHARS) { RsvgNodeChars *chars = (RsvgNodeChars *) node; GString *str = _rsvg_text_chomp (rsvg_current_state (ctx), chars->contents, lastwasspace); double offset = 0; // Factor in start offset // Handle percentages as percent of path length if (self->startOffset.factor == 'p') { offset = self->startOffset.length *_rsvg_path_length(path); } else { offset = _rsvg_css_normalize_length (&self->startOffset, ctx, 'h'); } if (PANGO_GRAVITY_IS_VERTICAL (rsvg_current_state(ctx)->text_gravity)) *y += offset; else *x += offset; draw_twisted (ctx, cr, path, x, y, str->str); g_string_free (str, TRUE); } } rsvg_pop_discrete_layer (ctx); cairo_path_destroy (path); } }
static int _rsvg_node_text_length_children (RsvgNode * self, RsvgDrawingCtx * ctx, gdouble * length, gboolean * lastwasspace, gboolean usetextonly) { guint i; int out = FALSE; for (i = 0; i < self->children->len; i++) { RsvgNode *node = g_ptr_array_index (self->children, i); RsvgNodeType type = RSVG_NODE_TYPE (node); rsvg_state_push (ctx); rsvg_state_reinherit_top (ctx, node->state, 0); if (type == RSVG_NODE_TYPE_CHARS) { RsvgNodeChars *chars = (RsvgNodeChars *) node; GString *str = _rsvg_text_chomp (rsvg_current_state (ctx), chars->contents, lastwasspace); *length += rsvg_text_length_text_as_string (ctx, str->str); g_string_free (str, TRUE); } else { if (usetextonly || type == RSVG_NODE_TYPE_TEXT_PATH) { out = _rsvg_node_text_length_children(node, ctx, length, lastwasspace, usetextonly); } else { if (type == RSVG_NODE_TYPE_TSPAN) { RsvgNodeText *tspan = (RsvgNodeText *) node; out = _rsvg_node_text_length_tspan (tspan, ctx, length, lastwasspace, usetextonly); } else if (type == RSVG_NODE_TYPE_TREF) { RsvgNodeTref *tref = (RsvgNodeTref *) node; out = _rsvg_node_text_length_tref (tref, ctx, length, lastwasspace, usetextonly); } } } rsvg_state_pop (ctx); if (out) break; } return out; }
static void _rsvg_node_text_type_children (RsvgNode * self, RsvgDrawingCtx * ctx, gdouble * x, gdouble * y, gboolean * lastwasspace, gboolean usetextonly) { guint i; rsvg_push_discrete_layer (ctx); for (i = 0; i < self->children->len; i++) { RsvgNode *node = g_ptr_array_index (self->children, i); RsvgNodeType type = RSVG_NODE_TYPE (node); if (type == RSVG_NODE_TYPE_CHARS) { RsvgNodeChars *chars = (RsvgNodeChars *) node; GString *str = _rsvg_text_chomp (rsvg_current_state (ctx), chars->contents, lastwasspace); rsvg_text_render_text (ctx, str->str, x, y); g_string_free (str, TRUE); } else { if (usetextonly) { _rsvg_node_text_type_children (node, ctx, x, y, lastwasspace, usetextonly); } else { if (type == RSVG_NODE_TYPE_TSPAN) { RsvgNodeText *tspan = (RsvgNodeText *) node; rsvg_state_push (ctx); _rsvg_node_text_type_tspan (tspan, ctx, x, y, lastwasspace, usetextonly); rsvg_state_pop (ctx); } else if (type == RSVG_NODE_TYPE_TREF) { RsvgNodeTref *tref = (RsvgNodeTref *) node; _rsvg_node_text_type_tref (tref, ctx, x, y, lastwasspace, usetextonly); } else if (type == RSVG_NODE_TYPE_TEXT_PATH) { RsvgNodeTextPath *textpath = (RsvgNodeTextPath *) node; _rsvg_node_text_type_text_path(textpath, ctx, x, y, lastwasspace, usetextonly); } } } } rsvg_pop_discrete_layer (ctx); }
/* TODO: renders each character individually */ static void _rsvg_node_text_path_type_children(RsvgNode * self, RsvgNodePath * path, RsvgDrawingCtx * ctx, gdouble * x, gdouble * y, gboolean * lastwasspace, gboolean usetextonly) { int i; rsvg_push_discrete_layer (ctx); for (i = 0; i < self->children->len; i++) { RsvgNode *node = g_ptr_array_index (self->children, i); RsvgNodeType type = RSVG_NODE_TYPE (node); if (type == RSVG_NODE_TYPE_CHARS) { RsvgNodeChars *chars = (RsvgNodeChars *) node; GString *str = _rsvg_text_chomp (rsvg_current_state (ctx), chars->contents, lastwasspace); //draw_twisted (ctx, cr, path, x, y, str->str); g_string_free (str, TRUE); } } rsvg_pop_discrete_layer (ctx); }