From: <md...@us...> - 2007-08-10 18:50:34
|
Revision: 3699 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3699&view=rev Author: mdboom Date: 2007-08-10 11:49:41 -0700 (Fri, 10 Aug 2007) Log Message: ----------- Don't pass "angle" into mathtext parser since it was always ignored anyway. (Any rotation should be performed on the mathtext after it's done.) Support scalable fonts for mathtext in Cairo backend. Simplify passing of mathtext layout back to Pdf backend. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py trunk/matplotlib/lib/matplotlib/backends/backend_ps.py trunk/matplotlib/lib/matplotlib/mathtext.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-08-10 18:45:44 UTC (rev 3698) +++ trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-08-10 18:49:41 UTC (rev 3699) @@ -174,7 +174,7 @@ if __debug__: verbose.report('RendererAgg.draw_mathtext', 'debug-annoying') width, height, fonts, used_characters = math_parse_s_ft2font( - s, self.dpi.get(), prop, angle) + s, self.dpi.get(), prop) if angle == 90: width, height = height, width @@ -190,8 +190,6 @@ self.height-int(y), width, height) - - def draw_text(self, gc, x, y, s, prop, angle, ismath): """ Render the text Modified: trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py 2007-08-10 18:45:44 UTC (rev 3698) +++ trunk/matplotlib/lib/matplotlib/backends/backend_cairo.py 2007-08-10 18:49:41 UTC (rev 3699) @@ -36,10 +36,11 @@ from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\ FigureManagerBase, FigureCanvasBase -from matplotlib.cbook import enumerate, izip -from matplotlib.figure import Figure -from matplotlib.mathtext import math_parse_s_ft2font -from matplotlib.transforms import Bbox +from matplotlib.cbook import enumerate, izip +from matplotlib.figure import Figure +from matplotlib.mathtext import math_parse_s_cairo +from matplotlib.transforms import Bbox +from matplotlib.font_manager import ttfFontProperty from matplotlib import rcParams _debug = False @@ -296,66 +297,47 @@ if angle: ctx.rotate (-angle * npy.pi / 180) ctx.set_font_size (size) - ctx.show_text (s) + ctx.show_text (s.encode("utf-8")) ctx.restore() - def _draw_mathtext(self, gc, x, y, s, prop, angle): if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) # mathtext using the gtk/gdk method - #if npy.which[0] == "numarray": - # warnings.warn("_draw_mathtext() currently works for numpy, but " - # "not numarray") - # return - - #if not HAVE_CAIRO_NUMPY: - # warnings.warn("cairo with Numeric support is required for " - # "_draw_mathtext()") - # return - - width, height, fonts, used_characters = math_parse_s_ft2font( + ctx = gc.ctx + width, height, glyphs, rects = math_parse_s_cairo( s, self.dpi.get(), prop) - if angle==90: - width, height = height, width - x -= width - y -= height + ctx.save() + ctx.translate(x, y) + if angle: + ctx.rotate (-angle * npy.pi / 180) + + for font, fontsize, s, ox, oy in glyphs: + ctx.new_path() + ctx.move_to(ox, oy) + + fontProp = ttfFontProperty(font) + ctx.save() + ctx.select_font_face (fontProp.name, + self.fontangles [fontProp.style], + self.fontweights[fontProp.weight]) - imw, imh, s = fonts[0].image_as_str() - N = imw*imh + # size = prop.get_size_in_points() * self.dpi.get() / 96.0 + size = fontsize * self.dpi.get() / 72.0 + ctx.set_font_size(size) + ctx.show_text(s.encode("utf-8")) + ctx.restore() - # a numpixels by num fonts array - Xall = npy.zeros((N,len(fonts)), npy.uint8) + for ox, oy, w, h in rects: + ctx.new_path() + ctx.rectangle (ox, oy, w, h) + ctx.set_source_rgb (0, 0, 0) + ctx.fill_preserve() - for i, font in enumerate(fonts): - if angle == 90: - font.horiz_image_to_vert_image() # <-- Rotate - imw, imh, s = font.image_as_str() - Xall[:,i] = npy.fromstring(s, npy.uint8) + ctx.restore() - # get the max alpha at each pixel - Xs = npy.max (Xall,1) - - # convert it to it's proper shape - Xs.shape = imh, imw - - pa = npy.zeros((imh,imw,4), npy.uint8) - rgb = gc.get_rgb() - pa[:,:,0] = int(rgb[0]*255) - pa[:,:,1] = int(rgb[1]*255) - pa[:,:,2] = int(rgb[2]*255) - pa[:,:,3] = Xs - - ## works for numpy pa, not a numarray pa - #surface = cairo.ImageSurface.create_for_array (pa) - surface = cairo.ImageSurface.create_for_data (pa, cairo.FORMAT_ARGB32, - imw, imh, imw*4) - gc.ctx.set_source_surface (surface, x, y) - gc.ctx.paint() - #gc.ctx.show_surface (surface, imw, imh) - - + def flipy(self): if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) return True @@ -371,7 +353,7 @@ def get_text_width_height(self, s, prop, ismath): if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) if ismath: - width, height, fonts, used_characters = math_parse_s_ft2font( + width, height, fonts, used_characters = math_parse_s_cairo( s, self.dpi.get(), prop) return width, height Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-08-10 18:45:44 UTC (rev 3698) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-08-10 18:49:41 UTC (rev 3699) @@ -1173,8 +1173,8 @@ def draw_mathtext(self, gc, x, y, s, prop, angle): # TODO: fix positioning and encoding - width, height, pswriter, used_characters = \ - math_parse_s_pdf(s, 72, prop, 0) + width, height, glyphs, rects, used_characters = \ + math_parse_s_pdf(s, 72, prop) self.merge_used_characters(used_characters) # When using Type 3 fonts, we can't use character codes higher @@ -1192,42 +1192,35 @@ self.file.output(Op.begin_text) prev_font = None, None oldx, oldy = 0, 0 - for record in pswriter: - if record[0] == 'glyph': - rec_type, ox, oy, fontname, fontsize, num, symbol_name = \ - record - if fonttype == 42 or num <= 255: - self._setup_textpos(ox, oy, 0, oldx, oldy) - oldx, oldy = ox, oy - if (fontname, fontsize) != prev_font: - self.file.output(self.file.fontName(fontname), fontsize, - Op.selectfont) - prev_font = fontname, fontsize - self.file.output(self.encode_string(unichr(num)), Op.show) + for ox, oy, fontname, fontsize, num, symbol_name in glyphs: + if fonttype == 42 or num <= 255: + self._setup_textpos(ox, oy, 0, oldx, oldy) + oldx, oldy = ox, oy + if (fontname, fontsize) != prev_font: + self.file.output(self.file.fontName(fontname), fontsize, + Op.selectfont) + prev_font = fontname, fontsize + self.file.output(self.encode_string(unichr(num)), Op.show) self.file.output(Op.end_text) # If using Type 3 fonts, render all of the two-byte characters # as XObjects using the 'Do' command. if fonttype == 3: - for record in pswriter: - if record[0] == 'glyph': - rec_type, ox, oy, fontname, fontsize, num, symbol_name = \ - record - if num > 255: - self.file.output(Op.gsave, - 0.001 * fontsize, 0, - 0, 0.001 * fontsize, - ox, oy, Op.concat_matrix) - name = self.file._get_xobject_symbol_name( - fontname, symbol_name) - self.file.output(Name(name), Op.use_xobject) - self.file.output(Op.grestore) + for ox, oy, fontname, fontsize, num, symbol_name in glyphs: + if num > 255: + self.file.output(Op.gsave, + 0.001 * fontsize, 0, + 0, 0.001 * fontsize, + ox, oy, Op.concat_matrix) + name = self.file._get_xobject_symbol_name( + fontname, symbol_name) + self.file.output(Name(name), Op.use_xobject) + self.file.output(Op.grestore) # Draw any horizontal lines in the math layout - for record in pswriter: - if record[0] == 'rect': - rec_type, ox, oy, width, height = record - self.file.output(Op.gsave, ox, oy, width, height, Op.rectangle, Op.fill, Op.grestore) + for ox, oy, width, height in rects: + self.file.output(Op.gsave, ox, oy, width, height, + Op.rectangle, Op.fill, Op.grestore) # Pop off the global transformation self.file.output(Op.grestore) @@ -1427,7 +1420,8 @@ # s = s.encode('cp1252', 'replace') if ismath: - w, h, pswriter, used_characters = math_parse_s_pdf(s, 72, prop, 0) + w, h, glyphs, rects, used_characters = \ + math_parse_s_pdf(s, 72, prop) elif rcParams['pdf.use14corefonts']: font = self._get_font_afm(prop) Modified: trunk/matplotlib/lib/matplotlib/backends/backend_ps.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007-08-10 18:45:44 UTC (rev 3698) +++ trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007-08-10 18:49:41 UTC (rev 3699) @@ -278,7 +278,7 @@ if ismath: width, height, pswriter, used_characters = math_parse_s_ps( - s, 72, prop, 0) + s, 72, prop) return width, height if rcParams['ps.useafm']: @@ -814,7 +814,7 @@ self._pswriter.write("% mathtext\n") width, height, pswriter, used_characters = \ - math_parse_s_ps(s, 72, prop, angle) + math_parse_s_ps(s, 72, prop) self.merge_used_characters(used_characters) self.set_color(*gc.get_rgb()) thetext = pswriter.getvalue() Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-10 18:45:44 UTC (rev 3698) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-10 18:49:41 UTC (rev 3699) @@ -296,22 +296,24 @@ class MathtextBackendPdf(MathtextBackend): def __init__(self): - self.pswriter = [] + self.glyphs = [] + self.rects = [] def render_glyph(self, ox, oy, info): filename = info.font.fname oy = self.height - oy + info.offset - self.pswriter.append( - ('glyph', ox, oy, filename, info.fontsize, + self.glyphs.append( + (ox, oy, filename, info.fontsize, info.num, info.symbol_name)) def render_rect_filled(self, x1, y1, x2, y2): - self.pswriter.append(('rect', x1, self.height - y2, x2 - x1, y2 - y1)) + self.rects.append((x1, self.height - y2, x2 - x1, y2 - y1)) def get_results(self): return (self.width, self.height, - self.pswriter, + self.glyphs, + self.rects, self.fonts_object.get_used_characters()) class MathtextBackendSvg(MathtextBackend): @@ -327,7 +329,7 @@ def render_rect_filled(self, x1, y1, x2, y2): self.svg_rects.append( - (x1, self.height - y1, x2 - x1, y2 - y1)) + (x1, self.height - y2, x2 - x1, y2 - y1)) def get_results(self): svg_elements = Bunch(svg_glyphs = self.svg_glyphs, @@ -336,7 +338,28 @@ self.height, svg_elements, self.fonts_object.get_used_characters()) - + +class MathtextBackendCairo(MathtextBackend): + def __init__(self): + self.glyphs = [] + self.rects = [] + + def render_glyph(self, ox, oy, info): + oy = oy - info.offset - self.height + thetext = unichr(info.num) + self.glyphs.append( + (info.font, info.fontsize, thetext, ox, oy)) + + def render_rect_filled(self, x1, y1, x2, y2): + self.rects.append( + (x1, y1 - self.height, x2 - x1, y2 - y1)) + + def get_results(self): + return (self.width, + self.height, + self.glyphs, + self.rects) + class Fonts(object): """ An abstract base class for fonts that want to render mathtext @@ -2339,21 +2362,22 @@ _parser = None _backend_mapping = { - 'Agg': MathtextBackendAgg, - 'PS' : MathtextBackendPs, - 'PDF': MathtextBackendPdf, - 'SVG': MathtextBackendSvg + 'Agg' : MathtextBackendAgg, + 'PS' : MathtextBackendPs, + 'PDF' : MathtextBackendPdf, + 'SVG' : MathtextBackendSvg, + 'Cairo' : MathtextBackendCairo } def __init__(self, output): self.output = output self.cache = {} - def __call__(self, s, dpi, prop, angle=0): - cacheKey = (s, dpi, hash(prop), angle) + def __call__(self, s, dpi, prop): + cacheKey = (s, dpi, hash(prop)) if self.cache.has_key(cacheKey): - w, h, fontlike, used_characters = self.cache[cacheKey] - return w, h, fontlike, used_characters + result = self.cache[cacheKey] + return result if self.output == 'PS' and rcParams['ps.useafm']: font_output = StandardPsFonts(prop) @@ -2373,14 +2397,17 @@ h += 4 font_output.set_canvas_size(w, h) ship(2, 2, box) - self.cache[cacheKey] = font_output.get_results() + result = font_output.get_results() + self.cache[cacheKey] = result # Free up the transient data structures self._parser.clear() # Remove a cyclical reference font_output.mathtext_backend.fonts_object = None - return self.cache[cacheKey] + + return result math_parse_s_ft2font = math_parse_s_ft2font_common('Agg') math_parse_s_ft2font_svg = math_parse_s_ft2font_common('SVG') math_parse_s_ps = math_parse_s_ft2font_common('PS') math_parse_s_pdf = math_parse_s_ft2font_common('PDF') +math_parse_s_cairo = math_parse_s_ft2font_common('Cairo') This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |