Mercurial > MadButterfly
view src/shape_text.c @ 167:73c4e93d331c
Make makefile more flexible that user can specify dirtories.
1. directory of macro files. (M4MACRODIR)
2. directory of installed include files. (INCDIR)
3. directory of installed libraries. (LIBDIR)
You can specify these variables as paramters of make command.
For example, "make M4MACRODIR='../../tools'" to change directory of macro
files.
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Tue, 21 Oct 2008 08:32:23 +0800 |
parents | b90abd31a281 |
children | c7e5b8779bb5 |
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 "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)); text->shape.sh_type = SHT_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); }