Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 77a484b

Browse files
committed
Merge in my Gtk3Agg changes with jrjohannson's Gtk3Cairo changes.
1 parent 9e4ab52 commit 77a484b

6 files changed

Lines changed: 149 additions & 52 deletions

File tree

lib/matplotlib/backends/backend_gtk3.py

Lines changed: 5 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ def fn_name(): return sys._getframe(1).f_code.co_name
66
try:
77
from gi.repository import Gtk, Gdk, GObject
88
from gi.repository import Pango
9-
import cairo
109
except ImportError:
1110
raise ImportError("GTK3 backend requires pygobject to be installed.")
1211

@@ -15,7 +14,6 @@ def fn_name(): return sys._getframe(1).f_code.co_name
1514
from matplotlib.backend_bases import RendererBase, GraphicsContextBase, \
1615
FigureManagerBase, FigureCanvasBase, NavigationToolbar2, cursors, TimerBase
1716
from matplotlib.backend_bases import ShowBase
18-
from matplotlib.backends import backend_cairo
1917

2018
from matplotlib.cbook import is_string_like, is_writable_file_like
2119
from matplotlib.colors import colorConverter
@@ -60,16 +58,6 @@ def mainloop(self):
6058

6159
show = Show()
6260

63-
def new_figure_manager(num, *args, **kwargs):
64-
"""
65-
Create a new figure manager instance
66-
"""
67-
FigureClass = kwargs.pop('FigureClass', Figure)
68-
thisFig = FigureClass(*args, **kwargs)
69-
canvas = FigureCanvasGTK3(thisFig)
70-
manager = FigureManagerGTK3(canvas, num)
71-
return manager
72-
7361

7462
class TimerGTK3(TimerBase):
7563
'''
@@ -112,11 +100,7 @@ def _on_timer(self):
112100
self._timer = None
113101
return False
114102

115-
class RendererGTK3Cairo (backend_cairo.RendererCairo):
116-
def set_context (self, ctx):
117-
self.gc.ctx = ctx
118-
119-
class FigureCanvasGTK3 (Gtk.DrawingArea, backend_cairo.FigureCanvasCairo):
103+
class FigureCanvasGTK3 (Gtk.DrawingArea, FigureCanvasBase):
120104
keyvald = {65507 : 'control',
121105
65505 : 'shift',
122106
65513 : 'alt',
@@ -319,30 +303,6 @@ def idle_draw(*args):
319303
if self._idle_draw_id == 0:
320304
self._idle_draw_id = GObject.idle_add(idle_draw)
321305

322-
def _renderer_init(self):
323-
"""use cairo renderer"""
324-
if _debug: print '%s.%s()' % (self.__class__.__name__, fn_name())
325-
self._renderer = RendererGTK3Cairo(self.figure.dpi)
326-
327-
def _render_figure(self, width, height):
328-
"""use cairo renderer"""
329-
self._renderer.set_width_height (width, height)
330-
self.figure.draw (self._renderer)
331-
332-
def on_draw_event(self, widget, ctx):
333-
""" GtkDrawable draw event, like expose_event in GTK 2.X
334-
"""
335-
if _debug: print 'FigureCanvasGTK3.%s' % fn_name()
336-
337-
if self._need_redraw:
338-
self._renderer.set_context(ctx)
339-
allocation = self.get_allocation()
340-
x, y, w, h = allocation.x, allocation.y, allocation.width, allocation.height
341-
self._render_figure(w, h)
342-
self._need_redraw = False
343-
344-
return False # finish event propagation?
345-
346306
def get_default_filetype(self):
347307
return 'png'
348308

@@ -561,7 +521,7 @@ def _init_toolbar(self):
561521
fname = os.path.join(basedir, image_file)
562522
image = Gtk.Image()
563523
image.set_from_file(fname)
564-
tbutton = Gtk.ToolButton()
524+
tbutton = Gtk.ToolButton()
565525
tbutton.set_label(text)
566526
tbutton.set_icon_widget(image)
567527
self.insert(tbutton, -1)
@@ -624,7 +584,7 @@ def configure_subplots(self, button):
624584
window.show()
625585

626586
def _get_canvas(self, fig):
627-
return FigureCanvasGTK3(fig)
587+
return self.canvas.__class__(fig)
628588

629589

630590
class NavigationToolbar(Gtk.Toolbar):
@@ -702,7 +662,7 @@ def _create_toolitems(self):
702662
continue
703663
image = Gtk.Image()
704664
image.set_from_stock(image_num, iconSize)
705-
tbutton = Gtk.ToolButton()
665+
tbutton = Gtk.ToolButton()
706666
tbutton.set_label(text)
707667
tbutton.set_icon_widget(image)
708668
self.insert(tbutton, -1)
@@ -736,7 +696,7 @@ def position_menu (menu):
736696
x0, y0 = self.window.get_origin()
737697
x1, y1, m = self.window.get_pointer()
738698
x2, y2 = self.menubutton.get_pointer()
739-
sc_h = self.get_screen().get_height()
699+
sc_h = self.get_screen().get_height()
740700
w, h = menu.size_request()
741701

742702
x = x0 + x1 - x2
@@ -1116,6 +1076,3 @@ def error_msg_gtk(msg, parent=None):
11161076
message_format = msg)
11171077
dialog.run()
11181078
dialog.destroy()
1119-
1120-
1121-
FigureManager = FigureManagerGTK3
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import cairo
2+
import numpy as np
3+
4+
import backend_agg
5+
import backend_gtk3
6+
from matplotlib.figure import Figure
7+
from matplotlib import transforms
8+
9+
10+
class FigureCanvasGTK3Agg(backend_gtk3.FigureCanvasGTK3,
11+
backend_agg.FigureCanvasAgg):
12+
def __init__(self, figure):
13+
backend_gtk3.FigureCanvasGTK3.__init__(self, figure)
14+
self._bbox_queue = []
15+
16+
def _renderer_init(self):
17+
pass
18+
19+
def _render_figure(self, width, height):
20+
backend_agg.FigureCanvasAgg.draw(self)
21+
22+
def on_draw_event(self, widget, ctx):
23+
""" GtkDrawable draw event, like expose_event in GTK 2.X
24+
"""
25+
allocation = self.get_allocation()
26+
w, h = allocation.width, allocation.height
27+
28+
if not len(self._bbox_queue):
29+
if self._need_redraw:
30+
self._render_figure(w, h)
31+
bbox_queue = [transforms.Bbox([[0, 0], [w, h]])]
32+
else:
33+
return
34+
else:
35+
bbox_queue = self._bbox_queue
36+
37+
for bbox in bbox_queue:
38+
area = self.copy_from_bbox(bbox)
39+
buf = np.fromstring(area.to_string_argb(), dtype='uint8')
40+
41+
x = int(bbox.x0)
42+
y = h - int(bbox.y1)
43+
width = int(bbox.x1) - int(bbox.x0)
44+
height = int(bbox.y1) - int(bbox.y0)
45+
46+
image = cairo.ImageSurface.create_for_data(
47+
buf, cairo.FORMAT_ARGB32, width, height)
48+
ctx.set_source_surface(image, x, y)
49+
ctx.paint()
50+
51+
if len(self._bbox_queue):
52+
self._bbox_queue = []
53+
54+
return False
55+
56+
def blit(self, bbox=None):
57+
self._bbox_queue.append(bbox)
58+
self.queue_draw()
59+
60+
def print_png(self, filename, *args, **kwargs):
61+
# Do this so we can save the resolution of figure in the PNG file
62+
agg = self.switch_backends(backend_agg.FigureCanvasAgg)
63+
return agg.print_png(filename, *args, **kwargs)
64+
65+
66+
class FigureManagerGTK3Agg(backend_gtk3.FigureManagerGTK3):
67+
pass
68+
69+
70+
def new_figure_manager(num, *args, **kwargs):
71+
"""
72+
Create a new figure manager instance
73+
"""
74+
FigureClass = kwargs.pop('FigureClass', Figure)
75+
thisFig = FigureClass(*args, **kwargs)
76+
canvas = FigureCanvasGTK3Agg(thisFig)
77+
manager = FigureManagerGTK3Agg(canvas, num)
78+
return manager
79+
80+
81+
FigureManager = FigureManagerGTK3Agg
82+
show = backend_gtk3.show
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import backend_gtk3
2+
import backend_cairo
3+
from matplotlib.figure import Figure
4+
5+
6+
class RendererGTK3Cairo(backend_cairo.RendererCairo):
7+
def set_context(self, ctx):
8+
self.gc.ctx = ctx
9+
10+
11+
class FigureCanvasGTK3Cairo(backend_gtk3.FigureCanvasGTK3,
12+
backend_cairo.FigureCanvasCairo):
13+
def __init__(self, figure):
14+
backend_gtk3.FigureCanvasGTK3.__init__(self, figure)
15+
16+
def _renderer_init(self):
17+
"""use cairo renderer"""
18+
self._renderer = RendererGTK3Cairo(self.figure.dpi)
19+
20+
def _render_figure(self, width, height):
21+
self._renderer.set_width_height (width, height)
22+
self.figure.draw (self._renderer)
23+
24+
def on_draw_event(self, widget, ctx):
25+
""" GtkDrawable draw event, like expose_event in GTK 2.X
26+
"""
27+
if _debug: print 'FigureCanvasGTK3.%s' % fn_name()
28+
29+
if self._need_redraw:
30+
self._renderer.set_context(ctx)
31+
allocation = self.get_allocation()
32+
x, y, w, h = allocation.x, allocation.y, allocation.width, allocation.height
33+
self._render_figure(w, h)
34+
self._need_redraw = False
35+
36+
return False # finish event propagation?
37+
38+
39+
class FigureManagerGTK3Cairo(backend_gtk3.FigureManagerGTK3):
40+
pass
41+
42+
43+
def new_figure_manager(num, *args, **kwargs):
44+
"""
45+
Create a new figure manager instance
46+
"""
47+
FigureClass = kwargs.pop('FigureClass', Figure)
48+
thisFig = FigureClass(*args, **kwargs)
49+
canvas = FigureCanvasGTK3Cairo(thisFig)
50+
manager = FigureManagerGTK3Cairo(canvas, num)
51+
return manager
52+
53+
54+
FigureManager = FigureManagerGTK3Cairo
55+
show = backend_gtk3.show

lib/matplotlib/rcsetup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
# change for later versions.
2626

2727
interactive_bk = ['GTK', 'GTKAgg', 'GTKCairo', 'FltkAgg', 'MacOSX',
28-
'QtAgg', 'Qt4Agg', 'TkAgg', 'WX', 'WXAgg', 'CocoaAgg']
28+
'QtAgg', 'Qt4Agg', 'TkAgg', 'WX', 'WXAgg', 'CocoaAgg',
29+
'Gtk3Cairo', 'Gtk3Agg']
2930

3031

3132
non_interactive_bk = ['agg', 'cairo', 'emf', 'gdk',

matplotlibrc.template

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@
2323

2424
#### CONFIGURATION BEGINS HERE
2525

26-
# the default backend; one of GTK GTKAgg GTKCairo CocoaAgg FltkAgg
27-
# MacOSX QtAgg Qt4Agg TkAgg WX WXAgg Agg Cairo GDK PS PDF SVG Template
26+
# the default backend; one of GTK GTKAgg GTKCairo GTK3Agg GTK3Cairo
27+
# CocoaAgg FltkAgg MacOSX QtAgg Qt4Agg TkAgg WX WXAgg Agg Cairo GDK PS
28+
# PDF SVG Template
2829
# You can also deploy your own backend outside of matplotlib by
2930
# referring to the module name (which must be in the PYTHONPATH) as
3031
# 'module://my_backend'

src/_backend_agg.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2199,7 +2199,8 @@ RendererAgg::buffer_rgba(const Py::Tuple& args)
21992199
return Py::asObject(PyMemoryView_FromObject(this));
22002200
#else
22012201
int row_len = width * 4;
2202-
return Py::asObject(PyBuffer_FromMemory(pixBuffer, row_len*height));
2202+
return Py::asObject(PyBuffer_FromReadWriteMemory(
2203+
pixBuffer, row_len*height));
22032204
#endif
22042205
}
22052206

0 commit comments

Comments
 (0)