diff options
author | Simon Schampijer <simon@schampijer.de> | 2012-03-14 16:37:23 (GMT) |
---|---|---|
committer | Simon Schampijer <simon@schampijer.de> | 2012-03-14 16:37:23 (GMT) |
commit | afcb2fcea9623ec5e089c1cbabbe99374c603a24 (patch) | |
tree | bdbb28a9347aab514dff56719d606707efc0be1f | |
parent | ca751fe004d582320602a29eee1df0083b2f3063 (diff) |
Port get_preview method to cairo
Previously we were using a GdkPixmap [1] created with the get_snapshot [2]
method of the Gtk.Widget. GTK 3 encourages to use cairo surfaces
now instead.
The ported mothod does create a cairo surface similar to that of the canvas'
window and draws on that. Then we create a cairo image surface with
the desired preview size and scale the canvas surface on that.
Several people have been involved in this work: Gonzalo Odiard,
Manuel QuiƱones and Benjamin Berg.
[1] http://developer.gnome.org/gdk/stable/gdk-Bitmaps-and-Pixmaps.html#GdkPixmap
[2] http://developer.gnome.org/gtk/stable/GtkWidget.html#gtk-widget-get-snapshot
-rw-r--r-- | src/sugar3/activity/activity.py | 67 |
1 files changed, 48 insertions, 19 deletions
diff --git a/src/sugar3/activity/activity.py b/src/sugar3/activity/activity.py index 19c1974..56371a4 100644 --- a/src/sugar3/activity/activity.py +++ b/src/sugar3/activity/activity.py @@ -54,11 +54,12 @@ import os import time from hashlib import sha1 from functools import partial +import StringIO +import cairo from gi.repository import GConf from gi.repository import Gtk from gi.repository import Gdk -from gi.repository import GdkPixbuf from gi.repository import GObject import dbus import dbus.service @@ -641,27 +642,55 @@ class Activity(Window, Gtk.Container): Activities can override this method, which should return a str with the binary content of a png image with a width of 300 and a height of 225 pixels. + + The method does create a cairo surface similar to that of the canvas' + window and draws on that. Then we create a cairo image surface with + the desired preview size and scale the canvas surface on that. """ - if self.canvas is None or not hasattr(self.canvas, 'get_snapshot'): + if self.canvas is None or not hasattr(self.canvas, 'get_window'): return None - pixmap = self.canvas.get_snapshot((-1, -1, 0, 0)) - - width, height = pixmap.get_size() - pixbuf = GdkPixbuf.Pixbuf(GdkPixbuf.Colorspace.RGB, 0, 8, width, height) - pixbuf = pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), - 0, 0, 0, 0, width, height) - pixbuf = pixbuf.scale_simple(style.zoom(300), style.zoom(225), - GdkPixbuf.InterpType.BILINEAR) - - preview_data = [] - - def save_func(buf, data): - data.append(buf) - - pixbuf.save_to_callback(save_func, 'png', user_data=preview_data) - preview_data = ''.join(preview_data) - return preview_data + window = self.canvas.get_window() + alloc = self.canvas.get_allocation() + + dummy_cr = Gdk.cairo_create(window) + target = dummy_cr.get_target() + canvas_width, canvas_height = alloc.width, alloc.height + screenshot_surface = target.create_similar(cairo.CONTENT_COLOR, + canvas_width, canvas_height) + del dummy_cr, target + + cr = cairo.Context(screenshot_surface) + r, g, b, a_ = style.COLOR_PANEL_GREY.get_rgba() + cr.set_source_rgb(r, g, b) + cr.paint() + self.canvas.draw(cr) + del cr + + preview_width, preview_height = style.zoom(300), style.zoom(225) + preview_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, + preview_width, preview_height) + cr = cairo.Context(preview_surface) + + scale_w = preview_width * 1.0 / canvas_width + scale_h = preview_height * 1.0 / canvas_height + scale = min(scale_w, scale_h) + + translate_x = int((preview_width - (canvas_width * scale)) / 2) + translate_y = int((preview_height - (canvas_height * scale)) / 2) + + cr.translate(translate_x, translate_y) + cr.scale(scale, scale) + + cr.set_source_rgba(1, 1, 1, 0) + cr.set_operator(cairo.OPERATOR_SOURCE) + cr.paint() + cr.set_source_surface(screenshot_surface) + cr.paint() + + preview_str = StringIO.StringIO() + preview_surface.write_to_png(preview_str) + return preview_str.getvalue() def _get_buddies(self): if self.shared_activity is not None: |