? build
? os
? svgloader.py.patch
? unnamed.sk
? Plugins/Filters/ailoader.pyc
? Plugins/Filters/epssaver.pyc
? Plugins/Filters/sk1loader.pyc
? Plugins/Filters/skloader.pyc
? Plugins/Filters/sksaver.pyc
? Plugins/Filters/svgloader.pyc
? Plugins/Filters/svgsaver.pyc
? Sketch/__init__.pyc
? Sketch/Base/__init__.pyc
? Sketch/Base/config.pyc
? Sketch/Base/configutil.pyc
? Sketch/Base/connector.pyc
? Sketch/Base/const.pyc
? Sketch/Base/loadres.pyc
? Sketch/Base/skexceptions.pyc
? Sketch/Base/undo.pyc
? Sketch/Base/undodict.pyc
? Sketch/Base/warn.pyc
? Sketch/Editor/__init__.pyc
? Sketch/Editor/builtins.pyc
? Sketch/Editor/command.pyc
? Sketch/Editor/const.pyc
? Sketch/Editor/context.pyc
? Sketch/Editor/curvefunc.pyc
? Sketch/Editor/doceditor.pyc
? Sketch/Editor/document.pyc
? Sketch/Editor/drawbezier.pyc
? Sketch/Editor/drawellipse.pyc
? Sketch/Editor/drawer.pyc
? Sketch/Editor/drawrectangle.pyc
? Sketch/Editor/editbezier.pyc
? Sketch/Editor/editellipse.pyc
? Sketch/Editor/editguide.pyc
? Sketch/Editor/editrectangle.pyc
? Sketch/Editor/edittool.pyc
? Sketch/Editor/handle.pyc
? Sketch/Editor/registry.pyc
? Sketch/Editor/selection.pyc
? Sketch/Editor/selectiontool.pyc
? Sketch/Editor/selrect.pyc
? Sketch/Editor/smoothcurve.pyc
? Sketch/Editor/texttool.pyc
? Sketch/Editor/tools.pyc
? Sketch/Editor/wrapper.pyc
? Sketch/Graphics/__init__.pyc
? Sketch/Graphics/arrow.pyc
? Sketch/Graphics/base.pyc
? Sketch/Graphics/bezier.pyc
? Sketch/Graphics/blend.pyc
? Sketch/Graphics/blendgroup.pyc
? Sketch/Graphics/color.pyc
? Sketch/Graphics/compound.pyc
? Sketch/Graphics/dashes.pyc
? Sketch/Graphics/device.pyc
? Sketch/Graphics/document.pyc
? Sketch/Graphics/ellipse.pyc
? Sketch/Graphics/eps.pyc
? Sketch/Graphics/external.pyc
? Sketch/Graphics/font.pyc
? Sketch/Graphics/gradient.pyc
? Sketch/Graphics/group.pyc
? Sketch/Graphics/guide.pyc
? Sketch/Graphics/image.pyc
? Sketch/Graphics/layer.pyc
? Sketch/Graphics/maskgroup.pyc
? Sketch/Graphics/pagelayout.pyc
? Sketch/Graphics/papersize.pyc
? Sketch/Graphics/pattern.pyc
? Sketch/Graphics/plugobj.pyc
? Sketch/Graphics/properties.pyc
? Sketch/Graphics/psdevice.pyc
? Sketch/Graphics/rectangle.pyc
? Sketch/Graphics/selinfo.pyc
? Sketch/Graphics/text.pyc
? Sketch/Lib/__init__.pyc
? Sketch/Lib/dscparser.pyc
? Sketch/Lib/encoding.pyc
? Sketch/Lib/psmisc.pyc
? Sketch/Lib/readxbm.pyc
? Sketch/Lib/type1.pyc
? Sketch/Lib/units.pyc
? Sketch/Lib/util.pyc
? Sketch/Plugin/__init__.pyc
? Sketch/Plugin/load.pyc
? Sketch/Plugin/loader.pyc
? Sketch/Plugin/plugins.pyc
? Sketch/Plugin/scaffold.pyc
? Sketch/UI/__init__.pyc
? Sketch/UI/canvas.pyc
? Sketch/UI/command.pyc
? Sketch/UI/converters.pyc
? Sketch/UI/cursors.pyc
? Sketch/UI/devcmds.pyc
? Sketch/UI/fillpanel.pyc
? Sketch/UI/gtkdevice.pyc
? Sketch/UI/gtkmisc.pyc
? Sketch/UI/libartdevice.pyc
? Sketch/UI/mainwindow.pyc
? Sketch/UI/menu.pyc
? Sketch/UI/metapanel.pyc
? Sketch/UI/msgpanel.pyc
? Sketch/UI/objectpanel.pyc
? Sketch/UI/palette.pyc
? Sketch/UI/poslabel.pyc
? Sketch/UI/properties.pyc
? Sketch/UI/read_palette.pyc
? Sketch/UI/reload.pyc
? Sketch/UI/scratchpad.pyc
? Sketch/UI/skapp.pyc
? Sketch/UI/skpanel.pyc
? Sketch/UI/skpixmaps.pyc
? Sketch/UI/toolbox.pyc
? Sketch/UI/tree.pyc
? Sketch/UI/view.pyc
? Sketch/UI/viewport.pyc
? test/support.pyc
? test/test_svg11_import.py
? test/volatile
Index: Plugins/Filters/svgloader.py
===================================================================
RCS file: /cvs/gnome/sketch/Plugins/Filters/svgloader.py,v
retrieving revision 1.14
diff -u -r1.14 svgloader.py
--- Plugins/Filters/svgloader.py	10 Nov 2004 18:46:08 -0000	1.14
+++ Plugins/Filters/svgloader.py	12 Dec 2004 10:48:04 -0000
@@ -1,6 +1,5 @@
 # Sketch - A Python-based interactive drawing program
 # Copyright (C) 2004 by Bernhard Herzog
-# Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 by Bernhard Herzog
 # Some code for Text elements contributed by Paul Giotta (2002)
 #
 # This library is free software; you can redistribute it and/or
@@ -74,7 +73,10 @@
 
 
 def csscolor(str):
-    str = strip(str)
+    if str is None:
+        return StandardColors.black 
+    else:
+        str = strip(str)
     if str[0] == '#':
         if len(str) == 7:
             r = atoi(str[1:3], 16) / 255.0
@@ -252,11 +254,119 @@
        'round': const.CapRound,
        'square': const.CapProjecting}
 
+# color and painting properties can occur as attributes
+# http://www.w3c.org/TR/SVG11/styling.html
+painting_properties = {
+    'fill': namedcolors['black'],
+    'fill-opacity': 1,
+    'stroke': 0,
+    'stroke-width':1,
+    'stroke-linejoin':'miter',
+    'stroke-linecap':'butt'
+    }
+    
+
 commatospace = string.maketrans(',', ' ')
 
 rx_command = re.compile(r'[a-df-zA-DF-Z]((\s*[-0-9.e]+)*)\s*')
 rx_trafo = re.compile(r'\s*([a-zA-Z]+)\(((\s*[-0-9.e]+,?)*)\s*\)')
 
+class SVGStyleHandler(object):
+    """ SVGStyleHandler handles svg properties 
+        create the object with a loader.styleCopy() 
+    """
+    def __init__(self, loader):
+        self.loader = loader
+        self.style = loader.style.Copy()
+        self.style.line_pattern = EmptyPattern
+        self.style.fill_pattern = SolidPattern(StandardColors.black)
+        self.style.font = GetFont("Times-Roman")
+        self.style.font_size = 12
+        self.trafo = self.basetrafo = Trafo()
+        
+    def _print(self, *args):
+        return
+        if args:
+            print self.depth * self.indent + args[0],
+        for s in args[1:]:
+            print s,
+        print
+  
+    def __getattr__(self, attr):
+        return getattr(self.style, attr)
+
+    def Copy(self):
+        """ delegating to loader """
+        return SVGStyleHandler(self.loader)
+
+    def IsEmpty(self):
+        return self.style.IsEmpty()
+
+    def try_add_style(self, loaderstyle, attrs):
+        self.style = loaderstyle
+        for style in attrs.keys():
+            try:
+                method = style.replace('-', '_')
+                getattr(self, method)(attrs[style])
+            except AttributeError:
+                pass
+        
+    def parse_style(self, style):
+        self.style = loaderstyle
+        parts = filter(None, map(strip, split(style, ';')))
+        for part in parts:
+            key, val = map(strip, split(part, ':', 1))
+            self._print('style', key, val)
+
+            # only try to parse the value if it's not empty
+            try:
+                getattr(self, key)(val)
+                #self.try_add_style(key, val)
+            except AttributeError:
+                # FIXME: we should probably print a message or something
+                print "no method for attribute: %s" %key
+    
+    def fill(self, val):
+        if val == 'none':
+            self.style.fill_pattern = EmptyPattern
+        else:
+            color = csscolor(val)
+            self.style.fill_pattern = SolidPattern(color)
+
+    def stroke(self, val):
+        if val== 'none':
+            self.style.line_pattern = EmptyPattern
+        else:
+            color = csscolor(val)
+            self.style.line_pattern = SolidPattern(color)
+    
+    def stroke_width(self, val):
+        width = self.user_length(val)
+        # Multiply the width with a value taken from the
+        # transformation matrix because so far transforming an
+        # object in Sketch does not affect the stroke width in any
+        # way. Thus we have to do that explicitly here.
+        # FIXME: using m11 is not really the best approach but in
+        # many cases better than using the width as is.
+        width = self.trafo.m11 * width
+        self.style.line_width = width
+        
+    def user_length(self, str):
+        # interpret string as a length and return the appropriate value
+        # user coordinates
+        str = strip(str)
+        factor = factors.get(str[-2:])
+        if factor is not None:
+            str = str[:-2]
+        elif str[-1] == '%':
+            # FIXME: this case depends on the width/height attrs of the
+            # SVG element
+            str = str[:-1]
+            factor = 1.0
+        else:
+            factor = 1.0
+        return float(str) * factor
+
 
 class SVGHandler(xml.sax.handler.ContentHandler):
 
@@ -265,6 +375,7 @@
                       'circle': 'circle',
                       'ellipse': 'ellipse',
                       'rect': 'rect',
+                      'stop': 'stop',
                       'polyline': 'polyline',
                       'polygon': 'polygon',
                       'path':   'begin_path',
@@ -277,19 +388,14 @@
     dispatch_end = {'g': 'end_group',
                     'path': 'end_path',
                     'defs': 'end_defs',
-                    'text': 'end_text'
+                    'text': 'end_text',
                     }
 
     def __init__(self, loader):
         self.loader = loader
         self.trafo = self.basetrafo = Trafo()
         self.state_stack = ()
-        self.style = loader.style.Copy()
-        self.style.line_pattern = EmptyPattern
-        self.style.fill_pattern = SolidPattern(StandardColors.black)
         self.current_text = ""
-        self.style.font = GetFont("Times-Roman")
-        self.style.font_size = 12
         self.halign = text.ALIGN_LEFT
         self.named_objects = {}
         self.in_defs = 0
@@ -297,6 +403,10 @@
         self.path = None
         self.depth = 0
         self.indent = '    '
+        self.style = loader.style.Copy()
+        self.style.fill_pattern = SolidPattern(StandardColors.black)
+        self.style.line_pattern = EmptyPattern
+        self.sth = SVGStyleHandler(loader)
 
     def _print(self, *args):
         return
@@ -333,7 +443,7 @@
                     trafo = trafo(Trafo(1, tan(args[0] * degrees), 0, 1, 0, 0))
             else:
                 trafo_string = ''
-        #print trafo
+        print trafo
         self.trafo = trafo
 
     def startElement(self, name, attrs):
@@ -398,55 +508,6 @@
                 # FIXME: we should probably print a message or something
                 pass
 
-    def try_add_style(self,key,val):
-        if key == 'fill':
-            if val == 'none':
-                self.style.fill_pattern = EmptyPattern
-            else:
-                color = csscolor(val)
-                self._print('fill', color)
-                self.style.fill_pattern = SolidPattern(color)
-        elif key == 'stroke':
-            if val == 'none':
-                self.style.line_pattern = EmptyPattern
-            else:
-                color = csscolor(val)
-                self._print('stroke', color)
-                self.style.line_pattern = SolidPattern(color)
-        elif key == 'stroke-width':
-            width = self.user_length(val)
-            # Multiply the width with a value taken from the
-            # transformation matrix because so far transforming an
-            # object in Sketch does not affect the stroke width in any
-            # way. Thus we have to do that explicitly here.
-            # FIXME: using m11 is not really the best approach but in
-            # many cases better than using the width as is.
-            width = self.trafo.m11 * width
-            self._print('width', width)
-            self.style.line_width = width
-        elif key == 'stroke-linejoin':
-            self.style.line_join = join[val]
-        elif key == 'stroke-linecap':
-            self.style.line_cap = cap[val]
-        elif key == 'font-family':
-            try:
-                # convert val to 8bit string.
-                self.style.font = GetFont(str(val))
-            except UnicodeError:
-                # If it's not ASCII we probably won't have the font, so
-                # use the default one.
-                # FIXME: Give a warning
-                pass
-        elif key == 'font-size':
-            self.style.font_size = self.user_length(val)
-            ####self.style.font_size = float(val)
-        elif key == 'text-anchor':
-            if val=='start':
-              self.halign = text.ALIGN_LEFT
-            elif val == 'middle':
-              self.halign = text.ALIGN_CENTER
-            elif val == 'end':
-              self.halign = text.ALIGN_RIGHT
 
     def set_loader_style(self, allow_font = 0):
         # Copy self.style to loader.
@@ -536,7 +597,6 @@
             p = self.trafo(x, y)
         return p
 
-
     def circle(self, attrs):
         if self.in_defs:
             id = attrs.get('id', '')
@@ -555,6 +615,8 @@
         r = self.point(attrs['r'], '0', relative = 1).x
         t = Trafo(r, 0, 0, r, x, y)
         self._print('circle', t)
+        
+        self.sth.try_add_style(self.style, attrs)
         style = attrs.get('style', '')
         if style:
             self.parse_style(style)
@@ -579,6 +641,8 @@
         rx, ry = self.point(attrs['rx'], attrs['ry'], relative = 1)
         t = Trafo(rx, 0, 0, ry, x, y)
         self._print('ellipse', t)
+        
+        self.sth.try_add_style(self.style, attrs)
         style = attrs.get('style', '')
         if style:
             self.parse_style(style)
@@ -600,17 +664,37 @@
             y = attrs['y']
         else:
             y = '0'
+
         x, y = self.point(x, y)
         wx, wy = self.point(attrs['width'], "0", relative = 1)
         hx, hy = self.point("0", attrs['height'], relative = 1)
         t = Trafo(wx, wy, hx, hy, x, y)
         self._print('rect', t)
+        rx = self.user_length(attrs.get('rx', '0'))
+        ry = self.user_length(attrs.get('ry', '0.1'))
+        width = self.user_length(attrs.get('width', '0'))
+        height = self.user_length(attrs.get('height', '0'))
+        
+        self.sth.try_add_style(self.style, attrs)
         style = attrs.get('style', '')
         if style:
-            self.parse_style(style)
+            #XXX don't work
+            self.style.parse_style(style)
         self.set_loader_style()
-        apply(self.loader.rectangle, t.coeff())
-
+        transform = t.coeff()
+        transform += (rx/width, rx/height)
+        print transform
+        apply(self.loader.rectangle, transform)
+
+    def stop(self, attrs):
+        """ a stop is a child element for gradients, which define the
+            colors to use
+        """
+        offset = attrs.get('offset', 0)
+        color = attrs.get('stop-color', namedcolors['black'])
+        color = csscolor(color)
+        return MultiGradient((offset, color))
+    
     def polyline(self, attrs):
         if self.in_defs:
             id = attrs.get('id', '')
@@ -645,6 +729,8 @@
             path.AppendLine(point(points[i], points[i + 1]))
         path.AppendLine(path.Node(0))
         path.ClosePath()
+        self.sth.try_add_style(self.style, attrs)
+        
         style = attrs.get('style', '')
         if style:
             self.parse_style(style)
@@ -974,10 +1060,8 @@
         try:
             self.document()
             self.layer()
-
             parser = make_parser()
             parser.setContentHandler(SVGHandler(self))
-
             # Make sure that we don't try to fetch DTDs etc.  We
             # currently don't use a validating parser anyway, and
             # fetching DTDs everytime we parse an SVG document is
