Mercurial > MadButterfly
view src/shape_text.c @ 234:889cdc5f23c5
When a scene is selected to0 edit, we copy all of its elements out of the scene so that inkscape can edit it directly. All elements add or delete by the inkspcae will be put back when we switch the scene. The svg2code.py must recognize this structure.
author | wycc |
---|---|
date | Wed, 24 Dec 2008 23:43:39 +0800 |
parents | 29e1b2bffe4c |
children | a90fd749af82 |
line wrap: on
line source
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <cairo.h> #include "mb_types.h" #include "mb_shapes.h" #define ASSERT(x) #define OK 0 #define ERR -1 typedef struct _sh_text { shape_t shape; char *data; co_aix x, y; co_aix d_x, d_y; /* device x and y */ co_aix font_size; co_aix d_font_size; cairo_font_face_t *face; cairo_scaled_font_t *scaled_font; int flags; } sh_text_t; #define TXF_SCALE_DIRTY 0x1 static void sh_text_free(shape_t *shape) { sh_text_t *text = (sh_text_t *)shape; if(text->scaled_font) cairo_scaled_font_destroy(text->scaled_font); cairo_font_face_destroy(text->face); } shape_t *rdman_shape_text_new(redraw_man_t *rdman, const char *txt, co_aix x, co_aix y, co_aix font_size, cairo_font_face_t *face) { sh_text_t *text; text = (sh_text_t *)malloc(sizeof(sh_text_t)); if(text == NULL) return NULL; memset(text, 0, sizeof(sh_text_t)); mb_obj_init(text, MBO_TEXT); text->data = strdup(txt); if(text->data == NULL) { free(text); return NULL; } text->x = x; text->y = y; text->font_size = font_size; cairo_font_face_reference(face); text->face = face; text->flags |= TXF_SCALE_DIRTY; text->shape.free = sh_text_free; rdman_shape_man(rdman, (shape_t *)text); return (shape_t *)text; } extern void sh_text_set_text(shape_t *shape, const char *txt) { sh_text_t *text = (sh_text_t *)shape; char *buf; buf = strdup(txt); if(text->data) free(text->data); text->data = buf; } static int get_extents(sh_text_t *text, cairo_text_extents_t *extents) { cairo_matrix_t fmatrix; cairo_matrix_t ctm; cairo_scaled_font_t *new_scaled; cairo_font_options_t *fopt; if((text->flags & TXF_SCALE_DIRTY) || text->scaled_font == NULL) { fopt = cairo_font_options_create(); if(fopt == NULL) return ERR; memset(&fmatrix, 0, sizeof(cairo_matrix_t)); fmatrix.xx = text->d_font_size; fmatrix.yy = text->d_font_size; memset(&ctm, 0, sizeof(cairo_matrix_t)); ctm.xx = 1; ctm.yy = 1; new_scaled = cairo_scaled_font_create(text->face, &fmatrix, &ctm, fopt); cairo_font_options_destroy(fopt); if(new_scaled == NULL) return ERR; if(text->scaled_font) cairo_scaled_font_destroy(text->scaled_font); text->scaled_font = new_scaled; text->flags &= ~TXF_SCALE_DIRTY; } cairo_scaled_font_text_extents(text->scaled_font, text->data, extents); return OK; } void sh_text_transform(shape_t *shape) { sh_text_t *text; co_aix x, y; co_aix shw; cairo_text_extents_t extents; co_aix poses[2][2]; int r; text = (sh_text_t *)shape; text->d_font_size = coord_trans_size(shape->coord, text->font_size); x = text->x; y = text->y; coord_trans_pos(shape->coord, &x, &y); r = get_extents(text, &extents); ASSERT(r == OK); text->d_x = x; text->d_y = y; shw = shape->stroke_width / 2; /* FIXME: It is unreasonable that a font exceed it's bbox. * We add 5 pixels in get right bbox. But, it is unreasonable. */ poses[0][0] = x + extents.x_bearing - 5 - shw; poses[0][1] = y + extents.y_bearing - 5 - shw; poses[1][0] = poses[0][0] + extents.width + 10 + shape->stroke_width; poses[1][1] = poses[0][1] + extents.height + 10 + shape->stroke_width; geo_from_positions(shape->geo, 2, poses); /*! \todo Support ratation for shape_text. */ } static void draw_text(sh_text_t *text, cairo_t *cr) { cairo_set_scaled_font(cr, text->scaled_font); cairo_move_to(cr, text->d_x, text->d_y); cairo_text_path(cr, text->data); } void sh_text_draw(shape_t *shape, cairo_t *cr) { draw_text((sh_text_t *)shape, cr); }