changeset 83:ea758bb3bbe2

example
author Thinker K.F. Li <thinker@branda.to>
date Fri, 22 Aug 2008 00:12:04 +0800
parents 4bb6451ef036
children 42698de1f653
files examples/svg2code_ex/main.c examples/svg2code_ex/svg2code_ex.svg src/X_supp.c src/X_supp.h src/mb_types.h tools/mb_c_header.m4 tools/mb_c_source.m4 tools/svg2code.py
diffstat 8 files changed, 128 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/examples/svg2code_ex/main.c	Thu Aug 21 14:13:50 2008 +0800
+++ b/examples/svg2code_ex/main.c	Fri Aug 22 00:12:04 2008 +0800
@@ -3,16 +3,41 @@
 #include <X_supp.h>
 #include "svg2code_ex.h"
 
+typedef struct _ex_rt ex_rt_t;
+struct _ex_rt {
+    X_MB_runtime_t *rt;
+    svg2code_ex_t *code;
+};
+
+static void file_button_handler(event_t *evt, void *arg) {
+    ex_rt_t *ex_rt = (ex_rt_t *)arg;
+
+    coord_show(ex_rt->code->file_menu);
+    rdman_coord_changed(ex_rt->rt->rdman, ex_rt->code->file_menu);
+    rdman_redraw_changed(ex_rt->rt->rdman);
+}
+
 int main(int argc, char * const argv[]) {
     X_MB_runtime_t rt;
     svg2code_ex_t *svg2code;
+    ob_factory_t *factory;
+    subject_t *subject;
+    ex_rt_t ex_rt;
     int r;
 
     r = X_MB_init(":0.0", 800, 600, &rt);
 
     svg2code = svg2code_ex_new(rt.rdman);
-    X_MB_handle_connection(rt.display, rt.rdman, rt.tman);
 
+    factory = rdman_get_ob_factory(rt.rdman);
+    subject = coord_get_mouse_event(svg2code->file_button);
+    ex_rt.rt = &rt;
+    ex_rt.code = svg2code;
+    subject_add_observer(factory, subject, file_button_handler, &ex_rt);
+
+    X_MB_handle_connection(&rt);
+
+    svg2code_ex_free(svg2code);
     X_MB_destroy(&rt);
 
     return 0;
--- a/examples/svg2code_ex/svg2code_ex.svg	Thu Aug 21 14:13:50 2008 +0800
+++ b/examples/svg2code_ex/svg2code_ex.svg	Fri Aug 22 00:12:04 2008 +0800
@@ -15,8 +15,8 @@
    sodipodi:version="0.32"
    inkscape:version="0.45.1"
    version="1.0"
-   sodipodi:docbase="/usr/home/thinker"
-   sodipodi:docname="drawing.svg"
+   sodipodi:docbase="/usr/home/thinker/progm/MadButterfly/examples/svg2code_ex"
+   sodipodi:docname="svg2code_ex.svg"
    inkscape:output_extension="org.inkscape.output.svg.inkscape">
   <defs
      id="defs4">
@@ -229,7 +229,7 @@
        rx="4.0216751"
        ry="5.0559778" />
     <g
-       id="g3167"
+       id="file_menu"
        transform="translate(20,40)"
        style="display:none">
       <rect
@@ -282,7 +282,7 @@
        d="M 20.580475,489.18206 L 471.76781,490.76517"
        id="path5146" />
     <g
-       id="g8091"
+       id="file_button"
        transform="translate(6.3324538,1.5831135)">
       <rect
          ry="3.0364513"
--- a/src/X_supp.c	Thu Aug 21 14:13:50 2008 +0800
+++ b/src/X_supp.c	Fri Aug 22 00:12:04 2008 +0800
@@ -70,9 +70,9 @@
 
 /*! \brief Dispatch all X events in the queue.
  */
-static void handle_x_event(Display *display,
-			   redraw_man_t *rdman,
-			   mb_tman_t *tman) {
+static void handle_x_event(X_MB_runtime_t *rt) {
+    Display *display = rt->display;
+    redraw_man_t *rdman = rt->rdman;
     XEvent evt;
     XMotionEvent *mevt;
     XButtonEvent *bevt;
@@ -164,9 +164,10 @@
  * The display is managed by specified rdman and tman.  rdman draws
  * on the display, and tman trigger actions according timers.
  */
-void X_MB_handle_connection(Display *display,
-			    redraw_man_t *rdman,
-			    mb_tman_t *tman) {
+void X_MB_handle_connection(X_MB_runtime_t *rt) {
+    Display *display = rt->display;
+    redraw_man_t *rdman = rt->rdman;
+    mb_tman_t *tman = rt->tman;
     int fd;
     mb_timeval_t now, tmo;
     struct timeval tv;
@@ -204,7 +205,7 @@
 	    rdman_redraw_changed(rdman);
 	    XFlush(display);
 	} else if(FD_ISSET(fd, &rfds)){
-	    handle_x_event(display, rdman, tman);
+	    handle_x_event(rt);
 	}
     }
 }
@@ -291,6 +292,8 @@
 
     xmb_rt->tman = mb_tman_new();
 
+    xmb_rt->last = NULL;
+
     return OK;
 }
 
--- a/src/X_supp.h	Thu Aug 21 14:13:50 2008 +0800
+++ b/src/X_supp.h	Fri Aug 22 00:12:04 2008 +0800
@@ -2,6 +2,7 @@
 #define __X_SUPP_H_
 
 #include <X11/Xlib.h>
+#include "mb_types.h"
 #include "mb_timer.h"
 #include "redraw_man.h"
 
@@ -15,11 +16,12 @@
     redraw_man_t *rdman;
     mb_tman_t *tman;
     int w, h;
+
+    /* States */
+    shape_t *last;
 };
 
-extern void X_MB_handle_connection(Display *display,
-				   redraw_man_t *rdman,
-				   mb_tman_t *tman);
+extern void X_MB_handle_connection(X_MB_runtime_t *rt);
 extern int X_MB_init(const char *display_name,
 		     int w, int h, X_MB_runtime_t *xmb_rt);
 extern void X_MB_destroy(X_MB_runtime_t *xmb_rt);
--- a/src/mb_types.h	Thu Aug 21 14:13:50 2008 +0800
+++ b/src/mb_types.h	Fri Aug 22 00:12:04 2008 +0800
@@ -112,6 +112,7 @@
 extern coord_t *preorder_coord_subtree(coord_t *root, coord_t *last);
 #define coord_hide(co) do { co->flags |= COF_HIDDEN; } while(0)
 #define coord_show(co) do { co->flags &= ~COF_HIDDEN; } while(0)
+#define coord_get_mouse_event(coord) ((coord)->mouse_event)
 
 
 /*! \brief A grahpic shape.
--- a/tools/mb_c_header.m4	Thu Aug 21 14:13:50 2008 +0800
+++ b/tools/mb_c_header.m4	Fri Aug 22 00:12:04 2008 +0800
@@ -17,6 +17,9 @@
 define([ADD_COORD],[
 [    coord_t *$1;
 ]])
+define([ADD_TEXT],[
+[    shape_t *$1;
+]])
 define([COLOR_STOP],[ ])
 
 define([REF_STOPS_RADIAL],)
--- a/tools/mb_c_source.m4	Thu Aug 21 14:13:50 2008 +0800
+++ b/tools/mb_c_source.m4	Fri Aug 22 00:12:04 2008 +0800
@@ -37,6 +37,7 @@
 define([ADD_PATH])
 define([ADD_RECT])
 define([ADD_COORD])
+define([ADD_TEXT],)
 define([FILL_SHAPE])
 define([STROKE_SHAPE])
 define([FILL_SHAPE_WITH_PAINT])
@@ -93,6 +94,11 @@
     obj->$1 = rdman_coord_new(rdman, obj->$2);
 ]])
 
+define([S_ADD_TEXT],[[
+    obj->$1 = sh_text_new("$2", $3, $4, $5, cairo_get_font_face(rdman->cr));
+    rdman_add_shape(rdman, obj->$1, obj->$6);
+]])
+
 define([S_FILL_SHAPE_WITH_PAINT],[dnl
 [    rdman_paint_fill(rdman, obj->$2, obj->$1);
 ]])
@@ -137,6 +143,7 @@
 SIMPORT([ADD_PATH],)
 SIMPORT([ADD_RECT])
 SIMPORT([ADD_COORD])
+SIMPORT([ADD_TEXT])
 SIMPORT([FILL_SHAPE])
 SIMPORT([STROKE_SHAPE])
 SIMPORT([FILL_SHAPE_WITH_PAINT])
@@ -161,11 +168,15 @@
 
 define([F_ADD_PATH],[[
     obj->$1->free(obj->$1);
-]]);
+]])
 
 define([F_ADD_RECT],[[
     obj->$1->free(obj->$1);
-]]);
+]])
+
+define([F_ADD_TEXT],[[
+    obj->$1->free(obj->$1);
+]])
 
 define([F_FILL_SHAPE],[[
     obj->$1_fill->free(obj->$1_fill);
@@ -185,6 +196,7 @@
 FIMPORT([ADD_PATH],)
 FIMPORT([ADD_RECT])
 define([ADD_COORD])
+FIMPORT([ADD_TEXT])
 FIMPORT([FILL_SHAPE])
 FIMPORT([STROKE_SHAPE])
 define([FILL_SHAPE_WITH_PAINT])
--- a/tools/svg2code.py	Thu Aug 21 14:13:50 2008 +0800
+++ b/tools/svg2code.py	Fri Aug 22 00:12:04 2008 +0800
@@ -99,13 +99,17 @@
         int(code[3:5], 16) / 255.0, \
         int(code[5:7], 16) / 255.0
 
-def translate_style(node, coord_id, codefo, doc, prefix):
-    node_id = node.getAttribute('id')
-    style_str = node.getAttribute('style')
+def get_style_map(style_str):
     prop_strs = [s.strip() for s in style_str.split(';')]
     prop_kvs = [s.split(':') for s in prop_strs if s]
     prop_kvs = [(k.strip(), v.strip()) for k, v in prop_kvs]
     prop_map = dict(prop_kvs)
+    return prop_map
+
+def translate_style(node, coord_id, codefo, doc, prefix):
+    node_id = node.getAttribute('id')
+    style_str = node.getAttribute('style')
+    prop_map = get_style_map(style_str)
 
     try:
         opacity = float(node.getAttribute('opacity'))
@@ -143,13 +147,19 @@
             paint_id = stroke[5:-1]
             print >> codefo, 'STROKE_SHAPE_WITH_PAINT([%s], [%s])dnl' % (
                 node_id, paint_id)
+        elif stroke.lower() == 'none':
+            pass
         else:
             raise ValueError, '\'%s\' is an invalid value for stroke.' \
                 % (stroke)
         pass
 
     if prop_map.has_key('stroke-width'):
-        stroke_width = float(prop_map['stroke-width'])
+        if prop_map['stroke-width'].endswith('px'):
+            stroke_width = float(prop_map['stroke-width'][:-2])
+        else:
+            stroke_width = float(prop_map['stroke-width'])
+            pass
         print >> codefo, 'STROKE_WIDTH([%s], %f)dnl' % (
             node_id, stroke_width)
         pass
@@ -190,6 +200,55 @@
     translate_style(rect, coord_id, codefo, doc, 'RECT_')
     pass
 
+def translate_font_style(text, codefo):
+    text_id = text.getAttribute('id')
+    style_str = text.getAttribute('style')
+    style_map = get_style_map(style_str)
+
+    font_sz = 10.0
+    if style_map.has_key('font-size'):
+        if style_map['font-size'].endswith('px'):
+            font_sz = float(style_map['font-size'][:-2])
+            print >> codefo, 'define([MB_FONT_SZ], %f)dnl' % (font_sz)
+            pass
+        pass
+
+    font_style = 'normal'
+    if style_map.has_key('font-style'):
+        font_style = style_map['font-style'].lower()
+        pass
+
+    font_family = 'Roman'
+    if style_map.has_key('font-family'):
+        font_family = style_map['font-family'].lower()
+        pass
+    pass
+
+def translate_text(text, coord_id, codefo, doc):
+    translate_font_style(text, codefo)
+
+    txt_strs = []
+    for node in text.childNodes:
+        if node.localName == None:
+            txt_strs.append(node.data)
+        elif node.localName == 'tspan':
+            node.setAttribute('style', text.getAttribute('style'))
+            translate_text(node, coord_id, codefo, doc)
+            pass
+        pass
+    if txt_strs:
+        text_id = text.getAttribute('id')
+        x = float(text.getAttribute('x'))
+        y = float(text.getAttribute('y'))
+        print >> codefo, 'dnl'
+        print >> codefo, \
+            'ADD_TEXT([%s], [%s], %f, %f, MB_FONT_SZ, [%s])dnl' % (
+            text_id.encode('utf8'), u''.join(txt_strs).encode('utf8'),
+            x, y, coord_id.encode('utf8'))
+        translate_style(text, coord_id, codefo, doc, 'TEXT_')
+        pass
+    pass
+
 def translate_group(group, parent_id, codefo, doc):
     group_id = group.getAttribute('id')
     print >> codefo, 'dnl'
@@ -204,6 +263,8 @@
             translate_path(node, group_id, codefo, doc)
         elif node.localName == 'rect':
             translate_rect(node, group_id, codefo, doc)
+        elif node.localName == 'text':
+            translate_text(node, group_id, codefo, doc)
             pass
         pass
     pass