1 |
# Copyright (c) 2001, 2002, 2003 by Intevation GmbH |
# Copyright (c) 2001, 2002, 2003, 2004 by Intevation GmbH |
2 |
# Authors: |
# Authors: |
3 |
# Markus Rechtien <[email protected]> |
# Markus Rechtien <[email protected]> |
4 |
# |
# |
5 |
# This program is free software under the GPL (>=v2) |
# This program is free software under the GPL (>=v2) |
6 |
# Read the file COPYING coming with Thuban for details. |
# Read the file COPYING coming with Thuban for details. |
7 |
|
|
|
__version__ = "$Revision$" |
|
|
# $Source$ |
|
|
# $Id$ |
|
|
|
|
8 |
|
|
9 |
""" |
""" |
10 |
Classes needed to write a session in SVG format |
Classes needed to write a session in SVG format |
11 |
""" |
""" |
12 |
|
|
13 |
|
# For compatibility with python 2.2 |
|
# For compatibility with python > 2.3 |
|
14 |
from __future__ import generators |
from __future__ import generators |
15 |
|
|
16 |
|
|
17 |
|
__version__ = "$Revision$" |
18 |
|
# $Source$ |
19 |
|
# $Id$ |
20 |
|
|
21 |
|
|
22 |
# Regular expressions used with Fontnames |
# Regular expressions used with Fontnames |
23 |
import re |
import re |
24 |
# Combining strings |
# Combining strings |
25 |
from string import join |
from string import join |
26 |
# We need to determine some object types |
# We need to determine some object types |
27 |
from types import ListType, TupleType |
from types import ListType |
28 |
# VirtualDC extends XMLWriter |
# VirtualDC extends XMLWriter |
29 |
from Thuban.Model.xmlwriter import XMLWriter, escape |
from Thuban.Model.xmlwriter import XMLWriter, escape |
30 |
# Color related classes from the model of thuban |
# Color related classes from the model of thuban |
31 |
from Thuban.Model.color import Transparent, Color, Black |
from Thuban.Model.color import Transparent, Black |
32 |
# The SVGRenderer is subclass of BaseRenderer |
# The SVGRenderer is subclass of BaseRenderer |
33 |
from Thuban.UI.baserenderer import BaseRenderer |
from Thuban.UI.baserenderer import BaseRenderer |
34 |
|
|
47 |
# Some pseudo classes to be compatible with the Baserenderer-class. |
# Some pseudo classes to be compatible with the Baserenderer-class. |
48 |
# |
# |
49 |
class Point: |
class Point: |
50 |
'''A simple Point class.''' |
"""A simple Point class.""" |
51 |
def __init__(self, xp=0, yp=0): |
def __init__(self, xp=0, yp=0): |
52 |
'''Init the point object.''' |
"""Init the point object.""" |
53 |
self.x = xp |
self.x = xp |
54 |
self.y = yp |
self.y = yp |
55 |
|
|
56 |
class Trafo: |
class Trafo: |
57 |
'''Class for tranformation properties transfer.''' |
"""Class for tranformation properties transfer.""" |
58 |
def __init__(self): |
def __init__(self): |
59 |
'''Initialize the class.''' |
"""Initialize the class.""" |
60 |
self.trafos = [] |
self.trafos = [] |
61 |
|
|
62 |
def Append(self, type, coeffs): |
def Append(self, type, coeffs): |
63 |
'''Append a transformation to the list.''' |
"""Append a transformation to the list.""" |
64 |
self.trafos.append((type, coeffs)) |
self.trafos.append((type, coeffs)) |
65 |
|
|
66 |
def Count(self): |
def Count(self): |
67 |
'''Get the number of transformations in list.''' |
"""Get the number of transformations in list.""" |
68 |
return len(self.trafos) |
return len(self.trafos) |
69 |
|
|
70 |
def Pop(self): |
def Pop(self): |
71 |
'''Pop and return a transformation from the end of the list.''' |
"""Pop and return a transformation from the end of the list.""" |
72 |
if len(self.trafos) > 0: |
if len(self.trafos) > 0: |
73 |
return self.trafos.pop() |
return self.trafos.pop() |
74 |
else: return None |
else: return None |
75 |
|
|
76 |
class Pattern: |
class Pattern: |
77 |
'''Pattern object ''' |
"""Pattern object """ |
78 |
def __init__(self, solid=1): |
def __init__(self, solid=1): |
79 |
'''Init the Pattern object.''' |
"""Init the Pattern object.""" |
80 |
self.solid = solid |
self.solid = solid |
81 |
|
|
82 |
class Pen: |
class Pen: |
83 |
'''Pen object for property transfer.''' |
"""Pen object for property transfer.""" |
84 |
def __init__(self, pcolor = Black, pwidth = 1, pdashes = None): |
def __init__(self, pcolor = Black, pwidth = 1, pdashes = None): |
85 |
self.color = pcolor |
self.color = pcolor |
86 |
self.width = pwidth |
self.width = pwidth |
89 |
self.cap = 'round' |
self.cap = 'round' |
90 |
|
|
91 |
def GetColor(self): |
def GetColor(self): |
92 |
'''Return the pen's color.''' |
"""Return the pen's color.""" |
93 |
return self.color |
return self.color |
94 |
|
|
95 |
def GetWidth(self): |
def GetWidth(self): |
96 |
'''Return the pen's width.''' |
"""Return the pen's width.""" |
97 |
return self.width |
return self.width |
98 |
|
|
99 |
def GetJoin(self): |
def GetJoin(self): |
100 |
'''Return the pen's join type.''' |
"""Return the pen's join type.""" |
101 |
return self.join |
return self.join |
102 |
|
|
103 |
def GetCap(self): |
def GetCap(self): |
104 |
'''Return the pen's cap type.''' |
"""Return the pen's cap type.""" |
105 |
return self.cap |
return self.cap |
106 |
|
|
107 |
def GetDashes(self): |
def GetDashes(self): |
108 |
'''Return the pen's dashes.''' |
"""Return the pen's dashes.""" |
109 |
if self.dashes is None or self.dashes is SOLID: |
if self.dashes is None or self.dashes is SOLID: |
110 |
return [] |
return [] |
111 |
else: return self.dashes |
else: return self.dashes |
112 |
|
|
113 |
class Brush: |
class Brush: |
114 |
'''Brush property class.''' |
"""Brush property class.""" |
115 |
def __init__(self, bfill=Black, bpattern=None): |
def __init__(self, bfill=Black, bpattern=None): |
116 |
'''Init the brush with the given values.''' |
"""Init the brush with the given values.""" |
117 |
self.fill = bfill |
self.fill = bfill |
118 |
self.pattern = bpattern |
self.pattern = bpattern |
119 |
|
|
120 |
def GetColor(self): |
def GetColor(self): |
121 |
'''Return the brush color.''' |
"""Return the brush color.""" |
122 |
return self.fill |
return self.fill |
123 |
|
|
124 |
def GetPattern(self): |
def GetPattern(self): |
125 |
'''Return the Brush pattern object.''' |
"""Return the Brush pattern object.""" |
126 |
return self.pattern |
return self.pattern |
127 |
|
|
128 |
class Font: |
class Font: |
129 |
'''Font class that accts as property object.''' |
"""Font class that accts as property object.""" |
130 |
def __init__(self, ffamily='Helvetica', fsize=12): |
def __init__(self, ffamily='Helvetica', fsize=12): |
131 |
'''Init the font with the given values.''' |
"""Init the font with the given values.""" |
132 |
self.family = ffamily |
self.family = ffamily |
133 |
self.size = fsize |
self.size = fsize |
134 |
|
|
135 |
def GetFaceName(self): |
def GetFaceName(self): |
136 |
'''Return the fontfamily the font belongs to.''' |
"""Return the fontfamily the font belongs to.""" |
137 |
return self.family |
return self.family |
138 |
|
|
139 |
def GetPointSize(self): |
def GetPointSize(self): |
140 |
'''Return the size of the font in points.''' |
"""Return the size of the font in points.""" |
141 |
return self.size |
return self.size |
142 |
|
|
143 |
# Instantiate an empty pen. |
# Instantiate an empty pen. |
158 |
""" |
""" |
159 |
def __init__(self, dc, map, scale, offset, region, |
def __init__(self, dc, map, scale, offset, region, |
160 |
resolution = 1.0, honor_visibility = 1): |
resolution = 1.0, honor_visibility = 1): |
161 |
'''Init SVGRenderer and call superclass init.''' |
"""Init SVGRenderer and call superclass init.""" |
162 |
BaseRenderer.__init__(self, dc, map, scale, offset, region, |
BaseRenderer.__init__(self, dc, map, scale, offset, region, |
163 |
resolution, honor_visibility) |
resolution, honor_visibility) |
164 |
# |
# |
165 |
self.factor = (abs(region[2]) + abs(region[3])) / (2.0 * 1000.0) |
self.factor = (abs(region[2]) + abs(region[3])) / (2.0 * 1000.0) |
166 |
|
|
167 |
def make_point(self, x, y): |
def make_point(self, x, y): |
168 |
'''Return a Point object from two values.''' |
"""Return a Point object from two values.""" |
169 |
return Point(x, y) |
return Point(x, y) |
170 |
|
|
171 |
def label_font(self): |
def label_font(self): |
173 |
return Font() |
return Font() |
174 |
|
|
175 |
def tools_for_property(self, prop): |
def tools_for_property(self, prop): |
176 |
'''Return a pen/brush tuple build from a property object.''' |
"""Return a pen/brush tuple build from a property object.""" |
177 |
fill = prop.GetFill() |
fill = prop.GetFill() |
178 |
if fill is Transparent: |
if fill is Transparent: |
179 |
brush = TRANSPARENT_BRUSH |
brush = TRANSPARENT_BRUSH |
298 |
dc.EndGroup() |
dc.EndGroup() |
299 |
|
|
300 |
def draw_raster_layer(self, layer): |
def draw_raster_layer(self, layer): |
301 |
'''Draw the raster layer''' |
"""Draw the raster layer""" |
302 |
# For now we cannot draw raster layers onto our VirtualDC |
# For now we cannot draw raster layers onto our VirtualDC |
303 |
pass |
pass |
304 |
|
|
308 |
pass |
pass |
309 |
|
|
310 |
def RenderMap(self, selected_layer, selected_shapes): |
def RenderMap(self, selected_layer, selected_shapes): |
311 |
'''Overriden to avoid automatic rendering of legend, |
"""Overriden to avoid automatic rendering of legend, |
312 |
scalbar and frame. |
scalbar and frame. |
313 |
''' |
""" |
314 |
dc = self.dc |
dc = self.dc |
315 |
self.selected_layer = selected_layer |
self.selected_layer = selected_layer |
316 |
self.selected_shapes = selected_shapes |
self.selected_shapes = selected_shapes |
330 |
|
|
331 |
|
|
332 |
class VirtualDC(XMLWriter): |
class VirtualDC(XMLWriter): |
333 |
'''This class imitates a DC and writes SVG instead. |
"""This class imitates a DC and writes SVG instead. |
334 |
|
|
335 |
All shapes and graphic objects will be turned into |
All shapes and graphic objects will be turned into |
336 |
SVG elements and will be written into a file. |
SVG elements and will be written into a file. |
337 |
Any properties, such as stroke width or stroke color, |
Any properties, such as stroke width or stroke color, |
338 |
will be written together with the SVG elementents. |
will be written together with the SVG elementents. |
339 |
''' |
""" |
340 |
def __init__(self, file, dim=(0,0), units=''): |
def __init__(self, file, dim=(0,0), units=''): |
341 |
'''Setup some variables and objects for property collection.''' |
"""Setup some variables and objects for property collection.""" |
342 |
XMLWriter.__init__(self) |
XMLWriter.__init__(self) |
343 |
self.dim = dim |
self.dim = dim |
344 |
self.units = units |
self.units = units |
354 |
self.write(file) |
self.write(file) |
355 |
|
|
356 |
def write_indent(self, str): |
def write_indent(self, str): |
357 |
'''Write a string to the file with the current indention level. |
"""Write a string to the file with the current indention level. |
358 |
''' |
""" |
359 |
from Thuban.Model.xmlwriter import TAB |
from Thuban.Model.xmlwriter import TAB |
360 |
self.file.write("%s%s" % (TAB*self.indent_level, str)) |
self.file.write("%s%s" % (TAB*self.indent_level, str)) |
361 |
|
|
362 |
def AddMeta(self, key, val): |
def AddMeta(self, key, val): |
363 |
'''Append some metadata to the array that will be |
"""Append some metadata to the array that will be |
364 |
written with the next svg-element |
written with the next svg-element |
365 |
''' |
""" |
366 |
if key is '' or val is '': |
if key is '' or val is '': |
367 |
return |
return |
368 |
self.meta[key] = val |
self.meta[key] = val |
369 |
|
|
370 |
def SetMeta(self, pairs, flush_after=1): |
def SetMeta(self, pairs, flush_after=1): |
371 |
'''Delete old meta informations and set the new ones.''' |
"""Delete old meta informations and set the new ones.""" |
372 |
self.meta = {} |
self.meta = {} |
373 |
self.flush_meta = flush_after |
self.flush_meta = flush_after |
374 |
for key, val in pairs.items(): |
for key, val in pairs.items(): |
375 |
self.AddMeta(key, val) |
self.AddMeta(key, val) |
376 |
|
|
377 |
def FlushMeta(self): |
def FlushMeta(self): |
378 |
'''Drop collected metadata.''' |
"""Drop collected metadata.""" |
379 |
self.meta = {} |
self.meta = {} |
380 |
|
|
381 |
def BeginGroup(self, **args): |
def BeginGroup(self, **args): |
382 |
'''Begin a group of elements. |
"""Begin a group of elements. |
383 |
|
|
384 |
Possible arguments: |
Possible arguments: |
385 |
meta A list of key, value metadata pairs |
meta A list of key, value metadata pairs |
386 |
style A list of key, value style attributes |
style A list of key, value style attributes |
387 |
clipid The ID of a clipPath definition to be |
clipid The ID of a clipPath definition to be |
388 |
applied to this group |
applied to this group |
389 |
''' |
""" |
390 |
self.FlushMeta() |
self.FlushMeta() |
391 |
# adding meta data |
# adding meta data |
392 |
if args.has_key('meta'): |
if args.has_key('meta'): |
411 |
self.indent_level += 1 |
self.indent_level += 1 |
412 |
|
|
413 |
def parse_trafo(self, trafo): |
def parse_trafo(self, trafo): |
414 |
'''Examine a trafo object for asigned transformations details.''' |
"""Examine a trafo object for asigned transformations details.""" |
415 |
if not trafo: |
if not trafo: |
416 |
return '' |
return '' |
417 |
retval = '' |
retval = '' |
424 |
return retval |
return retval |
425 |
|
|
426 |
def EndGroup(self): |
def EndGroup(self): |
427 |
'''End a group of elements''' |
"""End a group of elements""" |
428 |
self.indent_level -= 1 |
self.indent_level -= 1 |
429 |
self.write_indent('</g>\n') |
self.write_indent('</g>\n') |
430 |
self.FlushMeta() |
self.FlushMeta() |
431 |
|
|
432 |
def BeginExport(self): |
def BeginExport(self): |
433 |
'''Start the export process and write basic document |
"""Start the export process and write basic document |
434 |
informations to the file. |
informations to the file. |
435 |
''' |
""" |
436 |
self.write_indent('<?xml version="1.0" encoding="ISO-8859-1" ' |
self.write_indent('<?xml version="1.0" encoding="ISO-8859-1" ' |
437 |
'standalone="yes"?>\n') |
'standalone="yes"?>\n') |
438 |
width, height = self.dim |
width, height = self.dim |
440 |
self.indent_level += 1 |
self.indent_level += 1 |
441 |
|
|
442 |
def EndExport(self): |
def EndExport(self): |
443 |
'''End the export process with closing the SVG tag and close |
"""End the export process with closing the SVG tag and close |
444 |
the file accessor''' |
the file accessor""" |
445 |
self.indent_level -= 1 |
self.indent_level -= 1 |
446 |
self.write_indent('</svg>\n') |
self.write_indent('</svg>\n') |
447 |
self.close() |
self.close() |
448 |
|
|
449 |
def Close(self): |
def Close(self): |
450 |
'''Close the file.''' |
"""Close the file.""" |
451 |
self.close() |
self.close() |
452 |
|
|
453 |
def BeginDrawing(self): |
def BeginDrawing(self): |
454 |
'''Dummy function to work with the Thuban renderers.''' |
"""Dummy function to work with the Thuban renderers.""" |
455 |
pass |
pass |
456 |
|
|
457 |
def EndDrawing(self): |
def EndDrawing(self): |
458 |
'''Dummy function to work with the Thuban renderers.''' |
"""Dummy function to work with the Thuban renderers.""" |
459 |
pass |
pass |
460 |
|
|
461 |
def GetSizeTuple(self): |
def GetSizeTuple(self): |
462 |
'''Return the dimension of this virtual canvas.''' |
"""Return the dimension of this virtual canvas.""" |
463 |
return self.dim |
return self.dim |
464 |
|
|
465 |
def GetTextExtent(self, text): |
def GetTextExtent(self, text): |
466 |
'''Return the dimension of the given text.''' |
"""Return the dimension of the given text.""" |
467 |
# FIXME: find something more appropriate |
# FIXME: find something more appropriate |
468 |
try: |
try: |
469 |
if self.font: |
if self.font: |
474 |
return (12,len(text) * 10) |
return (12,len(text) * 10) |
475 |
|
|
476 |
def SetID(self, id): |
def SetID(self, id): |
477 |
'''Set the ID stored by the svg elements.''' |
"""Set the ID stored by the svg elements.""" |
478 |
self.id = id |
self.id = id |
479 |
|
|
480 |
def SetBaseID(self, id): |
def SetBaseID(self, id): |
481 |
'''Set the ID stored by the svg elements.''' |
"""Set the ID stored by the svg elements.""" |
482 |
self.baseid = id |
self.baseid = id |
483 |
|
|
484 |
def SetFont(self, font): |
def SetFont(self, font): |
485 |
'''Set the fontproperties to use with text elements.''' |
"""Set the fontproperties to use with text elements.""" |
486 |
if font is not None: |
if font is not None: |
487 |
fontname = font.GetFaceName() |
fontname = font.GetFaceName() |
488 |
size = font.GetPointSize() |
size = font.GetPointSize() |
498 |
else: self.font["font-size"] = None |
else: self.font["font-size"] = None |
499 |
|
|
500 |
def SetPen(self, pen): |
def SetPen(self, pen): |
501 |
'''Set the style of the pen used to draw graphics.''' |
"""Set the style of the pen used to draw graphics.""" |
502 |
if pen is TRANSPARENT_PEN: |
if pen is TRANSPARENT_PEN: |
503 |
self.pen = {} |
self.pen = {} |
504 |
else: |
else: |
509 |
self.pen["stroke-linecap"] = svg_caps[pen.GetCap()] |
self.pen["stroke-linecap"] = svg_caps[pen.GetCap()] |
510 |
|
|
511 |
def SetBrush(self, brush): |
def SetBrush(self, brush): |
512 |
'''Set the fill properties.''' |
"""Set the fill properties.""" |
513 |
if brush is TRANSPARENT_BRUSH: |
if brush is TRANSPARENT_BRUSH: |
514 |
self.brush['fill'] = 'none' |
self.brush['fill'] = 'none' |
515 |
elif brush.GetPattern() is SOLID: |
elif brush.GetPattern() is SOLID: |
518 |
pass |
pass |
519 |
|
|
520 |
def SetTextForeground(self, color): |
def SetTextForeground(self, color): |
521 |
'''Set the color of the text foreground.''' |
"""Set the color of the text foreground.""" |
522 |
self.font['fill'] = color.hex() |
self.font['fill'] = color.hex() |
523 |
|
|
524 |
def make_style(self, line=0, fill=0, font=0): |
def make_style(self, line=0, fill=0, font=0): |
525 |
'''Build the style attribute including desired properties |
"""Build the style attribute including desired properties |
526 |
such as fill, forground, stroke, etc.''' |
such as fill, forground, stroke, etc.""" |
527 |
result = [] |
result = [] |
528 |
# little helper function |
# little helper function |
529 |
def append(pairs): |
def append(pairs): |
544 |
return '' |
return '' |
545 |
|
|
546 |
def make_meta(self, meta=None): |
def make_meta(self, meta=None): |
547 |
'''Build the meta attribute.''' |
"""Build the meta attribute.""" |
548 |
result = [] |
result = [] |
549 |
if not meta: |
if not meta: |
550 |
meta = self.meta |
meta = self.meta |
558 |
return 'meta="%s"' % (join(result, '; ')) |
return 'meta="%s"' % (join(result, '; ')) |
559 |
|
|
560 |
def make_id(self): |
def make_id(self): |
561 |
'''Get the ID for the next object - if current ID is valid.''' |
"""Get the ID for the next object - if current ID is valid.""" |
562 |
if self.id < 0: |
if self.id < 0: |
563 |
return '' |
return '' |
564 |
else: return 'id="%s%s"' % (self.baseid, self.id) |
else: return 'id="%s%s"' % (self.baseid, self.id) |
565 |
|
|
566 |
def DrawEllipse(self, x, y, dx, dy): |
def DrawEllipse(self, x, y, dx, dy): |
567 |
'''Draw an ellipse.''' |
"""Draw an ellipse.""" |
568 |
elips = '<ellipse cx="%s" cy="%s" rx="%s" ry="%s" %s %s %s/>\n' |
elips = '<ellipse cx="%s" cy="%s" rx="%s" ry="%s" %s %s %s/>\n' |
569 |
self.write_indent(elips % (x, y, dx, dy, self.make_id(), |
self.write_indent(elips % (x, y, dx, dy, self.make_id(), |
570 |
self.make_style(1,1,0), self.make_meta()) ) |
self.make_style(1,1,0), self.make_meta()) ) |
571 |
|
|
572 |
def DrawCircle(self, x, y, radius): |
def DrawCircle(self, x, y, radius): |
573 |
'''Draw a circle onto the virtual dc.''' |
"""Draw a circle onto the virtual dc.""" |
574 |
self.write_indent('<circle cx="%s" cy="%s" r="%s" %s %s %s/>\n' % |
self.write_indent('<circle cx="%s" cy="%s" r="%s" %s %s %s/>\n' % |
575 |
(x, y, radius, self.make_id(), self.make_style(1,1,0), |
(x, y, radius, self.make_id(), self.make_style(1,1,0), |
576 |
self.make_meta()) ) |
self.make_meta()) ) |
577 |
|
|
578 |
def DrawRectangle(self, x, y, width, height): |
def DrawRectangle(self, x, y, width, height): |
579 |
'''Draw a rectangle with the given parameters.''' |
"""Draw a rectangle with the given parameters.""" |
580 |
rect = '<rect x="%s" y="%s" width="%s" height="%s" %s %s %s/>\n' |
rect = '<rect x="%s" y="%s" width="%s" height="%s" %s %s %s/>\n' |
581 |
self.write_indent(rect % ( x, y, width, height, self.make_id(), |
self.write_indent(rect % ( x, y, width, height, self.make_id(), |
582 |
self.make_style(1,1,0), self.make_meta()) ) |
self.make_style(1,1,0), self.make_meta()) ) |
583 |
|
|
584 |
def DrawText(self, text, x, y): |
def DrawText(self, text, x, y): |
585 |
'''Draw Text at the given position.''' |
"""Draw Text at the given position.""" |
586 |
beginText = '<text x="%s" y="%s" %s %s %s>' |
beginText = '<text x="%s" y="%s" %s %s %s>' |
587 |
self.write_indent(beginText % ( x, y, self.make_id(), |
self.write_indent(beginText % ( x, y, self.make_id(), |
588 |
self.make_style(0,0,1), self.make_meta()) ) |
self.make_style(0,0,1), self.make_meta()) ) |
590 |
self.file.write('</text>\n') |
self.file.write('</text>\n') |
591 |
|
|
592 |
def DrawLines(self, points): |
def DrawLines(self, points): |
593 |
'''Draw some points into a Buffer that will be |
"""Draw some points into a Buffer that will be |
594 |
written before the next object. |
written before the next object. |
595 |
''' |
""" |
596 |
self.DrawPolygon(points,0) |
self.DrawPolygon(points,0) |
597 |
|
|
598 |
def DrawPolygon(self, polygon, closed=1): |
def DrawPolygon(self, polygon, closed=1): |
599 |
'''Draw a polygon onto the virtual dc.''' |
"""Draw a polygon onto the virtual dc.""" |
600 |
self.write_indent('<path %s ' % (self.make_style(1,1,0))) |
self.write_indent('<path %s ' % (self.make_style(1,1,0))) |
601 |
data = [] |
data = [] |
602 |
i = 0 |
i = 0 |
614 |
self.make_meta(), join(data, '') ) ) |
self.make_meta(), join(data, '') ) ) |
615 |
|
|
616 |
def DrawSpline(self, points, closed=0): |
def DrawSpline(self, points, closed=0): |
617 |
'''Draw a spline object. |
"""Draw a spline object. |
618 |
''' |
""" |
619 |
self.DrawPolygon(points, 0) |
self.DrawPolygon(points, 0) |
620 |
print "TODO: DrawSpline(..)" |
print "TODO: DrawSpline(..)" |
621 |
return # TODO: Implement |
return # TODO: Implement |
622 |
|
|
623 |
def BeginClipPath(self, id): |
def BeginClipPath(self, id): |
624 |
'''Build a clipping region to draw in.''' |
"""Build a clipping region to draw in.""" |
625 |
self.write_indent('<clipPath id="%s">\n' % id) |
self.write_indent('<clipPath id="%s">\n' % id) |
626 |
self.indent_level += 1 |
self.indent_level += 1 |
627 |
|
|
628 |
def EndClipPath(self): |
def EndClipPath(self): |
629 |
'''End a clip path.''' |
"""End a clip path.""" |
630 |
self.indent_level -= 1 |
self.indent_level -= 1 |
631 |
self.write_indent("</clipPath>\n") |
self.write_indent("</clipPath>\n") |