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

Skip to content

Commit eea4d80

Browse files
committed
Use Agg for rendering in the Mac OSX backend
1 parent 2b97396 commit eea4d80

File tree

3 files changed

+231
-3531
lines changed

3 files changed

+231
-3531
lines changed

lib/matplotlib/backends/backend_macosx.py

Lines changed: 34 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -4,231 +4,29 @@
44
from matplotlib.externals import six
55

66
import os
7-
import numpy
87

98
from matplotlib._pylab_helpers import Gcf
10-
from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\
11-
FigureManagerBase, FigureCanvasBase, NavigationToolbar2, TimerBase
9+
from matplotlib.backend_bases import FigureManagerBase, FigureCanvasBase, \
10+
NavigationToolbar2, TimerBase
1211
from matplotlib.backend_bases import ShowBase
1312

14-
from matplotlib.cbook import maxdict
1513
from matplotlib.figure import Figure
16-
from matplotlib.path import Path
17-
from matplotlib.mathtext import MathTextParser
18-
from matplotlib.colors import colorConverter
1914
from matplotlib import rcParams
2015

2116
from matplotlib.widgets import SubplotTool
2217

2318
import matplotlib
2419
from matplotlib.backends import _macosx
2520

21+
from .backend_agg import RendererAgg
22+
2623

2724
class Show(ShowBase):
2825
def mainloop(self):
2926
_macosx.show()
3027
show = Show()
3128

3229

33-
class RendererMac(RendererBase):
34-
"""
35-
The renderer handles drawing/rendering operations. Most of the renderer's
36-
methods forward the command to the renderer's graphics context. The
37-
renderer does not wrap a C object and is written in pure Python.
38-
"""
39-
40-
texd = maxdict(50) # a cache of tex image rasters
41-
42-
def __init__(self, dpi, width, height):
43-
RendererBase.__init__(self)
44-
self.dpi = dpi
45-
self.width = width
46-
self.height = height
47-
self.gc = GraphicsContextMac()
48-
self.gc.set_dpi(self.dpi)
49-
self.mathtext_parser = MathTextParser('MacOSX')
50-
51-
def set_width_height (self, width, height):
52-
self.width, self.height = width, height
53-
54-
def draw_path(self, gc, path, transform, rgbFace=None):
55-
if rgbFace is not None:
56-
rgbFace = tuple(rgbFace)
57-
linewidth = gc.get_linewidth()
58-
gc.draw_path(path, transform, linewidth, rgbFace)
59-
60-
def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None):
61-
if rgbFace is not None:
62-
rgbFace = tuple(rgbFace)
63-
linewidth = gc.get_linewidth()
64-
gc.draw_markers(marker_path, marker_trans, path, trans, linewidth, rgbFace)
65-
66-
def draw_path_collection(self, gc, master_transform, paths, all_transforms,
67-
offsets, offsetTrans, facecolors, edgecolors,
68-
linewidths, linestyles, antialiaseds, urls,
69-
offset_position):
70-
if offset_position=='data':
71-
offset_position = True
72-
else:
73-
offset_position = False
74-
path_ids = []
75-
for path, transform in self._iter_collection_raw_paths(
76-
master_transform, paths, all_transforms):
77-
path_ids.append((path, transform))
78-
master_transform = master_transform.get_matrix()
79-
offsetTrans = offsetTrans.get_matrix()
80-
gc.draw_path_collection(master_transform, path_ids, all_transforms,
81-
offsets, offsetTrans, facecolors, edgecolors,
82-
linewidths, linestyles, antialiaseds,
83-
offset_position)
84-
85-
def draw_quad_mesh(self, gc, master_transform, meshWidth, meshHeight,
86-
coordinates, offsets, offsetTrans, facecolors,
87-
antialiased, edgecolors):
88-
gc.draw_quad_mesh(master_transform.get_matrix(),
89-
meshWidth,
90-
meshHeight,
91-
coordinates,
92-
offsets,
93-
offsetTrans.get_matrix(),
94-
facecolors,
95-
antialiased,
96-
edgecolors)
97-
98-
def new_gc(self):
99-
self.gc.save()
100-
self.gc.set_hatch(None)
101-
self.gc._alpha = 1.0
102-
self.gc._forced_alpha = False # if True, _alpha overrides A from RGBA
103-
return self.gc
104-
105-
def draw_gouraud_triangle(self, gc, points, colors, transform):
106-
points = transform.transform(points)
107-
gc.draw_gouraud_triangle(points, colors)
108-
109-
def get_image_magnification(self):
110-
return self.gc.get_image_magnification()
111-
112-
def draw_image(self, gc, x, y, im):
113-
nrows, ncols, data = im.as_rgba_str()
114-
gc.draw_image(x, y, nrows, ncols, data)
115-
116-
def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None):
117-
# todo, handle props, angle, origins
118-
scale = self.gc.get_image_magnification()
119-
size = prop.get_size_in_points()
120-
texmanager = self.get_texmanager()
121-
key = s, size, self.dpi, angle, texmanager.get_font_config()
122-
im = self.texd.get(key) # Not sure what this does; just copied from backend_agg.py
123-
if im is None:
124-
Z = texmanager.get_grey(s, size, self.dpi*scale)
125-
Z = numpy.array(255.0 - Z * 255.0, numpy.uint8)
126-
127-
gc.draw_mathtext(x, y, angle, Z)
128-
129-
def _draw_mathtext(self, gc, x, y, s, prop, angle):
130-
scale = self.gc.get_image_magnification()
131-
ox, oy, width, height, descent, image, used_characters = \
132-
self.mathtext_parser.parse(s, self.dpi*scale, prop)
133-
descent /= scale
134-
xd = descent * numpy.sin(numpy.deg2rad(angle))
135-
yd = descent * numpy.cos(numpy.deg2rad(angle))
136-
x = numpy.round(x + ox + xd)
137-
y = numpy.round(y + oy - yd)
138-
gc.draw_mathtext(x, y, angle, 255 - image.as_array())
139-
140-
def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
141-
if ismath:
142-
self._draw_mathtext(gc, x, y, s, prop, angle)
143-
else:
144-
family = prop.get_family()
145-
weight = prop.get_weight()
146-
# transform weight into string for the native backend
147-
if weight >= 700:
148-
weight = 'bold'
149-
else:
150-
weight = 'normal'
151-
style = prop.get_style()
152-
points = prop.get_size_in_points()
153-
size = self.points_to_pixels(points)
154-
gc.draw_text(x, y, six.text_type(s), family, size, weight, style, angle)
155-
156-
def get_text_width_height_descent(self, s, prop, ismath):
157-
if ismath=='TeX':
158-
# todo: handle props
159-
texmanager = self.get_texmanager()
160-
fontsize = prop.get_size_in_points()
161-
w, h, d = texmanager.get_text_width_height_descent(s, fontsize,
162-
renderer=self)
163-
return w, h, d
164-
if ismath:
165-
ox, oy, width, height, descent, fonts, used_characters = \
166-
self.mathtext_parser.parse(s, self.dpi, prop)
167-
return width, height, descent
168-
family = prop.get_family()
169-
weight = prop.get_weight()
170-
# transform weight into string for the native backend
171-
if weight >= 700:
172-
weight = 'bold'
173-
else:
174-
weight = 'normal'
175-
style = prop.get_style()
176-
points = prop.get_size_in_points()
177-
size = self.points_to_pixels(points)
178-
width, height, descent = self.gc.get_text_width_height_descent(
179-
six.text_type(s), family, size, weight, style)
180-
return width, height, descent
181-
182-
def flipy(self):
183-
return False
184-
185-
def points_to_pixels(self, points):
186-
return points/72.0 * self.dpi
187-
188-
def option_image_nocomposite(self):
189-
return True
190-
191-
192-
class GraphicsContextMac(_macosx.GraphicsContext, GraphicsContextBase):
193-
"""
194-
The GraphicsContext wraps a Quartz graphics context. All methods
195-
are implemented at the C-level in macosx.GraphicsContext. These
196-
methods set drawing properties such as the line style, fill color,
197-
etc. The actual drawing is done by the Renderer, which draws into
198-
the GraphicsContext.
199-
"""
200-
def __init__(self):
201-
GraphicsContextBase.__init__(self)
202-
_macosx.GraphicsContext.__init__(self)
203-
204-
def set_alpha(self, alpha):
205-
GraphicsContextBase.set_alpha(self, alpha)
206-
_alpha = self.get_alpha()
207-
_macosx.GraphicsContext.set_alpha(self, _alpha, self.get_forced_alpha())
208-
rgb = self.get_rgb()
209-
_macosx.GraphicsContext.set_foreground(self, rgb)
210-
211-
def set_foreground(self, fg, isRGBA=False):
212-
GraphicsContextBase.set_foreground(self, fg, isRGBA)
213-
rgb = self.get_rgb()
214-
_macosx.GraphicsContext.set_foreground(self, rgb)
215-
216-
def set_graylevel(self, fg):
217-
GraphicsContextBase.set_graylevel(self, fg)
218-
_macosx.GraphicsContext.set_graylevel(self, fg)
219-
220-
def set_clip_rectangle(self, box):
221-
GraphicsContextBase.set_clip_rectangle(self, box)
222-
if not box: return
223-
_macosx.GraphicsContext.set_clip_rectangle(self, box.bounds)
224-
225-
def set_clip_path(self, path):
226-
GraphicsContextBase.set_clip_path(self, path)
227-
if not path: return
228-
path = path.get_fully_transformed_path()
229-
_macosx.GraphicsContext.set_clip_path(self, path)
230-
231-
23230
########################################################################
23331
#
23432
# The following functions and classes are for pylab and implement
@@ -311,14 +109,42 @@ class FigureCanvasMac(_macosx.FigureCanvas, FigureCanvasBase):
311109
def __init__(self, figure):
312110
FigureCanvasBase.__init__(self, figure)
313111
width, height = self.get_width_height()
314-
self.renderer = RendererMac(figure.dpi, width, height)
315112
_macosx.FigureCanvas.__init__(self, width, height)
316113

114+
@property
115+
def renderer(self):
116+
l, b, w, h = self.figure.bbox.bounds
117+
key = w, h, self.figure.dpi
118+
try:
119+
self._lastKey, self._renderer
120+
except AttributeError:
121+
need_new_renderer = True
122+
else:
123+
need_new_renderer = (self._lastKey != key)
124+
125+
if need_new_renderer:
126+
self._renderer = RendererAgg(w, h, self.figure.dpi)
127+
self._lastKey = key
128+
129+
return self._renderer
130+
131+
def _draw(self, device_scale):
132+
figure = self.figure
133+
134+
orig_dpi = figure.dpi
135+
try:
136+
figure.dpi *= device_scale
137+
renderer = self.renderer
138+
figure.draw(renderer)
139+
finally:
140+
figure.dpi = orig_dpi
141+
142+
return renderer
143+
317144
def draw_idle(self, *args, **kwargs):
318145
self.invalidate()
319146

320147
def resize(self, width, height):
321-
self.renderer.set_width_height(width, height)
322148
dpi = self.figure.dpi
323149
width /= dpi
324150
height /= dpi

setupext.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2140,14 +2140,11 @@ def check_requirements(self):
21402140

21412141
def get_extension(self):
21422142
sources = [
2143-
'src/_macosx.m',
2144-
'src/py_converters.cpp',
2145-
'src/path_cleanup.cpp'
2143+
'src/_macosx.m'
21462144
]
21472145

21482146
ext = make_extension('matplotlib.backends._macosx', sources)
21492147
Numpy().add_flags(ext)
2150-
LibAgg().add_flags(ext)
21512148
ext.extra_link_args.extend(['-framework', 'Cocoa'])
21522149
return ext
21532150

0 commit comments

Comments
 (0)