From: <md...@us...> - 2007-12-10 16:21:40
|
Revision: 4689 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4689&view=rev Author: mdboom Date: 2007-12-10 08:21:36 -0800 (Mon, 10 Dec 2007) Log Message: ----------- Merged revisions 4683-4688 via svnmerge from http://matplotlib.svn.sf.net/svnroot/matplotlib/trunk/matplotlib ........ r4684 | mdboom | 2007-12-10 10:23:08 -0500 (Mon, 10 Dec 2007) | 2 lines Fix variable name. ........ r4685 | mdboom | 2007-12-10 10:34:29 -0500 (Mon, 10 Dec 2007) | 2 lines Fix syntax for pre-Python 2.5 ........ r4686 | mdboom | 2007-12-10 11:15:30 -0500 (Mon, 10 Dec 2007) | 4 lines Support draw_path (importantly for ellipses) in Pdf, Svg and Cairo backends. Fix SVG text rendering bug. ........ Modified Paths: -------------- branches/transforms/CHANGELOG branches/transforms/lib/matplotlib/backends/backend_cairo.py branches/transforms/lib/matplotlib/backends/backend_pdf.py branches/transforms/lib/matplotlib/backends/backend_svg.py branches/transforms/lib/matplotlib/font_manager.py branches/transforms/lib/matplotlib/patches.py Property Changed: ---------------- branches/transforms/ Property changes on: branches/transforms ___________________________________________________________________ Name: svnmerge-integrated - /trunk/matplotlib:1-4682 + /trunk/matplotlib:1-4688 Modified: branches/transforms/CHANGELOG =================================================================== --- branches/transforms/CHANGELOG 2007-12-10 16:17:42 UTC (rev 4688) +++ branches/transforms/CHANGELOG 2007-12-10 16:21:36 UTC (rev 4689) @@ -1,3 +1,9 @@ +2007-12-10 Fix SVG text rendering bug. + +2007-12-10 Increase accuracy of circle and ellipse drawing by using an 8-piece + bezier approximation, rather than a 4-piece one. Fix PDF, SVG and + Cairo backends so they can draw paths (meaning ellipses as well). + 2007-12-07 Issue a warning when drawing an image on a non-linear axis. - MGD 2007-12-06 let widgets.Cursor initialize to the lower x and y bounds Modified: branches/transforms/lib/matplotlib/backends/backend_cairo.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_cairo.py 2007-12-10 16:17:42 UTC (rev 4688) +++ branches/transforms/lib/matplotlib/backends/backend_cairo.py 2007-12-10 16:21:36 UTC (rev 4689) @@ -34,6 +34,7 @@ backend_version = cairo.version del _version_required +from matplotlib import agg from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\ FigureManagerBase, FigureCanvasBase from matplotlib.cbook import enumerate, izip, is_string_like @@ -117,6 +118,7 @@ ctx.stroke() +<<<<<<< .working #@staticmethod def convert_path(ctx, tpath): for points, code in tpath.iter_segments(): @@ -133,12 +135,48 @@ elif code == Path.CLOSEPOLY: ctx.close_path() convert_path = staticmethod(convert_path) +======= + def draw_path(self, gc, rgbFace, path): + ctx = gc.ctx + ctx.new_path() +>>>>>>> .merge-right.r4686 +<<<<<<< .working def draw_path(self, gc, path, transform, rgbFace=None): if len(path.vertices) > 18980: raise ValueError("The Cairo backend can not draw paths longer than 18980 points.") +======= + while 1: + code, xp, yp = path.vertex() + yp = self.height - yp + + if code == agg.path_cmd_stop: + ctx.close_path() + break + elif code == agg.path_cmd_move_to: + ctx.move_to(xp, yp) + elif code == agg.path_cmd_line_to: + ctx.line_to(xp, yp) + elif code == agg.path_cmd_curve3: + _, xp1, yp1 = path.vertex() + yp1 = self.height - yp1 + ctx.curve_to(xp, yp, xp, yp, xp1, yp1) + elif code == agg.path_cmd_curve4: + _, xp1, yp1 = path.vertex() + yp1 = self.height - yp1 + _, xp2, yp2 = path.vertex() + yp2 = self.height - yp2 + ctx.curve_to(xp, yp, xp1, yp1, xp2, yp2) + elif code == agg.path_cmd_end_poly: + ctx.close_path() + self._fill_and_stroke(ctx, rgbFace) + + def draw_arc(self, gc, rgbFace, x, y, width, height, angle1, angle2, + rotation): + if _debug: print '%s.%s()' % (self.__class__.__name__, _fn_name()) +>>>>>>> .merge-right.r4686 ctx = gc.ctx transform = transform + \ Affine2D().scale(1.0, -1.0).translate(0, self.height) Modified: branches/transforms/lib/matplotlib/backends/backend_pdf.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_pdf.py 2007-12-10 16:17:42 UTC (rev 4688) +++ branches/transforms/lib/matplotlib/backends/backend_pdf.py 2007-12-10 16:21:36 UTC (rev 4689) @@ -1211,7 +1211,97 @@ stat_key, (realpath, Set())) used_characters[1].update(set) +<<<<<<< .working def draw_image(self, x, y, im, bbox, clippath=None, clippath_trans=None): +======= + def draw_arc(self, gcEdge, rgbFace, x, y, width, height, + angle1, angle2, rotation): + """ + Draw an arc using GraphicsContext instance gcEdge, centered at x,y, + with width and height and angles from 0.0 to 360.0 + 0 degrees is at 3-o'clock, rotated by `rotation` degrees + positive angles are anti-clockwise + + If the color rgbFace is not None, fill the arc with it. + """ + # source: agg_bezier_arc.cpp in agg23 + + def arc_to_bezier(cx, cy, rx, ry, angle1, sweep, rotation): + halfsweep = sweep / 2.0 + x0, y0 = cos(halfsweep), sin(halfsweep) + tx = (1.0 - x0) * 4.0/3.0; + ty = y0 - tx * x0 / y0; + px = x0, x0+tx, x0+tx, x0 + py = -y0, -ty, ty, y0 + sn, cs = sin(angle1 + halfsweep), cos(angle1 + halfsweep) + result = [ (rx * (pxi * cs - pyi * sn), + ry * (pxi * sn + pyi * cs)) + for pxi, pyi in zip(px, py) ] + result = [ (cx + cos(rotation)*x - sin(rotation)*y, + cy + sin(rotation)*x + cos(rotation)*y) + for x, y in result ] + return reduce(lambda x, y: x + y, result) + + epsilon = 0.01 + angle1 *= pi/180.0 + angle2 *= pi/180.0 + rotation *= pi/180.0 + sweep = angle2 - angle1 + angle1 = angle1 % (2*pi) + sweep = min(max(-2*pi, sweep), 2*pi) + + if sweep < 0.0: + sweep, angle1, angle2 = -sweep, angle2, angle1 + bp = [ pi/2.0 * i + for i in range(4) + if pi/2.0 * i < sweep-epsilon ] + bp.append(sweep) + subarcs = [ arc_to_bezier(x, y, width/2.0, height/2.0, + bp[i], bp[i+1]-bp[i], rotation) + for i in range(len(bp)-1) ] + + self.check_gc(gcEdge, rgbFace) + self.file.output(subarcs[0][0], subarcs[0][1], Op.moveto) + for arc in subarcs: + self.file.output(*(arc[2:] + (Op.curveto,))) + + self.file.output(self.gc.close_and_paint()) + + def draw_path(self, gc, rgbFace, path): + self.check_gc(gc, rgbFace) + + cmds = [] + + while 1: + code, xp, yp = path.vertex() + + if code == agg.path_cmd_stop: + cmds.append(Op.closepath) + break + elif code == agg.path_cmd_move_to: + cmds.extend([xp, yp, Op.moveto]) + elif code == agg.path_cmd_line_to: + cmds.extend([xp, yp, Op.lineto]) + elif code == agg.path_cmd_curve3: + cmds.extend([xp, yp]) + cmds.extend([xp, yp]) + cmds.extend(path.vertex()[1:]) + cmds.append(Op.curveto) + elif code == agg.path_cmd_curve4: + cmds.extend([xp, yp]) + cmds.extend(path.vertex()[1:]) + cmds.extend(path.vertex()[1:]) + cmds.append(Op.curveto) + elif code == agg.path_cmd_end_poly: + cmds.append(Op.closepath) + self.file.output(*cmds) + self.file.output(self.gc.paint()) + + def get_image_magnification(self): + return self.image_magnification + + def draw_image(self, x, y, im, bbox): +>>>>>>> .merge-right.r4686 #print >>sys.stderr, "draw_image called" # MGDTODO: Support clippath here Modified: branches/transforms/lib/matplotlib/backends/backend_svg.py =================================================================== --- branches/transforms/lib/matplotlib/backends/backend_svg.py 2007-12-10 16:17:42 UTC (rev 4688) +++ branches/transforms/lib/matplotlib/backends/backend_svg.py 2007-12-10 16:21:36 UTC (rev 4689) @@ -2,6 +2,7 @@ import os, codecs, base64, tempfile, urllib, gzip +from matplotlib import agg from matplotlib import verbose, __version__, rcParams from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\ FigureManagerBase, FigureCanvasBase @@ -139,6 +140,49 @@ def close_group(self, s): self._svgwriter.write('</g>\n') +<<<<<<< .working +======= + def draw_path(self, gc, rgbFace, path): + cmd = [] + + while 1: + code, xp, yp = path.vertex() + yp = self.height - yp + + if code == agg.path_cmd_stop: + cmd.append('z') # Hack, path_cmd_end_poly not found + break + elif code == agg.path_cmd_move_to: + cmd.append('M%g %g' % (xp, yp)) + elif code == agg.path_cmd_line_to: + cmd.append('L%g %g' % (xp, yp)) + elif code == agg.path_cmd_curve3: + verts = [xp, yp] + verts.extent(path.vertex()[1:]) + verts[-1] = self.height - verts[-1] + cmd.append('Q%g %g %g %g' % tuple(verts)) + elif code == agg.path_cmd_curve4: + verts = [xp, yp] + verts.extend(path.vertex()[1:]) + verts[-1] = self.height - verts[-1] + verts.extend(path.vertex()[1:]) + verts[-1] = self.height - verts[-1] + cmd.append('C%g %g %g %g %g %g'%tuple(verts)) + elif code == agg.path_cmd_end_poly: + cmd.append('z') + + path_data = "".join(cmd) + self._draw_svg_element("path", 'd="%s"' % path_data, gc, rgbFace) + + def draw_arc(self, gc, rgbFace, x, y, width, height, angle1, angle2, rotation): + """ + Ignores angles for now + """ + details = 'cx="%s" cy="%s" rx="%s" ry="%s" transform="rotate(%1.1f %s %s)"' % \ + (x, self.height-y, width/2.0, height/2.0, -rotation, x, self.height-y) + self._draw_svg_element('ellipse', details, gc, rgbFace) + +>>>>>>> .merge-right.r4686 def option_image_nocomposite(self): """ if svg.image_noscale is True, compositing multiple images into one is prohibited @@ -327,7 +371,7 @@ svg.append(' x="%s"' % (currx * (self.FONT_SCALE / fontsize))) svg.append('/>\n') - currx += (glyph.linearHoriAdvance / 65536.0) + currx += (glyph.linearHoriAdvance / 65536.0) / (self.FONT_SCALE / fontsize) svg.append('</g>\n') svg = ''.join(svg) else: Modified: branches/transforms/lib/matplotlib/font_manager.py =================================================================== --- branches/transforms/lib/matplotlib/font_manager.py 2007-12-10 16:17:42 UTC (rev 4688) +++ branches/transforms/lib/matplotlib/font_manager.py 2007-12-10 16:21:36 UTC (rev 4689) @@ -109,9 +109,10 @@ else: user = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, MSFolders) try: - return _winreg.QueryValueEx(user, 'Fonts')[0] - except OSError: - pass # Fall through to default + try: + return _winreg.QueryValueEx(user, 'Fonts')[0] + except OSError: + pass # Fall through to default finally: _winreg.CloseKey(user) return os.path.join(os.environ['WINDIR'], 'Fonts') Modified: branches/transforms/lib/matplotlib/patches.py =================================================================== --- branches/transforms/lib/matplotlib/patches.py 2007-12-10 16:17:42 UTC (rev 4688) +++ branches/transforms/lib/matplotlib/patches.py 2007-12-10 16:21:36 UTC (rev 4689) @@ -820,49 +820,6 @@ """ A scale-free ellipse """ -<<<<<<< .working -======= - MAGIC = 0.2652031 - SQRT2 = npy.sqrt(0.5) - MAGIC45 = npy.sqrt((MAGIC*MAGIC) / 2.0) - - circle = npy.array( - [[0.0, -1.0], - - [MAGIC, -1.0], - [SQRT2-MAGIC45, -SQRT2-MAGIC45], - [SQRT2, -SQRT2], - - [SQRT2+MAGIC45, -SQRT2+MAGIC45], - [1.0, -MAGIC], - [1.0, 0.0], - - [1.0, MAGIC], - [SQRT2+MAGIC45, SQRT2-MAGIC45], - [SQRT2, SQRT2], - - [SQRT2-MAGIC45, SQRT2+MAGIC45], - [MAGIC, 1.0], - [0.0, 1.0], - - [-MAGIC, 1.0], - [-SQRT2+MAGIC45, SQRT2+MAGIC45], - [-SQRT2, SQRT2], - - [-SQRT2-MAGIC45, SQRT2-MAGIC45], - [-1.0, MAGIC], - [-1.0, 0.0], - - [-1.0, -MAGIC], - [-SQRT2-MAGIC45, -SQRT2+MAGIC45], - [-SQRT2, -SQRT2], - - [-SQRT2+MAGIC45, -SQRT2-MAGIC45], - [-MAGIC, -1.0], - [0.0, -1.0]], - npy.float_) - ->>>>>>> .merge-right.r4679 def __str__(self): return "Ellipse(%d,%d;%dx%d)"%(self.center[0],self.center[1],self.width,self.height) @@ -898,17 +855,10 @@ def get_patch_transform(self): return self._patch_transform -<<<<<<< .working def contains(self,ev): if ev.x is None or ev.y is None: return False,{} x, y = self.get_transform().inverted().transform_point((ev.x, ev.y)) return (x*x + y*y) <= 1.0, {} -======= - xcenter = self.convert_xunits(xcenter) - width = self.convert_xunits(width) - ycenter = self.convert_yunits(ycenter) - height = self.convert_xunits(height) ->>>>>>> .merge-right.r4679 def _get_center(self): return self._center @@ -932,105 +882,6 @@ angle = property(_get_angle, _set_angle) -<<<<<<< .working -======= - rtheta = angle*npy.pi/180. - R = npy.array([ - [npy.cos(rtheta), -npy.sin(rtheta)], - [npy.sin(rtheta), npy.cos(rtheta)], - ]) - - - x, y = npy.dot(R, npy.array([x, y])) - x += xcenter - y += ycenter - - return zip(x, y) - - def draw(self, renderer): - if not self.get_visible(): return - #renderer.open_group('patch') - gc = renderer.new_gc() - gc.set_foreground(self._edgecolor) - gc.set_linewidth(self._linewidth) - gc.set_alpha(self._alpha) - gc.set_antialiased(self._antialiased) - self._set_gc_clip(gc) - - gc.set_capstyle('projecting') - - if not self.fill or self._facecolor is None: rgbFace = None - else: rgbFace = colors.colorConverter.to_rgb(self._facecolor) - - if self._hatch: - gc.set_hatch(self._hatch ) - - - if not hasattr(renderer, 'draw_path'): - mpl.verbose.report('patches.Ellipse renderer does not support path drawing; falling back on vertex approximation for nonlinear transformation') - renderer.draw_polygon(gc, rgbFace, self.get_verts()) - return - - - x, y = self.center - x = self.convert_xunits(x) - y = self.convert_yunits(y) - w = self.convert_xunits(self.width)/2. - h = self.convert_yunits(self.height)/2. - - theta = self.angle * npy.pi/180. - T = npy.array([ - [1, 0, x], - [0, 1, y], - [0, 0, 1]]) - - - - - S = npy.array([ - [w, 0, 0], - [0, h, 0], - [0, 0, 1]]) - - - - # rotate by theta - R = npy.array([ - [npy.cos(theta), -npy.sin(theta), 0], - [npy.sin(theta), npy.cos(theta), 0], - [0, 0, 1]]) - - # transform unit circle into ellipse - E = npy.dot(T, npy.dot(R, S)) - - - # Apply the display affine - sx, b, c, sy, tx, ty = self.get_transform().as_vec6_val() - - # display coords - D = npy.array([ - [sx, b, tx], - [c, sy, ty], - [0, 0, 1]], npy.float_) - - M = npy.dot(D,E) - - C = npy.ones((3, len(self.circle))) - C[0:2,:] = self.circle.T - - ellipse = npy.dot(M, C).T[:,:2] - - path = agg.path_storage() - path.move_to(*ellipse[0]) - for i in range(1, 25, 3): - path.curve4(*ellipse[i:i+3].flat) - path.close_polygon() - - renderer.draw_path(gc, rgbFace, path) - - ->>>>>>> .merge-right.r4679 - class Circle(Ellipse): """ A circle patch This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |