Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/sliderenderer.py
diff options
context:
space:
mode:
Diffstat (limited to 'sliderenderer.py')
-rwxr-xr-xsliderenderer.py145
1 files changed, 145 insertions, 0 deletions
diff --git a/sliderenderer.py b/sliderenderer.py
new file mode 100755
index 0000000..9c89e88
--- /dev/null
+++ b/sliderenderer.py
@@ -0,0 +1,145 @@
+# -*- mode:python; tab-width:4; indent-tabs-mode:t; -*-
+
+# sliderenderer.py
+#
+# Class for rendering slides to a surface
+# B. Mayton <bmayton@cs.washington.edu>
+#
+# 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
+
+import cairo
+import rsvg
+import gtk
+import os
+import utils
+import time
+import logging
+
+class Renderer(object):
+ def __init__(self, deck):
+ """Constructs a new SlideRenderer that will render slides from deck"""
+ self.__logger = logging.getLogger('Renderer')
+ self.__logger.setLevel('error')
+ self.__deck = deck
+
+ def getSlideDimensionsFromFirstLayer(self, n=None):
+ """Returns the [width, height] of the first slide layer"""
+ if n is None:
+ n = self.__deck.getIndex()
+ layers = self.__deck.getSlideLayers(n)
+
+ # return some default reasonable value if this is an empty slide
+ if len(layers) == 0:
+ return [640.0, 480.0]
+
+ ftype = utils.getFileType(layers[0])
+
+ # This may be optimizable to avoid having to open the first layer to get its size,
+ # or at least keeping it around to re-use it when the slide is first rendered
+ if ftype == "svg":
+ f = open(layers[0], 'rb')
+ svg_data = f.read()
+ f.close()
+ handle = rsvg.Handle(data=svg_data)
+ a, b, w, h = handle.get_dimension_data()
+ return [w,h]
+ elif ftype == "png":
+ surface = cairo.ImageSurface.create_from_png(layers[0])
+ return [float(surface.get_width()), float(surface.get_height())]
+ elif ftype == "jpg":
+ pbuf = gtk.gdk.pixbuf_new_from_file(layers[0])
+ return [float(pbuf.get_width()), float(pbuf.get_height())]
+ else:
+ return [640.0, 480.0]
+
+ def getSlideDimensions(self, n=None):
+ """Returns the slide dimensions, using the value in the XML file first, if it exists, and then the size of the first layer"""
+ if n is None:
+ n = self.__deck.getIndex()
+ dims = self.__deck.getSlideDimensionsFromXML(n)
+ if dims == False:
+ return self.getSlideDimensionsFromFirstLayer(n)
+ else:
+ w, h = dims
+ return [w, h]
+
+ def renderSlideToSurface(self, surface, n=None):
+ if n is None:
+ n = self.__deck.getIndex()
+
+ timerstart = time.time()
+
+ self.__logger.debug("rendering slide " + str(n))
+ ctx = gtk.gdk.CairoContext(cairo.Context(surface))
+ #ctx = cairo.Context(surface)
+
+ self.__logger.debug("Got context at " + str(time.time() - timerstart))
+
+ # Get the slide dimensions and set up a Cairo transformation matrix
+ srcw, srch = self.getSlideDimensions(n)
+ if srcw > 640:
+ srcw = 640
+ if srch > 480:
+ srch = 480
+ targw = float(surface.get_width())
+ targh = float(surface.get_height())
+ x_scale = targw/srcw
+ y_scale = targh/srch
+ print 'rendering slide', str(n), "w=", targw, srcw, x_scale, "h=", targh, srch, y_scale
+
+ self.__logger.debug("Surface is " + str(targw) + "x" + str(targh))
+
+ scale = x_scale
+ if y_scale < x_scale:
+ scale = y_scale
+
+ if scale < .98 or scale > 1.02:
+ ctx.transform(cairo.Matrix(scale, 0, 0, scale, 0, 0))
+
+ self.__logger.debug("Got transformation matrix at " + str(time.time() - timerstart))
+
+ # Paint the slide background
+ ctx.set_source_rgb(1.0, 1.0, 1.0)
+ ctx.rectangle(0, 0, srcw, srch)
+ ctx.fill()
+
+ self.__logger.debug("Filled background at " + str(time.time() - timerstart))
+
+ # Paint the layers
+ layers = self.__deck.getSlideLayers(n)
+ self.__logger.debug("Got layers at " + str(time.time() - timerstart))
+ for layer in layers:
+ type = utils.getFileType(layer)
+ self.__logger.debug("Drawing layer " + str(layer) +" " + str(scale) + " at " + str(time.time() - timerstart))
+ print 'drawing layer', type, str(layer)
+ if type == "svg":
+ f = open(layer, "rb")
+ svg_data = f.read()
+ f.close()
+ handle = rsvg.Handle(data=svg_data)
+ handle.render_cairo(ctx)
+ elif type == "png":
+ png_surface = cairo.ImageSurface.create_from_png(layer)
+ self.__logger.debug("Got PNG surface at "+ str(time.time() - timerstart))
+ ctx.set_source_surface(png_surface, 0, 0)
+ ctx.rectangle(0, 0, png_surface.get_width(), png_surface.get_height())
+ ctx.fill()
+ elif type == "jpg":
+ jpg_pixbuf = gtk.gdk.pixbuf_new_from_file(layer)
+ self.__logger.debug("Got JPG pixbuf at "+ str(time.time() - timerstart))
+ ctx.set_source_pixbuf(jpg_pixbuf, 0, 0)
+ ctx.rectangle(0, 0, jpg_pixbuf.get_width(), jpg_pixbuf.get_height())
+ ctx.fill()
+ self.__logger.debug("Finished drawing layer at "+ str(time.time() - timerstart))