comparison src/shape_image.c @ 257:50d253d0fcba

Simple image loader and image shape. - img_ldr.c is a simple image loader that rooted on a directory specified when a loader instance been created. - sh_image_t is corresponding shape of image tag in SVG. - This changeset is still buggy. It need more testing. - svg2code.py is not ready for image tag.
author Thinker K.F. Li <thinker@branda.to>
date Thu, 15 Jan 2009 16:46:47 +0800
parents
children 29acbd8a0dd0
comparison
equal deleted inserted replaced
256:cac9ad3df633 257:50d253d0fcba
1 #include <stdio.h>
2 #include <string.h>
3 #include <cairo.h>
4 #include "mb_types.h"
5 #include "mb_shapes.h"
6 #include "mb_img_ldr.h"
7 #include "mb_tools.h"
8
9 #define ASSERT(x)
10 #define OK 0
11 #define ERR -1
12
13 typedef struct _sh_image {
14 shape_t shape;
15
16 co_aix x, y;
17 co_aix w, h;
18
19 mb_img_data_t *img_data;
20 cairo_surface_t *surf;
21 } sh_image_t;
22
23 static void sh_image_free(shape_t *shape);
24
25 /*! \brief Creae a new image shape.
26 *
27 * \param img_data is image data whose owner-ship is transfered.
28 */
29 shape_t *rdman_shape_image_new(redraw_man_t *rdman, mb_img_data_t *img_data,
30 co_aix x, co_aix y, co_aix w, co_aix h) {
31 sh_image_t *img;
32 cairo_format_t fmt;
33
34 img = O_ALLOC(sh_image_t);
35 if(img == NULL)
36 return NULL;
37
38 memset(img, 0, sizeof(sh_image_t));
39
40 img->shape.free = sh_image_free;
41 mb_obj_init((mb_obj_t *)img, MBO_IMAGE);
42 img->x = x;
43 img->y = y;
44 img->w = w;
45 img->h = h;
46 img->img_data = img_data;
47
48 switch(img_data->fmt) {
49 case MB_IFMT_ARGB32:
50 fmt = CAIRO_FORMAT_ARGB32;
51 break;
52
53 case MB_IFMT_RGB24:
54 fmt = CAIRO_FORMAT_RGB24;
55 break;
56
57 case MB_IFMT_A8:
58 fmt = CAIRO_FORMAT_A8;
59 break;
60
61 case MB_IFMT_A1:
62 fmt = CAIRO_FORMAT_A1;
63 break;
64
65 case MB_IFMT_RGB16_565:
66 fmt = CAIRO_FORMAT_RGB16_565;
67 break;
68
69 default:
70 mb_obj_destroy(img);
71 free(img);
72 return NULL;
73 }
74
75 img->surf = cairo_image_surface_create_for_data(img_data->content,
76 fmt,
77 img_data->width,
78 img_data->height,
79 img_data->stride);
80 if(img->surf == NULL) {
81 mb_obj_destroy(img);
82 free(img);
83 return NULL;
84 }
85
86 return (shape_t *)img;
87 }
88
89 void sh_image_free(shape_t *shape) {
90 sh_image_t *img = (sh_image_t *)shape;
91
92 mb_obj_destroy(shape);
93 MB_IMG_DATA_FREE(img->img_data);
94 cairo_surface_destroy(img->surf);
95 free(img);
96 }
97
98 void sh_image_transform(shape_t *shape) {
99 sh_image_t *img = (sh_image_t *)shape;
100 co_aix poses[4][2];
101 int i;
102
103 poses[0][0] = img->x;
104 poses[0][1] = img->y;
105 poses[1][0] = img->x + img->w;
106 poses[1][1] = img->y;
107 poses[2][0] = img->x + img->w;
108 poses[2][1] = img->y + img->h;
109 poses[3][0] = img->x;
110 poses[3][1] = img->y + img->h;
111 for(i = 0; i < 4; i++)
112 coord_trans_pos(img->shape.coord, &poses[i][0], &poses[i][1]);
113
114 geo_from_positions(sh_get_geo(shape), 4, poses);
115 }
116
117 /*! \brief Draw image for an image shape.
118 *
119 * \note Image is not rescaled for size of the shape.
120 */
121 void sh_image_draw(shape_t *shape, cairo_t *cr) {
122 sh_image_t *img = (sh_image_t *)shape;
123 cairo_pattern_t *saved_source;
124 cairo_matrix_t matrix, saved_matrix;
125 co_aix *aggr;
126
127 aggr = coord_get_aggr_matrix(sh_get_coord(shape));
128 cairo_matrix_init(&matrix,
129 aggr[0], aggr[3],
130 aggr[1], aggr[4],
131 aggr[2], aggr[5]);
132
133 /* set matrix */
134 cairo_get_matrix(cr, &saved_matrix);
135 cairo_set_matrix(cr, &matrix);
136
137 /* set source */
138 saved_source = cairo_get_source(cr);
139 cairo_pattern_reference(saved_source);
140
141 /* draw image */
142 cairo_set_source_surface(cr, img->surf, 0, 0);
143 cairo_paint(cr);
144
145 /* restore source */
146 cairo_set_source(cr, saved_source);
147 cairo_pattern_destroy(saved_source);
148
149 /* restore matrix */
150 cairo_set_matrix(cr, &saved_matrix);
151 }
152
153 void sh_image_set(shape_t *shape, co_aix x, co_aix y,
154 co_aix w, co_aix h) {
155 sh_image_t *img = (sh_image_t *)shape;
156
157 img->x = x;
158 img->y = y;
159 img->w = w;
160 img->h = h;
161 }