I'm working on a Python+Gtk+Cairo app. My application needs to do some very complex (and expensive)drawings.
For performance reasons, I draw first on an ImageSurface(offscreen), then I would draw the ImageSurface content on my DrawingArea object.
NB: I need to scale / translate my drawings to make them visible; otherwise, large drawings would fall out of the window.
Unfortunately, something goes wrong: as you can see, I'm unable to paint the entire content of ImageSurface. By using the "canonical" Context.set_source_surface(imageSurface, xCoord, yCoord) Context.paint()
I only get this wrong output:
This is the result I want to achieve:
How can I force the painting of entire imagesurface?
A sample code below:
import gtk
import cairo
def main():
w = gtk.Window()
w.add(RubberTest())
w.show_all()
gtk.main()
class RubberTest(gtk.DrawingArea):
def __init__(self, model=None):
gtk.DrawingArea.__init__(self)
self.set_size_request(800, 500)
self.connect("expose-event", self._expose, self.create_basic_image())
self.add_events(gtk.gdk.EXPOSURE_MASK
| gtk.gdk.BUTTON_PRESS_MASK
| gtk.gdk.BUTTON_RELEASE_MASK
| gtk.gdk.POINTER_MOTION_MASK)
def create_basic_image(self):
img = cairo.ImageSurface(cairo.FORMAT_ARGB32, 24, 24)
cr = cairo.Context(img)
# due to large coordinates, the drawing fall out of the window
self.points = [(10000, 10000), (790000, 10000), (790000, 490000), (10000, 490000)]
xMax, yMax, xMin, yMin = max([c[0] for c in self.points]), max([c[1] for c in self.points]), min([c[0] for c in self.points]), min([c[1] for c in self.points])
maxRectWidth = xMax - xMin
maxRectHeight = yMax - yMin
w = 800
h = 500
width_ratio = float(w) / maxRectWidth
height_ratio = float(h) / maxRectHeight
# scale factor
scaleFactor = min(height_ratio, width_ratio)
cr.set_line_width(4)
cr.set_source_rgb(1, 0, 0)
cr.save()
# scale + translate
cr.scale(scaleFactor, scaleFactor)
cr.translate(-xMin, -yMin)
for i in range(0, len(self.points)):
currPoint = self.points[i]
currX = float(currPoint[0])
currY = float(currPoint[1])
nextIndex = i + 1
if (nextIndex == len(self.points)):
nextIndex = 0
nextPoint = self.points[nextIndex]
nextX = nextPoint[0]
nextY = nextPoint[1]
cr.move_to(currX, currY)
cr.line_to(nextX, nextY)
cr.restore()
cr.close_path()
cr.stroke_preserve()
return img
def _expose(self, sender, event, img):
cr = self.window.cairo_create()
cr.set_source_surface(img, 0, 0)
cr.paint()
return True
if __name__ == '__main__':
main()
Thanks, IT