changeset 241:104d83378582

Add scene support in svg2code.py. - Add mb_sprite_t::goto_scene() - svg2code.py recoganize "scenes" tag in metadata of SVG file. - tranform scenes into SCENE() macro. - define SCENE macro in mb_c_*.m4
author Thinker K.F. Li <thinker@branda.to>
date Wed, 31 Dec 2008 02:08:40 +0800
parents d347a577a232
children d3fe0a0f3a8b
files include/mb_types.h src/event.c tools/mb_c_header.m4 tools/mb_c_source.m4 tools/svg2code.py
diffstat 5 files changed, 220 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/include/mb_types.h	Tue Dec 30 09:21:23 2008 +0800
+++ b/include/mb_types.h	Wed Dec 31 02:08:40 2008 +0800
@@ -280,11 +280,16 @@
 struct _mb_sprite {
     void (*free)(mb_sprite_t *);
     mb_obj_t *(*get_obj_with_name)(mb_sprite_t *sprite, const char *id);
+    /*! Return non-zero for error. */
+    int (*goto_scene)(mb_sprite_t *sprite, int scene_no);
 };
 
 #define MB_SPRITE_FREE(sprite) ((mb_sprite_t *)(sprite))->free(sprite)
-#define MB_SPRITE_GET_OBJ(sprite, name)		\
-    ((mb_sprite_t *)(sprite))->get_obj_with_name((sprite), (name))
+#define MB_SPRITE_GET_OBJ(sprite, name)					\
+    ((mb_sprite_t *)(sprite))->get_obj_with_name((mb_sprite_t *)(sprite), \
+						 (name))
+#define MB_SPRITE_GOTO_SCENE(sprite, scene_no)				\
+    ((mb_sprite_t *)(sprite))->goto_scene((mb_sprite_t *)(sprite), scene_no)
 
 
 /*! \defgroup mb_sprite_lsym Sprite with linear symbol table.
--- a/src/event.c	Tue Dec 30 09:21:23 2008 +0800
+++ b/src/event.c	Wed Dec 31 02:08:40 2008 +0800
@@ -55,6 +55,13 @@
     co_aix x, y;
     co_aix w, h;
 };
+#define range_overlay(as, aw, bs, bw)			\
+    (((bs) - (as)) <= (aw) || ((as) - (bs)) <= (bw))
+#define areas_are_overlay(a1, a2)		\
+    (range_overlay((a1)->x, (a1)->w,		\
+		   (a2)->x, (a2)->w) &&		\
+     range_overlay((a1)->y, (a1)->h,		\
+		   (a2)->y, (a2)->h))
 
 struct mb_obj {
     int obj_type;
@@ -67,6 +74,8 @@
 struct shape {
     mb_obj_t obj;
     
+    area_t area;
+
     void *fill, *stroke;
     struct shape *sibling;
     int flags;
@@ -95,21 +104,58 @@
 #define sh_get_flags(shape, mask) ((shape)->flags & mask)
 #define sh_set_flags(shape, mask) do { (shape)->flags |= mask; } while(0)
 #define sh_clear_flags(shape, mask) do { (shape)->flags &= ~(mask); } while(0)
+#define sh_get_area(shape) (&(shape)->area)
 
 typedef struct coord coord_t;
 struct coord {
     mb_obj_t obj;
-    
+  
+    area_t area;
+    int flags;
+    coord_t *parent;
     coord_t *children;
     coord_t *sibling;
     shape_t *shapes;
 };
 
+#define COF_SKIP 0x1
+
+#define coord_get_area(coord) (&(coord)->area)
+#define FOR_COORD_SHAPES(coord, shape)		\
+    for(shape = (coord)->shapes;		\
+	shape != NULL;				\
+	shape = (shape)->sibling)
+#define FOR_COORDS_PREORDER(root, last)			\
+    for(last = root;					\
+	last != NULL;					\
+	last = preorder_coord_subtree(root, last))
+
+static
+coord_t *preorder_coord_subtree(coord_t *root, coord_t *last) {
+    if(last->children)
+	return last->children;
+    while(last->sibling == NULL)
+	last = last->parent;
+    return last->sibling;
+}
 
 static
 coord_t *postorder_coord_subtree(coord_t *root, coord_t *last) {
-    if(last == NULL)
-	return root;
+    coord_t *cur;
+
+    if(last != NULL) {
+	if(last->sibling == NULL) {
+	    cur = last->parent;
+	    return cur;
+	}
+	cur = last->sibling;
+    }
+
+    cur = last;
+    while(cur->children) {
+	cur = cur->children;
+    }
+    return cur;
 }
 
 #define sh_path_draw(path, cr)
--- a/tools/mb_c_header.m4	Tue Dec 30 09:21:23 2008 +0800
+++ b/tools/mb_c_header.m4	Wed Dec 31 02:08:40 2008 +0800
@@ -41,6 +41,7 @@
 define([SHAPE_TRANSLATE],)
 define([SHAPE_MATRIX],)
 define([ADD_SYMBOL],)
+define([SCENE])
 
 define([MADBUTTERFLY],[dnl
 [#ifndef __$1_H_
@@ -51,6 +52,7 @@
 struct $1 {
     mb_sprite_lsym_t lsym;
     redraw_man_t *rdman;
+    const int *last_scene;
     coord_t *root_coord;]
 $2[]dnl
 [};
--- a/tools/mb_c_source.m4	Tue Dec 30 09:21:23 2008 +0800
+++ b/tools/mb_c_source.m4	Wed Dec 31 02:08:40 2008 +0800
@@ -10,6 +10,32 @@
 
 define([IMPORT],[define([$1],[$2$1(]$[]@[)])])
 
+define([DECLARE_EMPTIES], [
+define([ADD_LINEAR_PAINT])
+define([ADD_RADIAL_PAINT])
+define([COLOR_STOP])
+define([REF_STOPS_RADIAL])
+define([REF_STOPS_LINEAR])
+define([ADD_PATH])
+define([ADD_RECT])
+define([ADD_COORD])
+define([ADD_TEXT],)
+define([FILL_SHAPE])
+define([STROKE_SHAPE])
+define([FILL_SHAPE_WITH_PAINT])
+define([STROKE_SHAPE_WITH_PAINT])
+define([STROKE_WIDTH])
+define([GROUP_HIDE],)
+define([RECT_HIDE],)
+define([PATH_HIDE],)
+define([COORD_TRANSLATE],)
+define([COORD_MATRIX],)
+define([SHAPE_TRANSLATE],)
+define([SHAPE_MATRIX],)
+define([ADD_SYMBOL],)
+define([SCENE])
+])
+
 define([D_COLOR_STOP],[
 	{$6,$2,$3,$4,$5}])
 
@@ -29,28 +55,10 @@
 
 define([DECLARE_VARS], [divert([-1])
 define([DIMPORT],[IMPORT(]QUOTE($[]1)[,[D_])])
+DECLARE_EMPTIES
 DIMPORT([ADD_LINEAR_PAINT])
 DIMPORT([ADD_RADIAL_PAINT])
 DIMPORT([COLOR_STOP])
-define([REF_STOPS_RADIAL])
-define([REF_STOPS_LINEAR])
-define([ADD_PATH])
-define([ADD_RECT])
-define([ADD_COORD])
-define([ADD_TEXT],)
-define([FILL_SHAPE])
-define([STROKE_SHAPE])
-define([FILL_SHAPE_WITH_PAINT])
-define([STROKE_SHAPE_WITH_PAINT])
-define([STROKE_WIDTH])
-define([GROUP_HIDE],)
-define([RECT_HIDE],)
-define([PATH_HIDE],)
-define([COORD_TRANSLATE],)
-define([COORD_MATRIX],)
-define([SHAPE_TRANSLATE],)
-define([SHAPE_MATRIX],)
-define([ADD_SYMBOL],)
 divert[]])
 
 define([S_ADD_LINEAR_PAINT],[
@@ -185,6 +193,7 @@
 
 define([SETUP_VARS],[divert([-1])
 define([SIMPORT],[IMPORT(]QUOTE($[]1)[,[S_])])
+DECLARE_EMPTIES
 SIMPORT([ADD_LINEAR_PAINT])
 SIMPORT([ADD_RADIAL_PAINT])
 SIMPORT([COLOR_STOP])
@@ -206,7 +215,6 @@
 SIMPORT([COORD_MATRIX])
 SIMPORT([SHAPE_TRANSLATE])
 SIMPORT([SHAPE_MATRIX])
-define([ADD_SYMBOL],)
 divert[]])
 
 define([F_ADD_LINEAR_PAINT],[[
@@ -243,28 +251,14 @@
 
 define([CLEAR_VARS],[divert([-1])
 define([FIMPORT],[IMPORT(]QUOTE($[]1)[,[F_])])
+DECLARE_EMPTIES
 FIMPORT([ADD_LINEAR_PAINT])
 FIMPORT([ADD_RADIAL_PAINT])
-define([COLOR_STOP])
-define([REF_STOPS_RADIAL])
-define([REF_STOPS_LINEAR])
 FIMPORT([ADD_PATH],)
 FIMPORT([ADD_RECT])
-define([ADD_COORD])
 FIMPORT([ADD_TEXT])
 FIMPORT([FILL_SHAPE])
 FIMPORT([STROKE_SHAPE])
-define([FILL_SHAPE_WITH_PAINT])
-define([STROKE_SHAPE_WITH_PAINT])
-define([STROKE_WIDTH])
-define([GROUP_HIDE],)
-define([RECT_HIDE],)
-define([PATH_HIDE],)
-define([COORD_TRANSLATE],)
-define([COORD_MATRIX],)
-define([SHAPE_TRANSLATE],)
-define([SHAPE_MATRIX],)
-define([ADD_SYMBOL],)
 divert[]])
 
 define([REVERSE_VARS],[divert([-1])
@@ -279,6 +273,7 @@
 	define(]QUOTE($[]1)[,
 		[PUSH_REV(]]QUOTE(QUOTE($[]1))[[(]QUOTE($[]@)[))])
 ])
+DECLARE_EMPTIES
 RIMPORT([ADD_LINEAR_PAINT])
 RIMPORT([ADD_RADIAL_PAINT])
 RIMPORT([COLOR_STOP])
@@ -300,7 +295,6 @@
 RIMPORT([COORD_MATRIX])
 RIMPORT([SHAPE_TRANSLATE])
 RIMPORT([SHAPE_MATRIX])
-define([ADD_SYMBOL],)
 divert[]dnl
 ])
 
@@ -308,31 +302,35 @@
 
 define([DECLARE_SYMS], [divert([-1])
 define([YIMPORT],[IMPORT(]QUOTE($[]1)[,[Y_])])
-define([ADD_LINEAR_PAINT])
-define([ADD_RADIAL_PAINT])
-define([COLOR_STOP])
-define([REF_STOPS_RADIAL])
-define([REF_STOPS_LINEAR])
-define([ADD_PATH])
-define([ADD_RECT])
-define([ADD_COORD])
-define([ADD_TEXT],)
-define([FILL_SHAPE])
-define([STROKE_SHAPE])
-define([FILL_SHAPE_WITH_PAINT])
-define([STROKE_SHAPE_WITH_PAINT])
-define([STROKE_WIDTH])
-define([GROUP_HIDE],)
-define([RECT_HIDE],)
-define([PATH_HIDE],)
-define([COORD_TRANSLATE],)
-define([COORD_MATRIX],)
-define([SHAPE_TRANSLATE],)
-define([SHAPE_MATRIX],)
+DECLARE_EMPTIES
 YIMPORT([ADD_SYMBOL])
 divert[]dnl
 ])
 
+define([SC_SCENE], [[static const int scene_$1[] = {]
+foreach([GROUP_NAME], ($2), [[	MB_SPRITE_OFFSET(]GROUP_NAME[),
+]])dnl
+[	0
+};
+]])
+
+define([DEFINE_SCENES], [divert([-1])
+define([SCIMPORT],[IMPORT(]QUOTE($[]1)[,[SC_])])
+DECLARE_EMPTIES
+SCIMPORT([SCENE])
+divert[]dnl
+])
+
+define([SCA_SCENE], [[	scene_$1,
+]])
+
+define([DEFINE_SCENES_ARRAY], [divert([-1])
+define([SCAIMPORT],[IMPORT(]QUOTE($[]1)[,[SCA_])])
+DECLARE_EMPTIES
+SCAIMPORT([SCENE])
+divert[]dnl
+])
+
 define([MADBUTTERFLY],[dnl
 [#include <stdio.h>
 #include <stdlib.h>
@@ -348,11 +346,6 @@
 #endif
 #define MB_SPRITE_OFFSET(x) ((int)&((($1_t *)0)->x))
 
-static
-mb_sprite_lsym_entry_t $1_symbols[] = {]DECLARE_SYMS
-$2[
-};
-
 #ifndef MB_LSYM_GET_OBJ_WITH_NAME
 #define MB_LSYM_GET_OBJ_WITH_NAME
 
@@ -372,6 +365,59 @@
 }
 #endif /* MB_LSYM_GET_OBJ_WITH_NAME */
 
+static
+mb_sprite_lsym_entry_t $1_symbols[] = {]DECLARE_SYMS
+$2[
+};
+
+]DEFINE_SCENES
+$2
+DEFINE_SCENES_ARRAY
+static const int *$1_scenes[[]] = {
+$2[]dnl
+	NULL
+};[
+
+#define SCENES_NUM ((sizeof($1_scenes) / sizeof(const int *)) - 1)
+
+static
+int $1_goto_scene($1_t *sprite, int scene_no) {
+    coord_t *coord;
+    const int *p;
+    const int *scene;
+
+    if(scene_no >= SCENES_NUM || scene_no < -1)
+        return 1;
+
+    if(sprite->last_scene) {
+        p = sprite->last_scene;
+    	while(*p != 0) {
+	    coord = (coord_t *)MB_SPRITE_OFF_2_PTR(sprite, *p);
+	    coord_hide(coord);
+	    rdman_coord_changed(sprite->rdman, coord);
+	    p++;
+	}
+    }
+
+    if(scene_no == -1) {
+        sprite->last_scene = NULL;
+	return 0;
+    }
+
+    scene = $1_scenes[scene_no];
+    p = scene;
+    while(*p != 0) {
+	coord = (coord_t *)MB_SPRITE_OFF_2_PTR(sprite, *p);
+	coord_show(coord);
+	rdman_coord_changed(sprite->rdman, coord);
+	p++;
+    }
+
+    sprite->last_scene = scene;
+
+    return 0;
+}
+
 void $1_free($1_t *);
 
 $1_t *$1_new(redraw_man_t *rdman, coord_t *parent_coord) {
@@ -382,7 +428,8 @@
     obj = ($1_t *)malloc(sizeof($1_t));
     if(obj == NULL) return NULL;
 
-    obj->lsym.sprite.free = (void (*)(mb_sprite_t))$1_free;
+    obj->lsym.sprite.free = (void (*)(mb_sprite_t *))$1_free;
+    obj->lsym.sprite.goto_scene = (int (*)(mb_sprite_t *, int))$1_goto_scene;
     obj->lsym.sprite.get_obj_with_name =
 	(mb_obj_t *(*)(mb_sprite_t *, const char *))mb_lsym_get_obj_with_name;
     obj->lsym.num_entries =
@@ -390,6 +437,7 @@
     obj->lsym.entries = $1_symbols;
 
     obj->rdman = rdman;
+    obj->last_scene = NULL;
 ]SETUP_VARS[
     obj->root_coord = rdman_coord_new(rdman, parent_coord);]
 $2
--- a/tools/svg2code.py	Tue Dec 30 09:21:23 2008 +0800
+++ b/tools/svg2code.py	Wed Dec 31 02:08:40 2008 +0800
@@ -216,12 +216,14 @@
 # H x               : horizontal line to x
 # V y               : Vertical line to y
 # C x1 y1 x2 y2 x y : Draw a segment of bezier curve
-# S x2 y2 x t       : Draw a segment of bezier curve from the last control point
+# S x2 y2 x t       : Draw a segment of bezier curve from the last
+#                     control point
 # Q x1 y1 x y       : Draw a segment of quadratic curve
-# T x y             : Draw a segment of quadratic curve from the last control pint
+# T x y             : Draw a segment of quadratic curve from the last
+#                     control pint
 # A x y r f s x y   : Draw an arc
-# translate the path data into two arrays. The first is an integer whose upper 8
-# bits are the command type The second array hold all arguments.
+# translate the path data into two arrays. The first is an integer whose
+# upper 8 bits are the command type The second array hold all arguments.
 
 command_length={'M': 2, 'm':2,
                 'Z': 0, 'z':0,
@@ -450,6 +452,44 @@
         pass
     pass
 
+## \brief Translate "scenes" tag in "metadata" tag.
+#
+def translate_scenes(scenes_node, codefo, doc):
+    scenes = []
+    for scene in scenes_node.childNodes:
+        if scene.localName != 'scene' or \
+                not scene.hasAttribute('ref') or \
+                not scene.hasAttribute('start'):
+            continue
+        
+        start_str = scene.getAttribute('start')
+        start = end = int(start_str)
+        if scene.hasAttribute('end'):
+            end_str = scene.getAttribute('end')
+            end = int(end_str)
+            pass
+        ref = scene.getAttribute('ref')
+        
+        while len(scenes) <= end:
+            scenes.append([])
+            pass
+        
+        for i in range(start, end + 1):
+            scenes[i].append(ref)
+            pass
+        pass
+
+    for scene_idx, groups_in_scene in enumerate(scenes):
+        if groups_in_scene:
+            groups_str = '[' + '],['.join(groups_in_scene) + ']'
+        else:
+            groups_str = ''
+            pass
+        print >> codefo, \
+            'SCENE(%d, [%s])dnl' % (scene_idx, groups_str)
+        pass
+    pass
+
 def svg_2_code(dom, codefo):
     for node in dom.childNodes:
         if node.localName == 'svg' and node.namespaceURI == svgns:
@@ -462,6 +502,12 @@
     for node in svg.childNodes:
         if node.localName == 'defs' and node.namespaceURI == svgns:
             translate_defs(node, codefo, dom)
+        elif node.localName == 'metadata' and node.namespaceURI == svgns:
+            for meta_node in node.childNodes:
+                if meta_node.localName == 'scenes':
+                    translate_scenes(meta_node, codefo, dom)
+                    pass
+                pass
             pass
         elif node.localName == 'g' and node.namespaceURI == svgns:
             translate_group(node, 'root_coord', codefo, dom)
@@ -479,6 +525,7 @@
         codefn = 'out.mb'
     else:
         print >> sys.stderr, '%s <SVG file> [<output>]' % (sys.argv[0])
+        sys.exit(1)
         pass
     
     struct_name = path.basename(codefn).split('.')[0]