backend_gtk3agg.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import numpy as np
  2. from .. import cbook
  3. try:
  4. from . import backend_cairo
  5. except ImportError as e:
  6. raise ImportError('backend Gtk3Agg requires cairo') from e
  7. from . import backend_agg, backend_gtk3
  8. from .backend_cairo import cairo
  9. from .backend_gtk3 import Gtk, _BackendGTK3
  10. from matplotlib import transforms
  11. class FigureCanvasGTK3Agg(backend_gtk3.FigureCanvasGTK3,
  12. backend_agg.FigureCanvasAgg):
  13. def __init__(self, figure):
  14. backend_gtk3.FigureCanvasGTK3.__init__(self, figure)
  15. self._bbox_queue = []
  16. def _renderer_init(self):
  17. pass
  18. def _render_figure(self, width, height):
  19. backend_agg.FigureCanvasAgg.draw(self)
  20. def on_draw_event(self, widget, ctx):
  21. """GtkDrawable draw event, like expose_event in GTK 2.X.
  22. """
  23. allocation = self.get_allocation()
  24. w, h = allocation.width, allocation.height
  25. if not len(self._bbox_queue):
  26. Gtk.render_background(
  27. self.get_style_context(), ctx,
  28. allocation.x, allocation.y,
  29. allocation.width, allocation.height)
  30. bbox_queue = [transforms.Bbox([[0, 0], [w, h]])]
  31. else:
  32. bbox_queue = self._bbox_queue
  33. ctx = backend_cairo._to_context(ctx)
  34. for bbox in bbox_queue:
  35. x = int(bbox.x0)
  36. y = h - int(bbox.y1)
  37. width = int(bbox.x1) - int(bbox.x0)
  38. height = int(bbox.y1) - int(bbox.y0)
  39. buf = cbook._unmultiplied_rgba8888_to_premultiplied_argb32(
  40. np.asarray(self.copy_from_bbox(bbox)))
  41. image = cairo.ImageSurface.create_for_data(
  42. buf.ravel().data, cairo.FORMAT_ARGB32, width, height)
  43. ctx.set_source_surface(image, x, y)
  44. ctx.paint()
  45. if len(self._bbox_queue):
  46. self._bbox_queue = []
  47. return False
  48. def blit(self, bbox=None):
  49. # If bbox is None, blit the entire canvas to gtk. Otherwise
  50. # blit only the area defined by the bbox.
  51. if bbox is None:
  52. bbox = self.figure.bbox
  53. allocation = self.get_allocation()
  54. x = int(bbox.x0)
  55. y = allocation.height - int(bbox.y1)
  56. width = int(bbox.x1) - int(bbox.x0)
  57. height = int(bbox.y1) - int(bbox.y0)
  58. self._bbox_queue.append(bbox)
  59. self.queue_draw_area(x, y, width, height)
  60. def draw(self):
  61. if self.get_visible() and self.get_mapped():
  62. allocation = self.get_allocation()
  63. self._render_figure(allocation.width, allocation.height)
  64. super().draw()
  65. def print_png(self, filename, *args, **kwargs):
  66. # Do this so we can save the resolution of figure in the PNG file
  67. agg = self.switch_backends(backend_agg.FigureCanvasAgg)
  68. return agg.print_png(filename, *args, **kwargs)
  69. class FigureManagerGTK3Agg(backend_gtk3.FigureManagerGTK3):
  70. pass
  71. @_BackendGTK3.export
  72. class _BackendGTK3Cairo(_BackendGTK3):
  73. FigureCanvas = FigureCanvasGTK3Agg
  74. FigureManager = FigureManagerGTK3Agg