diff options
author | Sin Nombre <sin@ubuntu.(none)> | 2010-05-28 20:45:29 (GMT) |
---|---|---|
committer | Sin Nombre <sin@ubuntu.(none)> | 2010-05-28 20:45:29 (GMT) |
commit | 9e93d1b9802385900b6f833f81f84c0ac50f91ef (patch) | |
tree | f2c16599bde31b31e5d44bae4a87e7e4093f3cab /olpcgames/svgsprite.py | |
parent | ac8cbb6691ba3de1c7c42f4362edbe11270f4506 (diff) |
Diffstat (limited to 'olpcgames/svgsprite.py')
-rwxr-xr-x | olpcgames/svgsprite.py | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/olpcgames/svgsprite.py b/olpcgames/svgsprite.py new file mode 100755 index 0000000..ad247dd --- /dev/null +++ b/olpcgames/svgsprite.py @@ -0,0 +1,84 @@ +"""RSVG/Cairo-based rendering of SVG into Pygame Images""" +from pygame import sprite, Rect +from olpcgames import _cairoimage + +class SVGSprite( sprite.Sprite ): + """Sprite class which renders SVG source-code as a Pygame image + + Note: + + Currently this sprite class is a bit over-engineered, it gets in the way + if you want to, e.g. animate among a number of SVG drawings, as it + assumes that setSVG will always set a single SVG file for rendering. + """ + rect = image = None + resolution = None + def __init__( + self, svg=None, size=None, *args + ): + """Initialise the svg sprite + + svg -- svg source text (i.e. content of an svg file) + size -- optional, to constrain size, (width,height), leaving one + as None or 0 causes proportional scaling, leaving both + as None or 0 causes natural scaling (screen resolution) + args -- if present, groups to which to automatically add + """ + self.size = size + super( SVGSprite, self ).__init__( *args ) + if svg: + self.setSVG( svg ) + def setSVG( self, svg ): + """Set our SVG source""" + self.svg = svg + # XXX could delay this until actually asked to display... + if self.size: + width,height = self.size + else: + width,height = None,None + self.image = self._render( width,height ).convert_alpha() + rect = self.image.get_rect() + if self.rect: + rect.move( self.rect ) # should let something higher-level do that... + self.rect = rect + + def _render( self, width, height ): + """Render our SVG to a Pygame image""" + import rsvg + handle = rsvg.Handle( data = self.svg ) + originalSize = (width,height) + scale = 1.0 + hw,hh = handle.get_dimension_data()[:2] + if hw and hh: + if not width: + if not height: + width,height = hw,hh + else: + scale = float(height)/hh + width = hh/float(hw) * height + elif not height: + scale = float(width)/hw + height = hw/float(hh) * width + else: + # scale only, only rendering as large as it is... + if width/height > hw/hh: + # want it taller than it is... + width = hh/float(hw) * height + else: + height = hw/float(hh) * width + scale = float(height)/hh + + csrf, ctx = _cairoimage.newContext( int(width), int(height) ) + ctx.scale( scale, scale ) + handle.render_cairo( ctx ) + return _cairoimage.asImage( csrf ) + return None + def copy( self ): + """Create a copy of this sprite without reloading the svg image""" + result = self.__class__( + size = self.size + ) + result.image = self.image + result.rect = Rect(self.rect) + result.resolution = self.resolution + return result |