Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Area.py
diff options
context:
space:
mode:
authorGonzalo Odiard <godiard@gmail.com>2012-10-02 14:48:31 (GMT)
committer Gonzalo Odiard <godiard@gmail.com>2012-10-02 20:52:49 (GMT)
commitf6198bd9019c85cc4ee16ae5a8e1d70ee8d4eb1a (patch)
tree471a3e6b8533ac7ba966188ddb8a1739f01e8be1 /Area.py
parent1df3e8f52bc19af58daac4a0e8e81b2c1469de22 (diff)
Use a similar surface to improve performance
As the surface is created in draw callback, we need delay some operations until the surface is created. The undo keep is delayed until finish draw, then enable_undo() now only enable a flag, and a new method keep_undo() do the real task. This patch breaks rotation and mirror, will be adressed in another patch. Signed-off-by: Gonzalo Odiard <gonzalo@laptop.org>
Diffstat (limited to 'Area.py')
-rw-r--r--Area.py94
1 files changed, 59 insertions, 35 deletions
diff --git a/Area.py b/Area.py
index 6ab5fa2..dfb80c1 100644
--- a/Area.py
+++ b/Area.py
@@ -176,6 +176,8 @@ class Area(Gtk.DrawingArea):
self.oldx = 0
self.oldy = 0
self.drawing_canvas = None
+ # This surface is used when need load data from a file or a process
+ self.drawing_canvas_data = None
self.textos = []
self.text_in_progress = False
self.activity = activity
@@ -197,6 +199,7 @@ class Area(Gtk.DrawingArea):
# List of pixbuf for the Undo function:
self._undo_list = []
self._undo_index = None
+ self._keep_undo = False
# variables to show the tool shape
self.drawing = False
@@ -221,7 +224,8 @@ class Area(Gtk.DrawingArea):
return style.zoom(44)
def load_from_file(self, file_path):
- self.drawing_canvas = cairo.ImageSurface.create_from_png(file_path)
+ self.drawing_canvas_data = \
+ cairo.ImageSurface.create_from_png(file_path)
def setup(self, width, height):
"""Configure the Area object."""
@@ -230,24 +234,9 @@ class Area(Gtk.DrawingArea):
self.set_size_request(width, height)
- ##It is the main canvas, who is display most of the time
- # if is not None was read from a file
- if self.drawing_canvas is None:
- self.drawing_canvas = cairo.ImageSurface(cairo.FORMAT_ARGB32,
- width, height)
- self.drawing_ctx = cairo.Context(self.drawing_canvas)
- # paint background white
- self.drawing_ctx.rectangle(0, 0, width, height)
- self.drawing_ctx.set_source_rgb(1.0, 1.0, 1.0)
- self.drawing_ctx.fill()
- else:
- self.drawing_ctx = cairo.Context(self.drawing_canvas)
-
- ##This canvas is showed when we need show something and not draw it.
- self.temp_canvas = cairo.ImageSurface(cairo.FORMAT_ARGB32,
- width, height)
- self.temp_ctx = cairo.Context(self.temp_canvas)
- self._init_temp_canvas()
+ self.drawing_canvas = None
+ self._width = width
+ self._height = height
self.enable_undo()
@@ -321,11 +310,28 @@ class Area(Gtk.DrawingArea):
@param event -- GdkEvent
"""
-# area = event.area
-# context = self.get_window().cairo_create()
-# context.rectangle(area.x, area.y, area.width, area.height)
-# context.clip()
+ ##It is the main canvas, who is display most of the time
+ # if is not None was read from a file
+ if self.drawing_canvas is None:
+ self.drawing_canvas = context.get_target().create_similar(
+ cairo.CONTENT_COLOR_ALPHA, self._width, self._height)
+ self.drawing_ctx = cairo.Context(self.drawing_canvas)
+ # paint background white
+ self.drawing_ctx.rectangle(0, 0, self._width, self._height)
+ if self.drawing_canvas_data is None:
+ self.drawing_ctx.set_source_rgb(1.0, 1.0, 1.0)
+ self.drawing_ctx.fill()
+ else:
+ self.drawing_ctx.set_source_surface(self.drawing_canvas_data)
+ self.drawing_ctx.paint()
+ self.drawing_canvas_data = None
+
+ ##canvas showed when we need display something and not draw it
+ self.temp_canvas = context.get_target().create_similar(
+ cairo.CONTENT_COLOR_ALPHA, self._width, self._height)
+ self.temp_ctx = cairo.Context(self.temp_canvas)
+ self._init_temp_canvas()
if self.desenha:
#logging.error('Expose use temp canvas area')
@@ -340,6 +346,8 @@ class Area(Gtk.DrawingArea):
# TODO: gtk3 how get the area to avoid redrawing all ?
self._init_temp_canvas() # area)
self.display_selection_border(context)
+ if self._keep_undo:
+ self.keep_undo()
def show_tool_shape(self, context):
"""
@@ -766,7 +774,15 @@ class Area(Gtk.DrawingArea):
break
else:
raise AssertionError()
- pixels.fromstring(self.drawing_canvas.get_data())
+ # need copy self.drawing_canvas in a ImageSurface
+ # because 'cairo.XlibSurface do not have get_data
+ image_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, self._width,
+ self._height)
+ ctx = cairo.Context(image_surface)
+ ctx.set_source_surface(self.drawing_canvas)
+ ctx.paint()
+
+ pixels.fromstring(image_surface)
# process the pixels in the array
width = self.drawing_canvas.get_width()
@@ -801,7 +817,7 @@ class Area(Gtk.DrawingArea):
edge = newedge
# create a updated drawing_canvas
- self.drawing_canvas = cairo.ImageSurface.create_for_data(pixels,
+ self.drawing_canvas_data = cairo.ImageSurface.create_for_data(pixels,
cairo.FORMAT_ARGB32, width, height)
self.setup(width, height)
@@ -945,10 +961,15 @@ class Area(Gtk.DrawingArea):
self.emit('redo')
- def enable_undo(self, overrite=False):
- """Keep the last change in a list for Undo/Redo commands.
+ def enable_undo(self):
+ """Save a flag to keep the last change in a list for Undo/Redo.
+ """
+ self._keep_undo = True
+ def keep_undo(self):
+ """Keep the last change in a list for Undo/Redo commands.
"""
+ self._keep_undo = False
if len(self._undo_list) == 0:
# first undo pix, start index:
self._undo_index = 0
@@ -965,12 +986,6 @@ class Area(Gtk.DrawingArea):
# Forget the redos after this one:
self._undo_list = self._undo_list[:self._undo_index]
- # If a tool needs to do several drawings, uses overrite to
- # undo them in only one step. In that case, the index is not
- # changed:
- if overrite and self._undo_index != 0:
- self._undo_index -= 1
-
if self.is_selected():
self.getout(clear_selection=False)
@@ -1160,7 +1175,15 @@ class Area(Gtk.DrawingArea):
break
else:
raise AssertionError()
- pixels.fromstring(self.drawing_canvas.get_data())
+ # need copy self.drawing_canvas in a ImageSurface
+ # because 'cairo.XlibSurface do not have get_data
+ image_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
+ self._width, self._height)
+ ctx = cairo.Context(image_surface)
+ ctx.set_source_surface(self.drawing_canvas)
+ ctx.paint()
+
+ pixels.fromstring(image_surface)
# process the pixels in the array
new_array = array.array(pixels.typecode, len(pixels) * [0])
@@ -1172,7 +1195,6 @@ class Area(Gtk.DrawingArea):
height = self.drawing_canvas.get_height()
self.drawing_canvas = cairo.ImageSurface.create_for_data(new_array,
cairo.FORMAT_ARGB32, width, height)
- self.setup(width, height)
self.queue_draw()
self.enable_undo()
@@ -1490,6 +1512,8 @@ class Area(Gtk.DrawingArea):
pass
self.set_tool_cursor()
+ # clear points in Desenha
+ self.d.points = []
def set_tool_cursor(self):
# Setting the cursor