# HG changeset patch # User wycc # Date 1233376190 -28800 # Node ID c8b6ca46950bc11b07a29b300a9614ae4db089b4 # Parent 86a5ae82ccf2ba864f6ce7427d38aaa8254c084a# Parent 892d86c1a4097248976bb589def0d61bea28a9bb Add merged result diff -r 892d86c1a409 -r c8b6ca46950b configure.ac --- a/configure.ac Thu Jan 29 23:57:59 2009 +0800 +++ b/configure.ac Sat Jan 31 12:29:50 2009 +0800 @@ -13,7 +13,8 @@ AC_PROG_LIBTOOL # Checks for libraries. -PKG_CHECK_MODULES([cairo], [cairo >= 1.6], , AC_MSG_ERROR([cairo >= 1.6 not found])) +PKG_CHECK_MODULES([cairo], [cairo >= 0.22], , AC_MSG_ERROR([cairo >= 0.22 not found])) +PKG_CHECK_MODULES([pangocairo], [pangocairo >= 0.22], , AC_MSG_ERROR([pangocairo >= 0.22 not found])) # Checks for header files. AC_PATH_X diff -r 892d86c1a409 -r c8b6ca46950b examples/calculator/Makefile.am --- a/examples/calculator/Makefile.am Thu Jan 29 23:57:59 2009 +0800 +++ b/examples/calculator/Makefile.am Sat Jan 31 12:29:50 2009 +0800 @@ -5,8 +5,8 @@ calc_SOURCES = main.c nodist_calc_SOURCES = calculator_scr.c calculator_scr.h -calc_CPPFLAGS = @cairo_CFLAGS@ $(INCLUDES) -calc_LDFLAGS = @cairo_LIBS@ +calc_CPPFLAGS = @pangocairo_CFLAGS@ $(INCLUDES) +calc_LDFLAGS = @pangocairo_LIBS@ calc_LDADD = $(top_builddir)/src/libmbfly.la BUILT_SOURCES = calculator_scr.c calculator_scr.h calculator_scr.mb CLEANFILES = calculator_scr.c calculator_scr.h calculator_scr.mb diff -r 892d86c1a409 -r c8b6ca46950b examples/calculator/calculator_scr.svg --- a/examples/calculator/calculator_scr.svg Thu Jan 29 23:57:59 2009 +0800 +++ b/examples/calculator/calculator_scr.svg Sat Jan 31 12:29:50 2009 +0800 @@ -509,9 +509,9 @@ style="font-size:28px;font-style:normal;font-weight:normal;fill:#008000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" x="36.939316" y="61.546173" - id="screen_text_u">0 rt); sprintf(buf, "%d%s", num, suffix); - sh_text_set_text(calc_data->code->screen_text, buf); - rdman_shape_changed(rdman, calc_data->code->screen_text); + sh_text_set_text(calc_data->code->screen_text_u, buf); + rdman_shape_changed(rdman, calc_data->code->screen_text_u); if(op == 'n') sprintf(buf, "None"); diff -r 892d86c1a409 -r c8b6ca46950b examples/drag/Makefile.am --- a/examples/drag/Makefile.am Thu Jan 29 23:57:59 2009 +0800 +++ b/examples/drag/Makefile.am Sat Jan 31 12:29:50 2009 +0800 @@ -5,8 +5,8 @@ ex1_SOURCES = main.c nodist_ex1_SOURCES = menu.c menu.h -ex1_CPPFLAGS = @cairo_CFLAGS@ -I$(top_srcdir) -ex1_LDFLAGS = @cairo_LIBS@ +ex1_CPPFLAGS = @pangocairo_CFLAGS@ -I$(top_srcdir) +ex1_LDFLAGS = @pangocairo_LIBS@ ex1_LDADD = $(top_builddir)/src/libmbfly.la BUILT_SOURCES = menu.c menu.h menu.mb CLEANFILES = menu.c menu.h menu.mb diff -r 892d86c1a409 -r c8b6ca46950b examples/dynamic/Makefile.am --- a/examples/dynamic/Makefile.am Thu Jan 29 23:57:59 2009 +0800 +++ b/examples/dynamic/Makefile.am Sat Jan 31 12:29:50 2009 +0800 @@ -1,57 +1,31 @@ include $(top_srcdir)/config.mk -noinst_PROGRAMS = dynamic hello button.so scene.so -EXTRA_DIST = menu.svg button.svg scene.svg +SUFFIXES=.svg .so + +%.so:%.svg + $(top_srcdir)/tools/svg2code.py $< $<.mb + m4 -I $(top_srcdir)/tools mb_c_source.m4 $<.mb > $(<:.svg=.c) + m4 -I $(top_srcdir)/tools mb_c_header.m4 $<.mb > $(<:.svg=.h) + make $(<:.svg=.o) + gcc -shared -o $@ $(<:.svg=.o) + +noinst_PROGRAMS = dynamic hello list +EXTRA_DIST = menu.svg button.svg dynamic_SOURCES = main.c mbapp.c mbapp.h mbbutton.c mbbutton.h -nodist_dynamic_SOURCES = \ - menu.c menu.h menu.mb \ - button.c button.h button.mb \ - scene.c scene.h scene.mb -CPPFLAGS = @cairo_CFLAGS@ $(INCLUDES) -dynamic_LDFLAGS = @cairo_LIBS@ +nodist_dynamic_SOURCES = +CPPFLAGS = @pangocairo_CFLAGS@ $(INCLUDES) +dynamic_LDFLAGS = @pangocairo_LIBS@ dynamic_LDADD = $(top_builddir)/src/libmbfly.la -BUILT_SOURCES = menu.c menu.h menu.mb button.c button.h button.mb -CLEANFILES = menu.c menu.h menu.mb button.c button.h button.mb +CLEANFILES = menu.c menu.h menu.mb button.c button.o button.mb button.so hello_SOURCES = hello.c mbapp.c mbapp.h -hello_LDFLAGS = @cairo_LIBS@ +hello_LDFLAGS = @pangocairo_LIBS@ hello_LDADD = $(top_builddir)/src/libmbfly.la -menu.mb: $(srcdir)/menu.svg - $(top_srcdir)/tools/svg2code.py $? $@ - -menu.h: menu.mb - m4 -I $(top_srcdir)/tools mb_c_header.m4 $< > $@ - -menu.c: menu.mb - m4 -I $(top_srcdir)/tools mb_c_source.m4 $< > $@ - -button.so: button.o - gcc -shared -o button.so button.o - -button.mb: $(srcdir)/button.svg - $(top_srcdir)/tools/svg2code.py $? $@ - -button.h: button.mb - m4 -I $(top_srcdir)/tools mb_c_header.m4 $< > $@ +list_SOURCES = list.c mbapp.c mbapp.h +list_LDFLAGS = @pangocairo_LIBS@ +list_LDADD = $(top_builddir)/src/libmbfly.la -button.c: button.mb - m4 -I $(top_srcdir)/tools mb_c_source.m4 $< > $@ -button.o: button.h - -scene.so: scene.o - gcc -shared -o scene.so scene.o - -scene.mb: $(srcdir)/scene.svg - $(top_srcdir)/tools/svg2code.py $? $@ - -scene.h: scene.mb - m4 -I $(top_srcdir)/tools mb_c_header.m4 $< > $@ - -scene.c: scene.mb - m4 -I $(top_srcdir)/tools mb_c_source.m4 $< > $@ - -scene.o: scene.h diff -r 892d86c1a409 -r c8b6ca46950b examples/dynamic/button.svg --- a/examples/dynamic/button.svg Thu Jan 29 23:57:59 2009 +0800 +++ b/examples/dynamic/button.svg Sat Jan 31 12:29:50 2009 +0800 @@ -198,6 +198,20 @@ sodipodi:role="line">Click Me + ssssssssss - + inkscape:window-height="721" + inkscape:window-x="130" + inkscape:window-y="120" /> @@ -422,6 +415,7 @@ test + sodipodi:role="line" + style="font-size:28px">test + sodipodi:open="true"/> + transform="translate(0,-17.414248)" /> diff -r 892d86c1a409 -r c8b6ca46950b examples/tank/Makefile.am --- a/examples/tank/Makefile.am Thu Jan 29 23:57:59 2009 +0800 +++ b/examples/tank/Makefile.am Sat Jan 31 12:29:50 2009 +0800 @@ -7,8 +7,8 @@ tank_SOURCES = tank_main.c nodist_tank_SOURCES = svgs.h \ $(svg_sources) $(svg_sources:.c=.h) $(svg_sources:.c=.mb) -tank_CPPFLAGS = @cairo_CFLAGS@ -tank_LDFLAGS = @cairo_LIBS@ +tank_CPPFLAGS = @pangocairo_CFLAGS@ +tank_LDFLAGS = @pangocairo_LIBS@ tank_LDADD = $(top_builddir)/src/libmbfly.la BUILT_SOURCES = svgs.h \ $(svg_sources) $(svg_sources:.c=.h) $(svg_sources:.c=.mb) diff -r 892d86c1a409 -r c8b6ca46950b include/mb_shapes.h --- a/include/mb_shapes.h Thu Jan 29 23:57:59 2009 +0800 +++ b/include/mb_shapes.h Sat Jan 31 12:29:50 2009 +0800 @@ -11,6 +11,7 @@ #include "mb_types.h" #include "mb_redraw_man.h" #include "mb_img_ldr.h" +#include /*! \page define_shape How to Define Shapes * @@ -61,12 +62,97 @@ extern shape_t *rdman_shape_text_new(redraw_man_t *rdman, const char *txt, co_aix x, co_aix y, co_aix font_size, - cairo_font_face_t *face); + cairo_font_face_t *face,PangoAttrList *attrs); extern void sh_text_set_text(shape_t *shape, const char *txt); extern void sh_text_transform(shape_t *shape); extern void sh_text_draw(shape_t *shape, cairo_t *cr); /* @} */ +/*! \defgroup mb_text_t Shape of Text + * @{ + */ +#define TEXTSTYLE_BOLD 1 +#define TEXTSTYLE_ITALIC 2 +#define TEXTSTYLE_UNDERLINE 4 +#define TEXTSTYLE_COLOR 8 +#define TEXTSTYLE_FONT 0x10 +#define TEXTSTYLE_ALIGN 0x20 + +typedef struct { + int property; + unsigned int color; + unsigned int align; + char *font; +} mb_textstyle_t; + +typedef struct _textsegment { + int x; + int y; + mb_textstyle_t style; + int size; + char *buf; + struct _textsegment *next; +} mb_text_segment_t; + +#define MBTEXT_DIRTY 1 + +typedef struct { + int nseg; + mb_text_segment_t *segs; + int flag; + cairo_surface_t *surface; +} mb_text_t; + +extern void mb_textstyle_init(mb_textstyle_t *style); +extern void mb_textstyle_set_font(mb_textstyle_t *style, char *font); +static inline char *mb_textstyle_get_font(mb_textstyle_t *style) +{ + if (style->property & TEXTSTYLE_FONT) + return style->font; + else + return NULL; +} +extern void mb_textstyle_set_bold(mb_textstyle_t *style, int bold); +static inline int mb_textstyle_get_bold(mb_textstyle_t *style) +{ + return style->property & TEXTSTYLE_BOLD; +} +extern void mb_textstyle_set_italic(mb_textstyle_t *style, int italic); +static inline int mb_textstyle_get_italic(mb_textstyle_t *style) +{ + return style->property & TEXTSTYLE_ITALIC; +} +extern void mb_textstyle_set_underline(mb_textstyle_t *style, int underline); +static inline int mb_textstyle_get_undeline(mb_textstyle_t *style) +{ + return style->property & TEXTSTYLE_UNDERLINE; +} +extern void mb_textstyle_set_color(mb_textstyle_t *style, unsigned int color); +static inline unsigned int mb_textstyle_get_color(mb_textstyle_t *style) +{ + if (style->property & TEXTSTYLE_COLOR) + return style->color; + else + return 0; +} + +static inline int mb_textstyle_has_color(mb_textstyle_t *style) +{ + return style->property & TEXTSTYLE_COLOR; +} +extern void mb_textstyle_set_alignment(mb_textstyle_t *style, int alignment); +extern int mb_textstyle_get_alignment(mb_textstyle_t *style); + + + +extern void mb_text_set_style(mb_text_t *text, int begin,int end,mb_textstyle_t *style); +extern void mb_text_get_style(mb_text_t *text, int n,mb_textstyle_t *style); +extern void mb_text_set_text(mb_text_t *text, char *string,int begin,int end); +extern void mb_text_get_text(mb_text_t *text, int begin,int end, char *string); + + +/* @} */ + /*! \defgroup shape_rect Shape of Rectangle * @{ */ diff -r 892d86c1a409 -r c8b6ca46950b inkscape/AssignSymbol.py --- a/inkscape/AssignSymbol.py Thu Jan 29 23:57:59 2009 +0800 +++ b/inkscape/AssignSymbol.py Sat Jan 31 12:29:50 2009 +0800 @@ -46,9 +46,6 @@ return for id,node in self.selected.iteritems(): #self.dump(node) - if node.tag != '{http://www.w3.org/2000/svg}g': - self.confirm('Only group element can be converted into a symbol') - return self.node = node vbox = gtk.VBox() vbox.pack_start(gtk.Label('Please input the symbol name')) diff -r 892d86c1a409 -r c8b6ca46950b inkscape/MB_Frame.py --- a/inkscape/MB_Frame.py Thu Jan 29 23:57:59 2009 +0800 +++ b/inkscape/MB_Frame.py Sat Jan 31 12:29:50 2009 +0800 @@ -494,7 +494,7 @@ def effect(self): - self.OK = False + self.OK = True self.parseScene() self.showGrid() self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) diff -r 892d86c1a409 -r c8b6ca46950b inkscape/Makefile.am --- a/inkscape/Makefile.am Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -extdir=$(datadir)/inkscape/extenstions -ext_py=AssignSymbol.py MB_EditButton.py MB_Frame.py -ext_DATA=$(ext_py) MB_EditButton.inx MB_Frame.inx MB_assignSymbol.inx mbtest.svg - -install-data-hook: - for file in $(ext_py); do cd "$(DESTDIR)$(extdir)"; tgt=$${file#inkscape/}; chmod +x $${tgt}; done - -EXTRA_DIST=$(ext_DATA) diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/MBFilter.inx --- a/inkscape/firefox/MBFilter.inx Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,17 +0,0 @@ - - MadServer - net.sourceforge.madbutterfly.filter.update - MBServer.py - inkex.py - - any - - - - - - - - diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/MBServer.py --- a/inkscape/firefox/MBServer.py Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,484 +0,0 @@ -#!/usr/bin/python -import inkex -import pygtk -import gtk -from copy import deepcopy -from lxml import etree -from twisted.web import server, resource,soap -from twisted.internet import reactor -import traceback - -import random - -# Please refer to http://www.assembla.com/wiki/show/MadButterfly/Inkscape_extention for the designed document. - - -# Algorithm: -# -# We will parse the first two level of the SVG DOM. collect a table of layer and scene. -# 1. Collect the layer table which will be displayed as the first column of the grid. -# 2. Get the maximum scene number. This will decide the size of the grid. -# 3. When F6 is pressed, we will check if this scene has been defined. This can be done by scan all second level group and check if the current scene number is within the -# range specified by scene field. The function IsSceneDefined(scene) can be used for this purpose. -# 4. If this is a new scene, we will append a new group which duplication the content of the last scene in the same group. The scene field will contain the number from the -# last scene number of the last scene to the current scenen number. For example, if the last scene is from 4-7 and the new scene is 10, we will set the scene field as -# "8-10". -# 5. If this scene are filled screne, we will split the existing scene into two scenes with the same content. - -class Layer: - def __init__(self,node): - self.scene = [] - self.node = node - self.nodes=[] -class Scene: - def __init__(self, node, start,end): - self.node = node - self.start = int(start) - self.end = int(end) - - -class MBScene(inkex.Effect): - def confirm(self,msg): - vbox = gtk.VBox() - vbox.pack_start(gtk.Label(msg)) - self.button = gtk.Button('OK') - vbox.pack_start(self.button) - self.button.connect("clicked", self.onQuit) - self.window.add(vbox) - def dumpattr(self,n): - s = "" - for a,v in n.attrib.items(): - s = s + ("%s=%s" % (a,v)) - return s - - def dump(self,node,l=0): - print " " * l*2,"<", node.tag, self.dumpattr(node),">" - for n in node: - self.dump(n,l+1) - print " " * l * 2,"/>" - def parseMetadata(self,node): - self.current = 1 - for n in node: - if n.tag == '{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scenes': - self.scenemap={} - cur = int(n.get("current")) - self.current = cur - - for s in n: - if s.tag == '{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scene': - try: - start = int(s.get("start")) - except: - continue - try: - end = s.get("end") - if end == None: - end = start - except: - end = start - link = s.get("ref") - self.scenemap[link] = [int(start),int(end)] - if cur >= start and cur <= end: - self.currentscene = link - - pass - pass - pass - pass - - - def parseScene(self): - """ - In this function, we will collect all items for the current scene and then relocate them back to the appropriate scene object. - """ - self.layer = [] - self.scenemap = None - for node in self.document.getroot(): - if node.tag == '{http://www.w3.org/2000/svg}metadata': - self.parseMetadata(node) - elif node.tag == '{http://www.w3.org/2000/svg}g': - oldscene = None - #print layer.attrib.get("id") - lyobj = Layer(node) - self.layer.append(lyobj) - lyobj.current_scene = [] - for scene in node: - if scene.tag == '{http://www.w3.org/2000/svg}g': - try: - scmap = self.scenemap[scene.get("id")] - if scmap == None: - lyobj.current_scene.append(scene) - continue - if self.current <= scmap[1] and self.current >= scmap[0]: - oldscene = scene - except: - lyobj.current_scene.append(scene) - continue - - lyobj.scene.append(Scene(scene,scmap[0],scmap[1])) - else: - lyobj.current_scene.append(scene) - pass - pass - - if oldscene != None: - # Put the objects back to the current scene - for o in lyobj.current_scene: - #print o.tag - oldscene.append(o) - pass - pass - pass - pass - - self.collectID() - #self.dumpID() - def collectID(self): - self.ID = {} - root = self.document.getroot() - for n in root: - self.collectID_recursive(n) - def collectID_recursive(self,node): - self.ID[node.get("id")] = 1 - for n in node: - self.collectID_recursive(n) - def newID(self): - while True: - n = 's%d' % int(random.random()*10000) - #print "try %s" % n - if self.ID.has_key(n) == False: - return n - def dumpID(self): - for a,v in self.ID.items(): - print a - - - def getLayer(self, layer): - for l in self.layer: - if l.node.attrib.get("id") == layer: - return l - return None - - - def insertKeyScene(self,layer,nth): - """ - Insert a new key scene into the stage. If the nth is always a key scene, we will return without changing anything. - If the nth is a filled scene, we will break the original scene into two parts. If the nth is out of any scene, we will - append a new scene. - - """ - if layer == None: return - - # Check if the nth is in the middle of any scene - for i in range(0,len(layer.scene)): - s = layer.scene[i] - if nth >= s.start and nth <= s.end: - if nth == s.start: return - newscene = Scene(deepcopy(s.node),nth,s.end) - newscene.node.set("id", self.newID()) - layer.scene.insert(i+1,newscene) - layer.scene[i].end = nth-1 - return - if len(layer.scene) > 0: - # extend the last scene befor eit automatically - last = nth - lastscene = None - # Find the last scene before it - for s in layer.scene: - if s.end < nth and last < s.end: - last = s.end - lastscene = s - if lastscene == None: - node = etree.Element('{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scene') - node.set("id", self.newID()) - newscene = Scene(node,nth,nth) - else: - lastscene.end = nth-1 - newscene = Scene(deepcopy(lastscene.node),nth,nth) - newscene.node.set("id",self.newID()) - layer.scene.append(newscene) - else: - # This is the first scene in the layer - node = etree.Element('{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scene') - node.set("id", self.newID()) - newscene = Scene(node,nth,nth) - layer.scene.append(newscene) - - - def deleteScene(self,layer,nth): - for i in range(0,len(layer.scene)): - s = layer.scene[i] - if nth == s.start: - if i == 0: - layer.scene.remove(s) - else: - if s.start == layer.scene[i-1].end+1: - # If the start of the delete scene segment is the end of the last scene segmenet, convert all scenes in the deleted - # scene segmenet to the last one - layer.scene[i-1].end = s.end - layer.scene.remove(s) - else: - # Convert all scenes into empty cell - layer.scene.remove(s) - - return - pass - pass - - - def extendScene(self,layer,nth): - if layer == None: return - - for i in range(0,len(layer.scene)-1): - s = layer.scene[i] - if nth >= layer.scene[i].start and nth <= layer.scene[i].end: - return - - for i in range(0,len(layer.scene)-1): - s = layer.scene[i] - if nth >= layer.scene[i].start and nth < layer.scene[i+1].start: - layer.scene[i].end = nth - return - if len(layer.scene) > 0 and nth > layer.scene[len(layer.scene)-1].end: - layer.scene[len(layer.scene)-1].end = nth - - def setCurrentScene(self,nth): - self.current = nth - for layer in self.layer: - for s in layer.scene: - if nth >= s.start and nth <= s.end: - s.node.set("style","") - #print "Put the elemenets out" - layer.nodes = [] - - for o in s.node: - #print " ",o.tag - layer.nodes.append(o) - for o in s.node: - s.node.remove(o) - else: - s.node.set("style","display:none") - def generate(self): - newdoc = deepcopy(self.document) - root = newdoc.getroot() - has_scene = False - for n in root: - if n.tag == '{http://www.w3.org/2000/svg}metadata': - for nn in n: - if nn.tag == '{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scenes': - nn.clear() - nn.set("current", "%d" % self.current) - scenes = [] - for l in self.layer: - for s in l.scene: - id = s.node.get("id") - scene = etree.Element('{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scene') - scene.set("ref", id) - if s.start == s.end: - scene.set("start", "%d" % s.start) - else: - scene.set("start", "%d" % s.start) - scene.set("end", "%d" % s.end) - - scenes.append(scene) - for s in scenes: - nn.append(s) - has_scene = True - if has_scene == False: - scenes = etree.Element('{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scenes') - scenes.set("current","%d" % self.current) - for l in self.layer: - for s in l.scene: - scene = etree.Element('{http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd}scene') - scene.set("ref", s.node.get("id")) - if s.start == s.end: - scene.set("start", "%d" % s.start) - else: - scene.set("start", "%d" % s.start) - scene.set("end", "%d" % s.end) - scenes.append(scene) - n.append(scenes) - if n.tag == '{http://www.w3.org/2000/svg}g': - root.remove(n) - - for l in self.layer: - # Duplicate all attribute of the layer - lnode = etree.Element("{http://www.w3.org/2000/svg}g") - for a,v in l.node.attrib.items(): - lnode.set(a,v) - for n in l.nodes: - lnode.append(n) - root.append(lnode) - for s in l.scene: - snode = etree.Element("{http://www.w3.org/2000/svg}g") - for a,v in s.node.attrib.items(): - snode.set(a,v) - for n in s.node: - snode.append(deepcopy(n)) - lnode.append(snode) - self.document = newdoc - def newCell(self,file): - img = gtk.Image() - img.set_from_file(file) - btn = gtk.EventBox() - btn.add(img) - btn.connect("button_press_event", self.cellSelect) - btn.modify_bg(gtk.STATE_NORMAL, btn.get_colormap().alloc_color("gray")) - return btn - def showGrid(self): - max = 0 - for layer in self.layer: - for s in layer.scene: - if s.end > max: - max = s.end - max = 50 - - self.grid = gtk.Table(len(self.layer)+1, 50) - self.scrollwin = gtk.ScrolledWindow() - self.scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - self.scrollwin.add_with_viewport(self.grid) - for i in range(1,max): - self.grid.attach(gtk.Label('%d'% i), i,i+1,0,1,0,0,0,0) - for i in range(1,len(self.layer)+1): - l = self.layer[i-1] - self.grid.attach(gtk.Label(l.node.get('{http://www.inkscape.org/namespaces/inkscape}label')), 0, 1, i, i+1,0,0,10,0) - for s in l.scene: - btn = self.newCell('start.png') - btn.nScene = s.start - btn.layer = l.node.get('id') - btn.nLayer = i - - self.grid.attach(btn, s.start, s.start+1, i, i+1,0,0,0,0) - for j in range(s.start+1,s.end+1): - btn = self.newCell('fill.png') - self.grid.attach(btn, j, j+1, i , i+1,0,0,0,0) - btn.modify_bg(gtk.STATE_NORMAL, btn.get_colormap().alloc_color("gray")) - btn.nScene = j - btn.layer = l.node.get('id') - btn.nLayer = i - if len(l.scene) == 0: - start = 0 - else: - start = l.scene[len(l.scene)-1].end - for j in range(start,max): - btn = self.newCell('empty.png') - self.grid.attach(btn, j+1, j+2,i,i+1,0,0,0,0) - btn.modify_bg(gtk.STATE_NORMAL, btn.get_colormap().alloc_color("gray")) - btn.nScene = j+1 - btn.layer = l.node.get('id') - btn.nLayer = i - self.last_cell = None - def cellSelect(self, cell, data): - if self.last_cell: - self.last_cell.modify_bg(gtk.STATE_NORMAL, self.last_cell.get_colormap().alloc_color("gray")) - - self.last_cell = cell - cell.modify_bg(gtk.STATE_NORMAL, cell.get_colormap().alloc_color("green")) - - def doEditScene(self,w): - self.setCurrentScene(self.last_cell.nScene) - self.generate() - gtk.main_quit() - - def doRemoveScene(self,w): - self.removeKeyScene() - self.grid.show_all() - self.generate() - def addButtons(self,hbox): - btn = gtk.Button('Edit') - btn.connect('clicked', self.doEditScene) - hbox.pack_start(btn) - btn = gtk.Button('Insert Key') - btn.connect('clicked',self.doInsertKeyScene) - hbox.pack_start(btn) - btn=gtk.Button('Remove Key') - btn.connect('clicked', self.doRemoveScene) - hbox.pack_start(btn) - btn=gtk.Button('Extend scene') - btn.connect('clicked', self.doExtendScene) - hbox.pack_start(btn) - def onQuit(self, event): - self.OK = False - gtk.main_quit() - def onOK(self,event): - self.OK = True - gtk.main_quit() - - def onConfirmDelete(self): - if self.scenemap == None: - vbox = gtk.VBox() - vbox.pack_start(gtk.Label('Convert the SVG into a MadButterfly SVG file. All current element will be delted')) - hbox = gtk.HBox() - self.button = gtk.Button('OK') - hbox.pack_start(self.button) - self.button.connect('clicked', self.onOK) - self.button = gtk.Button('Cancel') - hbox.pack_start(self.button) - self.button.connect("clicked", self.onQuit) - vbox.pack_start(hbox) - self.window.add(vbox) - self.window.show_all() - gtk.main() - self.window.remove(vbox) - - def start_server(self): - root = MB() - root.target = self - site = server.Site(root) - reactor.listenTCP(8080, site) - reactor.run() - - - def effect(self): - self.OK = False - self.parseScene() - self.start_server() - self.generate() - -class MB(soap.SOAPPublisher): - """ - SOAP server for inkscape extension. - """ - - def soap_PUBLISH(self): - reactor.callLater(1,self.quit) - return "OK" - def quit(self): - reactor.stop() - def soap_SCENE(self,n): - self.target.setCurrentScene(int(n)) - return "OK" - def soap_INSERTKEY(self,layer,n): - try: - layer = self.target.getLayer(layer) - self.target.insertKeyScene(layer,int(n)) - return "OK" - except: - return traceback.format_exc() - def soap_EXTENDSCENE(self,layer,n): - try: - layer = self.target.getLayer(layer) - self.target.extendScene(layer,int(n)) - return "OK" - except: - return traceback.format_exc() - def soap_DELETESCENE(self,layer,n): - try: - layer = self.target.getLayer(layer) - self.target.deleteScene(layer,int(n)) - return "OK" - except: - return traceback.format_exc() - def soap_GETDOC(self): - try: - self.target.generate() - return etree.tostring(self.target.document) - except: - return traceback.format_exc() -import os -os.chdir('/usr/share/inkscape/extensions') - -A = MBScene() -A.affect() - - diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/README --- a/inkscape/firefox/README Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -How to execute the unit test -====================================== - -(1) Execute the proxy damon - -First of all, we need to execute the MadButterfly helper. This help will start the inkscape and then execute a SOAP proxy to wait for the commands from the web client. - -# python helper_mb.py - - -(2) Use testsoap.py to send command to helper. - -# python testsoap.py START -# python testsoap.py SCENE 1 -# python testsoap.py PUBLISH - - - diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/active-empty.png Binary file inkscape/firefox/active-empty.png has changed diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/active-empty.svg --- a/inkscape/firefox/active-empty.svg Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ - - - - - - - - - - - image/svg+xml - - - - - - - - diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/active-fill.png Binary file inkscape/firefox/active-fill.png has changed diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/active-fill.svg --- a/inkscape/firefox/active-fill.svg Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ - - - - - - - - - - - image/svg+xml - - - - - - - - - diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/active-start.png Binary file inkscape/firefox/active-start.png has changed diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/active-start.svg --- a/inkscape/firefox/active-start.svg Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/empty.png Binary file inkscape/firefox/empty.png has changed diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/empty.svg --- a/inkscape/firefox/empty.svg Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ - - - - - - - - - - - image/svg+xml - - - - - - - - diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/fill.png Binary file inkscape/firefox/fill.png has changed diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/fill.svg --- a/inkscape/firefox/fill.svg Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ - - - - - - - - - - - image/svg+xml - - - - - - - - - diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/helper_mb.py --- a/inkscape/firefox/helper_mb.py Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -#!/usr/bin/python -from twisted.web import server, resource,soap -from twisted.internet import reactor,defer -import os,time -import traceback - - - - -class Server(soap.SOAPPublisher): - """ - SOAP server for inkscape extension. - """ - def soap_PUBLISH(self): - if self.client == None: - os.kill(self.pid,12) - time.sleep(1) - self.client = Client() - d = defer.Deferred() - self.client.PUBLISH().addCallback(self.quit,d) - return d - - def quit(self,result,d): - print [result] - d.callback(result) - self.client = None - def soap_INSERTKEY(self,layer,n): - if self.client == None: - os.kill(self.pid,12) - time.sleep(1) - self.client = Client() - try: - n = int(n) - except: - n = 0 - d = defer.Deferred() - self.client.INSERTKEY(layer,n).addCallback(self.generic_return,d).addErrback(self.generic_error,d) - return d - def soap_EXTENDSCENE(self,layer,n): - if self.client == None: - os.kill(self.pid,12) - time.sleep(1) - self.client = Client() - try: - n = int(n) - except: - n = 0 - d = defer.Deferred() - self.client.EXTENDSCENE(layer,n).addCallback(self.generic_return,d).addErrback(self.generic_error,d) - return d - def soap_DELETESCENE(self,layer,n): - if self.client == None: - os.kill(self.pid,12) - time.sleep(1) - self.client = Client() - try: - n = int(n) - except: - n = 0 - d = defer.Deferred() - self.client.DELETESCENE(layer,n).addCallback(self.generic_return,d).addErrback(self.generic_error,d) - return d - - def soap_SCENE(self,n): - if self.client == None: - os.kill(self.pid,12) - time.sleep(1) - self.client = Client() - - d = defer.Deferred() - self.client.SCENE(n).addCallback(self.generic_return,d) - return d - def generic_return(self,result,d): - print [result] - d.callback(result) - def generic_error(self,result,d): - print [result] - d.errback(result) - def soap_START(self): - if self.client == None: - os.kill(self.pid,12) - time.sleep(1) - self.client = Client() - return "OK" - def soap_GETDOC(self): - try: - print "xxxxx" - if self.client == None: - os.kill(self.pid,12) - time.sleep(1) - self.client = Client() - d = defer.Deferred() - self.client.GETDOC().addCallback(self.generic_return,d) - print "yyy" - return d - except: - traceback.print_exc() - - - - -class Client(object): - def __init__(self): - self.proxy = soap.Proxy('http://localhost:8080') - def PUBLISH(self): - return self.proxy.callRemote('PUBLISH') - def SCENE(self,n): - return self.proxy.callRemote('SCENE',n) - def INSERTKEY(self,layer,n): - return self.proxy.callRemote('INSERTKEY',layer,n) - def GETDOC(self): - return self.proxy.callRemote('GETDOC') - def EXTENDSCENE(self,layer,n): - return self.proxy.callRemote('EXTENDSCENE',layer,n) - def DELETESCENE(self,layer,n): - return self.proxy.callRemote('DELETESCENE',layer,n) - -os.system("killall -9 inkscape-mb") -pid = os.fork() -if pid==0: - os.execvp("inkscape-mb",["inkscape-mb","/tmp/scene.mbsvg"]) -s = Server() -s.client = None -s.pid = pid -site = server.Site(s) -reactor.listenTCP(19192,site) -reactor.run() - - diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/inkscape.js --- a/inkscape/firefox/inkscape.js Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,394 +0,0 @@ -var isInProgress=0; - -var MAX_DUMP_DEPTH = 10; -var inkscape; - - - -function dumpObj(obj, name, indent, depth) { - if (depth > MAX_DUMP_DEPTH) { - return indent + name + ": \n"; - } - if (typeof obj == "object") { - var child = null; - var output = indent + name + "\n"; - indent += "\t"; - for (var item in obj) - { - try { - child = obj[item]; - } catch (e) { - child = ""; - } - if (typeof child == "object") { - output += dumpObj(child, item, indent, depth + 1); - } else { - output += indent + item + ": " + child + "\n"; - } - } - return output; - } else { - return obj; - } -} -function dumpObjItem(obj, name, indent, depth) { - if (depth > MAX_DUMP_DEPTH) { - return indent + name + ": \n"; - } - if (typeof obj == "object") { - var child = null; - var output = indent + name + "\n"; - indent += "\t"; - for (var item in obj) - { - try { - child = obj[item]; - } catch (e) { - child = ""; - } - if (typeof child == "object") { - output += dumpObjItem(child, item, indent, depth + 1); - } else { - output += indent + item + ":\n"; - } - } - return output; - } else { - return obj; - } -} -/** - * Inkscape class - * - */ -function Inkscape(file) -{ - var ink = document.getElementById('inkscape'); - ink.innerHTML = ""; - this.isInProgress = 0; - - setTimeout("inkscape.fetchDocument()",4000); -} - -Inkscape.prototype.gotoScene = function (n) -{ - nextScene = n; - var soapBody = new SOAPObject("START"); - var sr = new SOAPRequest("START", soapBody); - SOAPClient.Proxy = "http://localhost:19192/"; - SOAPClient.SendRequest(sr, function (resp,arg) {arg.gotoScene1(resp);},this); - this.isInProgress++; -} -Inkscape.prototype.gotoScene1 = function (resp,n) -{ - var soapBody = new SOAPObject("SCENE"); - var v1 = new SOAPObject("v1"); - v1.val(nextScene); - soapBody.appendChild(v1); - var sr = new SOAPRequest("SCENE", soapBody); - SOAPClient.Proxy = "http://localhost:19192/"; - SOAPClient.SendRequest(sr, function (resp,arg) {arg.gotoScene2(resp);},this); -} -Inkscape.prototype.gotoScene2 = function (resp) -{ - var soapBody = new SOAPObject("PUBLISH"); - var sr = new SOAPRequest("PUBLISH", soapBody); - SOAPClient.Proxy = "http://localhost:19192/"; - SOAPClient.SendRequest(sr, function (resp,arg) {arg.gotoScene3(resp);},this); -} - -Inkscape.prototype.gotoScene3 = function (resp) -{ - this.isInProgress--; -} -Inkscape.prototype.publishDocument= function(resp) -{ - mbsvg = new MBSVGString(resp.Body[0].GETDOCResponse[0].Result[0].Text); - mbsvg.renderUI(); - - var soapBody = new SOAPObject("PUBLISH"); - var sr = new SOAPRequest("PUBLISH", soapBody); - SOAPClient.Proxy = "http://localhost:19192/"; - SOAPClient.SendRequest(sr, function(resp,arg) {arg.operationDone(resp);},this); -} - -Inkscape.prototype.refreshDocument = function(resp) -{ - var soapBody = new SOAPObject("GETDOC"); - var sr = new SOAPRequest("GETDOC", soapBody); - SOAPClient.Proxy = "http://localhost:19192/"; - SOAPClient.SendRequest(sr, function(resp,arg) { arg.publishDocument(resp);},this); -} - -Inkscape.prototype.operationDone = function (res) -{ - this.isInProgress--; -} -Inkscape.prototype.insertKey= function(n) -{ - nextScene = n; - var soapBody = new SOAPObject("START"); - var sr = new SOAPRequest("START", soapBody); - SOAPClient.Proxy = "http://localhost:19192/"; - SOAPClient.SendRequest(sr, function (resp,arg) {arg.insertKey1(resp);},this); - this.isInProgress++; -} -Inkscape.prototype.insertKey1 = function(resp) -{ - var soapBody = new SOAPObject("INSERTKEY"); - var v1 = new SOAPObject("v1"); - v1.attr('type','string'); - v1.val(currentLayer); - soapBody.appendChild(v1); - var v2 = new SOAPObject("v2"); - v2.val(nextScene); - soapBody.appendChild(v2); - var sr = new SOAPRequest("INSERTKEY", soapBody); - SOAPClient.Proxy = "http://localhost:19192/"; - SOAPClient.SendRequest(sr, function (resp,arg) {arg.refreshDocument(resp);},this); -} - -Inkscape.prototype.extendScene=function() -{ - var soapBody = new SOAPObject("START"); - var sr = new SOAPRequest("START", soapBody); - SOAPClient.Proxy = "http://localhost:19192/"; - SOAPClient.SendRequest(sr, function (resp,arg) {arg.extendScene1(resp);},this); - this.isInProgress++; -} - - -Inkscape.prototype.extendScene1 = function(resp) -{ - var soapBody = new SOAPObject("EXTENDSCENE"); - var v1 = new SOAPObject("v1"); - v1.attr('type','string'); - v1.val(currentLayer); - soapBody.appendChild(v1); - var v2 = new SOAPObject("v2"); - v2.val(currentScene); - soapBody.appendChild(v2); - var sr = new SOAPRequest("EXTENDSCENE", soapBody); - SOAPClient.Proxy = "http://localhost:19192/"; - SOAPClient.SendRequest(sr, function (resp,arg) {arg.refreshDocument(resp);},this); -} - - -Inkscape.prototype.deleteScene=function() -{ - var soapBody = new SOAPObject("START"); - var sr = new SOAPRequest("START", soapBody); - SOAPClient.Proxy = "http://localhost:19192/"; - SOAPClient.SendRequest(sr, function (resp,arg) {arg.deleteScene1(resp);},this); - this.isInProgress++; -} - -Inkscape.prototype.deleteScene1=function(resp) -{ - var soapBody = new SOAPObject("DELETESCENE"); - var v1 = new SOAPObject("v1"); - v1.attr('type','string'); - v1.val(currentLayer); - soapBody.appendChild(v1); - var v2 = new SOAPObject("v2"); - v2.val(currentScene); - soapBody.appendChild(v2); - var sr = new SOAPRequest("EXTENDSCENE", soapBody); - SOAPClient.Proxy = "http://localhost:19192/"; - SOAPClient.SendRequest(sr, function (resp,arg) {arg.refreshDocument(resp);},this); -} - -Inkscape.prototype.fetchDocument = function() -{ - var soapBody = new SOAPObject("START"); - var sr = new SOAPRequest("START", soapBody); - SOAPClient.Proxy = "http://localhost:19192/"; - SOAPClient.SendRequest(sr,function(resp,arg) {arg.refreshDocument(resp);},this); - this.isInProgress++; -} - - - -function MBSVG(file) -{ - var xmlDoc=document.implementation.createDocument("http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd","",null); - xmlDoc.async=false; - xmlDoc.load(file); - MBSVG_loadFromDoc(this,xmlDoc); - -} -function MBSVGString(xml) -{ - var xmlParser = new DOMParser(); - var xmlDoc = xmlParser.parseFromString( xml, 'text/xml'); - MBSVG_loadFromDoc(this,xmlDoc); -} - - - -function MBSVG_loadFromDoc(self,xmlDoc) -{ - var scenesNode = xmlDoc.getElementsByTagNameNS("http://madbutterfly.sourceforge.net/DTD/madbutterfly.dtd","scene"); - if (scenesNode == null) { - alert('This is not a valid scene file'); - } - var len = scenesNode.length; - var i,j; - var max = 0; - var scenes = new Array(); - - // Get the length of scenes - for(i=0;i"; - for(var j=1;j<=max;j++) - cmd = cmd + ""+j+""; - - for(var i=layers.length-1;i>=0;i--) { - var l = layers[i]; - var id = l.getAttribute('id'); - var label = l.getAttribute('inkscape:label'); - cmd = cmd + ""+label+""; - for(j=0;j"; - empty = 0; - break; - } else if ((n>scenes[k].start)&&(n <= scenes[k].end)) { - cmd = cmd + ""; - empty = 0; - break; - } - } - if (empty) { - cmd = cmd + ""; - } - - } - cmd = cmd + "\n"; - } - cmd = cmd + "\n"; - var frame = document.getElementById('frame'); - frame.innerHTML=cmd; -} - - - -/** - * UI for madbuilder.html to build the scene editor - */ - -function selectCell(obj) -{ - var id = obj.getAttribute('id'); - var layer,n; - var f = id.split('#'); - layer=f[0]; - n = f[1]; - var img = obj.getAttribute('src'); - var f = img.split('-'); - - if (f[0] == 'active') - return; - else { - obj.setAttribute('src', 'active-'+img); - } - - if (last_select != null) { - f = last_select.getAttribute('src').split('-'); - last_select.setAttribute('src', f[1]); - } - last_select = obj; - currentScene = n; - currentLayer = layer; -} - - -function onButtonClick(obj) -{ - if (inkscape.isInProgress != 0) return; - var id = obj.getAttribute('id'); - if (id == 'Jump') { - if (currentScene != 0) - inkscape.gotoScene(currentScene); - } else if (id == 'InsertKey') { - inkscape.insertKey(currentScene); - } else if (id == 'ExtendScene') { - inkscape.extendScene(currentScene); - } else if (id == 'DeleteScene') { - inkscape.deleteScene(currentScene); - } else { - alert(id+' has not been implemented yet'); - } -} - -function gotoScene_cb(resObj) -{ - -} -var nextScene; -var currentScene = 0; -var currentLayer = ''; - -var last_select = null; -inkscape = new Inkscape("scene.mbsvg"); - -$('a.button').mouseover(function () { - if (inkscape.isInProgress==0) - this.style.MozOpacity = 0.1; - }).mouseout(function () { - this.style.MozOpacity= 1; - }); - diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/install.sh --- a/inkscape/firefox/install.sh Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -#!/bin/sh -cp inkscape.js madbuilder.html *.png jq*.js /home/wycc/.mozilla/firefox/tmkakd0b.devel/extensions/madswatter@madswatter.branda.to/content/ -cp MBServer.py /usr/local/share/inkscape/extensions -cp helper_mb.py /usr/bin diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/jqSOAPClient.js --- a/inkscape/firefox/jqSOAPClient.js Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,159 +0,0 @@ -/* - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ -//Singleton SOAP Client -var SOAPClient = { - Proxy: "", - SOAPServer: "", - ContentType: "text/xml", - CharSet: "utf-8", - ResponseXML: null, - ResponseText: "", - Status: 0, - ContentLength: 0, - Namespace: function(name, uri) { - return {"name":name, "uri":uri}; - }, - SendRequest: function(soapReq, callback,arg) { - if(!!SOAPClient.Proxy) { - SOAPClient.ResponseText = ""; - SOAPClient.ResponseXML = null; - SOAPClient.Status = 0; - - var content = soapReq.toString(); - SOAPClient.ContentLength = content.length; - - function getResponse(xData) { - if(!!callback) { - SOAPClient.Status = xData.status; - SOAPClient.ResponseText = xData.responseText; - SOAPClient.ResponseXML = xData.responseXML; - var jsOut = $.xmlToJSON(xData.responseXML); - callback(jsOut,arg); - } - } - $.ajax({ - type: "POST", - url: SOAPClient.Proxy, - dataType: "xml", - processData: false, - data: content, - complete: getResponse, - contentType: SOAPClient.ContentType + "; charset=\"" + SOAPClient.CharSet + "\"", - beforeSend: function(req) { - req.setRequestHeader("Method", "POST"); - req.setRequestHeader("Content-Length", SOAPClient.ContentLength); - req.setRequestHeader("SOAPServer", SOAPClient.SOAPServer); - req.setRequestHeader("SOAPAction", soapReq.Action); - } - }); - } - }, - ToXML: function(soapObj) { - var out = []; - var isNSObj=false; - try { - if(!!soapObj&&typeof(soapObj)==="object"&&soapObj.typeOf==="SOAPObject") { - //Namespaces - if(!!soapObj.ns) { - if(typeof(soapObj.ns)==="object") { - isNSObj=true; - out.push("<"+soapObj.ns.name+":"+soapObj.name); - out.push(" xmlns:"+soapObj.ns.name+"=\""+soapObj.ns.uri+"\""); - } else { - out.push("<"+soapObj.name); - out.push(" xmlns=\""+soapObj.ns+"\""); - } - } else { - out.push("<"+soapObj.name); - } - //Node Attributes - if(soapObj.attributes.length > 0) { - var cAttr; - var aLen=soapObj.attributes.length-1; - do { - cAttr=soapObj.attributes[aLen]; - if(isNSObj) { - out.push(" "+soapObj.ns.name+":"+cAttr.name+"=\""+cAttr.value+"\""); - } else { - out.push(" "+cAttr.name+"=\""+cAttr.value+"\""); - } - } while(aLen--); - } - out.push(">"); - //Node children - if(soapObj.hasChildren()) { - var cPos, cObj; - for(cPos in soapObj.children){ - cObj = soapObj.children[cPos]; - if(typeof(cObj)==="object"){out.push(SOAPClient.ToXML(cObj));} - } - } - //Node Value - if(!!soapObj.value){out.push(soapObj.value);} - //Close Tag - if(isNSObj){out.push("");} - else {out.push("");} - return out.join(""); - } - } catch(e){alert("Unable to process SOAPObject! Object must be an instance of SOAPObject");} - } -}; -//Soap request - this is what being sent using SOAPClient.SendRequest -var SOAPRequest=function(action, soapObj) { - this.Action=action; - var nss=[]; - var headers=[]; - var bodies=(!!soapObj)?[soapObj]:[]; - this.addNamespace=function(ns, uri){nss.push(new SOAPClient.Namespace(ns, uri));}; - this.addHeader=function(soapObj){headers.push(soapObj);}; - this.addBody=function(soapObj){bodies.push(soapObj);}; - this.toString=function() { - var soapEnv = new SOAPObject("soapenv:Envelope"); - soapEnv.attr("xmlns:soapenv","http://schemas.xmlsoap.org/soap/envelope/"); - //Add Namespace(s) - if(nss.length>0){ - var tNs, tNo; - for(tNs in nss){if(!nss.hasOwnProperty || nss.hasOwnProperty(tNs)){tNo=nss[tNs];if(typeof(tNo)==="object"){soapEnv.attr("xmlns:"+tNo.name, tNo.uri);}}} - } - //Add Header(s) - if(headers.length>0) { - var soapHeader = soapEnv.appendChild(new SOAPObject("soapenv:Header")); - var tHdr; - for(tHdr in headers){if(!headers.hasOwnProperty || headers.hasOwnProperty(tHdr)){soapHeader.appendChild(headers[tHdr]);}} - } - //Add Body(s) - if(bodies.length>0) { - var soapBody = soapEnv.appendChild(new SOAPObject("soapenv:Body")); - var tBdy; - for(tBdy in bodies){if(!bodies.hasOwnProperty || bodies.hasOwnProperty(tBdy)){soapBody.appendChild(bodies[tBdy]);}} - } - return soapEnv.toString(); - }; -}; - -//Soap Object - Used to build body envelope and other structures -var SOAPObject = function(name) { - this.typeOf="SOAPObject"; - this.ns=null; - this.name=name; - this.attributes=[]; - this.children=[]; - this.value=null; - this.attr=function(name, value){this.attributes.push({"name":name, "value":value});return this;}; - this.appendChild=function(obj){this.children.push(obj);return obj;}; - this.hasChildren=function(){return (this.children.length > 0)?true:false;}; - this.val=function(v){if(!v){return this.value;}else{this.value=v;return this;}}; - this.toString=function(){return SOAPClient.ToXML(this);}; -}; diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/jqSOAPClient.pack.js --- a/inkscape/firefox/jqSOAPClient.pack.js Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -/* - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ -var SOAPClient={Proxy:"",SOAPServer:"",ContentType:"text/xml",CharSet:"utf-8",ResponseXML:null,ResponseText:"",Status:0,ContentLength:0,Namespace:function(a,b){return{"name":a,"uri":b}},SendRequest:function(c,d){if(!!SOAPClient.Proxy){SOAPClient.ResponseText="";SOAPClient.ResponseXML=null;SOAPClient.Status=0;var e=c.toString();SOAPClient.ContentLength=e.length;function getResponse(a){if(!!d){SOAPClient.Status=a.status;SOAPClient.ResponseText=a.responseText;SOAPClient.ResponseXML=a.responseXML;var b=$.xmlToJSON(a.responseXML);d(b)}}$.ajax({type:"POST",url:SOAPClient.Proxy,dataType:"xml",processData:false,data:e,complete:getResponse,contentType:SOAPClient.ContentType+"; charset=\""+SOAPClient.CharSet+"\"",beforeSend:function(a){a.setRequestHeader("Method","POST");a.setRequestHeader("Content-Length",SOAPClient.ContentLength);a.setRequestHeader("SOAPServer",SOAPClient.SOAPServer);a.setRequestHeader("SOAPAction",c.Action)}})}},ToXML:function(a){var b=[];var c=false;try{if(!!a&&typeof(a)==="object"&&a.typeOf==="SOAPObject"){if(!!a.ns){if(typeof(a.ns)==="object"){c=true;b.push("<"+a.ns.name+":"+a.name);b.push(" xmlns:"+a.ns.name+"=\""+a.ns.uri+"\"")}else{b.push("<"+a.name);b.push(" xmlns=\""+a.ns+"\"")}}else{b.push("<"+a.name)}if(a.attributes.length>0){var d;var f=a.attributes.length-1;do{d=a.attributes[f];if(c){b.push(" "+a.ns.name+":"+d.name+"=\""+d.value+"\"")}else{b.push(" "+d.name+"=\""+d.value+"\"")}}while(f--)}b.push(">");if(a.hasChildren()){var g,cObj;for(g in a.children){cObj=a.children[g];if(typeof(cObj)==="object"){b.push(SOAPClient.ToXML(cObj))}}}if(!!a.value){b.push(a.value)}if(c){b.push("")}else{b.push("")}return b.join("")}}catch(e){alert("Unable to process SOAPObject! Object must be an instance of SOAPObject")}}};var SOAPRequest=function(g,h){this.Action=g;var i=[];var j=[];var k=(!!h)?[h]:[];this.addNamespace=function(a,b){i.push(new SOAPClient.Namespace(a,b))};this.addHeader=function(a){j.push(a)};this.addBody=function(a){k.push(a)};this.toString=function(){var a=new SOAPObject("soapenv:Envelope");a.attr("xmlns:soapenv","http://schemas.xmlsoap.org/soap/envelope/");if(i.length>0){var b,tNo;for(b in i){if(!i.hasOwnProperty||i.hasOwnProperty(b)){tNo=i[b];if(typeof(tNo)==="object"){a.attr("xmlns:"+tNo.name,tNo.uri)}}}}if(j.length>0){var c=a.appendChild(new SOAPObject("soapenv:Header"));var d;for(d in j){if(!j.hasOwnProperty||j.hasOwnProperty(d)){c.appendChild(j[d])}}}if(k.length>0){var e=a.appendChild(new SOAPObject("soapenv:Body"));var f;for(f in k){if(!k.hasOwnProperty||k.hasOwnProperty(f)){e.appendChild(k[f])}}}return a.toString()}};var SOAPObject=function(c){this.typeOf="SOAPObject";this.ns=null;this.name=c;this.attributes=[];this.children=[];this.value=null;this.attr=function(a,b){this.attributes.push({"name":a,"value":b});return this};this.appendChild=function(a){this.children.push(a);return a};this.hasChildren=function(){return(this.children.length>0)?true:false};this.val=function(v){if(!v){return this.value}else{this.value=v;return this}};this.toString=function(){return SOAPClient.ToXML(this)}}; \ No newline at end of file diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/jqXMLUtils.js --- a/inkscape/firefox/jqXMLUtils.js Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,250 +0,0 @@ -/* - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ -(function($) { - //Converts XML DOM to JSON - $.extend ({ - xmlToJSON: function(xdoc) { - try { - if(!xdoc){ return null; } - var tmpObj = {}; - tmpObj.typeOf = "JSXBObject"; - var xroot = (xdoc.nodeType == 9)?xdoc.documentElement:xdoc; - tmpObj.RootName = xroot.nodeName || ""; - if(xdoc.nodeType == 3 || xdoc.nodeType == 4) { - return xdoc.nodeValue; - } - var isNumeric = function(s) { - var testStr = ""; - if(s && typeof s == "string") { testStr = s; } - var pattern = /^((-)?([0-9]*)((\.{0,1})([0-9]+))?$)/; - return pattern.test(testStr); - }; - //Alters attribute and collection names to comply with JS - function formatName(name) { - var regEx = /-/g; - var tName = String(name).replace(regEx,"_"); - return tName; - } - //Set Attributes of an object - function setAttributes(obj, node) { - if(node.attributes.length > 0) { - var a = node.attributes.length-1; - var attName; - obj._attributes = []; - do { //Order is irrelevant (speed-up) - attName = String(formatName(node.attributes[a].name)); - obj._attributes.push(attName); - obj[attName] = $.trim(node.attributes[a].value); - } while(a--); - } - } - //Set collections - function setHelpers(grpObj) { - //Selects a node withing array where attribute = value - grpObj.getNodeByAttribute = function(attr, obj) { - if(this.length > 0) { - var cNode; - var maxLen = this.length -1; - try { - do { - cNode = this[maxLen]; - if(cNode[attr] == obj) { - return cNode; - } - } while(maxLen--); - } catch(e) {return false;} - return false; - } - }; - - grpObj.contains = function(attr, obj) { - if(this.length > 0) { - var maxLen = this.length -1; - try { - do { - if(this[maxLen][attr] == obj) { - return true; - } - } while(maxLen--); - } catch(e) {return false;} - return false; - } - }; - - grpObj.indexOf = function(attr, obj) { - var pos = -1; - if(this.length > 0) { - var maxLen = this.length -1; - try { - do { - if(this[maxLen][attr] == obj) { - pos = maxLen; - } - } while(maxLen--); - } catch(e) {return -1;} - return pos; - } - }; - - grpObj.SortByAttribute = function(col, dir) { - if(this.length) { - function getValue(pair, idx) { - var out = pair[idx]; - out = (isNumeric(out))?parseFloat(out):out; - return out; - } - function sortFn(a, b) { - var res = 0; - var tA, tB; - tA = getValue(a, col); - tB = getValue(b, col); - if(tA < tB) { res = -1; } else if(tB < tA) { res = 1; } - if(dir) { - res = (dir.toUpperCase() == "DESC")?(0 - res):res; - } - return res; - } - this.sort(sortFn); - } - }; - - grpObj.SortByValue = function(dir) { - if(this.length) { - function getValue(pair) { - var out = pair.Text; - out = (isNumeric(out))?parseFloat(out):out; - return out; - } - function sortFn(a, b) { - var res = 0; - var tA, tB; - tA = getValue(a); - tB = getValue(b); - if(tA < tB) { res = -1; } else if(tB < tA) { res = 1; } - if(dir) { - res = (dir.toUpperCase() == "DESC")?(0 - res):res; - } - return res; - } - this.sort(sortFn); - } - }; - grpObj.SortByNode = function(node, dir) { - if(this.length) { - function getValue(pair, node) { - var out = pair[node][0].Text; - out = (isNumeric(out))?parseFloat(out):out; - return out; - } - function sortFn(a, b) { - var res = 0; - var tA, tB; - tA = getValue(a, node); - tB = getValue(b, node); - if(tA < tB) { res = -1; } else if(tB < tA) { res = 1; } - if(dir) { - res = (dir.toUpperCase() == "DESC")?(0 - res):res; - } - return res; - } - this.sort(sortFn); - } - }; - } - //Recursive JSON Assembler - //Set Object Nodes - function setObjects(obj, node) { - var elemName; //Element name - var cnode; //Current Node - var tObj; //New subnode - var cName = ""; - if(!node) { return null; } - //Set node attributes if any - if(node.attributes.length > 0){setAttributes(obj, node);} - obj.Text = ""; - if(node.hasChildNodes()) { - var nodeCount = node.childNodes.length - 1; - var n = 0; - do { //Order is irrelevant (speed-up) - cnode = node.childNodes[n]; - switch(cnode.nodeType) { - case 1: //Node - //Process child nodes - obj._children = []; - //SOAP XML FIX to remove namespaces (i.e. soapenv:) - elemName = (cnode.localName)?cnode.localName:cnode.baseName; - elemName = formatName(elemName); - if(cName != elemName) { obj._children.push(elemName); } - //Create sub elemns array - if(!obj[elemName]) { - obj[elemName] = []; //Create Collection - } - tObj = {}; - obj[elemName].push(tObj); - if(cnode.attributes.length > 0) { - setAttributes(tObj, cnode); - } - //Set Helper functions (contains, indexOf, sort, etc); - if(!obj[elemName].contains) { - setHelpers(obj[elemName]); - } - cName = elemName; - if(cnode.hasChildNodes()) { - setObjects(tObj, cnode); //Recursive Call - } - break; - case 3: //Text Value - obj.Text += $.trim(cnode.nodeValue); - break; - case 4: //CDATA - obj.Text += (cnode.text)?$.trim(cnode.text):$.trim(cnode.nodeValue); - break; - } - } while(n++ < nodeCount); - } - } - //RUN - setObjects(tmpObj, xroot); - //Clean-up memmory - xdoc = null; - xroot = null; - return tmpObj; - - } catch(e) { - return null; - } - } - }); - - //Converts Text to XML DOM - $.extend({ - textToXML: function(strXML) { - var xmlDoc = null; - try { - xmlDoc = ($.browser.msie)?new ActiveXObject("Microsoft.XMLDOM"):new DOMParser(); - xmlDoc.async = false; - } catch(e) {throw new Error("XML Parser could not be instantiated");} - var out; - try { - if($.browser.msie) { - out = (xmlDoc.loadXML(strXML))?xmlDoc:false; - } else { - out = xmlDoc.parseFromString(strXML, "text/xml"); - } - } catch(e) { throw new Error("Error parsing XML string"); } - return out; - } - }); -})(jQuery); \ No newline at end of file diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/jquery-1.3.1.js --- a/inkscape/firefox/jquery-1.3.1.js Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4241 +0,0 @@ -/*! - * jQuery JavaScript Library v1.3.1 - * http://jquery.com/ - * - * Copyright (c) 2009 John Resig - * Dual licensed under the MIT and GPL licenses. - * http://docs.jquery.com/License - * - * Date: 2009-01-21 20:42:16 -0500 (Wed, 21 Jan 2009) - * Revision: 6158 - */ -(function(){ - -var - // Will speed up references to window, and allows munging its name. - window = this, - // Will speed up references to undefined, and allows munging its name. - undefined, - // Map over jQuery in case of overwrite - _jQuery = window.jQuery, - // Map over the $ in case of overwrite - _$ = window.$, - - jQuery = window.jQuery = window.$ = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - return new jQuery.fn.init( selector, context ); - }, - - // A simple way to check for HTML strings or ID strings - // (both of which we optimize for) - quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/, - // Is it a simple selector - isSimple = /^.[^:#\[\.,]*$/; - -jQuery.fn = jQuery.prototype = { - init: function( selector, context ) { - // Make sure that a selection was provided - selector = selector || document; - - // Handle $(DOMElement) - if ( selector.nodeType ) { - this[0] = selector; - this.length = 1; - this.context = selector; - return this; - } - // Handle HTML strings - if ( typeof selector === "string" ) { - // Are we dealing with HTML string or an ID? - var match = quickExpr.exec( selector ); - - // Verify a match, and that no context was specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) - selector = jQuery.clean( [ match[1] ], context ); - - // HANDLE: $("#id") - else { - var elem = document.getElementById( match[3] ); - - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem && elem.id != match[3] ) - return jQuery().find( selector ); - - // Otherwise, we inject the element directly into the jQuery object - var ret = jQuery( elem || [] ); - ret.context = document; - ret.selector = selector; - return ret; - } - - // HANDLE: $(expr, [context]) - // (which is just equivalent to: $(content).find(expr) - } else - return jQuery( context ).find( selector ); - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) - return jQuery( document ).ready( selector ); - - // Make sure that old selector state is passed along - if ( selector.selector && selector.context ) { - this.selector = selector.selector; - this.context = selector.context; - } - - return this.setArray(jQuery.makeArray(selector)); - }, - - // Start with an empty selector - selector: "", - - // The current version of jQuery being used - jquery: "1.3.1", - - // The number of elements contained in the matched element set - size: function() { - return this.length; - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num === undefined ? - - // Return a 'clean' array - jQuery.makeArray( this ) : - - // Return just the object - this[ num ]; - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems, name, selector ) { - // Build a new jQuery matched element set - var ret = jQuery( elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - ret.context = this.context; - - if ( name === "find" ) - ret.selector = this.selector + (this.selector ? " " : "") + selector; - else if ( name ) - ret.selector = this.selector + "." + name + "(" + selector + ")"; - - // Return the newly-formed element set - return ret; - }, - - // Force the current matched set of elements to become - // the specified array of elements (destroying the stack in the process) - // You should use pushStack() in order to do this, but maintain the stack - setArray: function( elems ) { - // Resetting the length to 0, then using the native Array push - // is a super-fast way to populate an object with array-like properties - this.length = 0; - Array.prototype.push.apply( this, elems ); - - return this; - }, - - // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - // Locate the position of the desired element - return jQuery.inArray( - // If it receives a jQuery object, the first element is used - elem && elem.jquery ? elem[0] : elem - , this ); - }, - - attr: function( name, value, type ) { - var options = name; - - // Look for the case where we're accessing a style value - if ( typeof name === "string" ) - if ( value === undefined ) - return this[0] && jQuery[ type || "attr" ]( this[0], name ); - - else { - options = {}; - options[ name ] = value; - } - - // Check to see if we're setting style values - return this.each(function(i){ - // Set all the styles - for ( name in options ) - jQuery.attr( - type ? - this.style : - this, - name, jQuery.prop( this, options[ name ], type, i, name ) - ); - }); - }, - - css: function( key, value ) { - // ignore negative width and height values - if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 ) - value = undefined; - return this.attr( key, value, "curCSS" ); - }, - - text: function( text ) { - if ( typeof text !== "object" && text != null ) - return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); - - var ret = ""; - - jQuery.each( text || this, function(){ - jQuery.each( this.childNodes, function(){ - if ( this.nodeType != 8 ) - ret += this.nodeType != 1 ? - this.nodeValue : - jQuery.fn.text( [ this ] ); - }); - }); - - return ret; - }, - - wrapAll: function( html ) { - if ( this[0] ) { - // The elements to wrap the target around - var wrap = jQuery( html, this[0].ownerDocument ).clone(); - - if ( this[0].parentNode ) - wrap.insertBefore( this[0] ); - - wrap.map(function(){ - var elem = this; - - while ( elem.firstChild ) - elem = elem.firstChild; - - return elem; - }).append(this); - } - - return this; - }, - - wrapInner: function( html ) { - return this.each(function(){ - jQuery( this ).contents().wrapAll( html ); - }); - }, - - wrap: function( html ) { - return this.each(function(){ - jQuery( this ).wrapAll( html ); - }); - }, - - append: function() { - return this.domManip(arguments, true, function(elem){ - if (this.nodeType == 1) - this.appendChild( elem ); - }); - }, - - prepend: function() { - return this.domManip(arguments, true, function(elem){ - if (this.nodeType == 1) - this.insertBefore( elem, this.firstChild ); - }); - }, - - before: function() { - return this.domManip(arguments, false, function(elem){ - this.parentNode.insertBefore( elem, this ); - }); - }, - - after: function() { - return this.domManip(arguments, false, function(elem){ - this.parentNode.insertBefore( elem, this.nextSibling ); - }); - }, - - end: function() { - return this.prevObject || jQuery( [] ); - }, - - // For internal use only. - // Behaves like an Array's .push method, not like a jQuery method. - push: [].push, - - find: function( selector ) { - if ( this.length === 1 && !/,/.test(selector) ) { - var ret = this.pushStack( [], "find", selector ); - ret.length = 0; - jQuery.find( selector, this[0], ret ); - return ret; - } else { - var elems = jQuery.map(this, function(elem){ - return jQuery.find( selector, elem ); - }); - - return this.pushStack( /[^+>] [^+>]/.test( selector ) ? - jQuery.unique( elems ) : - elems, "find", selector ); - } - }, - - clone: function( events ) { - // Do the clone - var ret = this.map(function(){ - if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) { - // IE copies events bound via attachEvent when - // using cloneNode. Calling detachEvent on the - // clone will also remove the events from the orignal - // In order to get around this, we use innerHTML. - // Unfortunately, this means some modifications to - // attributes in IE that are actually only stored - // as properties will not be copied (such as the - // the name attribute on an input). - var clone = this.cloneNode(true), - container = document.createElement("div"); - container.appendChild(clone); - return jQuery.clean([container.innerHTML])[0]; - } else - return this.cloneNode(true); - }); - - // Need to set the expando to null on the cloned set if it exists - // removeData doesn't work here, IE removes it from the original as well - // this is primarily for IE but the data expando shouldn't be copied over in any browser - var clone = ret.find("*").andSelf().each(function(){ - if ( this[ expando ] !== undefined ) - this[ expando ] = null; - }); - - // Copy the events from the original to the clone - if ( events === true ) - this.find("*").andSelf().each(function(i){ - if (this.nodeType == 3) - return; - var events = jQuery.data( this, "events" ); - - for ( var type in events ) - for ( var handler in events[ type ] ) - jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data ); - }); - - // Return the cloned set - return ret; - }, - - filter: function( selector ) { - return this.pushStack( - jQuery.isFunction( selector ) && - jQuery.grep(this, function(elem, i){ - return selector.call( elem, i ); - }) || - - jQuery.multiFilter( selector, jQuery.grep(this, function(elem){ - return elem.nodeType === 1; - }) ), "filter", selector ); - }, - - closest: function( selector ) { - var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null; - - return this.map(function(){ - var cur = this; - while ( cur && cur.ownerDocument ) { - if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) - return cur; - cur = cur.parentNode; - } - }); - }, - - not: function( selector ) { - if ( typeof selector === "string" ) - // test special case where just one selector is passed in - if ( isSimple.test( selector ) ) - return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector ); - else - selector = jQuery.multiFilter( selector, this ); - - var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; - return this.filter(function() { - return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; - }); - }, - - add: function( selector ) { - return this.pushStack( jQuery.unique( jQuery.merge( - this.get(), - typeof selector === "string" ? - jQuery( selector ) : - jQuery.makeArray( selector ) - ))); - }, - - is: function( selector ) { - return !!selector && jQuery.multiFilter( selector, this ).length > 0; - }, - - hasClass: function( selector ) { - return !!selector && this.is( "." + selector ); - }, - - val: function( value ) { - if ( value === undefined ) { - var elem = this[0]; - - if ( elem ) { - if( jQuery.nodeName( elem, 'option' ) ) - return (elem.attributes.value || {}).specified ? elem.value : elem.text; - - // We need to handle select boxes special - if ( jQuery.nodeName( elem, "select" ) ) { - var index = elem.selectedIndex, - values = [], - options = elem.options, - one = elem.type == "select-one"; - - // Nothing was selected - if ( index < 0 ) - return null; - - // Loop through all the selected options - for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { - var option = options[ i ]; - - if ( option.selected ) { - // Get the specifc value for the option - value = jQuery(option).val(); - - // We don't need an array for one selects - if ( one ) - return value; - - // Multi-Selects return an array - values.push( value ); - } - } - - return values; - } - - // Everything else, we just grab the value - return (elem.value || "").replace(/\r/g, ""); - - } - - return undefined; - } - - if ( typeof value === "number" ) - value += ''; - - return this.each(function(){ - if ( this.nodeType != 1 ) - return; - - if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) ) - this.checked = (jQuery.inArray(this.value, value) >= 0 || - jQuery.inArray(this.name, value) >= 0); - - else if ( jQuery.nodeName( this, "select" ) ) { - var values = jQuery.makeArray(value); - - jQuery( "option", this ).each(function(){ - this.selected = (jQuery.inArray( this.value, values ) >= 0 || - jQuery.inArray( this.text, values ) >= 0); - }); - - if ( !values.length ) - this.selectedIndex = -1; - - } else - this.value = value; - }); - }, - - html: function( value ) { - return value === undefined ? - (this[0] ? - this[0].innerHTML : - null) : - this.empty().append( value ); - }, - - replaceWith: function( value ) { - return this.after( value ).remove(); - }, - - eq: function( i ) { - return this.slice( i, +i + 1 ); - }, - - slice: function() { - return this.pushStack( Array.prototype.slice.apply( this, arguments ), - "slice", Array.prototype.slice.call(arguments).join(",") ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map(this, function(elem, i){ - return callback.call( elem, i, elem ); - })); - }, - - andSelf: function() { - return this.add( this.prevObject ); - }, - - domManip: function( args, table, callback ) { - if ( this[0] ) { - var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(), - scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ), - first = fragment.firstChild, - extra = this.length > 1 ? fragment.cloneNode(true) : fragment; - - if ( first ) - for ( var i = 0, l = this.length; i < l; i++ ) - callback.call( root(this[i], first), i > 0 ? extra.cloneNode(true) : fragment ); - - if ( scripts ) - jQuery.each( scripts, evalScript ); - } - - return this; - - function root( elem, cur ) { - return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ? - (elem.getElementsByTagName("tbody")[0] || - elem.appendChild(elem.ownerDocument.createElement("tbody"))) : - elem; - } - } -}; - -// Give the init function the jQuery prototype for later instantiation -jQuery.fn.init.prototype = jQuery.fn; - -function evalScript( i, elem ) { - if ( elem.src ) - jQuery.ajax({ - url: elem.src, - async: false, - dataType: "script" - }); - - else - jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); - - if ( elem.parentNode ) - elem.parentNode.removeChild( elem ); -} - -function now(){ - return +new Date; -} - -jQuery.extend = jQuery.fn.extend = function() { - // copy reference to target object - var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction(target) ) - target = {}; - - // extend jQuery itself if only one argument is passed - if ( length == i ) { - target = this; - --i; - } - - for ( ; i < length; i++ ) - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) - // Extend the base object - for ( var name in options ) { - var src = target[ name ], copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) - continue; - - // Recurse if we're merging object values - if ( deep && copy && typeof copy === "object" && !copy.nodeType ) - target[ name ] = jQuery.extend( deep, - // Never move original objects, clone them - src || ( copy.length != null ? [ ] : { } ) - , copy ); - - // Don't bring in undefined values - else if ( copy !== undefined ) - target[ name ] = copy; - - } - - // Return the modified object - return target; -}; - -// exclude the following css properties to add px -var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i, - // cache defaultView - defaultView = document.defaultView || {}, - toString = Object.prototype.toString; - -jQuery.extend({ - noConflict: function( deep ) { - window.$ = _$; - - if ( deep ) - window.jQuery = _jQuery; - - return jQuery; - }, - - // See test/unit/core.js for details concerning isFunction. - // Since version 1.3, DOM methods and functions like alert - // aren't supported. They return false on IE (#2968). - isFunction: function( obj ) { - return toString.call(obj) === "[object Function]"; - }, - - isArray: function( obj ) { - return toString.call(obj) === "[object Array]"; - }, - - // check if an element is in a (or is an) XML document - isXMLDoc: function( elem ) { - return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" || - !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument ); - }, - - // Evalulates a script in a global context - globalEval: function( data ) { - data = jQuery.trim( data ); - - if ( data ) { - // Inspired by code by Andrea Giammarchi - // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html - var head = document.getElementsByTagName("head")[0] || document.documentElement, - script = document.createElement("script"); - - script.type = "text/javascript"; - if ( jQuery.support.scriptEval ) - script.appendChild( document.createTextNode( data ) ); - else - script.text = data; - - // Use insertBefore instead of appendChild to circumvent an IE6 bug. - // This arises when a base node is used (#2709). - head.insertBefore( script, head.firstChild ); - head.removeChild( script ); - } - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); - }, - - // args is for internal usage only - each: function( object, callback, args ) { - var name, i = 0, length = object.length; - - if ( args ) { - if ( length === undefined ) { - for ( name in object ) - if ( callback.apply( object[ name ], args ) === false ) - break; - } else - for ( ; i < length; ) - if ( callback.apply( object[ i++ ], args ) === false ) - break; - - // A special, fast, case for the most common use of each - } else { - if ( length === undefined ) { - for ( name in object ) - if ( callback.call( object[ name ], name, object[ name ] ) === false ) - break; - } else - for ( var value = object[0]; - i < length && callback.call( value, i, value ) !== false; value = object[++i] ){} - } - - return object; - }, - - prop: function( elem, value, type, i, name ) { - // Handle executable functions - if ( jQuery.isFunction( value ) ) - value = value.call( elem, i ); - - // Handle passing in a number to a CSS property - return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ? - value + "px" : - value; - }, - - className: { - // internal only, use addClass("class") - add: function( elem, classNames ) { - jQuery.each((classNames || "").split(/\s+/), function(i, className){ - if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) - elem.className += (elem.className ? " " : "") + className; - }); - }, - - // internal only, use removeClass("class") - remove: function( elem, classNames ) { - if (elem.nodeType == 1) - elem.className = classNames !== undefined ? - jQuery.grep(elem.className.split(/\s+/), function(className){ - return !jQuery.className.has( classNames, className ); - }).join(" ") : - ""; - }, - - // internal only, use hasClass("class") - has: function( elem, className ) { - return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; - } - }, - - // A method for quickly swapping in/out CSS properties to get correct calculations - swap: function( elem, options, callback ) { - var old = {}; - // Remember the old values, and insert the new ones - for ( var name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - callback.call( elem ); - - // Revert the old values - for ( var name in options ) - elem.style[ name ] = old[ name ]; - }, - - css: function( elem, name, force ) { - if ( name == "width" || name == "height" ) { - var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; - - function getWH() { - val = name == "width" ? elem.offsetWidth : elem.offsetHeight; - var padding = 0, border = 0; - jQuery.each( which, function() { - padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; - border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; - }); - val -= Math.round(padding + border); - } - - if ( jQuery(elem).is(":visible") ) - getWH(); - else - jQuery.swap( elem, props, getWH ); - - return Math.max(0, val); - } - - return jQuery.curCSS( elem, name, force ); - }, - - curCSS: function( elem, name, force ) { - var ret, style = elem.style; - - // We need to handle opacity special in IE - if ( name == "opacity" && !jQuery.support.opacity ) { - ret = jQuery.attr( style, "opacity" ); - - return ret == "" ? - "1" : - ret; - } - - // Make sure we're using the right name for getting the float value - if ( name.match( /float/i ) ) - name = styleFloat; - - if ( !force && style && style[ name ] ) - ret = style[ name ]; - - else if ( defaultView.getComputedStyle ) { - - // Only "float" is needed here - if ( name.match( /float/i ) ) - name = "float"; - - name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); - - var computedStyle = defaultView.getComputedStyle( elem, null ); - - if ( computedStyle ) - ret = computedStyle.getPropertyValue( name ); - - // We should always get a number back from opacity - if ( name == "opacity" && ret == "" ) - ret = "1"; - - } else if ( elem.currentStyle ) { - var camelCase = name.replace(/\-(\w)/g, function(all, letter){ - return letter.toUpperCase(); - }); - - ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; - - // From the awesome hack by Dean Edwards - // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 - - // If we're not dealing with a regular pixel number - // but a number that has a weird ending, we need to convert it to pixels - if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { - // Remember the original values - var left = style.left, rsLeft = elem.runtimeStyle.left; - - // Put in the new values to get a computed value out - elem.runtimeStyle.left = elem.currentStyle.left; - style.left = ret || 0; - ret = style.pixelLeft + "px"; - - // Revert the changed values - style.left = left; - elem.runtimeStyle.left = rsLeft; - } - } - - return ret; - }, - - clean: function( elems, context, fragment ) { - context = context || document; - - // !context.createElement fails in IE with an error but returns typeof 'object' - if ( typeof context.createElement === "undefined" ) - context = context.ownerDocument || context[0] && context[0].ownerDocument || document; - - // If a single string is passed in and it's a single tag - // just do a createElement and skip the rest - if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) { - var match = /^<(\w+)\s*\/?>$/.exec(elems[0]); - if ( match ) - return [ context.createElement( match[1] ) ]; - } - - var ret = [], scripts = [], div = context.createElement("div"); - - jQuery.each(elems, function(i, elem){ - if ( typeof elem === "number" ) - elem += ''; - - if ( !elem ) - return; - - // Convert html string into DOM nodes - if ( typeof elem === "string" ) { - // Fix "XHTML"-style tags in all browsers - elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ - return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? - all : - front + ">"; - }); - - // Trim whitespace, otherwise indexOf won't work as expected - var tags = jQuery.trim( elem ).toLowerCase(); - - var wrap = - // option or optgroup - !tags.indexOf("", "" ] || - - !tags.indexOf("", "" ] || - - tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && - [ 1, "", "
" ] || - - !tags.indexOf("", "" ] || - - // matched above - (!tags.indexOf("", "" ] || - - !tags.indexOf("", "" ] || - - // IE can't serialize and - - - - - - -
-
- - -
-
- - - diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/scene.mbsvg --- a/inkscape/firefox/scene.mbsvg Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,105 +0,0 @@ - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/start.png Binary file inkscape/firefox/start.png has changed diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/start.svg --- a/inkscape/firefox/start.svg Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff -r 892d86c1a409 -r c8b6ca46950b inkscape/firefox/testsoap.py --- a/inkscape/firefox/testsoap.py Thu Jan 29 23:57:59 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -from twisted.web import soap -from twisted.internet import reactor -import sys,os -class Inkscape(object): - def __init__(self): - self.server = soap.Proxy('http://localhost:8080') - def PUBLISH(self): - return self.server.callRemote('PUBLISH') - def SCENE(self,n): - return self.server.callRemote('SCENE',n) - def START(self): - return self.server.callRemote('START') - def INSERTKEY(self,layer,n): - return self.server.callRemote('INSERTKEY',layer,n) - def EXTENDSCENE(self,layer,n): - return self.server.callRemote('EXTENDSCENE',layer,n) - def GETDOC(self): - return self.server.callRemote('GETDOC') - - -def quitSession(result): - print [result] - reactor.stop() -def quitError(result): - print "Error" - print[result] - reactor.stop() - - -ink = Inkscape() - -if sys.argv[1] == 'PUBLISH': - d = ink.PUBLISH() -elif sys.argv[1] == 'SCENE': - d = ink.SCENE(sys.argv[2]) -elif sys.argv[1] == 'START': - d = ink.START() -elif sys.argv[1] == 'INSERTKEY': - d = ink.INSERTKEY(sys.argv[2], sys.argv[3]) -elif sys.argv[1] == 'GETDOC': - d = ink.GETDOC() -elif sys.argv[1] == 'EXTENDSCENE': - d = ink.EXTENDSCENE(sys.argv[2],sys.argv[3]) -else: - print 'Unknown command %s' % sys.argv[1] - sys.exit(-1) -d.addCallback(quitSession) -d.addErrback(quitError) - - -reactor.run() diff -r 892d86c1a409 -r c8b6ca46950b src/Makefile.am --- a/src/Makefile.am Thu Jan 29 23:57:59 2009 +0800 +++ b/src/Makefile.am Sat Jan 31 12:29:50 2009 +0800 @@ -9,10 +9,11 @@ shape_rect.c shape_text.c shift.c subtree_free.c timer.c \ timertool.c tools.c visibility.c X_supp.c prop.c sprite.c \ mouse.c shape_image.c img_ldr.c -libmbfly_la_CPPFLAGS = @cairo_CFLAGS@ -libmbfly_la_LDFLAGS = @cairo_LIBS@ + +libmbfly_la_CPPFLAGS = @cairo_CFLAGS@ `pkg-config --cflags pangocairo` +libmbfly_la_LDFLAGS = @cairo_LIBS@ `pkg-config --libs pangocairo` X_main_SOURCES = X_main.c X_main_LDADD = $(top_builddir)/src/libmbfly.la -X_main_CPPFLAGS = @cairo_CFLAGS@ -I$(top_builddir)/src -X_main_LDFLAGS = @cairo_LIBS@ +X_main_CPPFLAGS = @pangocairo_CFLAGS@ -I$(top_builddir)/src +X_main_LDFLAGS = @pangocairo_LIBS@ diff -r 892d86c1a409 -r c8b6ca46950b src/X_main.c --- a/src/X_main.c Thu Jan 29 23:57:59 2009 +0800 +++ b/src/X_main.c Sat Jan 31 12:29:50 2009 +0800 @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "mb_shapes.h" @@ -138,6 +139,7 @@ mb_progm_t *progm; mb_word_t *word; mb_action_t *act; + PangoAttrList *attrs = pango_attr_list_new(); tmpsuf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); tmpcr = cairo_create(tmpsuf); @@ -155,7 +157,7 @@ face = cairo_get_font_face(tmpcr); text = rdman_shape_text_new(&rdman, "hello \xe6\xbc\xa2\xe5\xad\x97", - 10, h / 4, 36.0, face); + 10, h / 4, 36.0, face, attrs); text_fill = rdman_paint_radial_new(&rdman, 100, h / 4, 70); grad_stop_init(text_stops, 0, 0.2, 0.9, 0.2, 1); grad_stop_init(text_stops + 1, 1, 0.9, 0.2, 0.2, 0.1); diff -r 892d86c1a409 -r c8b6ca46950b src/shape_text.c --- a/src/shape_text.c Thu Jan 29 23:57:59 2009 +0800 +++ b/src/shape_text.c Sat Jan 31 12:29:50 2009 +0800 @@ -3,6 +3,7 @@ #include #include #include +#include #include "mb_types.h" #include "mb_shapes.h" @@ -20,6 +21,8 @@ cairo_font_face_t *face; cairo_scaled_font_t *scaled_font; int flags; + PangoLayout *layout; + PangoAttrList *attrs; } sh_text_t; #define TXF_SCALE_DIRTY 0x1 @@ -32,15 +35,17 @@ cairo_font_face_destroy(text->face); } +static void sh_text_P_generate_layout(sh_text_t *text,cairo_t *cr); shape_t *rdman_shape_text_new(redraw_man_t *rdman, const char *txt, co_aix x, co_aix y, - co_aix font_size, cairo_font_face_t *face) { + co_aix font_size, cairo_font_face_t *face,PangoAttrList *attrs) { sh_text_t *text; text = (sh_text_t *)malloc(sizeof(sh_text_t)); if(text == NULL) return NULL; + memset(text, 0, sizeof(sh_text_t)); mb_obj_init(text, MBO_TEXT); text->data = strdup(txt); @@ -56,6 +61,9 @@ text->flags |= TXF_SCALE_DIRTY; text->shape.free = sh_text_free; + text->layout = NULL; + text->attrs = attrs; + sh_text_P_generate_layout(text, rdman->cr); rdman_shape_man(rdman, (shape_t *)text); @@ -71,39 +79,14 @@ text->data = buf; } -static int get_extents(sh_text_t *text, cairo_text_extents_t *extents) { +static int get_extents(sh_text_t *text, PangoRectangle *extents) { cairo_matrix_t fmatrix; cairo_matrix_t ctm; cairo_scaled_font_t *new_scaled; cairo_font_options_t *fopt; - if((text->flags & TXF_SCALE_DIRTY) || - text->scaled_font == NULL) { - fopt = cairo_font_options_create(); - if(fopt == NULL) - return ERR; - memset(&fmatrix, 0, sizeof(cairo_matrix_t)); - fmatrix.xx = text->d_font_size; - fmatrix.yy = text->d_font_size; - memset(&ctm, 0, sizeof(cairo_matrix_t)); - ctm.xx = 1; - ctm.yy = 1; - new_scaled = cairo_scaled_font_create(text->face, - &fmatrix, - &ctm, - fopt); - cairo_font_options_destroy(fopt); - if(new_scaled == NULL) - return ERR; - - if(text->scaled_font) - cairo_scaled_font_destroy(text->scaled_font); - text->scaled_font = new_scaled; - text->flags &= ~TXF_SCALE_DIRTY; - } - - cairo_scaled_font_text_extents(text->scaled_font, - text->data, extents); + pango_layout_get_extents(text->layout, NULL, extents); + pango_extents_to_pixels(extents,NULL); return OK; } @@ -111,7 +94,7 @@ sh_text_t *text; co_aix x, y; co_aix shw; - cairo_text_extents_t extents; + PangoRectangle extents; co_aix poses[2][2]; int r; @@ -123,27 +106,45 @@ y = text->y; coord_trans_pos(shape->coord, &x, &y); r = get_extents(text, &extents); + + //printf("x=%f y=%f text=%s ascent=%d,descent=%d,width=%d height=%d\n", x,y,text->data,PANGO_ASCENT(extents), PANGO_DESCENT(extents), extents.width, extents.height); ASSERT(r == OK); text->d_x = x; - text->d_y = y; + text->d_y = y-text->font_size; shw = shape->stroke_width / 2; /* FIXME: It is unreasonable that a font exceed it's bbox. * We add 5 pixels in get right bbox. But, it is unreasonable. */ - poses[0][0] = x + extents.x_bearing - 5 - shw; - poses[0][1] = y + extents.y_bearing - 5 - shw; + + poses[0][0] = x + extents.x - 5 - shw; + poses[0][1] = y + extents.y - 5 - shw; poses[1][0] = poses[0][0] + extents.width + 10 + shape->stroke_width; poses[1][1] = poses[0][1] + extents.height + 10 + shape->stroke_width; geo_from_positions(shape->geo, 2, poses); /*! \todo Support ratation for shape_text. */ } +static void sh_text_P_generate_layout(sh_text_t *text,cairo_t *cr) +{ + PangoAttribute *attr; + PangoAttrList *attrlist; + PangoFontDescription *desc; + if (text->layout) { + g_object_unref(text->layout); + } + text->layout = pango_cairo_create_layout(cr); + desc = pango_font_description_from_string("Sans Bold"); + pango_layout_set_font_description (text->layout, desc); + pango_cairo_update_layout(cr,text->layout); + pango_layout_set_text(text->layout,text->data,strlen(text->data)); + pango_layout_set_attributes(text->layout, text->attrs); +} static void draw_text(sh_text_t *text, cairo_t *cr) { - cairo_set_scaled_font(cr, text->scaled_font); + sh_text_P_generate_layout(text, cr); cairo_move_to(cr, text->d_x, text->d_y); - cairo_text_path(cr, text->data); + pango_cairo_show_layout(cr,text->layout); } diff -r 892d86c1a409 -r c8b6ca46950b tools/mb_c_header.m4 --- a/tools/mb_c_header.m4 Thu Jan 29 23:57:59 2009 +0800 +++ b/tools/mb_c_header.m4 Sat Jan 31 12:29:50 2009 +0800 @@ -24,6 +24,15 @@ mb_img_data_t *$1_img_data; shape_t *$1; ]]) +define([PANGO_BEGIN_TEXT],[ +[ shape_t *$1; +]]) +define([PANGO_END_TEXT],[ +]) +define([PANGO_SIZE],[]) +define([PANGO_STYLE],[]) +define([PANGO_WEIGHT],[]) +define([PANGO_FAMILY],[]) define([COLOR_STOP],[ ]) define([REF_STOPS_RADIAL],) diff -r 892d86c1a409 -r c8b6ca46950b tools/mb_c_source.m4 --- a/tools/mb_c_source.m4 Thu Jan 29 23:57:59 2009 +0800 +++ b/tools/mb_c_source.m4 Sat Jan 31 12:29:50 2009 +0800 @@ -21,6 +21,12 @@ define([ADD_COORD]) define([ADD_TEXT],) define([ADD_IMAGE],) +define([PANGO_BEGIN_TEXT],) +define([PANGO_END_TEXT],) +define([PANGO_SIZE],) +define([PANGO_STYLE],) +define([PANGO_WEIGHT],) +define([PANGO_FAMILY],) define([FILL_SHAPE]) define([STROKE_SHAPE]) define([FILL_SHAPE_WITH_PAINT]) @@ -126,6 +132,42 @@ $3, $4, $5, $6); rdman_add_shape(rdman, obj->$1, obj->$7); ]]) +define([S_PANGO_BEGIN_TEXT],[[ + { + PangoAttribute *attr; + PangoAttrList *attrs = pango_attr_list_new(); + +]]) +define([S_PANGO_END_TEXT],[[ + obj->$1 = rdman_shape_text_new(rdman, "$2", $3, $4, $5, + cairo_get_font_face(rdman->cr),attrs); + rdman_add_shape(rdman, obj->$1, obj->$6); + } +]]) +define([S_PANGO_SIZE],[[ + attr = pango_attr_size_new($1); + attr->start_index = $2; + attr->end_index = $3; + pango_attr_list_insert(attrs,attr); +]]) +define([S_PANGO_WEIGHT],[[ + attr = pango_attr_weight_new($1); + attr->start_index = $2; + attr->end_index = $3; + pango_attr_list_insert(attrs,attr); +]]) +define([S_PANGO_FAMILY],[[ + attr = pango_attr_family_new("$1"); + attr->start_index = $2; + attr->end_index = $3; + pango_attr_list_insert(attrs,attr); +]]) +define([S_PANGO_STYLE],[[ + attr = pango_attr_style_new($1); + attr->start_index = $2; + attr->end_index = $3; + pango_attr_list_insert(attrs,attr); +]]) define([S_FILL_SHAPE_WITH_PAINT],[dnl [ rdman_paint_fill(rdman, obj->$2, obj->$1); @@ -212,6 +254,12 @@ SIMPORT([ADD_COORD]) SIMPORT([ADD_TEXT]) SIMPORT([ADD_IMAGE]) +SIMPORT([PANGO_BEGIN_TEXT]) +SIMPORT([PANGO_END_TEXT]) +SIMPORT([PANGO_SIZE]) +SIMPORT([PANGO_WEIGHT]) +SIMPORT([PANGO_FAMILY]) +SIMPORT([PANGO_STYLE]) SIMPORT([FILL_SHAPE]) SIMPORT([STROKE_SHAPE]) SIMPORT([FILL_SHAPE_WITH_PAINT]) @@ -254,6 +302,15 @@ rdman_shape_free(rdman, obj->$1); MB_IMAGE_DATA_FREE(obj->$1_img_data); ]]) +define([F_PANGO_BEGIN_TEXT],[[ + rdman_shape_free(rdman, obj->$1); +]]) +define([F_PANGO_SIZE],[[ +]]) +define([F_PANGO_STYLE],[[ +]]) +define([F_PANGO_WEIGHT],[[ +]]) define([F_FILL_SHAPE],[[ rdman_paint_free(rdman, obj->$1_fill); @@ -271,6 +328,7 @@ FIMPORT([ADD_PATH],) FIMPORT([ADD_RECT]) FIMPORT([ADD_TEXT]) +FIMPORT([PANGO_BEGIN_TEXT]) FIMPORT([FILL_SHAPE]) FIMPORT([STROKE_SHAPE]) divert[]]) @@ -297,6 +355,7 @@ RIMPORT([ADD_RECT]) RIMPORT([ADD_COORD]) RIMPORT([ADD_TEXT]) +RIMPORT([PANGO_BEGIN_TEXT]) RIMPORT([FILL_SHAPE]) RIMPORT([STROKE_SHAPE]) RIMPORT([FILL_SHAPE_WITH_PAINT]) @@ -436,12 +495,9 @@ $1_t *$1_new(redraw_man_t *rdman, coord_t *parent_coord) { $1_t *obj; - grad_stop_t *stops = NULL; - mb_img_ldr_t *img_ldr = NULL;]DECLARE_VARS + grad_stop_t *stops = NULL;]DECLARE_VARS $2[]dnl [ - img_ldr = rdman_img_ldr(rdman); - obj = ($1_t *)malloc(sizeof($1_t)); if(obj == NULL) return NULL; diff -r 892d86c1a409 -r c8b6ca46950b tools/svg2code.py --- a/tools/svg2code.py Thu Jan 29 23:57:59 2009 +0800 +++ b/tools/svg2code.py Sat Jan 31 12:29:50 2009 +0800 @@ -125,8 +125,11 @@ 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: + prop_map = node.style_map + except: + style_str = node.getAttribute('style') + prop_map = get_style_map(style_str) try: opacity = float(node.getAttribute('opacity')) @@ -301,10 +304,9 @@ if s != '': fields.append(s) cmd = '' - cmd_args = 0 + cmd_args=0 commands='' args=[] - narg = 0 fix_args=[] for f in fields: if f in command_length: @@ -372,7 +374,7 @@ path_id = path.getAttribute('id') d = path.getAttribute('d') - commands, args, fix_args = translate_path_data(d,codefo) + (commands,args,fix_args) = translate_path_data(d,codefo) print >> codefo, 'dnl' #print >> codefo, 'ADD_PATH([%s], [%s], [%s])dnl' % (path_id, d, coord_id) sarg='' @@ -415,89 +417,158 @@ 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) + return style_map + +def merge_style(tspan,text): + newmap = tspan.style_map + map = text.style_map + for k,v in text.style_map.items(): + if not newmap.has_key(k): + newmap[k] = v +def translate_tspan(tspan, text,coord_id, codefo, doc,txt_strs,attrs): + try: + map = tspan.style_map + except: + map = translate_font_style(tspan, codefo) + tspan.style_map = map + if tspan.hasAttribute('x'): + # Render the tspan as an independent text if the x attribute is defined. All elements inside + # the tspan will be ignore by the outter text or tspan elements. + # FIXME: We need to apply the style map recursively. + merge_style(tspan,text) + translate_text(tspan,coord_id,codefo,doc) + return '' + attr = [len(txt_strs.encode('utf8'))-1,0, tspan] + attrs.append(attr) + for node in tspan.childNodes: + if node.localName == None: + txt_strs = txt_strs + node.data + elif node.localName == 'tspan': + txt_strs = translate_tspan(node,coord_id, codefo, doc,txt_strs,attrs) pass pass + attr[1] = len(txt_strs.encode('utf8')) + return txt_strs - font_style = 'normal' - if style_map.has_key('font-style'): - font_style = style_map['font-style'].lower() + + +def generate_font_attributes(attrs,coord_id, codefo,doc): + for a in attrs: + start = a[0] + end = a[1] + node = a[2] + #print "generate attributes from %d to %d" %(start,end) + style_map = node.style_map + #print [style_map] + if style_map.has_key('font-size'): + # FIXME: Implement all units here + if style_map['font-size'].endswith('px'): + font_sz = float(style_map['font-size'][:-2]) + print >> codefo, 'PANGO_SIZE(%d,%d,%d)' % (font_sz*1024,start,end) + else: + font_sz = float(style_map['font-size']) + print >> codefo, 'PANGO_SIZE(%d,%d,%d)' % (font_sz*1024,start,end) + pass + + if style_map.has_key('font-style'): + font_style = style_map['font-style'].lower() + if font_style == 'normal': + print >> codefo, 'PANGO_STYLE(PANGO_STYLE_NORMAL,%d,%d)' % (start,end) + elif font_style == 'italic': + print >> codefo, 'PANGO_STYLE(PANGO_STYLE_ITALIC,%d,%d)' % (start,end) + elif font_style == 'oblique': + print >> codefo, 'PANGO_STYLE(PANGO_STYLE_OBLIQUE,%d,%d)' % (start,end) pass - font_family = 'Roman' - if style_map.has_key('font-family'): - font_family = style_map['font-family'].lower() + if style_map.has_key('font-family'): + font_family = style_map['font-family'].lower() + print >> codefo, 'PANGO_FAMILY(%s,%d,%d)' % (font_family,start,end) + pass + if style_map.has_key('text-anchor'): + text_anchor = style_map['text-anchor'].lower() + # FIXME: We need to implement a mb_text_set_aligment to implement SVG-styled alignment. + print "The text-anchor is not implemented yet" + pass + if style_map.has_key('font-variant'): + font_variant = style_map['font-variant'].lower() + print "The font-variant is not implemented yet" + pass + if style_map.has_key('font-weight'): + font_weight = style_map['font-weight'].lower() + if font_weight == 'normal': + print >> codefo, 'PANGO_STYLE(PANGO_WEIGHT_NORMAL,%d,%d)' % (start,end) + elif font_weight == 'bold': + print >> codefo, 'PANGO_STYLE(PANGO_WEIGHT_BOLD,%d,%d)' % (start,end) + elif font_weight == 'bolder': + print >> codefo, 'PANGO_STYLE(PANGO_WEIGHT_HEAVY,%d,%d)' % (start,end) + elif font_weight == 'lighter': + print >> codefo, 'PANGO_STYLE(PANGO_WEIGHT_ULTRALIGHT,%d,%d)' % (start,end) + elif font_weight == '100': + print >> codefo, 'PANGO_STYLE(PANGO_WEIGHT_ULTRALIGHT,%d,%d)' % (start,end) + elif font_weight == '200': + print >> codefo, 'PANGO_STYLE(PANGO_WEIGHT_ULTRALIGHT,%d,%d)' % (start,end) + elif font_weight == '300': + print >> codefo, 'PANGO_STYLE(PANGO_WEIGHT_LIGHT,%d,%d)' % (start,end) + elif font_weight == '400': + print >> codefo, 'PANGO_STYLE(PANGO_WEIGHT_NORMAL,%d,%d)' % (start,end) + elif font_weight == '500': + print >> codefo, 'PANGO_STYLE(PANGO_WEIGHT_NORMAL,%d,%d)' % (start,end) + elif font_weight == '600': + print >> codefo, 'PANGO_STYLE(PANGO_WEIGHT_SEMIBOLD,%d,%d)' % (start,end) + elif font_weight == '700': + print >> codefo, 'PANGO_STYLE(PANGO_WEIGHT_BOLD,%d,%d)' % (start,end) + elif font_weight == '800': + print >> codefo, 'PANGO_STYLE(PANGO_WEIGHT_ULTRABOLD,%d,%d)' % (start,end) + elif font_weight == '900': + print >> codefo, 'PANGO_STYLE(PANGO_WEIGHT_HEAVY,%d,%d)' % (start,end) + else: + print "The font-weight %s is not supported" % font_weight + pass + if style_map.has_key('direction'): + direction = style_map['direction'].lower() + print "The direction is not implemented yet" + pass + if style_map.has_key('unicode-bidi'): + bidi = style_map['unicode-bidi'].lower() + print "The bidi is not implemented yet" pass pass - -@check_mbname + def translate_text(text, coord_id, codefo, doc): - coord_id = translate_shape_transform(text, coord_id, codefo) - - translate_font_style(text, codefo) + try: + map = text.style_map + except: + map = translate_font_style(text, codefo) + text.style_map = map + attrs = [] + attr = [0,0, text] + attrs.append(attr) - txt_strs = [] + txt_strs = '' for node in text.childNodes: if node.localName == None: - txt_strs.append(node.data) + txt_strs = txt_strs + node.data elif node.localName == 'tspan': - node.setAttribute('style', text.getAttribute('style')) - translate_text(node, coord_id, codefo, doc) + txt_strs = translate_tspan(node,text,coord_id, codefo, doc,txt_strs,attrs) pass pass + attr[1] = len(txt_strs.encode('utf8')) if txt_strs: text_id = _get_id(text) 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' % ( + 'PANGO_BEGIN_TEXT([%s], [%s], %f, %f, 16, [%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 - -@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.hasAttributeNS(xlinkns, 'href'): - raise ValueError, 'image %s must has a href attribute.' % (image_id) - href = image.getAttributeNS(xlinkns, 'href') - if image.hasAttribute('x'): - x_str = image.getAttribute('x') - x = float(x_str) - else: - x = 0 + generate_font_attributes(attrs, coord_id, codefo, doc) + print >> codefo, \ + 'PANGO_END_TEXT([%s], [%s], %f, %f, 16, [%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 - if image.hasAttribute('y'): - y_str = image.getAttribute('y') - y = float(y_str) - else: - y = 0 - pass - if image.hasAttribute('width'): - width_str = image.getAttribute('width') - width = float(width_str) - else: - width = -1 - pass - if image.hasAttribute('height'): - height_str = image.getAttribute('height') - height = float(height_str) - else: - height = -1 - pass - print >> codefo, 'dnl' - print >> codefo, \ - '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]+)\\([^\\)]*\\)') @@ -554,8 +625,9 @@ translate_rect(node, group_id, codefo, doc) elif node.localName == 'text': translate_text(node, group_id, codefo, doc) - elif node.localName == 'image': - translate_image(node, group_id, codefo, doc) + pass + elif node.localName == 'textarea': + translate_textarea(node, group_id, codefo, doc) pass pass pass @@ -601,7 +673,7 @@ def svg_2_code(dom, codefo): for node in dom.childNodes: if node.localName == 'svg' and node.namespaceURI == svgns: - break + break; pass else: raise ValueErr, 'no any svg tag node.'