changeset 356:3e84458968ec

Move mb_img_data_t out from argument list of rdman_shape_image_new(). - Application should specify content of sh_image_t by fill the shape with a paint_image_t.
author Thinker K.F. Li <thinker@branda.to>
date Mon, 09 Mar 2009 23:05:57 +0800
parents 958b67d911db
children 6fd8da22a5ef
files examples/menu/Makefile.am examples/menu/filebrowser.c include/mb_paint.h include/mb_redraw_man.h include/mb_shapes.h include/mb_types.h src/img_ldr.c src/paint.c src/redraw_man.c src/shape_image.c tools/mb_c_header.m4 tools/mb_c_source.m4
diffstat 12 files changed, 110 insertions(+), 105 deletions(-) [+]
line wrap: on
line diff
--- a/examples/menu/Makefile.am	Mon Mar 09 01:35:19 2009 +0800
+++ b/examples/menu/Makefile.am	Mon Mar 09 23:05:57 2009 +0800
@@ -38,7 +38,9 @@
 menu_CFLAGS = @pangocairo_CFLAGS@ 
 menu_LDFLAGS = @pangocairo_LIBS@ 
 menu_LDADD = $(top_builddir)/src/libmbfly.la
-CLEANFILES = menu.mb menu.c menu.h
+CLEANFILES = menu.mb menu.c menu.h \
+	list.mb list.c list.h \
+	browser.mb browser.c browser.h
 
 filebrowser_SOURCES = filebrowser.c animated_menu.c animated_menu.h
 filebrowser_CFLAGS = @pangocairo_CFLAGS@ 
--- a/examples/menu/filebrowser.c	Mon Mar 09 01:35:19 2009 +0800
+++ b/examples/menu/filebrowser.c	Mon Mar 09 23:05:57 2009 +0800
@@ -68,24 +68,26 @@
 void mypreview(MyAppData *data, char *path)
 {
     redraw_man_t *rdman = MBAPP_RDMAN(myApp);
-    mb_img_ldr_t *ldr = rdman_img_ldr(rdman);
-    mb_img_data_t *img = MB_IMG_LDR_LOAD(ldr, path);
+    paint_t *paint, *old_paint;
+    paint_t *previewimg_paint;
     shape_t *obj = (shape_t *) MB_SPRITE_GET_OBJ(myApp->rootsprite, "previewimg");
-    mb_img_data_t *previewimg_img_data;
-    mb_img_data_t *old_img;
+    int w, h;
 
-    previewimg_img_data =
-	(mb_img_data_t *)MB_SPRITE_GET_OBJ(myApp->rootsprite,
-					   "previewimg_img_data");
+    previewimg_paint =
+	(paint_t *)MB_SPRITE_GET_OBJ(myApp->rootsprite,
+					   "previewimg_paint_img");
     printf("Preview %s\n",path);
-    if (img) {
-	    printf("image %d %d\n",img->w,img->h);
-	    old_img = sh_image_get_img_data(obj);
-	    sh_image_set_img_data(obj,img);
-	    if(old_img != previewimg_img_data)
-		MB_IMG_DATA_FREE(old_img);
-	    rdman_shape_changed(MBAPP_RDMAN(myApp),obj);
-            rdman_redraw_changed(MBAPP_RDMAN(myApp));
+    paint = rdman_img_ldr_load_paint(rdman, path);
+    if (paint) {
+	paint_image_get_size(paint, &w, &h);
+	printf("image %d %d\n",w, h);
+	old_paint = sh_get_fill(obj);
+	rdman_paint_fill(rdman, paint, obj);
+	if(old_paint != previewimg_paint)
+	    rdman_paint_free(rdman, old_paint);
+	    
+	rdman_shape_changed(MBAPP_RDMAN(myApp),obj);
+	rdman_redraw_changed(MBAPP_RDMAN(myApp));
     }
 }
 
--- a/include/mb_paint.h	Mon Mar 09 01:35:19 2009 +0800
+++ b/include/mb_paint.h	Mon Mar 09 23:05:57 2009 +0800
@@ -17,14 +17,15 @@
 extern void paint_color_get(paint_t *paint,
 			    co_comp_t *r, co_comp_t *g,
 			    co_comp_t *b, co_comp_t *a);
-#define paint_init(_paint, _prepare, _free)	\
-     do {					\
-	 (_paint)->flags = 0;			\
-	 (_paint)->prepare = _prepare;		\
-	 (_paint)->free = _free;		\
-	 STAILQ_INIT((_paint)->members);	\
-	 (_paint)->pnt_next = NULL;		\
-     } while(0)
+#define paint_init(_paint, _type, _prepare, _free)	\
+    do {						\
+	(_paint)->pnt_type = _type;			\
+	(_paint)->flags = 0;				\
+	(_paint)->prepare = _prepare;			\
+	(_paint)->free = _free;				\
+	STAILQ_INIT((_paint)->members);			\
+	(_paint)->pnt_next = NULL;			\
+    } while(0)
 #define paint_destroy(_paint)
 
 
@@ -61,5 +62,6 @@
 /*! \brief Set a matrix to transform image.
  */
 extern void paint_image_set_matrix(paint_t *paint, co_aix matrix[6]);
+extern void paint_image_get_size(paint_t *paint, int *w, int *h);
 
 #endif /* __PAINT_H_ */
--- a/include/mb_redraw_man.h	Mon Mar 09 01:35:19 2009 +0800
+++ b/include/mb_redraw_man.h	Mon Mar 09 23:05:57 2009 +0800
@@ -214,11 +214,15 @@
  * This function will search the object in the current working directory
  * and then search the system search path.
  */
-mb_sprite_t *sprite_load(const char *name, redraw_man_t *rdman, coord_t *root);
+extern mb_sprite_t *sprite_load(const char *name, redraw_man_t *rdman,
+				coord_t *root);
 
 /*! \brief Set the search path of dymanic object loading.
  *
  */
-void sprite_set_search_path(char *path);
+extern void sprite_set_search_path(char *path);
+
+extern paint_t *rdman_img_ldr_load_paint(redraw_man_t *rdman,
+					 const char *img_id);
 
 #endif /* __REDRAW_MAN_H_ */
--- a/include/mb_shapes.h	Mon Mar 09 01:35:19 2009 +0800
+++ b/include/mb_shapes.h	Mon Mar 09 23:05:57 2009 +0800
@@ -235,15 +235,12 @@
  * @{
  */
 extern 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);
 extern void sh_image_transform(shape_t *shape);
 extern void sh_image_draw(shape_t *shape, cairo_t *cr);
 extern void sh_image_set_geometry(shape_t *shape, co_aix x, co_aix y,
 				  co_aix w, co_aix h);
-extern int sh_image_set_img_data(shape_t *shape, mb_img_data_t *img_data);
-extern mb_img_data_t *sh_image_get_img_data(shape_t *shape);
 /* @} */
 /* @} */
 
--- a/include/mb_types.h	Mon Mar 09 01:35:19 2009 +0800
+++ b/include/mb_types.h	Mon Mar 09 23:05:57 2009 +0800
@@ -78,12 +78,19 @@
  * singleton for each paint type.
  */
 struct _paint {
+    int pnt_type;
     int flags;
     void (*prepare)(paint_t *paint, cairo_t *cr);
     void (*free)(struct _redraw_man *rdman, paint_t *paint);
     STAILQ(shnode_t) members;
     paint_t *pnt_next;		/*!< \brief Collect all paints of a rdman. */
 };
+enum { MBP_DUMMY,
+       MBP_COLOR,
+       MBP_LINEAR,
+       MBP_RADIAL,
+       MBP_IMAGE
+};
 
 #define PNTF_FREE 0x1
 
--- a/src/img_ldr.c	Mon Mar 09 01:35:19 2009 +0800
+++ b/src/img_ldr.c	Mon Mar 09 23:05:57 2009 +0800
@@ -2,6 +2,7 @@
 #include <string.h>
 #include <cairo.h>
 #include "mb_tools.h"
+#include "mb_paint.h"
 #include "mb_img_ldr.h"
 
 /*! \brief Simple image loader.
--- a/src/paint.c	Mon Mar 09 01:35:19 2009 +0800
+++ b/src/paint.c	Mon Mar 09 23:05:57 2009 +0800
@@ -39,7 +39,8 @@
     color->g = g;
     color->b = b;
     color->a = a;
-    paint_init(&color->paint, paint_color_prepare, paint_color_free);
+    paint_init(&color->paint, MBP_COLOR,
+	       paint_color_prepare, paint_color_free);
     return (paint_t *)color;
 }
 
@@ -122,7 +123,8 @@
     if(linear == NULL)
 	return NULL;
 
-    paint_init(&linear->paint, paint_linear_prepare, paint_linear_free);
+    paint_init(&linear->paint, MBP_LINEAR,
+	       paint_linear_prepare, paint_linear_free);
 
     linear->x1 = x1;
     linear->y1 = y1;
@@ -212,7 +214,8 @@
     if(radial == NULL)
 	return NULL;
 
-    paint_init(&radial->paint, paint_radial_prepare, paint_radial_free);
+    paint_init(&radial->paint, MBP_RADIAL,
+	       paint_radial_prepare, paint_radial_free);
     radial->cx = cx;
     radial->cy = cy;
     radial->r = r;
@@ -272,6 +275,7 @@
     
     cairo_surface_destroy(paint_img->surf);
     img_data = paint_img->img;
+    MB_IMG_DATA_FREE(img_data);
     paint_destroy(&paint_img->paint);
     free(paint);
 }
@@ -280,8 +284,8 @@
  *
  * Create a painter that fill/stroke shapes with an image.
  *
- * \param img is image data return by image load.  Life-cycle of img
- *            is managed by application code.
+ * \param img is image data return by image load.
+ *            Owner-ship of img is transfered.
  */
 paint_t *rdman_paint_image_new(redraw_man_t *rdman,
 			       mb_img_data_t *img) {
@@ -309,7 +313,8 @@
     if(paint == NULL)
 	return NULL;
     
-    paint_init(&paint->paint, paint_image_prepare, paint_image_free);
+    paint_init(&paint->paint, MBP_IMAGE,
+	       paint_image_prepare, paint_image_free);
     paint->img = img;
     paint->surf = cairo_image_surface_create_for_data(img->content,
 						      fmt,
@@ -351,3 +356,11 @@
     cmatrix.y0 = matrix[5];
     cairo_pattern_set_matrix(img_paint->ptn, &cmatrix);
 }
+
+void paint_image_get_size(paint_t *paint, int *w, int *h) {
+    paint_image_t *ipaint = (paint_image_t *)paint;
+    
+    ASSERT(paint->pnt_type == MBP_IMAGE);
+    *w = ipaint->img->w;
+    *h = ipaint->img->h;
+}
--- a/src/redraw_man.c	Mon Mar 09 01:35:19 2009 +0800
+++ b/src/redraw_man.c	Mon Mar 09 23:05:57 2009 +0800
@@ -2271,6 +2271,24 @@
 
 /* @} */
 
+/*! \brief Load an image as a paint_image_t.
+ */
+paint_t *rdman_img_ldr_load_paint(redraw_man_t *rdman, const char *img_id) {
+    mb_img_data_t *img_data;
+    paint_t *paint;
+    mb_img_ldr_t *ldr = rdman_img_ldr(rdman);
+    
+    img_data = MB_IMG_LDR_LOAD(ldr, img_id);
+    if(img_data == NULL)
+	return NULL;
+    
+    paint = rdman_paint_image_new(rdman, img_data);
+    if(paint == NULL)
+	MB_IMG_DATA_FREE(img_data);
+    
+    return paint;
+}
+
 #ifdef UNITTEST
 /* Test cases */
 
--- a/src/shape_image.c	Mon Mar 09 01:35:19 2009 +0800
+++ b/src/shape_image.c	Mon Mar 09 23:05:57 2009 +0800
@@ -10,8 +10,8 @@
  *
  * Image (\ref sh_image_t) is a shape to show an image on the output
  * device.  Programmers manipulate object of an image shape to show it
- * at specified position with specified size.  To create a new instance
- * of sh_iamge_t, an image should be specified.  Programmers must have
+ * at specified position with specified size.  For a sh_image_t, an
+ * image should be specified to fill the shape.  Programmers must have
  * a way to load image from files.  The solution proposed by MadButterfly
  * is image loader (\ref mb_img_ldr_t).
  *
@@ -58,48 +58,19 @@
     co_aix w, h;
     co_aix poses[4][2];
     
-    mb_img_data_t *img_data;
-    paint_t *paint;
     redraw_man_t *rdman;
 } sh_image_t;
 
 static void sh_image_free(shape_t *shape);
 
-int _sh_image_set_img_data(shape_t *shape, mb_img_data_t *img_data,
-			   co_aix x, co_aix y, co_aix w, co_aix h) {
-    sh_image_t *img = (sh_image_t *)shape;
-    paint_t *paint;
-    
-    ASSERT(img_data != NULL);
-    ASSERT(shape->obj.obj_type == MBO_IMAGE);
-
-    paint = rdman_paint_image_new(img->rdman, img_data);
-    if(paint == NULL)
-	return ERR;
-    
-    if(img->paint)
-	rdman_paint_free(img->rdman, img->paint);
-    
-    img->img_data = img_data;
-    img->x = x;
-    img->y = y;
-    img->w = w;
-    img->h = h;
-    img->paint = paint;
-    rdman_paint_fill(img->rdman, paint, (shape_t *)img);
-    
-    return OK;
-}
-
 /*! \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,
+shape_t *rdman_shape_image_new(redraw_man_t *rdman,
 			       co_aix x, co_aix y, co_aix w, co_aix h) {
     sh_image_t *img;
     cairo_format_t fmt;
-    paint_t *paint;
     int r;
 
     img = O_ALLOC(sh_image_t);
@@ -110,36 +81,32 @@
     mb_obj_init((mb_obj_t *)img, MBO_IMAGE);
     img->rdman = rdman;
     img->shape.free = sh_image_free;
+
+    img->x = x;
+    img->y = y;
+    img->w = w;
+    img->h = h;
     
-    r = _sh_image_set_img_data((shape_t *)img, img_data, x, y, w, h);
-    if(r != OK) {
-	mb_obj_destroy((shape_t *)img);
-	free(img);
-	return NULL;
-    }
-
     return (shape_t *)img;
 }
 
 void sh_image_free(shape_t *shape) {
     sh_image_t *img = (sh_image_t *)shape;
 
-    rdman_paint_free(img->rdman, img->paint);
     mb_obj_destroy(shape);
     free(img);
 }
 
 void sh_image_transform(shape_t *shape) {
     sh_image_t *img = (sh_image_t *)shape;
-    mb_img_data_t *img_data;
+    paint_t *paint;
     co_aix (*poses)[2];
     co_aix img_matrix[6];
     co_aix x_factor, y_factor;
+    int img_w, img_h;
     cairo_matrix_t cmatrix;
     int i;
     
-    img_data = img->img_data;
-    
     poses = img->poses;
     poses[0][0] = img->x;
     poses[0][1] = img->y;
@@ -151,7 +118,17 @@
     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);
 
+    paint = sh_get_fill(shape);
+    if(paint == NULL)
+	return;
+
+    ASSERT(paint.pnt_type == MBP_IMAGE);
+    
+    paint_image_get_size(paint, &img_w, &img_h);
+    
     /* Transformation from user space to image space */
     img_matrix[0] = (poses[1][0] - poses[0][0]) / img->w;
     img_matrix[1] = (poses[1][1] - poses[0][1]) / img->w;
@@ -159,21 +136,19 @@
     img_matrix[3] = (poses[3][0] - poses[0][0]) / img->h;
     img_matrix[4] = (poses[3][1] - poses[0][1]) / img->h;
     img_matrix[5] = -poses[0][1];
-    if(img->w != img_data->w ||
-       img->h != img_data->h) {
+    if(img->w != img_w ||
+       img->h != img_h) {
 	/* Resize image */
-	x_factor = img_data->w / img->w;
+	x_factor = img_w / img->w;
 	img_matrix[0] *= x_factor;
 	img_matrix[1] *= x_factor;
 	img_matrix[2] *= x_factor;
-	y_factor = img_data->h / img->h;
+	y_factor = img_h / img->h;
 	img_matrix[3] *= y_factor;
 	img_matrix[4] *= y_factor;
 	img_matrix[5] *= y_factor;
     }
     paint_image_set_matrix(sh_get_fill(shape), img_matrix);
-    
-    geo_from_positions(sh_get_geo(shape), 4, poses);
 }
 
 /*! \brief Draw image for an image shape.
@@ -206,20 +181,3 @@
     img->w = w;
     img->h = h;
 }
-
-int sh_image_set_img_data(shape_t *shape, mb_img_data_t *img_data) {
-    int r;
-    sh_image_t *img = (sh_image_t *)shape;
-
-    r = _sh_image_set_img_data(shape, img_data,
-			       img->x, img->y, img->w, img->h);
-    return r;
-}
-
-mb_img_data_t *sh_image_get_img_data(shape_t *shape) {
-    sh_image_t *img = (sh_image_t *)shape;
-    
-    ASSERT(shape->obj.obj_type == MBO_IMAGE);
-    
-    return img->img_data;
-}
--- a/tools/mb_c_header.m4	Mon Mar 09 01:35:19 2009 +0800
+++ b/tools/mb_c_header.m4	Mon Mar 09 23:05:57 2009 +0800
@@ -21,7 +21,7 @@
 [    shape_t *$1;
 ]])
 define([ADD_IMAGE],[[
-    mb_img_data_t *$1_img_data;
+    paint_t *$1_paint_img;
     shape_t *$1;
 ]])
 define([PANGO_BEGIN_TEXT],[
--- a/tools/mb_c_source.m4	Mon Mar 09 01:35:19 2009 +0800
+++ b/tools/mb_c_source.m4	Mon Mar 09 23:05:57 2009 +0800
@@ -127,9 +127,10 @@
 ]])
 
 define([S_ADD_IMAGE],[[
-    obj->$1_img_data = MB_IMG_LDR_LOAD(img_ldr, "$2");
-    obj->$1 = rdman_shape_image_new(rdman, obj->$1_img_data,
+    obj->$1_paint_img = rdman_img_ldr_load_paint(rdman, "$2");
+    obj->$1 = rdman_shape_image_new(rdman,
 				    $3, $4, $5, $6);
+    rdman_paint_fill(rdman, obj->$1_paint_img, obj->$1);
     rdman_add_shape(rdman, obj->$1, obj->$7);
 ]])
 define([S_PANGO_BEGIN_TEXT],[[
@@ -300,7 +301,7 @@
 
 define([F_ADD_IMAGE],[[
     rdman_shape_free(rdman, obj->$1);
-    MB_IMG_DATA_FREE(obj->$1_img_data);
+    rdman_paint_free(rdman, obj->$1_paint_img);
 ]])
 define([F_PANGO_BEGIN_TEXT],[[
     rdman_shape_free(rdman, obj->$1);