backend_gtk3agg.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import numpy as np
  2. from .. import cbook, transforms
  3. from . import backend_agg, backend_gtk3
  4. from .backend_gtk3 import GLib, Gtk, _BackendGTK3
  5. import cairo # Presence of cairo is already checked by _backend_gtk.
  6. class FigureCanvasGTK3Agg(backend_agg.FigureCanvasAgg,
  7. backend_gtk3.FigureCanvasGTK3):
  8. def __init__(self, figure):
  9. super().__init__(figure=figure)
  10. self._bbox_queue = []
  11. def on_draw_event(self, widget, ctx):
  12. if self._idle_draw_id:
  13. GLib.source_remove(self._idle_draw_id)
  14. self._idle_draw_id = 0
  15. self.draw()
  16. scale = self.device_pixel_ratio
  17. allocation = self.get_allocation()
  18. w = allocation.width * scale
  19. h = allocation.height * scale
  20. if not len(self._bbox_queue):
  21. Gtk.render_background(
  22. self.get_style_context(), ctx,
  23. allocation.x, allocation.y,
  24. allocation.width, allocation.height)
  25. bbox_queue = [transforms.Bbox([[0, 0], [w, h]])]
  26. else:
  27. bbox_queue = self._bbox_queue
  28. for bbox in bbox_queue:
  29. x = int(bbox.x0)
  30. y = h - int(bbox.y1)
  31. width = int(bbox.x1) - int(bbox.x0)
  32. height = int(bbox.y1) - int(bbox.y0)
  33. buf = cbook._unmultiplied_rgba8888_to_premultiplied_argb32(
  34. np.asarray(self.copy_from_bbox(bbox)))
  35. image = cairo.ImageSurface.create_for_data(
  36. buf.ravel().data, cairo.FORMAT_ARGB32, width, height)
  37. image.set_device_scale(scale, scale)
  38. ctx.set_source_surface(image, x / scale, y / scale)
  39. ctx.paint()
  40. if len(self._bbox_queue):
  41. self._bbox_queue = []
  42. return False
  43. def blit(self, bbox=None):
  44. # If bbox is None, blit the entire canvas to gtk. Otherwise
  45. # blit only the area defined by the bbox.
  46. if bbox is None:
  47. bbox = self.figure.bbox
  48. scale = self.device_pixel_ratio
  49. allocation = self.get_allocation()
  50. x = int(bbox.x0 / scale)
  51. y = allocation.height - int(bbox.y1 / scale)
  52. width = (int(bbox.x1) - int(bbox.x0)) // scale
  53. height = (int(bbox.y1) - int(bbox.y0)) // scale
  54. self._bbox_queue.append(bbox)
  55. self.queue_draw_area(x, y, width, height)
  56. @_BackendGTK3.export
  57. class _BackendGTK3Agg(_BackendGTK3):
  58. FigureCanvas = FigureCanvasGTK3Agg