changeset 260:29acbd8a0dd0

Integrate sh_image with svg2code.py. diff -r e8a784a306d0 examples/svg2code_ex/dsc_3241.png Binary file examples/svg2code_ex/dsc_3241.png has changed diff -r e8a784a306d0 examples/svg2code_ex/dsc_3241.png Binary file examples/svg2code_ex/dsc_3241.png has changed
author Thinker K.F. Li <thinker@branda.to>
date Fri, 23 Jan 2009 23:00:23 +0800
parents e8a784a306d0
children 11017576328c
files examples/svg2code_ex/svg2code_ex.svg include/mb_img_ldr.h include/mb_paint.h include/mb_redraw_man.h include/mb_shapes.h include/mb_types.h src/X_supp.c src/event.c src/paint.c src/redraw_man.c src/shape_image.c tools/mb_c_header.m4 tools/mb_c_source.m4 tools/svg2code.py
diffstat 14 files changed, 208 insertions(+), 83 deletions(-) [+]
line wrap: on
line diff
--- a/examples/svg2code_ex/svg2code_ex.svg	Thu Jan 22 18:10:47 2009 +0800
+++ b/examples/svg2code_ex/svg2code_ex.svg	Fri Jan 23 23:00:23 2009 +0800
@@ -309,6 +309,13 @@
        fx="175.7256"
        fy="143.89952"
        r="125.56596" />
+    <inkscape:perspective
+       id="perspective2495"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       sodipodi:type="inkscape:persp3d" />
   </defs>
   <sodipodi:namedview
      id="base"
@@ -322,7 +329,7 @@
      inkscape:pageshadow="2"
      inkscape:zoom="0.63166667"
      inkscape:cx="400"
-     inkscape:cy="176.10388"
+     inkscape:cy="306.21386"
      inkscape:document-units="px"
      inkscape:current-layer="layer1"
      width="800px"
@@ -330,8 +337,8 @@
      showgrid="true"
      inkscape:window-width="822"
      inkscape:window-height="695"
-     inkscape:window-x="130"
-     inkscape:window-y="120" />
+     inkscape:window-x="200"
+     inkscape:window-y="0" />
   <metadata
      id="metadata7">
     <rdf:RDF>
@@ -459,5 +466,13 @@
        sodipodi:end="9.4037459"
        sodipodi:open="true"
        transform="translate(0,-17.414248)" />
+    <image
+       y="87.316605"
+       x="605.409"
+       id="image2497"
+       height="66"
+       width="100"
+       sodipodi:absref="/usr/home/thinker/progm/MadButterfly/examples/svg2code_ex/dsc_3241.png"
+       xlink:href="dsc_3241.png" />
   </g>
 </svg>
--- a/include/mb_img_ldr.h	Thu Jan 22 18:10:47 2009 +0800
+++ b/include/mb_img_ldr.h	Fri Jan 23 23:00:23 2009 +0800
@@ -46,6 +46,7 @@
     void (*free)(mb_img_ldr_t *ldr);
 };
 #define MB_IMG_LDR_FREE(ldr) (ldr)->free(ldr)
+#define MB_IMG_LDR_LOAD(ldr, img_id) (ldr)->load(ldr, img_id)
 
 /*! \brief Create a simple image loader.
  *
--- a/include/mb_paint.h	Thu Jan 22 18:10:47 2009 +0800
+++ b/include/mb_paint.h	Fri Jan 23 23:00:23 2009 +0800
@@ -24,7 +24,8 @@
 	 (_paint)->free = _free;		\
 	 STAILQ_INIT((_paint)->members);	\
 	 (_paint)->pnt_next = NULL;		\
-     } while(0)					\
+     } while(0)
+#define paint_destroy(_paint)
 
 
 typedef struct _grad_stop {
@@ -53,5 +54,12 @@
 	(stop)->a = _a;					\
     } while(0)
 
+/*! \brief A paint that fill or stroke shape with an image.
+ */
+extern paint_t *rdman_paint_image_new(redraw_man_t *rdman,
+				      mb_img_data_t *img);
+/*! \brief Set a matrix to transform image.
+ */
+extern void paint_image_set_matrix(paint_t *paint, co_aix matrix[6]);
 
 #endif /* __PAINT_H_ */
--- a/include/mb_redraw_man.h	Thu Jan 22 18:10:47 2009 +0800
+++ b/include/mb_redraw_man.h	Fri Jan 23 23:00:23 2009 +0800
@@ -5,6 +5,7 @@
 #include "mb_tools.h"
 #include "mb_types.h"
 #include "mb_observer.h"
+#include "mb_img_ldr.h"
 
 typedef struct _redraw_man redraw_man_t;
 
@@ -79,6 +80,9 @@
 				*          \see rdman_attach_backend()
 				*/
     mb_prop_store_t props;
+    mb_img_ldr_t *img_ldr;	/*!< \brief Image Loader.
+				 *	This is initialized by backend.
+				 */
 };
 
 extern int redraw_man_init(redraw_man_t *rdman, cairo_t *cr,
@@ -190,6 +194,8 @@
     rdman_get_gen_geos(rdman)->num
 #define rdman_clear_shape_gl(rdman)		\
     DARRAY_CLEAN(rdman_get_gen_geos(rdman))
+#define rdman_prop_store(rdman) ((rdman)->props)
+#define rdman_img_ldr(rdman) ((rdman)->img_ldr)
 
 /*! \brief Attach backend to the redraw manager so that we can hide the backend from the users.
  *
@@ -197,9 +203,10 @@
 #define rdman_attach_backend(rdman,backend) (((rdman)->rt)=(backend))
 /*! \brief Load sprite dymanicly from the shared object module. 
  *  
- *   The search path can be changed by sprite_set_search_path. The name can have a relative path in the front of it.
- *   This function will search the object in the current working directory and then search the system search path.
- *
+ * The search path can be changed by sprite_set_search_path. The name
+ * can have a relative path in the front of it.
+ * 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);
 
--- a/include/mb_shapes.h	Thu Jan 22 18:10:47 2009 +0800
+++ b/include/mb_shapes.h	Fri Jan 23 23:00:23 2009 +0800
@@ -24,6 +24,8 @@
  *   - assigned to \ref shape_t::free.
  * - *_transform()
  * - *_draw()
+ *   - *_draw() is responsive to define shape.  How the shape is filled
+ *     or stroked is defined by paint.
  * - first member variable of a shape type must be a shape_t.
  * 
  * Must modify
--- a/include/mb_types.h	Thu Jan 22 18:10:47 2009 +0800
+++ b/include/mb_types.h	Fri Jan 23 23:00:23 2009 +0800
@@ -64,6 +64,9 @@
  * Paints should be freed by users by calling rdman_paint_free() of
  * the paint.
  *
+ * To define a foo paint, it should define a rdman_paint_foo_new()
+ * function.  It return a paint object.
+ *
  * \todo move member functions to a seperate structure and setup a
  * singleton for each paint type.
  */
@@ -273,6 +276,8 @@
 #define sh_pos_is_in(sh, x, y) geo_pos_is_in(sh_get_geo(sh), x, y)
 #define sh_get_area(sh) geo_get_area(sh_get_geo(sh))
 #define sh_get_coord(sh) ((sh)->coord)
+#define sh_get_fill(sh) ((sh)->fill)
+#define sh_get_stroke(sh) ((sh)->stroke)
 
 
 /*! \brief A sprite is a set of graphics that being an object in animation.
--- a/src/X_supp.c	Thu Jan 22 18:10:47 2009 +0800
+++ b/src/X_supp.c	Fri Jan 23 23:00:23 2009 +0800
@@ -451,7 +451,8 @@
     xmb_rt->tman = mb_tman_new();
 
     xmb_rt->img_ldr = simple_mb_img_ldr_new("./");
-
+    xmb_rt->rdman->img_ldr = xmb_rt->img_ldr;
+    
 #ifndef ONLY_MOUSE_MOVE_RAW
     xmb_rt->last = NULL;
 #endif
--- a/src/event.c	Thu Jan 22 18:10:47 2009 +0800
+++ b/src/event.c	Fri Jan 23 23:00:23 2009 +0800
@@ -534,6 +534,9 @@
     case MBO_RECT:
 	sh_rect_draw(shape, cr);
 	break;
+    case MBO_IMAGE:
+	sh_image_draw(shape, cr);
+	break;
     }
 }
 
--- a/src/paint.c	Thu Jan 22 18:10:47 2009 +0800
+++ b/src/paint.c	Fri Jan 23 23:00:23 2009 +0800
@@ -23,6 +23,7 @@
 
 static void paint_color_free(redraw_man_t *rdman, paint_t *paint) {
     shnode_list_free(rdman, paint->members);
+    paint_destroy(paint);
     elmpool_elm_free(rdman->paint_color_pool, paint);
 }
 
@@ -108,6 +109,7 @@
 
     if(linear->ptn)
 	cairo_pattern_destroy(linear->ptn);
+    paint_destroy(paint);
     free(paint);
 }
 
@@ -198,6 +200,7 @@
 
     if(radial->ptn)
 	cairo_pattern_destroy(radial->ptn);
+    paint_destroy(paint);
     free(paint);
 }
 
@@ -241,3 +244,94 @@
     return old_stops;
 }
 
+
+typedef struct _paint_image {
+    paint_t paint;
+    mb_img_data_t *img;
+    cairo_surface_t *surf;
+    cairo_pattern_t *ptn;
+} paint_image_t;
+
+static
+void paint_image_prepare(paint_t *paint, cairo_t *cr) {
+    paint_image_t *paint_img = (paint_image_t *)paint;
+    mb_img_data_t *img_data;
+
+    img_data = paint_img->img;
+    cairo_set_source(cr, paint_img->ptn);
+}
+
+static
+void paint_image_free(redraw_man_t *rdman, paint_t *paint) {
+    paint_image_t *paint_img = (paint_image_t *)paint;
+    mb_img_data_t *img_data;
+    
+    cairo_surface_destroy(paint_img->surf);
+    img_data = paint_img->img;
+    MB_IMG_DATA_FREE(img_data);
+    paint_destroy(&paint_img->paint);
+    free(paint);
+}
+
+paint_t *rdman_paint_image_new(redraw_man_t *rdman,
+			       mb_img_data_t *img) {
+    paint_image_t *paint;
+    int fmt;
+
+    switch(img->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;
+    default:
+	return NULL;
+    }
+    
+    paint = O_ALLOC(paint_image_t);
+    if(paint == NULL)
+	return NULL;
+    
+    paint_init(&paint->paint, paint_image_prepare, paint_image_free);
+    paint->img = img;
+    paint->surf = cairo_image_surface_create_for_data(img->content,
+						      fmt,
+						      img->width,
+						      img->height,
+						      img->stride);
+    if(paint->surf == NULL) {
+	paint_destroy(&paint->paint);
+	free(paint);
+	return NULL;
+    }
+    
+    paint->ptn = cairo_pattern_create_for_surface(paint->surf);
+    if(paint->ptn == NULL) {
+	paint_destroy(&paint->paint);
+	cairo_surface_destroy(paint->surf);
+	free(paint);
+	return NULL;
+    }
+
+    return (paint_t *)paint;
+}
+
+void paint_image_set_matrix(paint_t *paint, co_aix matrix[6]) {
+    paint_image_t *img_paint = (paint_image_t *)paint;
+    cairo_matrix_t cmatrix;
+    
+    cmatrix.xx = matrix[0];
+    cmatrix.xy = matrix[1];
+    cmatrix.x0 = matrix[2];
+    cmatrix.yx = matrix[3];
+    cmatrix.yy = matrix[4];
+    cmatrix.y0 = matrix[5];
+    cairo_pattern_set_matrix(img_paint->ptn, &cmatrix);
+}
--- a/src/redraw_man.c	Thu Jan 22 18:10:47 2009 +0800
+++ b/src/redraw_man.c	Fri Jan 23 23:00:23 2009 +0800
@@ -796,6 +796,9 @@
     case MBO_RECT:
 	sh_rect_transform(shape);
 	break;
+    case MBO_IMAGE:
+	sh_image_transform(shape);
+	break;
 #ifdef UNITTEST
     default:
 	sh_dummy_transform(shape);
@@ -996,6 +999,9 @@
 	case MBO_RECT:
 	    sh_rect_draw(shape, cr);
 	    break;
+	case MBO_IMAGE:
+	    sh_image_draw(shape, cr);
+	    break;
 #ifdef UNITTEST
 	default:
 	    sh_dummy_fill(shape, cr);
--- a/src/shape_image.c	Thu Jan 22 18:10:47 2009 +0800
+++ b/src/shape_image.c	Fri Jan 23 23:00:23 2009 +0800
@@ -15,9 +15,11 @@
     
     co_aix x, y;
     co_aix w, h;
+    co_aix poses[4][2];
     
     mb_img_data_t *img_data;
-    cairo_surface_t *surf;
+    paint_t *paint;
+    redraw_man_t *rdman;
 } sh_image_t;
 
 static void sh_image_free(shape_t *shape);
@@ -30,6 +32,7 @@
 			       co_aix x, co_aix y, co_aix w, co_aix h) {
     sh_image_t *img;
     cairo_format_t fmt;
+    paint_t *paint;
 
     img = O_ALLOC(sh_image_t);
     if(img == NULL)
@@ -45,61 +48,31 @@
     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;
+    paint = rdman_paint_image_new(rdman, img_data);
+    rdman_paint_fill(rdman, paint, (shape_t *)img);
+    img->paint = paint;
+    img->rdman = rdman;
 
-    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;
 
+    rdman_paint_free(img->rdman, img->paint);
     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];
+    co_aix (*poses)[2];
+    co_aix img_matrix[6];
+    cairo_matrix_t cmatrix;
     int i;
 
+    poses = img->poses;
     poses[0][0] = img->x;
     poses[0][1] = img->y;
     poses[1][0] = img->x + img->w;
@@ -110,6 +83,14 @@
     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]);
+
+    img_matrix[0] = (poses[1][0] - poses[0][0]) / img->w;
+    img_matrix[1] = (poses[1][1] - poses[0][1]) / img->w;
+    img_matrix[2] = -poses[0][0];
+    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];
+    paint_image_set_matrix(sh_get_fill(shape), img_matrix);
     
     geo_from_positions(sh_get_geo(shape), 4, poses);
 }
@@ -124,30 +105,11 @@
     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);
+    cairo_move_to(cr, img->poses[0][0], img->poses[0][1]);
+    cairo_line_to(cr, img->poses[1][0], img->poses[1][1]);
+    cairo_line_to(cr, img->poses[2][0], img->poses[2][1]);
+    cairo_line_to(cr, img->poses[3][0], img->poses[3][1]);
+    cairo_close_path(cr);
 }
 
 void sh_image_set(shape_t *shape, co_aix x, co_aix y,
--- a/tools/mb_c_header.m4	Thu Jan 22 18:10:47 2009 +0800
+++ b/tools/mb_c_header.m4	Fri Jan 23 23:00:23 2009 +0800
@@ -20,8 +20,9 @@
 define([ADD_TEXT],[
 [    shape_t *$1;
 ]])
-define([ADD_IMAGE],[
-[    shape_t *$1;
+define([ADD_IMAGE],[[
+    mb_img_data_t *$1_img_data;
+    shape_t *$1;
 ]])
 define([COLOR_STOP],[ ])
 
--- a/tools/mb_c_source.m4	Thu Jan 22 18:10:47 2009 +0800
+++ b/tools/mb_c_source.m4	Fri Jan 23 23:00:23 2009 +0800
@@ -120,6 +120,13 @@
     rdman_add_shape(rdman, obj->$1, obj->$6);
 ]])
 
+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,
+				    $3, $4, $5, $6);
+    rdman_add_shape(rdman, obj->$1, obj->$7);
+]])
+
 define([S_FILL_SHAPE_WITH_PAINT],[dnl
 [    rdman_paint_fill(rdman, obj->$2, obj->$1);
 ]])
@@ -204,6 +211,7 @@
 SIMPORT([ADD_RECT])
 SIMPORT([ADD_COORD])
 SIMPORT([ADD_TEXT])
+SIMPORT([ADD_IMAGE])
 SIMPORT([FILL_SHAPE])
 SIMPORT([STROKE_SHAPE])
 SIMPORT([FILL_SHAPE_WITH_PAINT])
@@ -242,6 +250,11 @@
     rdman_shape_free(rdman, obj->$1);
 ]])
 
+define([F_ADD_IMAGE],[[
+    rdman_shape_free(rdman, obj->$1);
+    MB_IMAGE_DATA_FREE(obj->$1_img_data);
+]])
+
 define([F_FILL_SHAPE],[[
     rdman_paint_free(rdman, obj->$1_fill);
 ]])
@@ -423,9 +436,12 @@
 
 $1_t *$1_new(redraw_man_t *rdman, coord_t *parent_coord) {
     $1_t *obj;
-    grad_stop_t *stops = NULL;]DECLARE_VARS
+    grad_stop_t *stops = NULL;
+    mb_img_ldr_t *img_ldr = NULL;]DECLARE_VARS
 $2[]dnl
 [
+    img_ldr = rdman_img_ldr(rdman);
+    
     obj = ($1_t *)malloc(sizeof($1_t));
     if(obj == NULL) return NULL;
 
--- a/tools/svg2code.py	Thu Jan 22 18:10:47 2009 +0800
+++ b/tools/svg2code.py	Fri Jan 23 23:00:23 2009 +0800
@@ -371,6 +371,8 @@
 
 @check_mbname
 def translate_text(text, coord_id, codefo, doc):
+    coord_id = translate_shape_transform(text, coord_id, codefo)
+    
     translate_font_style(text, codefo)
 
     txt_strs = []
@@ -397,38 +399,40 @@
 
 @check_mbname
 def translate_image(image, coord_id, codefo, doc):
+    coord_id = translate_shape_transform(image, coord_id, codefo)
+    
     image_id = _get_id(image)
-    if not image.hasAttribute('href'):
+    if not image.hasAttributeNS(xlinkns, 'href'):
         raise ValueError, 'image %s must has a href attribute.' % (image_id)
-    href = image.getAttribute('href')
+    href = image.getAttributeNS(xlinkns, 'href')
     if image.hasAttribute('x'):
         x_str = image.getAttribute('x')
-        x = int(x_str)
+        x = float(x_str)
     else:
         x = 0
         pass
     if image.hasAttribute('y'):
         y_str = image.getAttribute('y')
-        y = int(y_str)
+        y = float(y_str)
     else:
         y = 0
         pass
     if image.hasAttribute('width'):
         width_str = image.getAttribute('width')
-        width = int(width_str)
+        width = float(width_str)
     else:
         width = -1
         pass
     if image.hasAttribute('height'):
         height_str = image.getAttribute('height')
-        height = int(height_str)
+        height = float(height_str)
     else:
         height = -1
         pass
     print >> codefo, 'dnl'
     print >> codefo, \
-        'ADD_IMAGE([%s], [%s], %f, %f, %f, %f)dnl' % (
-        image_id, href, x, y, width, height)
+        'ADD_IMAGE([%s], [%s], %f, %f, %f, %f, [%s])dnl' % (
+        image_id, href, x, y, width, height, coord_id)
     pass
 
 reo_func = re.compile('([a-zA-Z]+)\\([^\\)]*\\)')