示例#1
0
文件: rsvg-text.c 项目: chagge/libsvg
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;
}
示例#2
0
文件: rsvg-text.c 项目: chagge/libsvg
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);
}
示例#3
0
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);
    }
}
示例#4
0
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;
}
示例#5
0
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);
}
示例#6
0
/* 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);    
}