Mercurial > MadButterfly
annotate src/shape_text.c @ 250:bd8ea44b421e
Fix bug and finish unit test for collision testing in event.c.
- mock for cairo, rdman, coord, and shape should be refactoried to a module.
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Sun, 04 Jan 2009 11:42:32 +0800 |
parents | 29e1b2bffe4c |
children | a90fd749af82 |
rev | line source |
---|---|
27 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 #include <string.h> | |
31
da770188a44d
resize font size for changige of coord.
Thinker K.F. Li <thinker@branda.to>
parents:
30
diff
changeset
|
4 #include <math.h> |
27 | 5 #include <cairo.h> |
186
530bb7728546
Move header files to $(top_srcdir)/include/ and prefixed with 'mb_'.
Thinker K.F. Li <thinker@branda.to>
parents:
185
diff
changeset
|
6 #include "mb_types.h" |
530bb7728546
Move header files to $(top_srcdir)/include/ and prefixed with 'mb_'.
Thinker K.F. Li <thinker@branda.to>
parents:
185
diff
changeset
|
7 #include "mb_shapes.h" |
27 | 8 |
104 | 9 #define ASSERT(x) |
27 | 10 #define OK 0 |
11 #define ERR -1 | |
12 | |
13 typedef struct _sh_text { | |
14 shape_t shape; | |
15 char *data; | |
16 co_aix x, y; | |
17 co_aix d_x, d_y; /* device x and y */ | |
18 co_aix font_size; | |
31
da770188a44d
resize font size for changige of coord.
Thinker K.F. Li <thinker@branda.to>
parents:
30
diff
changeset
|
19 co_aix d_font_size; |
27 | 20 cairo_font_face_t *face; |
21 cairo_scaled_font_t *scaled_font; | |
22 int flags; | |
23 } sh_text_t; | |
24 | |
25 #define TXF_SCALE_DIRTY 0x1 | |
26 | |
73
9ab15ebc9061
Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
58
diff
changeset
|
27 static void sh_text_free(shape_t *shape) { |
9ab15ebc9061
Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
58
diff
changeset
|
28 sh_text_t *text = (sh_text_t *)shape; |
9ab15ebc9061
Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
58
diff
changeset
|
29 |
9ab15ebc9061
Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
58
diff
changeset
|
30 if(text->scaled_font) |
9ab15ebc9061
Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
58
diff
changeset
|
31 cairo_scaled_font_destroy(text->scaled_font); |
9ab15ebc9061
Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
58
diff
changeset
|
32 cairo_font_face_destroy(text->face); |
9ab15ebc9061
Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
58
diff
changeset
|
33 } |
9ab15ebc9061
Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
58
diff
changeset
|
34 |
159
b90abd31a281
Postponse free of coords, shapes, and paints when the rdman is dirty.
Thinker K.F. Li <thinker@branda.to>
parents:
104
diff
changeset
|
35 shape_t *rdman_shape_text_new(redraw_man_t *rdman, |
b90abd31a281
Postponse free of coords, shapes, and paints when the rdman is dirty.
Thinker K.F. Li <thinker@branda.to>
parents:
104
diff
changeset
|
36 const char *txt, co_aix x, co_aix y, |
b90abd31a281
Postponse free of coords, shapes, and paints when the rdman is dirty.
Thinker K.F. Li <thinker@branda.to>
parents:
104
diff
changeset
|
37 co_aix font_size, cairo_font_face_t *face) { |
27 | 38 sh_text_t *text; |
39 | |
40 text = (sh_text_t *)malloc(sizeof(sh_text_t)); | |
41 if(text == NULL) | |
42 return NULL; | |
43 | |
44 memset(text, 0, sizeof(sh_text_t)); | |
224
29e1b2bffe4c
X backend only sent EVT_MOUSE_MOVE_RAW to MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
196
diff
changeset
|
45 mb_obj_init(text, MBO_TEXT); |
27 | 46 text->data = strdup(txt); |
47 if(text->data == NULL) { | |
48 free(text); | |
49 return NULL; | |
50 } | |
51 text->x = x; | |
52 text->y = y; | |
53 text->font_size = font_size; | |
54 cairo_font_face_reference(face); | |
55 text->face = face; | |
56 text->flags |= TXF_SCALE_DIRTY; | |
57 | |
73
9ab15ebc9061
Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
58
diff
changeset
|
58 text->shape.free = sh_text_free; |
27 | 59 |
159
b90abd31a281
Postponse free of coords, shapes, and paints when the rdman is dirty.
Thinker K.F. Li <thinker@branda.to>
parents:
104
diff
changeset
|
60 rdman_shape_man(rdman, (shape_t *)text); |
b90abd31a281
Postponse free of coords, shapes, and paints when the rdman is dirty.
Thinker K.F. Li <thinker@branda.to>
parents:
104
diff
changeset
|
61 |
73
9ab15ebc9061
Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
58
diff
changeset
|
62 return (shape_t *)text; |
27 | 63 } |
64 | |
88
dd813dcc232c
New example, calculator.
Thinker K.F. Li <thinker@branda.to>
parents:
73
diff
changeset
|
65 extern void sh_text_set_text(shape_t *shape, const char *txt) { |
dd813dcc232c
New example, calculator.
Thinker K.F. Li <thinker@branda.to>
parents:
73
diff
changeset
|
66 sh_text_t *text = (sh_text_t *)shape; |
dd813dcc232c
New example, calculator.
Thinker K.F. Li <thinker@branda.to>
parents:
73
diff
changeset
|
67 char *buf; |
dd813dcc232c
New example, calculator.
Thinker K.F. Li <thinker@branda.to>
parents:
73
diff
changeset
|
68 |
dd813dcc232c
New example, calculator.
Thinker K.F. Li <thinker@branda.to>
parents:
73
diff
changeset
|
69 buf = strdup(txt); |
dd813dcc232c
New example, calculator.
Thinker K.F. Li <thinker@branda.to>
parents:
73
diff
changeset
|
70 if(text->data) free(text->data); |
dd813dcc232c
New example, calculator.
Thinker K.F. Li <thinker@branda.to>
parents:
73
diff
changeset
|
71 text->data = buf; |
dd813dcc232c
New example, calculator.
Thinker K.F. Li <thinker@branda.to>
parents:
73
diff
changeset
|
72 } |
dd813dcc232c
New example, calculator.
Thinker K.F. Li <thinker@branda.to>
parents:
73
diff
changeset
|
73 |
27 | 74 static int get_extents(sh_text_t *text, cairo_text_extents_t *extents) { |
75 cairo_matrix_t fmatrix; | |
76 cairo_matrix_t ctm; | |
77 cairo_scaled_font_t *new_scaled; | |
78 cairo_font_options_t *fopt; | |
79 | |
80 if((text->flags & TXF_SCALE_DIRTY) || | |
81 text->scaled_font == NULL) { | |
82 fopt = cairo_font_options_create(); | |
83 if(fopt == NULL) | |
84 return ERR; | |
85 memset(&fmatrix, 0, sizeof(cairo_matrix_t)); | |
31
da770188a44d
resize font size for changige of coord.
Thinker K.F. Li <thinker@branda.to>
parents:
30
diff
changeset
|
86 fmatrix.xx = text->d_font_size; |
da770188a44d
resize font size for changige of coord.
Thinker K.F. Li <thinker@branda.to>
parents:
30
diff
changeset
|
87 fmatrix.yy = text->d_font_size; |
27 | 88 memset(&ctm, 0, sizeof(cairo_matrix_t)); |
89 ctm.xx = 1; | |
90 ctm.yy = 1; | |
91 new_scaled = cairo_scaled_font_create(text->face, | |
92 &fmatrix, | |
93 &ctm, | |
94 fopt); | |
95 cairo_font_options_destroy(fopt); | |
96 if(new_scaled == NULL) | |
97 return ERR; | |
98 | |
99 if(text->scaled_font) | |
100 cairo_scaled_font_destroy(text->scaled_font); | |
101 text->scaled_font = new_scaled; | |
102 text->flags &= ~TXF_SCALE_DIRTY; | |
103 } | |
104 | |
105 cairo_scaled_font_text_extents(text->scaled_font, | |
106 text->data, extents); | |
107 return OK; | |
108 } | |
109 | |
110 void sh_text_transform(shape_t *shape) { | |
111 sh_text_t *text; | |
112 co_aix x, y; | |
113 co_aix shw; | |
114 cairo_text_extents_t extents; | |
115 co_aix poses[2][2]; | |
116 int r; | |
117 | |
118 text = (sh_text_t *)shape; | |
31
da770188a44d
resize font size for changige of coord.
Thinker K.F. Li <thinker@branda.to>
parents:
30
diff
changeset
|
119 |
da770188a44d
resize font size for changige of coord.
Thinker K.F. Li <thinker@branda.to>
parents:
30
diff
changeset
|
120 text->d_font_size = coord_trans_size(shape->coord, text->font_size); |
da770188a44d
resize font size for changige of coord.
Thinker K.F. Li <thinker@branda.to>
parents:
30
diff
changeset
|
121 |
27 | 122 x = text->x; |
123 y = text->y; | |
124 coord_trans_pos(shape->coord, &x, &y); | |
125 r = get_extents(text, &extents); | |
104 | 126 ASSERT(r == OK); |
27 | 127 |
128 text->d_x = x; | |
129 text->d_y = y; | |
130 shw = shape->stroke_width / 2; | |
131 /* FIXME: It is unreasonable that a font exceed it's bbox. | |
132 * We add 5 pixels in get right bbox. But, it is unreasonable. | |
133 */ | |
134 poses[0][0] = x + extents.x_bearing - 5 - shw; | |
135 poses[0][1] = y + extents.y_bearing - 5 - shw; | |
136 poses[1][0] = poses[0][0] + extents.width + 10 + shape->stroke_width; | |
137 poses[1][1] = poses[0][1] + extents.height + 10 + shape->stroke_width; | |
138 geo_from_positions(shape->geo, 2, poses); | |
104 | 139 /*! \todo Support ratation for shape_text. */ |
27 | 140 } |
141 | |
142 | |
143 static void draw_text(sh_text_t *text, cairo_t *cr) { | |
144 cairo_set_scaled_font(cr, text->scaled_font); | |
145 cairo_move_to(cr, text->d_x, text->d_y); | |
146 cairo_text_path(cr, text->data); | |
147 } | |
148 | |
149 | |
30
e06a4a667ce2
Accept mouse/pointer event and hint the shape that the pointer is over.
Thinker K.F. Li <thinker@branda.to>
parents:
27
diff
changeset
|
150 void sh_text_draw(shape_t *shape, cairo_t *cr) { |
e06a4a667ce2
Accept mouse/pointer event and hint the shape that the pointer is over.
Thinker K.F. Li <thinker@branda.to>
parents:
27
diff
changeset
|
151 draw_text((sh_text_t *)shape, cr); |
e06a4a667ce2
Accept mouse/pointer event and hint the shape that the pointer is over.
Thinker K.F. Li <thinker@branda.to>
parents:
27
diff
changeset
|
152 } |
e06a4a667ce2
Accept mouse/pointer event and hint the shape that the pointer is over.
Thinker K.F. Li <thinker@branda.to>
parents:
27
diff
changeset
|
153 |