diff options
author | Reinier Heeres <reinier@heeres.eu> | 2007-09-07 14:04:24 (GMT) |
---|---|---|
committer | Reinier Heeres <reinier@heeres.eu> | 2007-09-07 14:04:24 (GMT) |
commit | b0cca9f16f0a57ea07c8a27f4421311e96b41680 (patch) | |
tree | 99128b2f913aaaf3bd3f4bb6345f2cb1fca304e0 | |
parent | d804d55f4cdde65b74bb105fca60b0494211f4d5 (diff) |
Basic plot() support!
-rw-r--r-- | calculate.py | 131 | ||||
-rw-r--r-- | eqnparser.py | 105 | ||||
-rw-r--r-- | layout.py | 9 | ||||
-rw-r--r-- | mathlib.py | 5 | ||||
-rw-r--r-- | plotlib.py | 138 | ||||
-rw-r--r-- | svgimage.py | 55 |
6 files changed, 338 insertions, 105 deletions
diff --git a/calculate.py b/calculate.py index 5e78185..ff00a1d 100644 --- a/calculate.py +++ b/calculate.py @@ -31,6 +31,7 @@ import pygtk pygtk.require('2.0') import gtk import pango +import base64 from sugar.activity import activity from sugar.presence import presenceservice @@ -43,6 +44,7 @@ from sharedstate.sharedstate import SharingHelper from layout import CalcLayout from mathlib import MathLib from eqnparser import EqnParser +from svgimage import SVGImage class Equation: def __init__(self, label=None, eqn=None, res=None, col=None, owner=None, str=None): @@ -59,8 +61,13 @@ class Equation: self.owner = owner def __str__(self): - return "%s;%s;%s;%s;%s\n" % \ - (self.label, self.equation, self.result, self.color.to_string(), self.owner) + if isinstance(self.result, SVGImage): + svg_data = "<svg>" + base64.b64encode(self.result.get_svg_data()) + return "%s;%s;%s;%s;%s\n" % \ + (self.label, self.equation, svg_data, self.color.to_string(), self.owner) + else: + return "%s;%s;%s;%s;%s\n" % \ + (self.label, self.equation, self.result, self.color.to_string(), self.owner) def parse(self, str): str = str.rstrip("\r\n") @@ -68,6 +75,10 @@ class Equation: if len(l) != 5: _logger.error('Equation.parse() string invalid (%s)', str) return False + + if l[2].startswith("<svg>"): + l[2] = SVGImage(data=base64.b64decode(l[2][5:])) + self.set(l[0], l[1], l[2], XoColor(color_string=l[3]), l[4]) class Calculate(activity.Activity): @@ -133,10 +144,19 @@ class Calculate(activity.Activity): IDENTIFIER_CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ " def __init__(self, handle): - try: - activity.Activity.__init__(self, handle) - except Exception, inst: - _logger.error('Exception: %s', inst) + activity.Activity.__init__(self, handle) + + self.helper_old_eqs = [] + + self.ml = MathLib() + self.parser = EqnParser(self.ml) + + self.clipboard = "" + self.select_reason = self.SELECT_SELECT + self.buffer = "" + self.showing_version = 0 + self.showing_error = False + self.show_vars = False self.set_title("Calculate") self.connect("key_press_event", self.keypress_cb) @@ -145,29 +165,18 @@ class Calculate(activity.Activity): ## self.icon = CanvasIcon( ## icon_name = 'theme:stock-buddy', ## xo_color = XoColor(self.color)) + self.layout = CalcLayout(self) self.label_entry = self.layout.label_entry self.text_entry = self.layout.text_entry self.history = self.layout.history self.last_eq = self.layout.last_eq.get_buffer() - - self.ml = MathLib() - self.parser = EqnParser(self.ml) - - self.clipboard = "" - self.select_reason = self.SELECT_SELECT - self.buffer = "" - self.showing_version = 0 - self.showing_error = False - self.show_vars = False self.presence = presenceservice.get_instance() self.owner = self.presence.get_owner() self.owner_id = str(self.owner._properties["nick"]) _logger.debug('Owner_id: %s', self.owner_id) - self.helper_old_eqs = [] - options = { 'receive_message': self.receive_message, 'on_connect': lambda: self.helper.send_message("req_sync", "") @@ -187,7 +196,7 @@ class Calculate(activity.Activity): _logger.info('\t%s', f) self.reset() - self.load_journal_entry() + self.layout.show_it() def ignore_key_cb(self, widget, event): return True @@ -234,12 +243,15 @@ class Calculate(activity.Activity): offset = 0 if eqn.result is not None: - text += '\n= ' + self.ml.format_number(eqn.result) + if isinstance(eqn.result, SVGImage): + pass + else: + text += '\n= ' + self.ml.format_number(eqn.result) + self.parser.set_var('Ans', self.ml.format_number(eqn.result)) + if len(eqn.label) > 0: + self.parser.set_var(eqn.label, eqn.equation) self.text_entry.set_text('') - self.parser.set_var('Ans', self.ml.format_number(eqn.result)) - if len(eqn.label) > 0: - self.label_entry.set_text('') - self.parser.set_var(eqn.label, eqn.equation) + self.label_entry.set_text('') else: pos = self.parser.get_error_offset() if pos == len(text) - 1: @@ -263,6 +275,8 @@ class Calculate(activity.Activity): label = self.label_entry.get_text() _logger.debug('process(): parsing \'%s\', label: \'%s\'', s, label) res = self.parser.parse(s) + if type(res) == types.StringType and res.find('</svg>') > -1: + res = SVGImage(data=res) eqn = Equation(label, s, res, self.color, self.owner_id) # Result ok @@ -270,7 +284,6 @@ class Calculate(activity.Activity): self.insert_equation(eqn) self.helper.send_message("add_eq", str(eqn)) self.showing_error = False - ans_but = self.layout.buttons["Ans"] # To change label # Show error else: @@ -309,7 +322,7 @@ class Calculate(activity.Activity): continue w = gtk.TextView() b = w.get_buffer() - b.set_text(name + ":\t" + value) + b.set_text(name + ":\t" + str(value)) self.format_var_buf(b) list.append(w) self.layout.show_history(list) @@ -350,20 +363,30 @@ class Calculate(activity.Activity): if not last_eq_drawn and e.owner == self.owner_id: self.set_last_equation(e) last_eq_drawn = True + if not isinstance(e.result, SVGImage): + continue + +# Skip if only drawing own equations + if self.layout.minebut.selected == 1 and e.owner != self.ownder_id: continue - text = "" - if len(e.label) > 0: - text += str(e.label) + ": " - r = self.ml.format_number(e.result) - text += str(e.equation) + "\n=" + r - w = gtk.TextView() - w.connect('button-press-event', lambda w, e, j: self.equation_pressed_cb(j), i) - b = w.get_buffer() -## b.modify_bg(gtk.STATE_ACTIVE | gtk.STATE_NORMAL, -## gtk.gdk.color_parse(e.color.get_fill_color()) - b.set_text(text) - self.format_history_buf(b, e) + if isinstance(e.result, SVGImage): + w = e.result.get_image() + + else: + text = "" + if len(e.label) > 0: + text += str(e.label) + ": " + r = self.ml.format_number(e.result) + text += str(e.equation) + "\n=" + r + w = gtk.TextView() + w.connect('button-press-event', lambda w, e, j: self.equation_pressed_cb(j), i) + b = w.get_buffer() +## b.modify_bg(gtk.STATE_ACTIVE | gtk.STATE_NORMAL, +## gtk.gdk.color_parse(e.color.get_fill_color()) + b.set_text(text) + self.format_history_buf(b, e) + list.append(w) i += 1 @@ -401,19 +424,6 @@ class Calculate(activity.Activity): f.close() -# We're not using the set_canvas function, which currently takes care of -# (setting up) loading journal entries! - def load_journal_entry(self): - if self._jobject and self._jobject.file_path: - ret = self.read_file(self._jobject.file_path) - if ret: - _logger.info('Loading from journal succesful') -# self.refresh_bar() # Done by SharingHelper - else: - _logger.info('Loading from journal failed') - else: - return False - def read_file(self, file_path): """Read journal entries, version 1.0""" @@ -444,10 +454,14 @@ class Calculate(activity.Activity): eqs = [] for str in f: eq = Equation(str=str) - if eq.equation is not None: - eqs.append(Equation(l[0], l[1], l[2], XoColor(color_string=l[3]), l[4])) + if eq.equation is not None and len(eq.equation) > 0: + eqs.append(eq) + if eq.label is not None and len(eq.label) > 0: + self.parser.set_var(eq.label, eq.result) self.helper_old_eqs = eqs + self.refresh_bar() + return True else: _logger.error('Unable to read journal entry, unknown version (%s)', version) @@ -632,14 +646,15 @@ class Calculate(activity.Activity): elif type == self.TYPE_OP_PRE: if len(sel) is 2: pos = start - elif pos == 0: - str = 'Ans' + str self.text_entry.insert_text(str, pos) self.text_entry.set_position(pos + len(str)) elif type == self.TYPE_OP_POST: if len(sel) is 2: pos = end + elif pos == 0: + ans = self.parser.ml.format_number(self.parser.get_var('Ans')) + str = ans + str self.text_entry.insert_text(str, pos) self.text_entry.set_position(pos + len(str)) @@ -648,8 +663,10 @@ class Calculate(activity.Activity): if len(sel) == 2: tlen -= (end - start) - if tlen == 0 and str in self.parser.get_diadic_operators(): - self.text_entry.set_text('Ans' + str) + if tlen == 0 and (str in self.parser.get_diadic_operators() \ + or str in self.parser.get_post_operators()): + ans = self.parser.ml.format_number(self.parser.get_var('Ans')) + self.text_entry.set_text(ans + str) self.text_entry.set_position(3 + len(str)) elif len(sel) is 2: self.text_entry.set_text(text[:start] + str + text[end:]) diff --git a/eqnparser.py b/eqnparser.py index 9b0e243..5e9a05c 100644 --- a/eqnparser.py +++ b/eqnparser.py @@ -22,6 +22,7 @@ _logger = logging.getLogger('EqnParser') import types from mathlib import MathLib +from plotlib import PlotLib class Equation: def __init__(self, eqn): @@ -109,45 +110,50 @@ class EqnParser: else: self.ml = ml + self.pl = PlotLib(self) + self.error_offset = 0 self.variables = {} self.functions = {} self.operators = [] - self.register_function('exp', 1, lambda x: self.ml.exp(x[0])) - self.register_function('ln', 1, lambda x: self.ml.ln(x[0])) - self.register_function('log', 1, lambda x: self.ml.log10(x[0])) - self.register_function('log10', 1, lambda x: self.ml.log10(x[0])) - self.register_function('pow', 2, lambda x: self.ml.pow(x[0], x[1])) + self.cached_diadic_ops = None + self.cached_post_ops = None + + self.register_function('exp', lambda x: self.ml.exp(x[0]), {"nargs": 1}) + self.register_function('ln', lambda x: self.ml.ln(x[0]), {"nargs": 1}) + self.register_function('log', lambda x: self.ml.log10(x[0]), {"nargs": 1}) + self.register_function('log10', lambda x: self.ml.log10(x[0]), {"nargs": 1}) + self.register_function('pow', lambda x: self.ml.pow(x[0], x[1]), {"nargs": 2}) - self.register_function('sqrt', 1, lambda x: self.ml.sqrt(x[0])) + self.register_function('sqrt', lambda x: self.ml.sqrt(x[0]), {"nargs": 1}) - self.register_function('sin', 1, lambda x: self.ml.sin(x[0])) - self.register_function('cos', 1, lambda x: self.ml.cos(x[0])) - self.register_function('tan', 1, lambda x: self.ml.tan(x[0])) + self.register_function('sin', lambda x: self.ml.sin(x[0]), {"nargs": 1}) + self.register_function('cos', lambda x: self.ml.cos(x[0]), {"nargs": 1}) + self.register_function('tan', lambda x: self.ml.tan(x[0]), {"nargs": 1}) - self.register_function('asin', 1, lambda x: self.ml.asin(x[0])) - self.register_function('acos', 1, lambda x: self.ml.acos(x[0])) - self.register_function('atan', 1, lambda x: self.ml.atan(x[0])) + self.register_function('asin', lambda x: self.ml.asin(x[0]), {"nargs": 1}) + self.register_function('acos', lambda x: self.ml.acos(x[0]), {"nargs": 1}) + self.register_function('atan', lambda x: self.ml.atan(x[0]), {"nargs": 1}) - self.register_function('sinh', 1, lambda x: self.ml.sinh(x[0])) - self.register_function('cosh', 1, lambda x: self.ml.cosh(x[0])) - self.register_function('tanh', 1, lambda x: self.ml.tanh(x[0])) + self.register_function('sinh', lambda x: self.ml.sinh(x[0]), {"nargs": 1}) + self.register_function('cosh', lambda x: self.ml.cosh(x[0]), {"nargs": 1}) + self.register_function('tanh', lambda x: self.ml.tanh(x[0]), {"nargs": 1}) - self.register_function('asinh', 1, lambda x: self.ml.asinh(x[0])) - self.register_function('acosh', 1, lambda x: self.ml.acosh(x[0])) - self.register_function('atanh', 1, lambda x: self.ml.atanh(x[0])) + self.register_function('asinh', lambda x: self.ml.asinh(x[0]), {"nargs": 1}) + self.register_function('acosh', lambda x: self.ml.acosh(x[0]), {"nargs": 1}) + self.register_function('atanh', lambda x: self.ml.atanh(x[0]), {"nargs": 1}) - self.register_function('round', 1, lambda x: self.ml.round(x[0])) - self.register_function('floor', 1, lambda x: self.ml.floor(x[0])) - self.register_function('ceil', 1, lambda x: self.ml.ceil(x[0])) + self.register_function('round', lambda x: self.ml.round(x[0]), {"nargs": 1}) + self.register_function('floor', lambda x: self.ml.floor(x[0]), {"nargs": 1}) + self.register_function('ceil', lambda x: self.ml.ceil(x[0]), {"nargs": 1}) - self.register_function('mod', 2, lambda x: self.ml.mod(x[0], x[1])) + self.register_function('mod', lambda x: self.ml.mod(x[0], x[1]), {"nargs": 2}) - self.register_function('factorize', 1, lambda x: self.ml.factorize(x[0])) + self.register_function('factorize', lambda x: self.ml.factorize(x[0]), {"nargs": 1}) - self.register_function('plot', 2, lambda x: self.pl.plot(x[0], x[1])) + self.register_function('plot', lambda x: self.pl.plot(x[0], x[1]), {"nargs": 2, 'parse_options': False}) self.register_operator('+', self.OP_DIADIC, 0, lambda x: self.ml.add(x[0], x[1])) self.register_operator('+', self.OP_PRE, 1, lambda x: x[0]) @@ -173,8 +179,8 @@ class EqnParser: self.register_operator('%', self.OP_DIADIC, 0, lambda x: self.ml.mod(x[0], x[1])) - def register_function(self, name, nargs, f): - self.functions[name] = (nargs, f) + def register_function(self, name, f, opts): + self.functions[name] = (f, opts) def register_operator(self, op, type, presedence, f): self.operators.append((op, type, presedence, f)) @@ -186,11 +192,20 @@ class EqnParser: self.OP_CHARS += c def get_diadic_operators(self): - res = [] - for (op, type, presedence, f) in self.operators: - if type == self.OP_DIADIC: - res.append(op) - return res + if self.cached_diadic_ops == None: + self.cached_diadic_ops = [] + for (op, type, presedence, f) in self.operators: + if type == self.OP_DIADIC: + self.cached_diadic_ops.append(op) + return self.cached_diadic_ops + + def get_post_operators(self): + if self.cached_post_ops == None: + self.cached_post_ops = [] + for (op, type, presedence, f) in self.operators: + if type == self.OP_POST: + self.cached_post_ops.append(op) + return self.cached_post_ops def reset_variable_level(self, level): return @@ -198,9 +213,12 @@ class EqnParser: # self.variables[i].highest_level = level def set_var(self, name, val): - self.variables[name] = val + if type(val) is types.FloatType: + self.variables[name] = self.ml.d(val) + else: + self.variables[name] = val - def get_var(self, name, val): + def get_var(self, name): if name in self.variables: return self.variables[name] else: @@ -254,17 +272,20 @@ class EqnParser: _logger.error('Function \'%s\' not defined', func) return None - (nargs, f) = self.functions[func] - if len(args) != nargs: - _logger.error('Invalid number of arguments (%d instead of %d)', len(args), nargs) + (f, opts) = self.functions[func] + if len(args) != opts['nargs']: + _logger.error('Invalid number of arguments (%d instead of %d)', len(args), opts['nargs']) return None - pargs = [] - for i in range(len(args)): - pargs.append(self.parse(args[i])) - if pargs[i] is None: - _logger.error('Unable to parse argument %d: \'%s\'', i, args[i]) - return None + if 'parse_options' in opts and opts['parse_options'] == False: + pargs = args + else: + pargs = [] + for i in range(len(args)): + pargs.append(self.parse(args[i])) + if pargs[i] is None: + _logger.error('Unable to parse argument %d: \'%s\'', i, args[i]) + return None res = f(pargs) _logger.debug('Function \'%s\' returned %s', func, self.ml.format_number(res)) @@ -39,7 +39,9 @@ class CalcLayout: [0, 3, 1, '0', self.col_gray2, lambda w: self._parent.add_text('0')], [1, 3, 1, '.', self.col_gray2, lambda w: self._parent.add_text('.')], - [2, 3, 1, 'Ans', self.col_gray2, lambda w: self._parent.add_text('Ans')], + +# Deprecated -- functionality available through interface and labels +# [2, 3, 1, 'Ans', self.col_gray2, lambda w: self._parent.add_text('Ans')], [3, 0, 3, 'clear', self.col_gray1, lambda w: self._parent.clear()], @@ -80,8 +82,6 @@ class CalcLayout: self.grid.set_row_spacings(6) self.grid.set_col_spacings(6) - self._parent.set_canvas(self.grid) - # Left part: container and input hc1 = gtk.HBox(False, 10) label1 = gtk.Label(_('Label:')) @@ -140,6 +140,9 @@ class CalcLayout: self.history.set_border_width(6) scrolled_window.add_with_viewport(self.history) self.grid.attach(scrolled_window, 6, 10, 5, 16) + + def show_it(self): + self._parent.set_canvas(self.grid) self._parent.show_all() def show_history(self, window_list): @@ -22,8 +22,7 @@ import math from decimal import Decimal import logging -_logger = logging.getLogger('calc-activity') - +_logger = logging.getLogger('MathLib') class MathLib: ANGLE_DEG = math.pi/180 @@ -170,7 +169,7 @@ class MathLib: def pow(self, x, y): if self.is_int(y): - return x ** y + return x ** int(y) else: return self.d(math.pow(x, y)) diff --git a/plotlib.py b/plotlib.py new file mode 100644 index 0000000..07db19c --- /dev/null +++ b/plotlib.py @@ -0,0 +1,138 @@ +# plotlib.py, svg plot generator by Reinier Heeres <reinier@heeres.eu> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +# Change log: +# 2007-09-04: rwh, first version + +import logging +_logger = logging.getLogger('PlotLib') + +class PlotLib: + """Class to generate an svg plot for a function. + Evaluation of values is done using the EqnParser class.""" + + def __init__(self, parser): + self.parser = parser + + self.svg_data = "" + self.set_size(0, 0) + + def set_size(self, width, height): + self.width = width + self.height = height + + def get_svg(self): + return self.svg_data + + def parse_range(self, range): + p1 = range.split('=') + if len(p1) != 2: + return None + p2 = p1[1].split('..') + if len(p2) != 2: + return None + return (p1[0], (float(p2[0]), float(p2[1]))) + + def evaluate(self, eqn, var, range, n=100): + x_old = self.parser.get_var(var) + + res = [] + d = float((range[1] - range[0])) / (n - 1) + x = range[0] + while n > 0: + self.parser.set_var(var, x) + v = float(self.parser.parse(eqn)) + res.append((x, v)) + x += d + n -= 1 + + self.parser.set_var(var, x_old) + return res + + def create_image(self): + self.svg_data = '<?xml version="1.0" standalone="no"?>\n' + self.svg_data += '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' + self.svg_data += '<svg width="%d" height="%d" version="1.1" xmlns="http://www.w3.org/2000/svg">\n' % (self.width, self.height) + + def finish_image(self): + self.svg_data += '</svg>' + + def plot_line(self, c0, c1, col): + c0 = self.rcoords_to_coords(c0) + c1 = self.rcoords_to_coords(c1) + self.svg_data += '<line style="stroke:%s;stroke-width:1" x1="%f" y1="%f" x2="%f" y2="%f" />\n' % (col, c0[0], c0[1], c1[0], c1[1]) + + def plot_polyline(self, coords, col): + self.svg_data += '<polyline style="fill:none;stroke:%s;stroke-width:1" points="' % (col) + for c in coords: + c = self.rcoords_to_coords(c) + self.svg_data += '%f,%f ' % (c[0], c[1]) + self.svg_data += '" />\n' + + def determine_bounds(self, vals): + self.minx = self.miny = 1e99 + self.maxx = self.maxy = -1e99 + for (x, y) in vals: + self.minx = min(float(x), self.minx) + self.miny = min(float(y), self.miny) + self.maxx = max(float(x), self.maxx) + self.maxy = max(float(y), self.maxy) + + def rcoords_to_coords(self, pair): + return (pair[0] * self.width, pair[1] * self.height) + + def vals_to_rcoords(self, pair): + ret = (0.1 + (pair[0] - self.minx) / (self.maxx - self.minx) * 0.8, \ + 0.9 - (pair[1] - self.miny) / (self.maxy - self.miny) * 0.8) + return ret + + def add_curve(self, vals): + self.determine_bounds(vals) + + self.plot_line((0.08, 0.08), (0.08, 0.92), "black") + self.plot_line((0.08, 0.92), (0.92, 0.92), "black") + + c = [] + for v in vals: + c.append(self.vals_to_rcoords(v)) +# print 'coords: %r' % c + + self.plot_polyline(c, "blue") + + def export_plot(self, fn): + f = open(fn, "w") + f.write(self.svg_data) + f.close() + + def plot(self, eqn, range_spec): + (var, range) = self.parse_range(range_spec) + if range is None: + _logger.error('Unable to parse range') + return False + _logger.info('Plot range for var %s: %r', var, range) + + self.set_size(200, 200) + self.create_image() + + vals = self.evaluate(eqn, var, range) +# print 'vals: %r' % vals + self.add_curve(vals) + + self.finish_image() + + self.export_plot("/tmp/calculate_graph.svg") + + return self.get_svg() diff --git a/svgimage.py b/svgimage.py new file mode 100644 index 0000000..1584873 --- /dev/null +++ b/svgimage.py @@ -0,0 +1,55 @@ +# svgimage.py, svg image class by Reinier Heeres <reinier@heeres.eu> +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +# Change log: +# 2007-09-07: rwh, first version + +import logging +_logger = logging.getLogger('SVGImage') + +import gtk +import rsvg + +class SVGImage: + + def __init__(self, fn=None, data=None): + if fn is not None: + self.load(fn) + elif data is not None: + self.load_data(data) + + def get_image(self): + return self._image + + def get_svg_data(self): + return self._svg_data + + def render_svg(self): + self._handle = rsvg.Handle(data=self._svg_data) + self._pixbuf = self._handle.get_pixbuf() + self._image = gtk.Image() + self._image.set_from_pixbuf(self._pixbuf) + return self._image + + def load(self, fn): + f = open(fn, 'rb') + self._svg_data = f.read() + f.close() + return self.render_svg() + + def load_data(self, svgdat): + self._svg_data = svgdat + return self.render_svg() |