def test_fontconfig_preamble(): """Test that the preamble is included in _fontconfig.""" plt.rcParams['text.usetex'] = True tm1 = TexManager() font_config1 = tm1.get_font_config() plt.rcParams['text.latex.preamble'] = '\\usepackage{txfonts}' tm2 = TexManager() font_config2 = tm2.get_font_config() assert font_config1 != font_config2
def test_fontconfig_preamble(): """ Test that the preamble is included in _fontconfig """ plt.rcParams['text.usetex'] = True tm1 = TexManager() font_config1 = tm1.get_font_config() plt.rcParams['text.latex.preamble'] = [r'\usepackage{txfonts}'] tm2 = TexManager() font_config2 = tm2.get_font_config() assert font_config1 != font_config2
class RendererAgg(RendererBase): """ The renderer handles all the drawing primitives using a graphics context instance that controls the colors/styles """ debug = 1 texd = {} # a cache of tex image rasters def __init__(self, width, height, dpi): if __debug__: verbose.report('RendererAgg.__init__', 'debug-annoying') self.dpi = dpi self.width = width self.height = height self._renderer = _RendererAgg(int(width), int(height), dpi.get(), debug=False) self.draw_polygon = self._renderer.draw_polygon self.draw_rectangle = self._renderer.draw_rectangle self.draw_path = self._renderer.draw_path self.draw_lines = self._renderer.draw_lines self.draw_markers = self._renderer.draw_markers self.draw_image = self._renderer.draw_image self.draw_line_collection = self._renderer.draw_line_collection self.draw_quad_mesh = self._renderer.draw_quad_mesh self.draw_poly_collection = self._renderer.draw_poly_collection self.draw_regpoly_collection = self._renderer.draw_regpoly_collection self.copy_from_bbox = self._renderer.copy_from_bbox self.restore_region = self._renderer.restore_region self.texmanager = TexManager() self.bbox = lbwh_to_bbox(0, 0, self.width, self.height) def draw_arc(self, gcEdge, rgbFace, x, y, width, height, angle1, angle2): """ Draw an arc centered at x,y with width and height and angles from 0.0 to 360.0 If rgbFace is not None, fill the rectangle with that color. gcEdge is a GraphicsContext instance Currently, I'm only supporting ellipses, ie angle args are ignored """ if __debug__: verbose.report('RendererAgg.draw_arc', 'debug-annoying') self._renderer.draw_ellipse(gcEdge, rgbFace, x, y, width / 2, height / 2) # ellipse takes radius def _draw_image(self, x, y, im): """ Draw the Image instance into the current axes; x, y is the upper left hand corner of the image """ if __debug__: verbose.report('RendererAgg.draw_image', 'debug-annoying') #self._renderer.draw_image(int(x), int(self.height-y), im) self._renderer.draw_image(int(x), int(y), im) def draw_line(self, gc, x1, y1, x2, y2): """ x and y are equal length arrays, draw lines connecting each point in x, y """ if __debug__: verbose.report('RendererAgg.draw_line', 'debug-annoying') x = array([x1, x2], typecode=Float) y = array([y1, y2], typecode=Float) self._renderer.draw_lines(gc, x, y) def draw_point(self, gc, x, y): """ Draw a single point at x,y """ if __debug__: verbose.report('RendererAgg.draw_point', 'debug-annoying') rgbFace = gc.get_rgb() self._renderer.draw_ellipse(gc, rgbFace, x, y, 0.5, 0.5) def draw_mathtext(self, gc, x, y, s, prop, angle): """ Draw the math text using matplotlib.mathtext """ if __debug__: verbose.report('RendererAgg.draw_mathtext', 'debug-annoying') size = prop.get_size_in_points() width, height, fonts = math_parse_s_ft2font(s, self.dpi.get(), size, angle) if angle == 90: width, height = height, width for font in fonts: if angle == 90: font.horiz_image_to_vert_image() # <-- Rotate self._renderer.draw_text(font, int(x) - width, int(y) - height, gc) else: self._renderer.draw_text(font, int(x), int(y) - height, gc) if 0: self._renderer.draw_rectangle(gc, None, int(x), self.height - int(y), width, height) def draw_text(self, gc, x, y, s, prop, angle, ismath): """ Render the text """ if __debug__: verbose.report('RendererAgg.draw_text', 'debug-annoying') if ismath: return self.draw_mathtext(gc, x, y, s, prop, angle) font = self._get_agg_font(prop) if font is None: return None if len(s) == 1 and ord(s) > 127: font.load_char(ord(s)) else: font.set_text(s, angle) font.draw_glyphs_to_bitmap() #print x, y, int(x), int(y) self._renderer.draw_text(font, int(x), int(y), gc) def get_text_width_height(self, s, prop, ismath, rgb=(0, 0, 0)): """ get the width and height in display coords of the string s with FontPropertry prop # passing rgb is a little hack to make cacheing in the # texmanager more efficient. It is not meant to be used # outside the backend """ if ismath == 'TeX': # todo: handle props size = prop.get_size_in_points() Z = self.texmanager.get_rgba(s, size, rgb) m, n, tmp = Z.shape return n, m if ismath: width, height, fonts = math_parse_s_ft2font( s, self.dpi.get(), prop.get_size_in_points()) return width, height font = self._get_agg_font(prop) font.set_text(s, 0.0) # the width and height of unrotated string w, h = font.get_width_height() w /= 64.0 # convert from subpixels h /= 64.0 return w, h def draw_tex(self, gc, x, y, s, prop, angle): # todo, handle props, angle, origins rgb = gc.get_rgb() size = prop.get_size_in_points() flip = angle == 90 w, h = self.get_text_width_height(s, prop, 'TeX', rgb) if flip: w, h = h, w x -= w key = s, size, rgb, angle, self.texmanager.get_font_config() im = self.texd.get(key) if im is None: Z = self.texmanager.get_rgba(s, size, rgb) if flip: r = Z[:, :, 0] g = Z[:, :, 1] b = Z[:, :, 2] a = Z[:, :, 3] m, n, tmp = Z.shape def func(x): return transpose(fliplr(x)) Z = zeros((n, m, 4), typecode=Float) Z[:, :, 0] = func(r) Z[:, :, 1] = func(g) Z[:, :, 2] = func(b) Z[:, :, 3] = func(a) im = fromarray(Z, 1) im.flipud_out() self.texd[key] = im cliprect = gc.get_clip_rectangle() if cliprect is None: bbox = None else: bbox = lbwh_to_bbox(*cliprect) self.draw_image(x, self.height - y, im, bbox) def get_canvas_width_height(self): 'return the canvas width and height in display coords' return self.width, self.height def _get_agg_font(self, prop): """ Get the font for text instance t, cacheing for efficiency """ if __debug__: verbose.report('RendererAgg._get_agg_font', 'debug-annoying') key = hash(prop) font = _fontd.get(key) if font is None: fname = fontManager.findfont(prop) font = FT2Font(str(fname)) _fontd[key] = font font.clear() size = prop.get_size_in_points() font.set_size(size, self.dpi.get()) return font def points_to_pixels(self, points): """ convert point measures to pixes using dpi and the pixels per inch of the display """ if __debug__: verbose.report('RendererAgg.points_to_pixels', 'debug-annoying') return points * self.dpi.get() / 72.0 def tostring_rgb(self): if __debug__: verbose.report('RendererAgg.tostring_rgb', 'debug-annoying') return self._renderer.tostring_rgb() def tostring_argb(self): if __debug__: verbose.report('RendererAgg.tostring_argb', 'debug-annoying') return self._renderer.tostring_argb() def buffer_rgba(self, x, y): if __debug__: verbose.report('RendererAgg.buffer_rgba', 'debug-annoying') return self._renderer.buffer_rgba(x, y) def clear(self): self._renderer.clear()
class RendererGR(RendererBase): """ Handles drawing/rendering operations using GR """ texd = maxdict(50) # a cache of tex image rasters def __init__(self, dpi, width, height): self.dpi = dpi self.width = float(width) * dpi / 80 self.height = float(height) * dpi / 80 self.mathtext_parser = MathTextParser('agg') self.texmanager = TexManager() def configure(self): aspect_ratio = self.width / self.height if aspect_ratio > 1: rect = np.array([0, 1, 0, 1.0 / aspect_ratio]) self.size = self.width else: rect = np.array([0, aspect_ratio, 0, 1]) self.size = self.height mwidth, mheight, width, height = gr.inqdspsize() if width / (mwidth / 0.0256) < 200: mwidth *= self.width / width gr.setwsviewport(*rect * mwidth) else: gr.setwsviewport(*rect * 0.192) gr.setwswindow(*rect) gr.setviewport(*rect) gr.setwindow(0, self.width, 0, self.height) def draw_path(self, gc, path, transform, rgbFace=None): path = transform.transform_path(path) points = path.vertices codes = path.codes bbox = gc.get_clip_rectangle() if bbox is not None: x, y, w, h = bbox.bounds clrt = np.array([x, x + w, y, y + h]) else: clrt = np.array([0, self.width, 0, self.height]) gr.setviewport(*clrt / self.size) gr.setwindow(*clrt) if rgbFace is not None and len(points) > 2: color = gr.inqcolorfromrgb(rgbFace[0], rgbFace[1], rgbFace[2]) gr.settransparency(rgbFace[3]) gr.setcolorrep(color, rgbFace[0], rgbFace[1], rgbFace[2]) gr.setfillintstyle(gr.INTSTYLE_SOLID) gr.setfillcolorind(color) gr.drawpath(points, codes, fill=True) lw = gc.get_linewidth() if lw != 0: rgba = gc.get_rgb()[:4] color = gr.inqcolorfromrgb(rgba[0], rgba[1], rgba[2]) gr.settransparency(rgba[3]) gr.setcolorrep(color, rgba[0], rgba[1], rgba[2]) if isinstance(gc._linestyle, str): gr.setlinetype(linetype[gc._linestyle]) gr.setlinewidth(lw) gr.setlinecolorind(color) gr.drawpath(points, codes, fill=False) def draw_image(self, gc, x, y, im): h, w, s = im.as_rgba_str() img = np.fromstring(s, np.uint32) img.shape = (h, w) gr.drawimage(x, x + w, y + h, y, w, h, img) def draw_mathtext(self, x, y, angle, Z): h, w = Z.shape img = np.zeros((h, w), np.uint32) for i in range(h): for j in range(w): img[i, j] = (255 - Z[i, j]) << 24 a = int(angle) if a == 90: gr.drawimage(x - h, x, y, y + w, h, w, np.resize(np.rot90(img, 1), (h, w))) elif a == 180: gr.drawimage(x - w, x, y - h, y, w, h, np.rot90(img, 2)) elif a == 270: gr.drawimage(x, x + h, y - w, y, h, w, np.resize(np.rot90(img, 3), (h, w))) else: gr.drawimage(x, x + w, y, y + h, w, h, img) def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None): size = prop.get_size_in_points() key = s, size, self.dpi, angle, self.texmanager.get_font_config() im = self.texd.get(key) if im is None: Z = self.texmanager.get_grey(s, size, self.dpi) Z = np.array(255.0 - Z * 255.0, np.uint8) self.draw_mathtext(x, y, angle, Z) def _draw_mathtext(self, gc, x, y, s, prop, angle): ox, oy, width, height, descent, image, used_characters = \ self.mathtext_parser.parse(s, self.dpi, prop) self.draw_mathtext(x, y, angle, 255 - image.as_array()) def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): if ismath: self._draw_mathtext(gc, x, y, s, prop, angle) else: x, y = gr.wctondc(x, y) s = s.replace(u'\u2212', '-') fontsize = prop.get_size_in_points() rgba = gc.get_rgb()[:4] color = gr.inqcolorfromrgb(rgba[0], rgba[1], rgba[2]) gr.settransparency(rgba[3]) gr.setcolorrep(color, rgba[0], rgba[1], rgba[2]) gr.setcharheight(fontsize * 0.0013) gr.settextcolorind(color) if angle != 0: gr.setcharup(-np.sin(angle * np.pi/180), np.cos(angle * np.pi/180)) else: gr.setcharup(0, 1) gr.text(x, y, s) def flipy(self): return False def get_canvas_width_height(self): return self.width, self.height def get_text_width_height_descent(self, s, prop, ismath): if ismath == 'TeX': fontsize = prop.get_size_in_points() w, h, d = self.texmanager.get_text_width_height_descent( s, fontsize, renderer=self) return w, h, d if ismath: ox, oy, width, height, descent, fonts, used_characters = \ self.mathtext_parser.parse(s, self.dpi, prop) return width, height, descent # family = prop.get_family() # weight = prop.get_weight() # style = prop.get_style() fontsize = prop.get_size_in_points() gr.setcharheight(fontsize * 0.0013) gr.setcharup(0, 1) (tbx, tby) = gr.inqtextext(0, 0, s) width, height, descent = tbx[1], tby[2], 0 return width, height, descent def new_gc(self): return GraphicsContextGR() def points_to_pixels(self, points): return points
class RendererGR(RendererBase): """ Handles drawing/rendering operations using GR """ texd = maxdict(50) # a cache of tex image rasters def __init__(self, dpi, width, height): self.dpi = dpi if __version__[0] >= '2': self.nominal_fontsize = 0.001625 default_dpi = 100 else: self.nominal_fontsize = 0.0013 default_dpi = 80 self.width = float(width) * dpi / default_dpi self.height = float(height) * dpi / default_dpi self.mathtext_parser = MathTextParser('agg') self.texmanager = TexManager() def configure(self): aspect_ratio = self.width / self.height if aspect_ratio > 1: rect = np.array([0, 1, 0, 1.0 / aspect_ratio]) self.size = self.width else: rect = np.array([0, aspect_ratio, 0, 1]) self.size = self.height mwidth, mheight, width, height = gr.inqdspsize() if width / (mwidth / 0.0256) < 200: mwidth *= self.width / width gr.setwsviewport(*rect * mwidth) else: gr.setwsviewport(*rect * 0.192) gr.setwswindow(*rect) gr.setviewport(*rect) gr.setwindow(0, self.width, 0, self.height) def draw_path(self, gc, path, transform, rgbFace=None): path = transform.transform_path(path) points = path.vertices codes = path.codes bbox = gc.get_clip_rectangle() if bbox is not None and not np.any(np.isnan(bbox.bounds)): x, y, w, h = bbox.bounds clrt = np.array([x, x + w, y, y + h]) else: clrt = np.array([0, self.width, 0, self.height]) gr.setviewport(*clrt / self.size) gr.setwindow(*clrt) if rgbFace is not None and len(points) > 2: color = gr.inqcolorfromrgb(rgbFace[0], rgbFace[1], rgbFace[2]) gr.settransparency(rgbFace[3]) gr.setcolorrep(color, rgbFace[0], rgbFace[1], rgbFace[2]) gr.setfillintstyle(gr.INTSTYLE_SOLID) gr.setfillcolorind(color) gr.drawpath(points, codes, fill=True) lw = gc.get_linewidth() if lw != 0: rgba = gc.get_rgb()[:4] color = gr.inqcolorfromrgb(rgba[0], rgba[1], rgba[2]) gr.settransparency(rgba[3]) gr.setcolorrep(color, rgba[0], rgba[1], rgba[2]) if isinstance(gc._linestyle, str): gr.setlinetype(linetype[gc._linestyle]) gr.setlinewidth(lw) gr.setlinecolorind(color) gr.drawpath(points, codes, fill=False) def draw_image(self, gc, x, y, im): if hasattr(im, 'as_rgba_str'): h, w, s = im.as_rgba_str() img = np.fromstring(s, np.uint32) img.shape = (h, w) elif len(im.shape) == 3 and im.shape[2] == 4 and im.dtype == np.uint8: img = im.view(np.uint32) img.shape = im.shape[:2] h, w = img.shape else: type_info = repr(type(im)) if hasattr(im, 'shape'): type_info += ' shape=' + repr(im.shape) if hasattr(im, 'dtype'): type_info += ' dtype=' + repr(im.dtype) warnings.warn('Unsupported image type ({}). Please report this at https://github.com/sciapp/python-gr/issues'.format(type_info)) return gr.drawimage(x, x + w, y + h, y, w, h, img) def draw_mathtext(self, x, y, angle, Z): h, w = Z.shape img = np.zeros((h, w), np.uint32) for i in range(h): for j in range(w): img[i, j] = (255 - Z[i, j]) << 24 a = int(angle) if a == 90: gr.drawimage(x - h, x, y, y + w, h, w, np.resize(np.rot90(img, 1), (h, w))) elif a == 180: gr.drawimage(x - w, x, y - h, y, w, h, np.rot90(img, 2)) elif a == 270: gr.drawimage(x, x + h, y - w, y, h, w, np.resize(np.rot90(img, 3), (h, w))) else: gr.drawimage(x, x + w, y, y + h, w, h, img) def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None): size = prop.get_size_in_points() key = s, size, self.dpi, angle, self.texmanager.get_font_config() im = self.texd.get(key) if im is None: Z = self.texmanager.get_grey(s, size, self.dpi) Z = np.array(255.0 - Z * 255.0, np.uint8) self.draw_mathtext(x, y, angle, Z) def _draw_mathtext(self, gc, x, y, s, prop, angle): ox, oy, width, height, descent, image, used_characters = \ self.mathtext_parser.parse(s, self.dpi, prop) self.draw_mathtext(x, y, angle, 255 - np.asarray(image)) def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): if ismath: self._draw_mathtext(gc, x, y, s, prop, angle) else: x, y = gr.wctondc(x, y) fontsize = prop.get_size_in_points() rgba = gc.get_rgb()[:4] color = gr.inqcolorfromrgb(rgba[0], rgba[1], rgba[2]) gr.settransparency(rgba[3]) gr.setcolorrep(color, rgba[0], rgba[1], rgba[2]) gr.setcharheight(fontsize * self.nominal_fontsize) gr.settextcolorind(color) if angle != 0: gr.setcharup(-np.sin(angle * np.pi/180), np.cos(angle * np.pi/180)) else: gr.setcharup(0, 1) gr.text(x, y, s) def flipy(self): return False def get_canvas_width_height(self): return self.width, self.height def get_text_width_height_descent(self, s, prop, ismath): if ismath == 'TeX': fontsize = prop.get_size_in_points() w, h, d = self.texmanager.get_text_width_height_descent( s, fontsize, renderer=self) return w, h, d if ismath: ox, oy, width, height, descent, fonts, used_characters = \ self.mathtext_parser.parse(s, self.dpi, prop) return width, height, descent # family = prop.get_family() # weight = prop.get_weight() # style = prop.get_style() fontsize = prop.get_size_in_points() gr.setcharheight(fontsize * self.nominal_fontsize) gr.setcharup(0, 1) (tbx, tby) = gr.inqtextext(0, 0, s) width, height, descent = tbx[1], tby[2], 0.2 * tby[2] return width, height, descent def new_gc(self): return GraphicsContextGR() def points_to_pixels(self, points): return points
class RendererGR(RendererBase): """ Handles drawing/rendering operations using GR """ texd = maxdict(50) # a cache of tex image rasters def __init__(self, dpi): self.dpi = dpi self.width = 640.0 * dpi / 80 self.height = 480.0 * dpi / 80 mwidth, mheight, width, height = gr.inqdspsize() if (width / (mwidth / 0.0256) < 200): mwidth *= self.width / width gr.setwsviewport(0, mwidth, 0, mwidth * 0.75) else: gr.setwsviewport(0, 0.192, 0, 0.144) gr.setwswindow(0, 1, 0, 0.75) gr.setviewport(0, 1, 0, 0.75) gr.setwindow(0, self.width, 0, self.height) self.mathtext_parser = MathTextParser('agg') self.texmanager = TexManager() def draw_path(self, gc, path, transform, rgbFace=None): path = transform.transform_path(path) points = path.vertices codes = path.codes bbox = gc.get_clip_rectangle() if bbox is not None: x, y, w, h = bbox.bounds clrt = np.array([x, x + w, y, y + h]) else: clrt = np.array([0, self.width, 0, self.height]) gr.setviewport(*clrt/self.width) gr.setwindow(*clrt) if rgbFace is not None and len(points) > 2: color = gr.inqcolorfromrgb(rgbFace[0], rgbFace[1], rgbFace[2]) gr.settransparency(rgbFace[3]) gr.setcolorrep(color, rgbFace[0], rgbFace[1], rgbFace[2]) gr.setfillintstyle(gr.INTSTYLE_SOLID) gr.setfillcolorind(color) gr.drawpath(points, codes, fill=True) lw = gc.get_linewidth() if lw != 0: rgba = gc.get_rgb()[:4] color = gr.inqcolorfromrgb(rgba[0], rgba[1], rgba[2]) gr.settransparency(rgba[3]) gr.setcolorrep(color, rgba[0], rgba[1], rgba[2]) if type(gc._linestyle) is unicode: gr.setlinetype(linetype[gc._linestyle]) gr.setlinewidth(lw) gr.setlinecolorind(color) gr.drawpath(points, codes, fill=False) def draw_image(self, gc, x, y, im): h, w, s = im.as_rgba_str() img = np.fromstring(s, np.uint32) img.shape = (h, w) gr.drawimage(x, x + w, y + h, y, w, h, img) def draw_mathtext(self, x, y, angle, Z): h, w = Z.shape img = np.zeros((h, w), np.uint32) for i in range(h): for j in range(w): img[i, j] = (255 - Z[i, j]) << 24 a = int(angle) if a == 90: gr.drawimage(x - h, x, y, y + w, h, w, np.resize(np.rot90(img, 1), (h, w))) elif a == 180: gr.drawimage(x - w, x, y - h, y, w, h, np.rot90(img, 2)) elif a == 270: gr.drawimage(x, x + h, y - w, y, h, w, np.resize(np.rot90(img, 3), (h, w))) else: gr.drawimage(x, x + w, y, y + h, w, h, img) def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None): size = prop.get_size_in_points() key = s, size, self.dpi, angle, self.texmanager.get_font_config() im = self.texd.get(key) if im is None: Z = self.texmanager.get_grey(s, size, self.dpi) Z = np.array(255.0 - Z * 255.0, np.uint8) self.draw_mathtext(x, y, angle, Z) def _draw_mathtext(self, gc, x, y, s, prop, angle): ox, oy, width, height, descent, image, used_characters = \ self.mathtext_parser.parse(s, self.dpi, prop) self.draw_mathtext(x, y, angle, 255 - image.as_array()) def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None): if ismath: self._draw_mathtext(gc, x, y, s, prop, angle) else: x, y = gr.wctondc(x, y) s = s.replace(u'\u2212', '-') fontsize = prop.get_size_in_points() rgba = gc.get_rgb()[:4] color = gr.inqcolorfromrgb(rgba[0], rgba[1], rgba[2]) gr.settransparency(rgba[3]) gr.setcolorrep(color, rgba[0], rgba[1], rgba[2]) gr.setcharheight(fontsize * 0.0013) gr.settextcolorind(color) if angle != 0: gr.setcharup(-np.sin(angle * np.pi/180), np.cos(angle * np.pi/180)) else: gr.setcharup(0, 1) gr.text(x, y, s.encode("latin-1")) def flipy(self): return False def get_canvas_width_height(self): return self.width, self.height def get_text_width_height_descent(self, s, prop, ismath): if ismath == 'TeX': fontsize = prop.get_size_in_points() w, h, d = self.texmanager.get_text_width_height_descent( s, fontsize, renderer=self) return w, h, d if ismath: ox, oy, width, height, descent, fonts, used_characters = \ self.mathtext_parser.parse(s, self.dpi, prop) return width, height, descent # family = prop.get_family() # weight = prop.get_weight() # style = prop.get_style() s = s.replace(u'\u2212', '-').encode("latin-1") fontsize = prop.get_size_in_points() gr.setcharheight(fontsize * 0.0013) gr.setcharup(0, 1) (tbx, tby) = gr.inqtextext(0, 0, s) width, height, descent = tbx[1], tby[2], 0 return width, height, descent def new_gc(self): return GraphicsContextGR() def points_to_pixels(self, points): return points
class RendererAgg(RendererBase): """ The renderer handles all the drawing primitives using a graphics context instance that controls the colors/styles """ debug=1 texd = {} # a cache of tex image rasters def __init__(self, width, height, dpi): if __debug__: verbose.report('RendererAgg.__init__', 'debug-annoying') self.dpi = dpi self.width = width self.height = height if __debug__: verbose.report('RendererAgg.__init__ width=%s, height=%s'%(width, height), 'debug-annoying') self._renderer = _RendererAgg(int(width), int(height), dpi.get(), debug=False) if __debug__: verbose.report('RendererAgg.__init__ _RendererAgg done', 'debug-annoying') self.draw_polygon = self._renderer.draw_polygon self.draw_rectangle = self._renderer.draw_rectangle self.draw_path = self._renderer.draw_path self.draw_lines = self._renderer.draw_lines self.draw_markers = self._renderer.draw_markers self.draw_image = self._renderer.draw_image self.draw_line_collection = self._renderer.draw_line_collection self.draw_quad_mesh = self._renderer.draw_quad_mesh self.draw_poly_collection = self._renderer.draw_poly_collection self.draw_regpoly_collection = self._renderer.draw_regpoly_collection self.copy_from_bbox = self._renderer.copy_from_bbox self.restore_region = self._renderer.restore_region self.texmanager = TexManager() self.bbox = lbwh_to_bbox(0,0, self.width, self.height) if __debug__: verbose.report('RendererAgg.__init__ done', 'debug-annoying') def draw_arc(self, gcEdge, rgbFace, x, y, width, height, angle1, angle2): """ Draw an arc centered at x,y with width and height and angles from 0.0 to 360.0 If rgbFace is not None, fill the rectangle with that color. gcEdge is a GraphicsContext instance Currently, I'm only supporting ellipses, ie angle args are ignored """ if __debug__: verbose.report('RendererAgg.draw_arc', 'debug-annoying') self._renderer.draw_ellipse( gcEdge, rgbFace, x, y, width/2, height/2) # ellipse takes radius def _draw_image(self, x, y, im): """ Draw the Image instance into the current axes; x, y is the upper left hand corner of the image """ if __debug__: verbose.report('RendererAgg.draw_image', 'debug-annoying') #self._renderer.draw_image(int(x), int(self.height-y), im) self._renderer.draw_image(int(x), int(y), im) def draw_line(self, gc, x1, y1, x2, y2): """ x and y are equal length arrays, draw lines connecting each point in x, y """ if __debug__: verbose.report('RendererAgg.draw_line', 'debug-annoying') x = array([x1,x2], typecode=Float) y = array([y1,y2], typecode=Float) self._renderer.draw_lines(gc, x, y) def draw_point(self, gc, x, y): """ Draw a single point at x,y """ if __debug__: verbose.report('RendererAgg.draw_point', 'debug-annoying') rgbFace = gc.get_rgb() self._renderer.draw_ellipse( gc, rgbFace, x, y, 0.5, 0.5) def draw_mathtext(self, gc, x, y, s, prop, angle): """ Draw the math text using matplotlib.mathtext """ if __debug__: verbose.report('RendererAgg.draw_mathtext', 'debug-annoying') size = prop.get_size_in_points() width, height, fonts = math_parse_s_ft2font( s, self.dpi.get(), size, angle) if angle == 90: width, height = height, width for font in fonts: if angle == 90: font.horiz_image_to_vert_image() # <-- Rotate self._renderer.draw_text( font, int(x)-width, int(y)-height, gc) else: self._renderer.draw_text( font, int(x), int(y)-height, gc) if 0: self._renderer.draw_rectangle(gc, None, int(x), self.height-int(y), width, height) def draw_text(self, gc, x, y, s, prop, angle, ismath): """ Render the text """ if __debug__: verbose.report('RendererAgg.draw_text', 'debug-annoying') if ismath: return self.draw_mathtext(gc, x, y, s, prop, angle) font = self._get_agg_font(prop) if font is None: return None if len(s)==1 and ord(s)>127: font.load_char(ord(s)) else: font.set_text(s, angle) font.draw_glyphs_to_bitmap() #print x, y, int(x), int(y) self._renderer.draw_text(font, int(x), int(y), gc) def get_text_width_height(self, s, prop, ismath, rgb=(0,0,0)): """ get the width and height in display coords of the string s with FontPropertry prop # passing rgb is a little hack to make cacheing in the # texmanager more efficient. It is not meant to be used # outside the backend """ if ismath=='TeX': # todo: handle props size = prop.get_size_in_points() Z = self.texmanager.get_rgba(s, size, rgb) m,n,tmp = Z.shape return n,m if ismath: width, height, fonts = math_parse_s_ft2font( s, self.dpi.get(), prop.get_size_in_points()) return width, height font = self._get_agg_font(prop) font.set_text(s, 0.0) # the width and height of unrotated string w, h = font.get_width_height() w /= 64.0 # convert from subpixels h /= 64.0 return w, h def draw_tex(self, gc, x, y, s, prop, angle): # todo, handle props, angle, origins rgb = gc.get_rgb() size = prop.get_size_in_points() flip = angle==90 w,h = self.get_text_width_height(s, prop, 'TeX', rgb) if flip: w,h = h,w x -= w key = s, size, rgb, angle, self.texmanager.get_font_config() im = self.texd.get(key) if im is None: Z = self.texmanager.get_rgba(s, size, rgb) if flip: r = Z[:,:,0] g = Z[:,:,1] b = Z[:,:,2] a = Z[:,:,3] m,n,tmp = Z.shape def func(x): return transpose(fliplr(x)) Z = zeros((n,m,4), typecode=Float) Z[:,:,0] = func(r) Z[:,:,1] = func(g) Z[:,:,2] = func(b) Z[:,:,3] = func(a) im = fromarray(Z, 1) im.flipud_out() self.texd[key] = im cliprect = gc.get_clip_rectangle() if cliprect is None: bbox = None else: bbox = lbwh_to_bbox(*cliprect) self.draw_image(x, self.height-y, im, bbox) def get_canvas_width_height(self): 'return the canvas width and height in display coords' return self.width, self.height def _get_agg_font(self, prop): """ Get the font for text instance t, cacheing for efficiency """ if __debug__: verbose.report('RendererAgg._get_agg_font', 'debug-annoying') key = hash(prop) font = _fontd.get(key) if font is None: fname = fontManager.findfont(prop) font = FT2Font(str(fname)) _fontd[key] = font font.clear() size = prop.get_size_in_points() font.set_size(size, self.dpi.get()) return font def points_to_pixels(self, points): """ convert point measures to pixes using dpi and the pixels per inch of the display """ if __debug__: verbose.report('RendererAgg.points_to_pixels', 'debug-annoying') return points*self.dpi.get()/72.0 def tostring_rgb(self): if __debug__: verbose.report('RendererAgg.tostring_rgb', 'debug-annoying') return self._renderer.tostring_rgb() def tostring_argb(self): if __debug__: verbose.report('RendererAgg.tostring_argb', 'debug-annoying') return self._renderer.tostring_argb() def buffer_rgba(self,x,y): if __debug__: verbose.report('RendererAgg.buffer_rgba', 'debug-annoying') return self._renderer.buffer_rgba(x,y) def clear(self): self._renderer.clear()