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-07-30 13:00:19 (GMT)
committer Gonzalo Odiard <godiard@gmail.com>2012-08-10 13:49:30 (GMT)
commit8816613106bf02a30dce4f9b92274c1ee36d8e5e (patch)
treeb8c7b6bbe8d9116befdf0f5c17401e3126710881 /Area.py
parent8a2fb245a6d1003616127a14fb9fdc91bef480f3 (diff)
Implement flood_fill tool using cairo.
Only the slow python implementation is done, the code used to import the c version is commented. Signed-off-by: Gonzalo Odiard <gonzalo@laptop.org>
Diffstat (limited to 'Area.py')
-rw-r--r--Area.py65
1 files changed, 39 insertions, 26 deletions
diff --git a/Area.py b/Area.py
index 65fe45d..90bf532 100644
--- a/Area.py
+++ b/Area.py
@@ -71,19 +71,20 @@ import math
import pango
import cairo
import StringIO
+import array
from Desenho import Desenho
from urlparse import urlparse
from sugar.graphics.style import zoom
FALLBACK_FILL = True
-try:
- from fill import fill
- FALLBACK_FILL = False
-except:
- logging.debug('No valid fill binaries. Using slower python code')
- pass
+#try:
+# from fill import fill
+# FALLBACK_FILL = False
+#except:
+# logging.debug('No valid fill binaries. Using slower python code')
+# pass
##Tools and events manipulation are handle with this class.
@@ -591,19 +592,8 @@ class Area(gtk.DrawingArea):
elif self.tool['name'] == 'bucket':
if FALLBACK_FILL:
- if self.tool['stroke color'] is not None:
- stroke_color = self.tool['stroke color']
- color_r = int(stroke_color.red_float * 65535)
- color_g = int(stroke_color.green_float * 65535)
- color_b = int(stroke_color.blue_float * 65535)
- else:
- color_r, color_g, color_b = 0, 0, 0
- cmap = self.pixmap.get_colormap()
- fill_color = \
- cmap.alloc_color(color_r, color_g, color_b).pixel
self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
- gobject.idle_add(self.flood_fill, coords[0], coords[1],
- fill_color)
+ gobject.idle_add(self.flood_fill, coords[0], coords[1])
else:
width, height = self.window.get_size()
self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
@@ -655,10 +645,29 @@ class Area(gtk.DrawingArea):
cursor = gtk.gdk.cursor_new_from_name(display, 'paint-bucket')
self.window.set_cursor(cursor)
- def flood_fill(self, x, y, fill_color):
- width, height = self.window.get_size()
+ def flood_fill(self, x, y):
+ stroke_color = self.tool['cairo_stroke_color']
+ r, g, b = stroke_color[0], stroke_color[1], stroke_color[2]
+
+ # pack the color in a int as 0xAARRGGBB
+ fill_color = 0xff000000 + \
+ (int(r * 255 * 65536) + \
+ int(g * 255 * 256) + \
+ int(b * 255))
+ logging.error('fill_color %d', fill_color)
+
+ # load a array with the surface data
+ for type in ['H', 'I', 'L']:
+ pixels = array.array(type)
+ if pixels.itemsize == 4:
+ break
+ else:
+ raise AssertionError()
+ pixels.fromstring(self.drawing_canvas.get_data())
- gdk_image = self.pixmap.get_image(0, 0, width, height)
+ # process the pixels in the array
+ width = self.drawing_canvas.get_width()
+ height = self.drawing_canvas.get_height()
def within(x, y):
if x < 0 or x >= width:
@@ -671,24 +680,28 @@ class Area(gtk.DrawingArea):
return
edge = [(x, y)]
- old_color = gdk_image.get_pixel(x, y)
+ old_color = pixels[x + y * width]
if old_color == fill_color:
logging.debug('Already filled')
return
- gdk_image.put_pixel(x, y, fill_color)
+ pixels[x + y * width] = fill_color
while len(edge) > 0:
newedge = []
for (x, y) in edge:
for (s, t) in ((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)):
if within(s, t) and \
- gdk_image.get_pixel(s, t) == old_color:
- gdk_image.put_pixel(s, t, fill_color)
+ pixels[s + t * width] == old_color:
+ pixels[s + t * width] = fill_color
newedge.append((s, t))
edge = newedge
- self.pixmap.draw_image(self.gc, gdk_image, 0, 0, 0, 0, width, height)
+ # create a updated drawing_canvas
+ self.drawing_canvas = cairo.ImageSurface.create_for_data(pixels,
+ cairo.FORMAT_ARGB32, width, height)
+ self.setup(width, height)
+
self.queue_draw()
self.enable_undo()