backend_gtk3agg.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import numpy as np
  2. from .. import cbook, transforms
  3. from . import backend_agg, backend_gtk3
  4. from .backend_gtk3 import 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. scale = self.device_pixel_ratio
  13. allocation = self.get_allocation()
  14. w = allocation.width * scale
  15. h = allocation.height * scale
  16. if not len(self._bbox_queue):
  17. Gtk.render_background(
  18. self.get_style_context(), ctx,
  19. allocation.x, allocation.y,
  20. allocation.width, allocation.height)
  21. bbox_queue = [transforms.Bbox([[0, 0], [w, h]])]
  22. else:
  23. bbox_queue = self._bbox_queue
  24. for bbox in bbox_queue:
  25. x = int(bbox.x0)
  26. y = h - int(bbox.y1)
  27. width = int(bbox.x1) - int(bbox.x0)
  28. height = int(bbox.y1) - int(bbox.y0)
  29. buf = cbook._unmultiplied_rgba8888_to_premultiplied_argb32(
  30. np.asarray(self.copy_from_bbox(bbox)))
  31. image = cairo.ImageSurface.create_for_data(
  32. buf.ravel().data, cairo.FORMAT_ARGB32, width, height)
  33. image.set_device_scale(scale, scale)
  34. ctx.set_source_surface(image, x / scale, y / scale)
  35. ctx.paint()
  36. if len(self._bbox_queue):
  37. self._bbox_queue = []
  38. return False
  39. def blit(self, bbox=None):
  40. # If bbox is None, blit the entire canvas to gtk. Otherwise
  41. # blit only the area defined by the bbox.
  42. if bbox is None:
  43. bbox = self.figure.bbox
  44. scale = self.device_pixel_ratio
  45. allocation = self.get_allocation()
  46. x = int(bbox.x0 / scale)
  47. y = allocation.height - int(bbox.y1 / scale)
  48. width = (int(bbox.x1) - int(bbox.x0)) // scale
  49. height = (int(bbox.y1) - int(bbox.y0)) // scale
  50. self._bbox_queue.append(bbox)
  51. self.queue_draw_area(x, y, width, height)
  52. @_BackendGTK3.export
  53. class _BackendGTK3Cairo(_BackendGTK3):
  54. FigureCanvas = FigureCanvasGTK3Agg