diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/shape_image.c	Thu Jan 15 16:46:47 2009 +0800
@@ -0,0 +1,161 @@
+#include <stdio.h>
+#include <string.h>
+#include <cairo.h>
+#include "mb_types.h"
+#include "mb_shapes.h"
+#include "mb_img_ldr.h"
+#include "mb_tools.h"
+
+#define ASSERT(x)
+#define OK 0
+#define ERR -1
+
+typedef struct _sh_image {
+    shape_t shape;
+    
+    co_aix x, y;
+    co_aix w, h;
+    
+    mb_img_data_t *img_data;
+    cairo_surface_t *surf;
+} sh_image_t;
+
+static void sh_image_free(shape_t *shape);
+
+/*! \brief Creae a new image shape.
+ *
+ * \param img_data is image data whose owner-ship is transfered.
+ */
+shape_t *rdman_shape_image_new(redraw_man_t *rdman, mb_img_data_t *img_data,
+			       co_aix x, co_aix y, co_aix w, co_aix h) {
+    sh_image_t *img;
+    cairo_format_t fmt;
+
+    img = O_ALLOC(sh_image_t);
+    if(img == NULL)
+	return NULL;
+
+    memset(img, 0, sizeof(sh_image_t));
+    
+    img->shape.free = sh_image_free;
+    mb_obj_init((mb_obj_t *)img, MBO_IMAGE);
+    img->x = x;
+    img->y = y;
+    img->w = w;
+    img->h = h;
+    img->img_data = img_data;
+
+    switch(img_data->fmt) {
+    case MB_IFMT_ARGB32:
+	fmt = CAIRO_FORMAT_ARGB32;
+	break;
+
+    case MB_IFMT_RGB24:
+	fmt = CAIRO_FORMAT_RGB24;
+	break;
+
+    case MB_IFMT_A8:
+	fmt = CAIRO_FORMAT_A8;
+	break;
+
+    case MB_IFMT_A1:
+	fmt = CAIRO_FORMAT_A1;
+	break;
+    
+    case MB_IFMT_RGB16_565:
+	fmt = CAIRO_FORMAT_RGB16_565;
+	break;
+    
+    default:
+	mb_obj_destroy(img);
+	free(img);
+	return NULL;
+    }
+    
+    img->surf = cairo_image_surface_create_for_data(img_data->content,
+						    fmt,
+						    img_data->width,
+						    img_data->height,
+						    img_data->stride);
+    if(img->surf == NULL) {
+	mb_obj_destroy(img);
+	free(img);
+	return NULL;
+    }
+    
+    return (shape_t *)img;
+}
+
+void sh_image_free(shape_t *shape) {
+    sh_image_t *img = (sh_image_t *)shape;
+
+    mb_obj_destroy(shape);
+    MB_IMG_DATA_FREE(img->img_data);
+    cairo_surface_destroy(img->surf);
+    free(img);
+}
+
+void sh_image_transform(shape_t *shape) {
+    sh_image_t *img = (sh_image_t *)shape;
+    co_aix poses[4][2];
+    int i;
+
+    poses[0][0] = img->x;
+    poses[0][1] = img->y;
+    poses[1][0] = img->x + img->w;
+    poses[1][1] = img->y;
+    poses[2][0] = img->x + img->w;
+    poses[2][1] = img->y + img->h;
+    poses[3][0] = img->x;
+    poses[3][1] = img->y + img->h;
+    for(i = 0; i < 4; i++)
+	coord_trans_pos(img->shape.coord, &poses[i][0], &poses[i][1]);
+    
+    geo_from_positions(sh_get_geo(shape), 4, poses);
+}
+
+/*! \brief Draw image for an image shape.
+ *
+ * \note Image is not rescaled for size of the shape.
+ */
+void sh_image_draw(shape_t *shape, cairo_t *cr) {
+    sh_image_t *img = (sh_image_t *)shape;
+    cairo_pattern_t *saved_source;
+    cairo_matrix_t matrix, saved_matrix;
+    co_aix *aggr;
+    
+    aggr = coord_get_aggr_matrix(sh_get_coord(shape));
+    cairo_matrix_init(&matrix,
+		      aggr[0], aggr[3],
+		      aggr[1], aggr[4],
+		      aggr[2], aggr[5]);
+
+    /* set matrix */
+    cairo_get_matrix(cr, &saved_matrix);
+    cairo_set_matrix(cr, &matrix);
+    
+    /* set source */
+    saved_source = cairo_get_source(cr);
+    cairo_pattern_reference(saved_source);
+
+    /* draw image */
+    cairo_set_source_surface(cr, img->surf, 0, 0);
+    cairo_paint(cr);
+    
+    /* restore source */
+    cairo_set_source(cr, saved_source);
+    cairo_pattern_destroy(saved_source);
+
+    /* restore matrix */
+    cairo_set_matrix(cr, &saved_matrix);
+}
+
+void sh_image_set(shape_t *shape, co_aix x, co_aix y,
+		  co_aix w, co_aix h) {
+    sh_image_t *img = (sh_image_t *)shape;
+
+    img->x = x;
+    img->y = y;
+    img->w = w;
+    img->h = h;
+}