You can subscribe to this list here.
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(115) |
Aug
(120) |
Sep
(137) |
Oct
(170) |
Nov
(461) |
Dec
(263) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2008 |
Jan
(120) |
Feb
(74) |
Mar
(35) |
Apr
(74) |
May
(245) |
Jun
(356) |
Jul
(240) |
Aug
(115) |
Sep
(78) |
Oct
(225) |
Nov
(98) |
Dec
(271) |
2009 |
Jan
(132) |
Feb
(84) |
Mar
(74) |
Apr
(56) |
May
(90) |
Jun
(79) |
Jul
(83) |
Aug
(296) |
Sep
(214) |
Oct
(76) |
Nov
(82) |
Dec
(66) |
2010 |
Jan
(46) |
Feb
(58) |
Mar
(51) |
Apr
(77) |
May
(58) |
Jun
(126) |
Jul
(128) |
Aug
(64) |
Sep
(50) |
Oct
(44) |
Nov
(48) |
Dec
(54) |
2011 |
Jan
(68) |
Feb
(52) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <jd...@us...> - 2007-09-05 15:21:13
|
Revision: 3786 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3786&view=rev Author: jdh2358 Date: 2007-09-05 08:21:08 -0700 (Wed, 05 Sep 2007) Log Message: ----------- fixed a load numpification bug Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/mlab.py trunk/matplotlib/lib/matplotlib/pylab.py Modified: trunk/matplotlib/lib/matplotlib/mlab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mlab.py 2007-09-05 14:46:14 UTC (rev 3785) +++ trunk/matplotlib/lib/matplotlib/mlab.py 2007-09-05 15:21:08 UTC (rev 3786) @@ -1253,7 +1253,7 @@ if r==1 or c==1: X.shape = max(r,c), if unpack: X.transpose() - else: return X + return X def csv2rec(fname, comments='#', skiprows=0, checkrows=5, delimiter=',', converterd=None, names=None, missing=None): Modified: trunk/matplotlib/lib/matplotlib/pylab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/pylab.py 2007-09-05 14:46:14 UTC (rev 3785) +++ trunk/matplotlib/lib/matplotlib/pylab.py 2007-09-05 15:21:08 UTC (rev 3786) @@ -124,6 +124,7 @@ fliplr - flip the rows of a matrix up/down flipud - flip the columns of a matrix left/right linspace - a linear spaced vector of N values from min to max inclusive + logspace - a log spaced vector of N values from min to max inclusive meshgrid - repeat x and y to make regular matrices ones - an array of ones rand - an array from the uniform distribution [0,1] @@ -307,7 +308,7 @@ diagonal_matrix, base_repr, binary_repr, log2, ispower2,\ bivariate_normal, load, save, stineman_interp -from numpy import meshgrid, linspace +from numpy import meshgrid, linspace, logspace """ problem syms This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-05 14:46:19
|
Revision: 3785 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3785&view=rev Author: mdboom Date: 2007-09-05 07:46:14 -0700 (Wed, 05 Sep 2007) Log Message: ----------- Fix segfault in FT2Font::clear() Modified Paths: -------------- trunk/matplotlib/src/ft2font.cpp Modified: trunk/matplotlib/src/ft2font.cpp =================================================================== --- trunk/matplotlib/src/ft2font.cpp 2007-09-05 14:03:09 UTC (rev 3784) +++ trunk/matplotlib/src/ft2font.cpp 2007-09-05 14:46:14 UTC (rev 3785) @@ -75,6 +75,7 @@ if (width != _width || height != _height) { if (numBytes > _width*_height) { delete [] _buffer; + _buffer = NULL; _buffer = new unsigned char [numBytes]; } @@ -781,6 +782,7 @@ args.verify_length(0); delete image; + image = NULL; angle = 0.0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-05 14:03:11
|
Revision: 3784 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3784&view=rev Author: mdboom Date: 2007-09-05 07:03:09 -0700 (Wed, 05 Sep 2007) Log Message: ----------- Fix over-allocation of alpha-channel buffer. (Reduces memory usage with Agg by ~25% Modified Paths: -------------- trunk/matplotlib/src/_backend_agg.cpp Modified: trunk/matplotlib/src/_backend_agg.cpp =================================================================== --- trunk/matplotlib/src/_backend_agg.cpp 2007-09-05 14:02:22 UTC (rev 3783) +++ trunk/matplotlib/src/_backend_agg.cpp 2007-09-05 14:03:09 UTC (rev 3784) @@ -247,7 +247,7 @@ renderingBuffer = new agg::rendering_buffer; renderingBuffer->attach(pixBuffer, width, height, stride); - alphaBuffer = new agg::int8u[NUMBYTES]; + alphaBuffer = new agg::int8u[width*height]; alphaMaskRenderingBuffer = new agg::rendering_buffer; alphaMaskRenderingBuffer->attach(alphaBuffer, width, height, stride); alphaMask = new alpha_mask_type(*alphaMaskRenderingBuffer); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-05 14:02:28
|
Revision: 3783 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3783&view=rev Author: mdboom Date: 2007-09-05 07:02:22 -0700 (Wed, 05 Sep 2007) Log Message: ----------- Add a helpful comment. Modified Paths: -------------- trunk/matplotlib/src/ft2font.cpp Modified: trunk/matplotlib/src/ft2font.cpp =================================================================== --- trunk/matplotlib/src/ft2font.cpp 2007-09-05 13:28:37 UTC (rev 3782) +++ trunk/matplotlib/src/ft2font.cpp 2007-09-05 14:02:22 UTC (rev 3783) @@ -243,7 +243,10 @@ _VERBOSE("FT2Image::as_str"); args.verify_length(0); - return Py::asObject(PyString_FromStringAndSize((const char *)_buffer, _width*_height)); + return Py::asObject + (PyString_FromStringAndSize((const char *)_buffer, + _width*_height) + ); } void FT2Image::makeRgbCopy() { @@ -298,6 +301,8 @@ unsigned char *dst = _rgbaCopy->_buffer; while (src != src_end) { + // We know the array has already been zero'ed out in + // the resize method, so we just skip over the r, g and b. dst += 3; *dst++ = *src++; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ds...@us...> - 2007-09-05 13:28:38
|
Revision: 3782 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3782&view=rev Author: dsdale Date: 2007-09-05 06:28:37 -0700 (Wed, 05 Sep 2007) Log Message: ----------- fixed qt version reporting in setupext.py Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/setupext.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2007-09-05 11:51:57 UTC (rev 3781) +++ trunk/matplotlib/CHANGELOG 2007-09-05 13:28:37 UTC (rev 3782) @@ -1,3 +1,5 @@ +2007-09-05 Fixed Qt version reporting in setupext.py - DSD + 2007-09-04 Embedding Type 1 fonts in PDF, and thus usetex support via dviread, sort of works. To test, enable it by renaming _draw_tex to draw_tex. - JKS Modified: trunk/matplotlib/setupext.py =================================================================== --- trunk/matplotlib/setupext.py 2007-09-05 11:51:57 UTC (rev 3781) +++ trunk/matplotlib/setupext.py 2007-09-05 13:28:37 UTC (rev 3782) @@ -278,6 +278,14 @@ ret = os.popen(s).read().strip() return ret +def convert_qt_version(version): + version = '%x'%version + temp = [] + while len(version) > 0: + version, chunk = version[:-2], version[-2:] + temp.insert(0, str(int(chunk, 16))) + return '.'.join(temp) + def check_for_qt(): try: import pyqtconfig @@ -286,20 +294,20 @@ return False else: print_status("Qt", "Qt: %s, pyqt: %s" % - (pyqtconfig.Configuration().pyqt_version_str, - pyqtconfig.Configuration().qt_version)) + (convert_qt_version(pyqtconfig.Configuration().qt_version), + pyqtconfig.Configuration().pyqt_version_str)) return True def check_for_qt4(): try: - import PyQt4.pyqtconfig + from PyQt4 import pyqtconfig except ImportError: print_status("Qt4", "no") return False else: print_status("Qt4", "Qt: %s, pyqt: %s" % - (PyQt4.pyqtconfig.Configuration().pyqt_version_str, - PyQt4.pyqtconfig.Configuration().qt_version)) + (convert_qt_version(pyqtconfig.Configuration().qt_version), + pyqtconfig.Configuration().pyqt_version_str)) return True def check_for_cairo(): @@ -455,14 +463,14 @@ if not os.environ.has_key('PKG_CONFIG_PATH'): # If Gtk+ is installed, pkg-config is required to be installed os.environ['PKG_CONFIG_PATH'] = 'C:\GTK\lib\pkgconfig' - - pygtkIncludes = getoutput('pkg-config --cflags-only-I pygtk-2.0').split() - gtkIncludes = getoutput('pkg-config --cflags-only-I gtk+-2.0').split() - includes = pygtkIncludes + gtkIncludes - module.include_dirs.extend([include[2:] for include in includes]) - - pygtkLinker = getoutput('pkg-config --libs pygtk-2.0').split() - gtkLinker = getoutput('pkg-config --libs gtk+-2.0').split() + + pygtkIncludes = getoutput('pkg-config --cflags-only-I pygtk-2.0').split() + gtkIncludes = getoutput('pkg-config --cflags-only-I gtk+-2.0').split() + includes = pygtkIncludes + gtkIncludes + module.include_dirs.extend([include[2:] for include in includes]) + + pygtkLinker = getoutput('pkg-config --libs pygtk-2.0').split() + gtkLinker = getoutput('pkg-config --libs gtk+-2.0').split() linkerFlags = pygtkLinker + gtkLinker module.libraries.extend( This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-05 11:51:58
|
Revision: 3781 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3781&view=rev Author: mdboom Date: 2007-09-05 04:51:57 -0700 (Wed, 05 Sep 2007) Log Message: ----------- Fix refactoring bug. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_ps.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007-09-04 20:49:00 UTC (rev 3780) +++ trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007-09-05 11:51:57 UTC (rev 3781) @@ -666,7 +666,7 @@ """ draw a Text instance """ - w, h, bl = self.get_text_width_height_baseline(s, prop, ismath) + w, h, bl = self.get_text_width_height_descent(s, prop, ismath) fontsize = prop.get_size_in_points() corr = 0#w/2*(fontsize-10)/10 pos = _nums_to_str(x-corr, y) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ds...@us...> - 2007-09-04 20:50:54
|
Revision: 3780 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3780&view=rev Author: dsdale Date: 2007-09-04 13:49:00 -0700 (Tue, 04 Sep 2007) Log Message: ----------- added missing import statement to config/rcparams.py Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/config/rcparams.py Modified: trunk/matplotlib/lib/matplotlib/config/rcparams.py =================================================================== --- trunk/matplotlib/lib/matplotlib/config/rcparams.py 2007-09-04 20:27:36 UTC (rev 3779) +++ trunk/matplotlib/lib/matplotlib/config/rcparams.py 2007-09-04 20:49:00 UTC (rev 3780) @@ -1,4 +1,5 @@ import os +import sys import warnings import checkdep @@ -193,4 +194,4 @@ Restore the default rc params - the ones that were created at matplotlib load time """ - rcParams.update(rcParamsDefault) \ No newline at end of file + rcParams.update(rcParamsDefault) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jo...@us...> - 2007-09-04 20:27:39
|
Revision: 3779 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3779&view=rev Author: jouni Date: 2007-09-04 13:27:36 -0700 (Tue, 04 Sep 2007) Log Message: ----------- More work on supporting Type 1 fonts in PDF. Sort of works now. Modified Paths: -------------- trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py trunk/matplotlib/lib/matplotlib/dviread.py Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2007-09-04 19:52:23 UTC (rev 3778) +++ trunk/matplotlib/CHANGELOG 2007-09-04 20:27:36 UTC (rev 3779) @@ -1,3 +1,7 @@ +2007-09-04 Embedding Type 1 fonts in PDF, and thus usetex support + via dviread, sort of works. To test, enable it by + renaming _draw_tex to draw_tex. - JKS + 2007-09-03 Added ability of errorbar show limits via caret or arrowhead ends on the bars; patch by Manual Metz. - EF Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-04 19:52:23 UTC (rev 3778) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-04 20:27:36 UTC (rev 3779) @@ -581,7 +581,7 @@ 'CapHeight': 1000, # default guess if missing from AFM file 'XHeight': afmdata.get_xheight(), 'FontFile': fontfileObject, - 'FontFamily': Name(familyname), + 'FontFamily': familyname, #'FontWeight': a number where 400 = Regular, 700 = Bold } try: @@ -1422,7 +1422,7 @@ self.file.output(Op.grestore) def _draw_tex(self, gc, x, y, s, prop, angle): - # Rename to draw_tex to enable, but it doesn't work at the moment + # Rename to draw_tex to enable texmanager = self.get_texmanager() fontsize = prop.get_size_in_points() @@ -1606,6 +1606,19 @@ return draw_text_woven(chunks) def get_text_width_height_descent(self, s, prop, ismath): + if rcParams['text.usetex']: + texmanager = self.get_texmanager() + fontsize = prop.get_size_in_points() + dvifile = texmanager.make_dvi(s, fontsize) + dvi = dviread.Dvi(dvifile, 72) + text, boxes = iter(dvi).next() + # TODO: better bounding box -- this is not quite right: + l = min(p[0] for p in text+boxes) + r = max(p[0] for p in text+boxes) + fontsize + b = min(p[1] for p in text+boxes) + t = max(p[1] for p in text+boxes) + fontsize + # (not to even mention finding the baseline) + return r-l, t-b, t-b if ismath: w, h, d, glyphs, rects, used_characters = \ self.mathtext_parser.parse(s, 72, prop) Modified: trunk/matplotlib/lib/matplotlib/dviread.py =================================================================== --- trunk/matplotlib/lib/matplotlib/dviread.py 2007-09-04 19:52:23 UTC (rev 3778) +++ trunk/matplotlib/lib/matplotlib/dviread.py 2007-09-04 20:27:36 UTC (rev 3779) @@ -15,6 +15,8 @@ ... """ +# TODO: support for TeX virtual fonts (*.vf) which are a dvi-like format + import matplotlib import matplotlib.cbook as mpl_cbook import os This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-04 19:52:26
|
Revision: 3778 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3778&view=rev Author: mdboom Date: 2007-09-04 12:52:23 -0700 (Tue, 04 Sep 2007) Log Message: ----------- Simplify and fix a memory leak. Modified Paths: -------------- trunk/matplotlib/src/ft2font.cpp trunk/matplotlib/src/ft2font.h Modified: trunk/matplotlib/src/ft2font.cpp =================================================================== --- trunk/matplotlib/src/ft2font.cpp 2007-09-04 19:29:45 UTC (rev 3777) +++ trunk/matplotlib/src/ft2font.cpp 2007-09-04 19:52:23 UTC (rev 3778) @@ -42,14 +42,14 @@ FT_Library _ft2Library; -FT2Image::FT2Image() : - _isDirty(true), - _buffer(NULL), - _width(0), _height(0), - _rgbCopy(NULL), - _rgbaCopy(NULL) { - _VERBOSE("FT2Image::FT2Image"); -} +// FT2Image::FT2Image() : +// _isDirty(true), +// _buffer(NULL), +// _width(0), _height(0), +// _rgbCopy(NULL), +// _rgbaCopy(NULL) { +// _VERBOSE("FT2Image::FT2Image"); +// } FT2Image::FT2Image(unsigned long width, unsigned long height) : _isDirty(true), @@ -65,75 +65,28 @@ _VERBOSE("FT2Image::~FT2Image"); delete [] _buffer; _buffer=NULL; + delete _rgbCopy; + delete _rgbaCopy; } void FT2Image::resize(unsigned long width, unsigned long height) { size_t numBytes = width*height; - if (_width != width || _height != height) { + if (width != _width || height != _height) { + if (numBytes > _width*_height) { + delete [] _buffer; + _buffer = new unsigned char [numBytes]; + } + _width = width; _height = height; - - delete [] _buffer; - _buffer = new unsigned char [numBytes]; } - for (size_t n=0; n<numBytes; n++) - _buffer[n] = 0; + memset(_buffer, 0, numBytes); _isDirty = true; } -char FT2Image::resize__doc__[] = -"resize(width, height)\n" -"\n" -"Resize the dimensions of the image (it is cleared in the process).\n" -; -Py::Object -FT2Image::py_resize(const Py::Tuple & args) { - _VERBOSE("FT2Image::resize"); - - args.verify_length(2); - - long x0 = Py::Int(args[0]); - long y0 = Py::Int(args[1]); - - resize(x0, y0); - - return Py::Object(); -} - -void FT2Image::clear() { - _VERBOSE("FT2Image::clear"); - - _width = 0; - _height = 0; - _isDirty = true; - delete [] _buffer; - _buffer = NULL; - if (_rgbCopy) { - delete _rgbCopy; - _rgbCopy = NULL; - } - if (_rgbaCopy) { - delete _rgbaCopy; - _rgbaCopy = NULL; - } -} -char FT2Image::clear__doc__[] = -"clear()\n" -"\n" -"Clear the contents of the image.\n" -; -Py::Object -FT2Image::py_clear(const Py::Tuple & args) { - args.verify_length(0); - - clear(); - - return Py::Object(); -} - void FT2Image::draw_bitmap( FT_Bitmap* bitmap, FT_Int x, @@ -345,9 +298,7 @@ unsigned char *dst = _rgbaCopy->_buffer; while (src != src_end) { - *dst++ = 0; - *dst++ = 0; - *dst++ = 0; + dst += 3; *dst++ = *src++; } } @@ -824,8 +775,7 @@ _VERBOSE("FT2Font::clear"); args.verify_length(0); - if (image) - image->clear(); + delete image; angle = 0.0; @@ -1194,11 +1144,9 @@ size_t width = (string_bbox.xMax-string_bbox.xMin) / 64 + 2; size_t height = (string_bbox.yMax-string_bbox.yMin) / 64 + 2; - if (!image) { - image = new FT2Image(width, height); - } else { - image->resize(width, height); - } + Py_XDECREF(image); + image = NULL; + image = new FT2Image(width, height); for ( size_t n = 0; n < glyphs.size(); n++ ) { @@ -1764,10 +1712,6 @@ behaviors().name("FT2Image"); behaviors().doc("FT2Image"); - add_varargs_method("clear", &FT2Image::py_clear, - FT2Image::clear__doc__); - add_varargs_method("resize", &FT2Image::py_resize, - FT2Image::resize__doc__); add_varargs_method("write_bitmap", &FT2Image::py_write_bitmap, FT2Image::write_bitmap__doc__); add_varargs_method("draw_rect", &FT2Image::py_draw_rect, Modified: trunk/matplotlib/src/ft2font.h =================================================================== --- trunk/matplotlib/src/ft2font.h 2007-09-04 19:29:45 UTC (rev 3777) +++ trunk/matplotlib/src/ft2font.h 2007-09-04 19:52:23 UTC (rev 3778) @@ -22,14 +22,12 @@ // the freetype string rendered into a width, height buffer class FT2Image : public Py::PythonExtension<FT2Image> { public: - FT2Image(); + // FT2Image(); FT2Image(unsigned long width, unsigned long height); ~FT2Image(); static void init_type(); - void resize(unsigned long width, unsigned long height); - void clear(); void draw_bitmap(FT_Bitmap* bitmap, FT_Int x, FT_Int y); void write_bitmap(const char* filename) const; void draw_rect(unsigned long x0, unsigned long y0, @@ -41,10 +39,6 @@ unsigned int get_height() const { return _height; }; const unsigned char *const get_buffer() const { return _buffer; }; - static char clear__doc__ []; - Py::Object py_clear(const Py::Tuple & args); - static char resize__doc__ []; - Py::Object py_resize(const Py::Tuple & args); static char write_bitmap__doc__ []; Py::Object py_write_bitmap(const Py::Tuple & args); static char draw_rect__doc__ []; @@ -71,6 +65,8 @@ void makeRgbCopy(); void makeRgbaCopy(); + + void resize(unsigned long width, unsigned long height); }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-04 19:29:47
|
Revision: 3777 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3777&view=rev Author: mdboom Date: 2007-09-04 12:29:45 -0700 (Tue, 04 Sep 2007) Log Message: ----------- Better error messages. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/mathtext.py Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007-09-04 19:00:18 UTC (rev 3776) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007-09-04 19:29:45 UTC (rev 3777) @@ -138,7 +138,7 @@ Combine, Group, Optional, Forward, NotAny, alphas, nums, alphanums, \ StringStart, StringEnd, ParseFatalException, FollowedBy, Regex, \ operatorPrecedence, opAssoc, ParseResults, Or, Suppress, oneOf, \ - ParseException, MatchFirst, NoMatch + ParseException, MatchFirst, NoMatch, Empty from matplotlib.afm import AFM from matplotlib.cbook import enumerate, iterable, Bunch, get_realpath_and_stat, \ @@ -1787,6 +1787,14 @@ ############################################################################## # PARSER +def Error(msg): + def raise_error(s, loc, toks): + raise ParseFatalException(msg) + + empty = Empty() + empty.setParseAction(raise_error) + return empty + class Parser(object): _binary_operators = Set(r''' + * @@ -1887,9 +1895,10 @@ ).setParseAction(self.space).setName('space') customspace =(Literal(r'\hspace') - + lbrace - + float - + rbrace + + (( lbrace + + float + + rbrace + ) | Error(r"Expected \hspace{n}")) ).setParseAction(self.customspace).setName('customspace') symbol =(Regex(r"([a-zA-Z0-9 +\-*/<>=:,.;!'@()])|(\\[%${}\[\]])") @@ -1926,8 +1935,8 @@ bslash + Literal("frac") ) - + group - + group + + ((group + group) + | Error(r"Expected \frac{num}{den}")) ).setParseAction(self.frac).setName("frac") sqrt = Group( @@ -1946,7 +1955,7 @@ + Suppress(Literal("]")), default = None ) - + group + + (group | Error("Expected \sqrt{value}")) ).setParseAction(self.sqrt).setName("sqrt") placeable <<(accent @@ -1955,7 +1964,7 @@ ^ group ^ frac ^ sqrt - ) + ) | Error("Expected symbol or group") simple <<(space | customspace @@ -1983,12 +1992,12 @@ leftDelim = oneOf(r"( [ { \lfloor \langle \lceil") rightDelim = oneOf(r") ] } \rfloor \rangle \rceil") autoDelim <<(Suppress(Literal(r"\left")) - + (leftDelim | ambiDelim) + + ((leftDelim | ambiDelim) | Error("Expected a delimiter")) + Group( autoDelim ^ OneOrMore(simple)) + Suppress(Literal(r"\right")) - + (rightDelim | ambiDelim) + + ((rightDelim | ambiDelim) | Error("Expected a delimiter")) ) math = OneOrMore( @@ -2007,7 +2016,8 @@ + ZeroOrMore( Suppress(math_delim) + math - + Suppress(math_delim) + + (Suppress(math_delim) + | Error("Expected end of math '$'")) + non_math ) ) + StringEnd() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-09-04 19:00:22
|
Revision: 3776 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3776&view=rev Author: mdboom Date: 2007-09-04 12:00:18 -0700 (Tue, 04 Sep 2007) Log Message: ----------- Add support for arbitrary angles of rotation on mathtext in Agg backend. Uses agg to rotate the raster of the text. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py trunk/matplotlib/lib/matplotlib/backends/backend_ps.py trunk/matplotlib/lib/matplotlib/mathtext.py trunk/matplotlib/src/_backend_agg.cpp trunk/matplotlib/src/ft2font.cpp trunk/matplotlib/src/ft2font.h Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-09-04 18:19:16 UTC (rev 3775) +++ trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-09-04 19:00:18 UTC (rev 3776) @@ -174,17 +174,10 @@ 'debug-annoying') ox, oy, width, height, descent, font_image, used_characters = \ self.mathtext_parser.parse(s, self.dpi.get(), prop) - - if angle == 90: - width, height = height, width - ox, oy = oy, ox - x = int(x) - width + ox - y = int(y) - height + oy - font_image.rotate() - else: - x = int(x) + ox - y = int(y) - height + oy - self._renderer.draw_text_image(font_image, x, y + 1, gc) + + x = int(x) + ox + y = int(y) - oy + self._renderer.draw_text_image(font_image, x, y + 1, angle, gc) if 0: self._renderer.draw_rectangle(gc, None, int(x), @@ -205,12 +198,14 @@ if len(s) == 1 and ord(s) > 127: font.load_char(ord(s), flags=LOAD_DEFAULT) else: - font.set_text(s, angle, flags=LOAD_DEFAULT) + font.set_text(s, 0, flags=LOAD_DEFAULT) font.draw_glyphs_to_bitmap() #print x, y, int(x), int(y) - self._renderer.draw_text_image(font.get_image(), int(x), int(y) + 1, gc) + # We pass '0' for angle here, since is has already been rotated + # (in vector space) in the above call to font.set_text. + self._renderer.draw_text_image(font.get_image(), int(x), int(y) + 1, angle, gc) def get_text_width_height_descent(self, s, prop, ismath, rgb=(0,0,0)): @@ -229,7 +224,7 @@ Z = texmanager.get_rgba(s, size, self.dpi.get(), rgb) m,n,tmp = Z.shape # TODO: descent of TeX text (I am imitating backend_ps here -JKS) - return n, m, m + return n, m, 0 if ismath: ox, oy, width, height, descent, fonts, used_characters = \ Modified: trunk/matplotlib/lib/matplotlib/backends/backend_ps.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007-09-04 18:19:16 UTC (rev 3775) +++ trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2007-09-04 19:00:18 UTC (rev 3776) @@ -275,10 +275,9 @@ l,b,r,t = texmanager.get_ps_bbox(s, fontsize) w = (r-l) h = (t-b) - #print s, w, h # TODO: We need a way to get a good baseline from # text.usetex - return w, h, h + return w, h, 0 if ismath: width, height, descent, pswriter, used_characters = \ Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007-09-04 18:19:16 UTC (rev 3775) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007-09-04 19:00:18 UTC (rev 3776) @@ -541,7 +541,7 @@ self.font = font self.charmap = font.get_charmap() self.glyphmap = dict( - [(glyphind, ccode) for ccode, glyphind in self.charmap.items()]) + [(glyphind, ccode) for ccode, glyphind in self.charmap.iteritems()]) def __repr__(self): return repr(self.font) @@ -671,7 +671,7 @@ def __init__(self, *args, **kwargs): TruetypeFonts.__init__(self, *args, **kwargs) if not len(self.fontmap): - for key, val in self._fontmap.items(): + for key, val in self._fontmap.iteritems(): fullpath = os.path.join(self.basepath, val + ".ttf") self.fontmap[key] = fullpath self.fontmap[val] = fullpath Modified: trunk/matplotlib/src/_backend_agg.cpp =================================================================== --- trunk/matplotlib/src/_backend_agg.cpp 2007-09-04 18:19:16 UTC (rev 3775) +++ trunk/matplotlib/src/_backend_agg.cpp 2007-09-04 19:00:18 UTC (rev 3776) @@ -16,6 +16,9 @@ #include "agg_scanline_storage_aa.h" #include "agg_scanline_storage_bin.h" #include "agg_renderer_primitives.h" +#include "agg_span_image_filter_gray.h" +#include "agg_span_interpolator_linear.h" +#include "agg_span_allocator.h" #include "util/agg_color_conv_rgb8.h" #include "ft2font.h" @@ -2103,13 +2106,74 @@ } +/** + * This is a custom span generator that converts spans in the + * 8-bit inverted greyscale font buffer to rgba that agg can use. + */ +template< + class ColorT, + class ChildGenerator> +class font_to_rgba : + public agg::span_generator<ColorT, + agg::span_allocator<ColorT> > +{ +public: + typedef ChildGenerator child_type; + typedef ColorT color_type; + typedef agg::span_allocator<color_type> allocator_type; + typedef agg::span_generator< + ColorT, + agg::span_allocator<ColorT> > base_type; +private: + child_type* _gen; + allocator_type _alloc; + color_type _color; + +public: + font_to_rgba(child_type* gen, color_type color) : + base_type(_alloc), + _gen(gen), + _color(color) { + } + color_type* generate(int x, int y, unsigned len) + { + color_type* dst = base_type::allocator().span(); + + typename child_type::color_type* src = _gen->generate(x, y, len); + + do { + *dst = _color; + dst->a = src->v; + ++src; + ++dst; + } while (--len); + + return base_type::allocator().span(); + } + + void prepare(unsigned max_span_len) + { + _alloc.allocate(max_span_len); + _gen->prepare(max_span_len); + } + +}; + Py::Object RendererAgg::draw_text_image(const Py::Tuple& args) { _VERBOSE("RendererAgg::draw_text"); + + typedef agg::span_interpolator_linear<> interpolator_type; + typedef agg::span_image_filter_gray<agg::gray8, interpolator_type> + image_span_gen_type; + typedef font_to_rgba<pixfmt::color_type, image_span_gen_type> + span_gen_type; + typedef agg::renderer_scanline_aa<renderer_base, span_gen_type> + renderer_type; - args.verify_length(4); + args.verify_length(5); FT2Image *image = static_cast<FT2Image*>(args[0].ptr()); if (!image->get_buffer()) @@ -2125,70 +2189,48 @@ return Py::Object(); } - GCAgg gc = GCAgg(args[3], dpi); + double angle = Py::Float( args[3] ); + + GCAgg gc = GCAgg(args[4], dpi); - set_clipbox_rasterizer( gc.cliprect); - - - pixfmt::color_type p; - p.r = int(255*gc.color.r); - p.b = int(255*gc.color.b); - p.g = int(255*gc.color.g); - p.a = int(255*gc.color.a); - - //y = y-font->image.height; - unsigned thisx, thisy; - - double l = 0; - double b = 0; - double r = width; - double t = height; - if (gc.cliprect!=NULL) { - l = gc.cliprect[0] ; - b = gc.cliprect[1] ; - double w = gc.cliprect[2]; - double h = gc.cliprect[3]; - r = l+w; - t = b+h; - } - + set_clipbox_rasterizer(gc.cliprect); + const unsigned char* const buffer = image->get_buffer(); + agg::rendering_buffer srcbuf + ((agg::int8u*)buffer, image->get_width(), + image->get_height(), image->get_width()); + agg::pixfmt_gray8 pixf_img(srcbuf); - for (size_t i=0; i< image->get_width(); i++) { - for (size_t j=0; j< image->get_height(); j++) { - thisx = i+x+image->offsetx; - thisy = j+y+image->offsety; - if (thisx<l || thisx>=r) continue; - if (thisy<height-t || thisy>=height-b) continue; - pixFmt->blend_pixel - (thisx, thisy, p, buffer[i + j*image->get_width()]); - } - } + agg::trans_affine mtx; + mtx *= agg::trans_affine_translation(0, -(int)image->get_height()); + mtx *= agg::trans_affine_rotation(-angle * agg::pi / 180.0); + mtx *= agg::trans_affine_translation(x, y); + + agg::path_storage rect; + rect.move_to(0, 0); + rect.line_to(image->get_width(), 0); + rect.line_to(image->get_width(), image->get_height()); + rect.line_to(0, image->get_height()); + rect.line_to(0, 0); + agg::conv_transform<agg::path_storage> rect2(rect, mtx); + + agg::trans_affine inv_mtx(mtx); + inv_mtx.invert(); + + agg::image_filter_lut filter; + filter.calculate(agg::image_filter_spline36()); + interpolator_type interpolator(inv_mtx); + agg::span_allocator<agg::gray8> gray_span_allocator; + image_span_gen_type image_span_generator(gray_span_allocator, + srcbuf, 0, interpolator, filter); + span_gen_type output_span_generator(&image_span_generator, gc.color); + renderer_type ri(*rendererBase, output_span_generator); + agg::rasterizer_scanline_aa<> rasterizer; + agg::scanline_p8 scanline; + rasterizer.add_path(rect2); + agg::render_scanlines(rasterizer, scanline, ri); - /* bbox the text for debug purposes - - agg::path_storage path; - - path.move_to(x, y); - path.line_to(x, y+font->image.height); - path.line_to(x+font->image.width, y+font->image.height); - path.line_to(x+font->image.width, y); - path.close_polygon(); - - agg::rgba edgecolor(1,0,0,1); - - //now fill the edge - agg::conv_stroke<agg::path_storage> stroke(path); - stroke.width(1.0); - rendererAA->color(edgecolor); - //self->theRasterizer->gamma(agg::gamma_power(gamma)); - theRasterizer->add_path(stroke); - agg::render_scanlines(*theRasterizer, *slineP8, *rendererAA); - - */ - return Py::Object(); - } Modified: trunk/matplotlib/src/ft2font.cpp =================================================================== --- trunk/matplotlib/src/ft2font.cpp 2007-09-04 18:19:16 UTC (rev 3775) +++ trunk/matplotlib/src/ft2font.cpp 2007-09-04 19:00:18 UTC (rev 3776) @@ -43,8 +43,6 @@ FT_Library _ft2Library; FT2Image::FT2Image() : - offsetx(0), offsety(0), - _bRotated(false), _isDirty(true), _buffer(NULL), _width(0), _height(0), @@ -54,8 +52,6 @@ } FT2Image::FT2Image(unsigned long width, unsigned long height) : - offsetx(0), offsety(0), - _bRotated(false), _isDirty(true), _buffer(NULL), _width(0), _height(0), @@ -85,7 +81,6 @@ for (size_t n=0; n<numBytes; n++) _buffer[n] = 0; - _bRotated = false; _isDirty = true; } @@ -113,10 +108,7 @@ _width = 0; _height = 0; - offsetx = 0; - offsety = 0; _isDirty = true; - _bRotated = false; delete [] _buffer; _buffer = NULL; if (_rgbCopy) { @@ -142,58 +134,6 @@ return Py::Object(); } -void FT2Image::rotate() { - // If we have already rotated, just return. - if (_bRotated) - return; - - unsigned long width = _width; - unsigned long height = _height; - - unsigned long newWidth = _height; - unsigned long newHeight = _width; - - unsigned long numBytes = _width * _height; - - unsigned char * buffer = new unsigned char [numBytes]; - - unsigned long i, j, k, offset, nhMinusOne; - - nhMinusOne = newHeight - 1; - - unsigned char * read_it = _buffer; - - for (i=0; i<height; i++) { - offset = i*width; - for (j=0; j<width; j++) { - k = nhMinusOne - j; - buffer[i + k*newWidth] = *(read_it++); - } - } - - delete [] _buffer; - _buffer = buffer; - _width = newWidth; - _height = newHeight; - _bRotated = true; - _isDirty = true; -} -char FT2Image::rotate__doc__[] = -"rotate()\n" -"\n" -"Rotates the image 90 degrees.\n" -; -Py::Object -FT2Image::py_rotate(const Py::Tuple & args) { - _VERBOSE("FT2Image::rotate"); - - args.verify_length(0); - - rotate(); - - return Py::Object(); -} - void FT2Image::draw_bitmap( FT_Bitmap* bitmap, FT_Int x, @@ -404,17 +344,11 @@ unsigned char *src_end = src + (_width * _height); unsigned char *dst = _rgbaCopy->_buffer; - // This pre-multiplies the alpha, which apparently shouldn't - // be necessary for wxGTK, but it sure as heck seems to be. - unsigned int c; - unsigned int tmp; while (src != src_end) { - c = *src++; - tmp = ((255 - c) * c) >> 8; - *dst++ = tmp; - *dst++ = tmp; - *dst++ = tmp; - *dst++ = c; + *dst++ = 0; + *dst++ = 0; + *dst++ = 0; + *dst++ = *src++; } } @@ -1266,12 +1200,6 @@ image->resize(width, height); } - image->offsetx = (int)(string_bbox.xMin / 64.0); - if (angle==0) - image->offsety = -image->get_height(); - else - image->offsety = (int)(-string_bbox.yMax/64.0); - for ( size_t n = 0; n < glyphs.size(); n++ ) { FT_BBox bbox; @@ -1840,8 +1768,6 @@ FT2Image::clear__doc__); add_varargs_method("resize", &FT2Image::py_resize, FT2Image::resize__doc__); - add_varargs_method("rotate", &FT2Image::py_rotate, - FT2Image::rotate__doc__); add_varargs_method("write_bitmap", &FT2Image::py_write_bitmap, FT2Image::write_bitmap__doc__); add_varargs_method("draw_rect", &FT2Image::py_draw_rect, Modified: trunk/matplotlib/src/ft2font.h =================================================================== --- trunk/matplotlib/src/ft2font.h 2007-09-04 18:19:16 UTC (rev 3775) +++ trunk/matplotlib/src/ft2font.h 2007-09-04 19:00:18 UTC (rev 3776) @@ -30,7 +30,6 @@ void resize(unsigned long width, unsigned long height); void clear(); - void rotate(); void draw_bitmap(FT_Bitmap* bitmap, FT_Int x, FT_Int y); void write_bitmap(const char* filename) const; void draw_rect(unsigned long x0, unsigned long y0, @@ -46,8 +45,6 @@ Py::Object py_clear(const Py::Tuple & args); static char resize__doc__ []; Py::Object py_resize(const Py::Tuple & args); - static char rotate__doc__ []; - Py::Object py_rotate(const Py::Tuple & args); static char write_bitmap__doc__ []; Py::Object py_write_bitmap(const Py::Tuple & args); static char draw_rect__doc__ []; @@ -64,11 +61,7 @@ Py::Object py_get_width(const Py::Tuple & args); Py::Object py_get_height(const Py::Tuple & args); - unsigned long offsetx; - unsigned long offsety; - private: - bool _bRotated; bool _isDirty; unsigned char *_buffer; unsigned long _width; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jo...@us...> - 2007-09-04 18:19:20
|
Revision: 3775 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3775&view=rev Author: jouni Date: 2007-09-04 11:19:16 -0700 (Tue, 04 Sep 2007) Log Message: ----------- More work on supporting Type 1 fonts in PDF, still doesn't produce usable files. Modified Paths: -------------- trunk/matplotlib/API_CHANGES trunk/matplotlib/lib/matplotlib/afm.py trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py trunk/matplotlib/lib/matplotlib/dviread.py Modified: trunk/matplotlib/API_CHANGES =================================================================== --- trunk/matplotlib/API_CHANGES 2007-09-04 14:52:03 UTC (rev 3774) +++ trunk/matplotlib/API_CHANGES 2007-09-04 18:19:16 UTC (rev 3775) @@ -15,7 +15,8 @@ to read an afm file in addition to a pfa/pfb file, to get metrics and kerning information for a Type 1 font. - The AFM class now supports querying CapHeight and stem widths. + The AFM class now supports querying CapHeight and stem widths. The + get_name_char method now has an isord kwarg like get_width_char. Changed pcolor default to shading='flat'; but as noted now in the docstring, it is preferable to simply use the edgecolor kwarg. Modified: trunk/matplotlib/lib/matplotlib/afm.py =================================================================== --- trunk/matplotlib/lib/matplotlib/afm.py 2007-09-04 14:52:03 UTC (rev 3774) +++ trunk/matplotlib/lib/matplotlib/afm.py 2007-09-04 18:19:16 UTC (rev 3775) @@ -378,11 +378,12 @@ """ return self.get_str_bbox_and_descent(s)[:4] - def get_name_char(self, c): + def get_name_char(self, c, isord=False): """ Get the name of the character, ie, ';' is 'semicolon' """ - wx, name, bbox = self._metrics[ord(c)] + if not isord: c=ord(c) + wx, name, bbox = self._metrics[c] return name def get_width_char(self, c, isord=False): Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-04 14:52:03 UTC (rev 3774) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-04 18:19:16 UTC (rev 3775) @@ -18,6 +18,7 @@ from math import ceil, cos, floor, pi, sin from sets import Set +import matplotlib from matplotlib import __version__, rcParams, agg, get_data_path from matplotlib._pylab_helpers import Gcf from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\ @@ -493,12 +494,16 @@ def embedType1(self, filename, fontinfo): fh = open(filename, 'rb') + matplotlib.verbose.report( + 'Embedding Type 1 font ' + filename, 'debug') try: fontdata = fh.read() finally: fh.close() fh = open(fontinfo.afmfile, 'rb') + matplotlib.verbose.report( + 'Reading metrics from ' + fontinfo.afmfile, 'debug') try: afmdata = AFM(fh) finally: @@ -519,9 +524,26 @@ differencesArray = [ Name(ch) for ch in dviread.Encoding(fontinfo.encodingfile) ] differencesArray = [ 0 ] + differencesArray + firstchar = 0 lastchar = len(differencesArray) - 2 + widths = [ 100 for x in range(firstchar,lastchar+1) ] # XXX TODO else: - lastchar = 255 # ? + widths = [ None for i in range(256) ] + for ch in range(256): + try: + widths[ch] = afmdata.get_width_char(ch, isord=True) + except KeyError: + pass + not_None = (ch for ch in range(256) + if widths[ch] is not None) + firstchar = not_None.next() + lastchar = max(not_None) + widths = widths[firstchar:lastchar+1] + + differencesArray = [ firstchar ] + for ch in range(firstchar, lastchar+1): + differencesArray.append(Name( + afmdata.get_name_char(ch, isord=True))) fontdict = { 'Type': Name('Font'), @@ -533,16 +555,15 @@ 'FontDescriptor': fontdescObject, } - if fontinfo.encodingfile is not None: - fontdict.update({ - 'Encoding': { 'Type': Name('Encoding'), - 'Differences': differencesArray }, - }) + fontdict.update({ + 'Encoding': { 'Type': Name('Encoding'), + 'Differences': differencesArray }, + }) flags = 0 if fixed_pitch: flags |= 1 << 0 # fixed width if 0: flags |= 1 << 1 # TODO: serif - if 0: flags |= 1 << 2 # TODO: symbolic + if 1: flags |= 1 << 2 # TODO: symbolic else: flags |= 1 << 5 # non-symbolic if italic_angle: flags |= 1 << 6 # italic if 0: flags |= 1 << 16 # TODO: all caps @@ -557,12 +578,16 @@ 'ItalicAngle': italic_angle, 'Ascent': font.ascender, 'Descent': font.descender, - 'CapHeight': afmdata.get_capheight(), + 'CapHeight': 1000, # default guess if missing from AFM file 'XHeight': afmdata.get_xheight(), 'FontFile': fontfileObject, 'FontFamily': Name(familyname), #'FontWeight': a number where 400 = Regular, 700 = Bold } + try: + descriptor['CapHeight'] = afmdata.get_capheight() + except KeyError: + pass # StemV is obligatory in PDF font descriptors but optional in # AFM files. The collection of AFM files in my TeX Live 2007 @@ -579,7 +604,7 @@ descriptor['StemH'] = StemH self.writeObject(fontdictObject, fontdict) - self.writeObject(widthsObject, [ 100 for i in range(256)]) # XXX TODO + self.writeObject(widthsObject, widths) self.writeObject(fontdescObject, descriptor) fontdata = type1font.Type1Font(filename) @@ -591,6 +616,8 @@ self.currentstream.write(fontdata.data) self.endStream() + return fontdictObject + def _get_xobject_symbol_name(self, filename, symbol_name): return "%s-%s" % ( os.path.splitext(os.path.basename(filename))[0], Modified: trunk/matplotlib/lib/matplotlib/dviread.py =================================================================== --- trunk/matplotlib/lib/matplotlib/dviread.py 2007-09-04 14:52:03 UTC (rev 3774) +++ trunk/matplotlib/lib/matplotlib/dviread.py 2007-09-04 18:19:16 UTC (rev 3775) @@ -35,6 +35,7 @@ opens the file; actually reading the file happens when iterating through the pages of the file. """ + matplotlib.verbose.report('Dvi: ' + filename, 'debug') self.file = open(filename, 'rb') self.dpi = dpi self.fonts = {} @@ -57,7 +58,7 @@ while True: have_page = self._read() if have_page: - yield self.text, self.boxes + yield self._output() else: break This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jd...@us...> - 2007-09-04 14:52:18
|
Revision: 3774 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3774&view=rev Author: jdh2358 Date: 2007-09-04 07:52:03 -0700 (Tue, 04 Sep 2007) Log Message: ----------- added manuels star poly patch Modified Paths: -------------- trunk/matplotlib/examples/scatter_star_poly.py trunk/matplotlib/lib/matplotlib/axes.py trunk/matplotlib/lib/matplotlib/collections.py trunk/matplotlib/lib/matplotlib/mpl-data/matplotlibrc trunk/matplotlib/lib/matplotlib/pylab.py trunk/matplotlib/mpl1/mpl1.py Modified: trunk/matplotlib/examples/scatter_star_poly.py =================================================================== --- trunk/matplotlib/examples/scatter_star_poly.py 2007-09-04 05:58:48 UTC (rev 3773) +++ trunk/matplotlib/examples/scatter_star_poly.py 2007-09-04 14:52:03 UTC (rev 3774) @@ -3,19 +3,25 @@ x = pylab.nx.mlab.rand(10) y = pylab.nx.mlab.rand(10) -pylab.subplot(221) +pylab.subplot(321) pylab.scatter(x,y,s=80,marker=">") -pylab.subplot(222) +pylab.subplot(322) pylab.scatter(x,y,s=80,marker=(5,0)) verts = zip([-1.,1.,1.],[-1.,-1.,1.]) -pylab.subplot(223) +pylab.subplot(323) pylab.scatter(x,y,s=80,marker=(verts,0)) # equivalent: #pylab.scatter(x,y,s=80,marker=None, verts=verts) -pylab.subplot(224) +pylab.subplot(324) pylab.scatter(x,y,s=80,marker=(5,1)) +pylab.subplot(325) +pylab.scatter(x,y,s=80,marker='+') + +pylab.subplot(326) +pylab.scatter(x,y,s=80,marker=(5,2), edgecolor='g') + pylab.show() Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2007-09-04 05:58:48 UTC (rev 3773) +++ trunk/matplotlib/lib/matplotlib/axes.py 2007-09-04 14:52:03 UTC (rev 3774) @@ -3976,16 +3976,18 @@ if not self._hold: self.cla() syms = { # a dict from symbol to (numsides, angle) - 's' : (4, math.pi/4.0), # square - 'o' : (20, 0), # circle - '^' : (3,0), # triangle up - '>' : (3,math.pi/2.0), # triangle right - 'v' : (3,math.pi), # triangle down - '<' : (3,3*math.pi/2.0), # triangle left - 'd' : (4,0), # diamond - 'p' : (5,0), # pentagram - 'h' : (6,0), # hexagon - '8' : (8,0), # octagon + 's' : (4,math.pi/4.0,0), # square + 'o' : (20,0,0), # circle + '^' : (3,0,0), # triangle up + '>' : (3,math.pi/2.0,0), # triangle right + 'v' : (3,math.pi,0), # triangle down + '<' : (3,3*math.pi/2.0,0), # triangle left + 'd' : (4,0,0), # diamond + 'p' : (5,0,0), # pentagram + 'h' : (6,0,0), # hexagon + '8' : (8,0,0), # octagon + '+' : (4,0,2), # plus + 'x' : (4,math.pi/4.0,2) # cross } self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs) @@ -4013,7 +4015,7 @@ else: edgecolors = 'None' sym = None - starlike = False + symstyle = 0 # to be API compatible if marker is None and not (verts is None): @@ -4025,7 +4027,7 @@ sym = syms.get(marker) if sym is None and verts is None: raise ValueError('Unknown marker symbol to scatter') - numsides, rotation = syms[marker] + numsides, rotation, symstyle = syms[marker] elif iterable(marker): # accept marker to be: @@ -4040,21 +4042,19 @@ # (numsides, style, [angle]) if len(marker)==2: - numsides, rotation = marker[0], math.pi/4. + numsides, rotation = marker[0], 0. elif len(marker)==3: numsides, rotation = marker[0], marker[2] sym = True - if marker[1]==1: - # starlike symbol, everthing else is interpreted - # as solid symbol - starlike = True + if marker[1] in (1,2): + symstyle = marker[1] else: verts = npy.asarray(marker[0]) if sym is not None: - if not starlike: + if symstyle==0: collection = mcoll.RegularPolyCollection( self.figure.dpi, @@ -4065,7 +4065,7 @@ offsets = zip(x,y), transOffset = self.transData, ) - else: + elif symstyle==1: collection = mcoll.StarPolygonCollection( self.figure.dpi, numsides, rotation, scales, @@ -4075,6 +4075,16 @@ offsets = zip(x,y), transOffset = self.transData, ) + elif symstyle==2: + collection = mcoll.AsteriskPolygonCollection( + self.figure.dpi, + numsides, rotation, scales, + facecolors = colors, + edgecolors = edgecolors, + linewidths = linewidths, + offsets = zip(x,y), + transOffset = self.transData, + ) else: # rescale verts rescale = npy.sqrt(max(verts[:,0]**2+verts[:,1]**2)) Modified: trunk/matplotlib/lib/matplotlib/collections.py =================================================================== --- trunk/matplotlib/lib/matplotlib/collections.py 2007-09-04 05:58:48 UTC (rev 3773) +++ trunk/matplotlib/lib/matplotlib/collections.py 2007-09-04 14:52:03 UTC (rev 3774) @@ -568,9 +568,42 @@ ns2 = self.numsides*2 r = scale*npy.ones(ns2) r[1::2] *= 0.5 - theta = (2.*math.pi/(ns2))*npy.arange(ns2) + self.rotation + theta = (math.pi/self.numsides)*npy.arange(ns2) + self.rotation self._verts = zip( r*npy.sin(theta), r*npy.cos(theta) ) +class AsteriskPolygonCollection(RegularPolyCollection): + def __init__(self, + dpi, + numsides, + rotation = 0 , + sizes = (1,), + **kwargs): + """ + Draw a regular asterisk Polygone with numsides spikes. + + * dpi is the figure dpi instance, and is required to do the + area scaling. + + * numsides: the number of spikes of the polygon + + * sizes gives the area of the circle circumscribing the + regular polygon in points^2 + + * rotation is the rotation of the polygon in radians + + %(PatchCollection)s + """ + + RegularPolyCollection.__init__(self, dpi, numsides, rotation, sizes, **kwargs) + __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd + + def _update_verts(self): + scale = 1.0/math.sqrt(math.pi) + r = scale*npy.ones(self.numsides*2) + r[1::2] = 0 + theta = (math.pi/self.numsides)*npy.arange(2*self.numsides) + self.rotation + self._verts = zip( r*npy.sin(theta), r*npy.cos(theta) ) + class LineCollection(Collection, cm.ScalarMappable): """ All parameters must be sequences or scalars; if scalars, they will Modified: trunk/matplotlib/lib/matplotlib/mpl-data/matplotlibrc =================================================================== --- trunk/matplotlib/lib/matplotlib/mpl-data/matplotlibrc 2007-09-04 05:58:48 UTC (rev 3773) +++ trunk/matplotlib/lib/matplotlib/mpl-data/matplotlibrc 2007-09-04 14:52:03 UTC (rev 3774) @@ -26,7 +26,7 @@ #### CONFIGURATION BEGINS HERE # the default backend; one of GTK GTKAgg GTKCairo FltkAgg QtAgg TkAgg # Agg Cairo GD GDK Paint PS PDF SVG Template -backend : WXAgg +backend : TkAgg numerix : numpy # numpy, Numeric or numarray #maskedarray : False # True to use external maskedarray module # instead of numpy.ma; this is a temporary Modified: trunk/matplotlib/lib/matplotlib/pylab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/pylab.py 2007-09-04 05:58:48 UTC (rev 3773) +++ trunk/matplotlib/lib/matplotlib/pylab.py 2007-09-04 14:52:03 UTC (rev 3774) @@ -1464,8 +1464,8 @@ is either an int or a string. if it is an int, it indicates the column number. If it is a string, it indicates the column header. mpl will make column headers lower case, replace spaces with - strings, and remove all illegal characters; so 'Adj Close*' will - have name 'adj_close' + underscores, and remove all illegal characters; so 'Adj Close*' + will have name 'adj_close' if len(cols)==1, only that column will be plotted on the y axis. if len(cols)>1, the first element will be an identifier for data @@ -1480,7 +1480,8 @@ names in both. comments, skiprows, checkrows, and delimiter are all passed on to - matplotlib.mlab.csv2rec to load the data into a record array + matplotlib.mlab.csv2rec to load the data into a record array. See + the help there fore more information. kwargs are passed on to plotting functions Modified: trunk/matplotlib/mpl1/mpl1.py =================================================================== --- trunk/matplotlib/mpl1/mpl1.py 2007-09-04 05:58:48 UTC (rev 3773) +++ trunk/matplotlib/mpl1/mpl1.py 2007-09-04 14:52:03 UTC (rev 3774) @@ -12,7 +12,7 @@ sudo rm -rf /usr/local/lib/python2.5/site-packages/enthought* sudo easy_install \ -f http://code.enthought.com/enstaller/eggs/source/unstable \ - "enthought.resource <3.0a" "enthought.traits < 3.0a" + "enthought.traits < 3.0a" """ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ef...@us...> - 2007-09-04 05:58:49
|
Revision: 3773 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3773&view=rev Author: efiring Date: 2007-09-03 22:58:48 -0700 (Mon, 03 Sep 2007) Log Message: ----------- Update CHANGELOG and API_CHANGES for Manuel Metz's errorbar patch. Modified Paths: -------------- trunk/matplotlib/API_CHANGES trunk/matplotlib/CHANGELOG Modified: trunk/matplotlib/API_CHANGES =================================================================== --- trunk/matplotlib/API_CHANGES 2007-09-04 05:53:56 UTC (rev 3772) +++ trunk/matplotlib/API_CHANGES 2007-09-04 05:58:48 UTC (rev 3773) @@ -1,3 +1,7 @@ + The errorbar method and function now accept additional kwargs + so that upper and lower limits can be indicated by capping the + bar with a caret instead of a straight line segment. + The dviread.py file now has a parser for files like psfonts.map and pdftex.map, to map TeX font names to external files. Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2007-09-04 05:53:56 UTC (rev 3772) +++ trunk/matplotlib/CHANGELOG 2007-09-04 05:58:48 UTC (rev 3773) @@ -1,3 +1,6 @@ +2007-09-03 Added ability of errorbar show limits via caret or + arrowhead ends on the bars; patch by Manual Metz. - EF + 2007-09-03 Created type1font.py, added features to AFM and FT2Font (see API_CHANGES), started work on embedding Type 1 fonts in pdf files. - JKS @@ -7,7 +10,7 @@ 2007-08-16 Added a set_extent method to AxesImage, allow data extent to be modified after initial call to imshow - DSD -2007-08-14 Fixed a bug in pyqt4 subplots-adjust. Thanks to +2007-08-14 Fixed a bug in pyqt4 subplots-adjust. Thanks to Xavier Gnata for the report and suggested fix - DSD 2007-08-13 Use pickle to cache entire fontManager; change to using This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ef...@us...> - 2007-09-04 05:53:57
|
Revision: 3772 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3772&view=rev Author: efiring Date: 2007-09-03 22:53:56 -0700 (Mon, 03 Sep 2007) Log Message: ----------- Errorbar limit symbols patch by Manuel Metz Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/axes.py trunk/matplotlib/lib/matplotlib/lines.py Added Paths: ----------- trunk/matplotlib/examples/errorbar_limits.py Added: trunk/matplotlib/examples/errorbar_limits.py =================================================================== --- trunk/matplotlib/examples/errorbar_limits.py (rev 0) +++ trunk/matplotlib/examples/errorbar_limits.py 2007-09-04 05:53:56 UTC (rev 3772) @@ -0,0 +1,40 @@ +''' +Illustration of upper and lower limit symbols on errorbars +''' + +from math import pi +from numpy import array, arange, sin +import pylab as P + +fig = P.figure() +x = arange(10.0) +y = sin(arange(10.0)/20.0*pi) + +P.errorbar(x,y,yerr=0.1,capsize=3) + +y = sin(arange(10.0)/20.0*pi) + 1 +P.errorbar(x,y,yerr=0.1, uplims=True) + +y = sin(arange(10.0)/20.0*pi) + 2 +upperlimits = array([1,0]*5) +lowerlimits = array([0,1]*5) +P.errorbar(x, y, yerr=0.1, uplims=upperlimits, lolims=lowerlimits) + +P.xlim(-1,10) + +fig = P.figure() +x = arange(10.0)/10.0 +y = (x+0.1)**2 + +P.errorbar(x, y, xerr=0.1, xlolims=True) +y = (x+0.1)**3 + +P.errorbar(x+0.6, y, xerr=0.1, xuplims=upperlimits, xlolims=lowerlimits) + +y = (x+0.1)**4 +P.errorbar(x+1.2, y, xerr=0.1, xuplims=True) + +P.xlim(-0.2,2.4) +P.ylim(-0.1,1.3) + +P.show() Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2007-09-03 22:16:19 UTC (rev 3771) +++ trunk/matplotlib/lib/matplotlib/axes.py 2007-09-04 05:53:56 UTC (rev 3772) @@ -3522,10 +3522,13 @@ def errorbar(self, x, y, yerr=None, xerr=None, fmt='-', ecolor=None, capsize=3, - barsabove=False, **kwargs): + barsabove=False, lolims=False, uplims=False, + xlolims=False, xuplims=False, **kwargs): """ ERRORBAR(x, y, yerr=None, xerr=None, - fmt='b-', ecolor=None, capsize=3, barsabove=False) + fmt='b-', ecolor=None, capsize=3, barsabove=False, + lolims=False, uplims=False, + xlolims=False, xuplims=False) Plot x versus y with error deltas in yerr and xerr. Vertical errorbars are plotted if yerr is not None @@ -3554,6 +3557,11 @@ barsabove, if True, will plot the errorbars above the plot symbols - default is below + lolims, uplims, xlolims, xuplims: These arguments can be used + to indicate that a value gives only upper/lower limits. In + that case a caret symbol is used to indicate this. lims-arguments + may be of the same type as xerr and yerr. + kwargs are passed on to the plot command for the markers. So you can add additional key=value pairs to control the errorbar markers. For example, this code makes big red @@ -3579,18 +3587,18 @@ if not self._hold: self.cla() # make sure all the args are iterable arrays - if not iterable(x): x = npy.asarray([x]) + if not iterable(x): x = npy.array([x]) else: x = npy.asarray(x) - if not iterable(y): y = npy.asarray([y]) + if not iterable(y): y = npy.array([y]) else: y = npy.asarray(y) if xerr is not None: - if not iterable(xerr): xerr = npy.asarray([xerr]) + if not iterable(xerr): xerr = npy.array([xerr]) else: xerr = npy.asarray(xerr) if yerr is not None: - if not iterable(yerr): yerr = npy.asarray([yerr]) + if not iterable(yerr): yerr = npy.array([yerr]) else: yerr = npy.asarray(yerr) l0 = None @@ -3607,6 +3615,18 @@ if 'lw' in kwargs: lines_kw['lw']=kwargs['lw'] + if not iterable(lolims): lolims = npy.array([lolims]*len(x), bool) + else: lolims = npy.asarray(lolims, bool) + + if not iterable(uplims): uplims = npy.array([uplims]*len(x), bool) + else: uplims = npy.asarray(uplims, bool) + + if not iterable(xlolims): xlolims = npy.array([xlolims]*len(x), bool) + else: xlolims = npy.asarray(xlolims, bool) + + if not iterable(xuplims): xuplims = npy.array([xuplims]*len(x), bool) + else: xuplims = npy.asarray(xuplims, bool) + if capsize > 0: plot_kw = { 'ms':2*capsize, @@ -3626,9 +3646,20 @@ barcols.append( self.hlines(y, left, right, **lines_kw ) ) if capsize > 0: - caplines.extend( self.plot(left, y, 'k|', **plot_kw) ) - caplines.extend( self.plot(right, y, 'k|', **plot_kw) ) + if xlolims.any(): + caplines.extend( self.plot(left[xlolims], y[xlolims], ls='None', marker=mlines.CARETLEFT, **plot_kw) ) + xlolims = ~xlolims + caplines.extend( self.plot(left[xlolims], y[xlolims], 'k|', **plot_kw) ) + else: + caplines.extend( self.plot(left, y, 'k|', **plot_kw) ) + if xuplims.any(): + caplines.extend( self.plot(right[xuplims], y[xuplims], ls='None', marker=mlines.CARETRIGHT, **plot_kw) ) + xuplims = ~xuplims + caplines.extend( self.plot(right[xuplims], y[xuplims], 'k|', **plot_kw) ) + else: + caplines.extend( self.plot(right, y, 'k|', **plot_kw) ) + if yerr is not None: if len(yerr.shape) == 1: lower = y-yerr @@ -3639,9 +3670,21 @@ barcols.append( self.vlines(x, lower, upper, **lines_kw) ) if capsize > 0: - caplines.extend( self.plot(x, lower, 'k_', **plot_kw) ) - caplines.extend( self.plot(x, upper, 'k_', **plot_kw) ) + if lolims.any(): + caplines.extend( self.plot(x[lolims], lower[lolims], ls='None', marker=mlines.CARETDOWN, **plot_kw) ) + lolims = ~lolims + caplines.extend( self.plot(x[lolims], lower[lolims], 'k_', **plot_kw) ) + else: + caplines.extend( self.plot(x, lower, 'k_', **plot_kw) ) + + if uplims.any(): + caplines.extend( self.plot(x[uplims], upper[uplims], ls='None', marker=mlines.CARETUP, **plot_kw) ) + uplims = ~uplims + caplines.extend( self.plot(x[uplims], upper[uplims], 'k_', **plot_kw) ) + else: + caplines.extend( self.plot(x, upper, 'k_', **plot_kw) ) + if not barsabove and fmt is not None: l0, = self.plot(x,y,fmt,**kwargs) Modified: trunk/matplotlib/lib/matplotlib/lines.py =================================================================== --- trunk/matplotlib/lib/matplotlib/lines.py 2007-09-03 22:16:19 UTC (rev 3771) +++ trunk/matplotlib/lib/matplotlib/lines.py 2007-09-04 05:53:56 UTC (rev 3772) @@ -21,7 +21,9 @@ from transforms import lbwh_to_bbox, LOG10 from matplotlib import rcParams -TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN = range(4) +# special-purpose marker identifiers: +(TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN, + CARETLEFT, CARETRIGHT, CARETUP, CARETDOWN) = range(8) def unmasked_index_ranges(mask, compressed = True): ''' @@ -97,7 +99,7 @@ point_hits = (cx - x)**2 + (cy - y)**2 <= radius**2 #if any(point_hits): print "points",xr[candidates] candidates = candidates & ~point_hits[:-1] & ~point_hits[1:] - + # For those candidates which remain, determine how far they lie away # from the line. px,py = xr+u*dx,yr+u*dy @@ -147,6 +149,10 @@ TICKRIGHT : '_draw_tickright', TICKUP : '_draw_tickup', TICKDOWN : '_draw_tickdown', + CARETLEFT : '_draw_caretleft', + CARETRIGHT : '_draw_caretright', + CARETUP : '_draw_caretup', + CARETDOWN : '_draw_caretdown', 'None' : '_draw_nothing', ' ' : '_draw_nothing', '' : '_draw_nothing', @@ -1201,6 +1207,62 @@ renderer.draw_line(gc, x, y, x-offset2, y+offset1) renderer.draw_line(gc, x, y, x-offset2, y-offset1) + def _draw_caretdown(self, renderer, gc, xt, yt): + offset = 0.5*renderer.points_to_pixels(self._markersize) + offset1 = 1.5*offset + if self._newstyle: + path = agg.path_storage() + path.move_to(-offset, offset1) + path.line_to(0, 0) + path.line_to(+offset, offset1) + renderer.draw_markers(gc, path, None, xt, yt, self.get_transform()) + else: + for (x,y) in zip(xt, yt): + renderer.draw_line(gc, x-offset, y+offset1, x, y) + renderer.draw_line(gc, x, y, x+offset, y+offset1) + + def _draw_caretup(self, renderer, gc, xt, yt): + offset = 0.5*renderer.points_to_pixels(self._markersize) + offset1 = 1.5*offset + if self._newstyle: + path = agg.path_storage() + path.move_to(-offset, -offset1) + path.line_to(0, 0) + path.line_to(+offset, -offset1) + renderer.draw_markers(gc, path, None, xt, yt, self.get_transform()) + else: + for (x,y) in zip(xt, yt): + renderer.draw_line(gc, x-offset, y-offset1, x, y) + renderer.draw_line(gc, x, y, x+offset, y-offset1) + + def _draw_caretleft(self, renderer, gc, xt, yt): + offset = 0.5*renderer.points_to_pixels(self._markersize) + offset1 = 1.5*offset + if self._newstyle: + path = agg.path_storage() + path.move_to(offset1, -offset) + path.line_to(0, 0) + path.line_to(offset1, offset) + renderer.draw_markers(gc, path, None, xt, yt, self.get_transform()) + else: + for (x,y) in zip(xt, yt): + renderer.draw_line(gc, x+offset1, y-offset, x, y) + renderer.draw_line(gc, x, y, x+offset1, y+offset) + + def _draw_caretright(self, renderer, gc, xt, yt): + offset = 0.5*renderer.points_to_pixels(self._markersize) + offset1 = 1.5*offset + if self._newstyle: + path = agg.path_storage() + path.move_to(-offset1, -offset) + path.line_to(0, 0) + path.line_to(-offset1, offset) + renderer.draw_markers(gc, path, None, xt, yt, self.get_transform()) + else: + for (x,y) in zip(xt, yt): + renderer.draw_line(gc, x-offset1, y-offset, x, y) + renderer.draw_line(gc, x, y, x-offset1, y+offset) + def _draw_x(self, renderer, gc, xt, yt): offset = 0.5*renderer.points_to_pixels(self._markersize) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jo...@us...> - 2007-09-03 22:16:24
|
Revision: 3771 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3771&view=rev Author: jouni Date: 2007-09-03 15:16:19 -0700 (Mon, 03 Sep 2007) Log Message: ----------- Fix some obvious bugs in Type 1 font support; now it at least produces a pdf file, at least with Computer Modern Roman, but viewer applications complain that the fonts are broken. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-03 21:36:17 UTC (rev 3770) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-03 22:16:19 UTC (rev 3771) @@ -515,21 +515,30 @@ _, _, fullname, familyname, weight, italic_angle, fixed_pitch, \ ul_position, ul_thickness = font.get_ps_font_info() - differencesArray = [ 0 ] + [ Name(ch) for ch in - dviread.Encoding(fontinfo.encoding) ] + if fontinfo.encodingfile is not None: + differencesArray = [ Name(ch) for ch in + dviread.Encoding(fontinfo.encodingfile) ] + differencesArray = [ 0 ] + differencesArray + lastchar = len(differencesArray) - 2 + else: + lastchar = 255 # ? fontdict = { 'Type': Name('Font'), 'Subtype': Name('Type1'), 'BaseFont': Name(font.postscript_name), 'FirstChar': 0, - 'LastChar': len(differencesArray) - 2, + 'LastChar': lastchar, 'Widths': widthsObject, 'FontDescriptor': fontdescObject, - 'Encoding': { 'Type': Name('Encoding'), - 'Differences': differencesArray }, } + if fontinfo.encodingfile is not None: + fontdict.update({ + 'Encoding': { 'Type': Name('Encoding'), + 'Differences': differencesArray }, + }) + flags = 0 if fixed_pitch: flags |= 1 << 0 # fixed width if 0: flags |= 1 << 1 # TODO: serif @@ -570,11 +579,11 @@ descriptor['StemH'] = StemH self.writeObject(fontdictObject, fontdict) - self.writeObject(widthsObject, widths) + self.writeObject(widthsObject, [ 100 for i in range(256)]) # XXX TODO self.writeObject(fontdescObject, descriptor) fontdata = type1font.Type1Font(filename) - len1, len2, len3 = fontdata.lenghts() + len1, len2, len3 = fontdata.lengths() self.beginStream(fontfileObject.id, None, { 'Length1': len1, 'Length2': len2, @@ -1386,14 +1395,8 @@ self.file.output(Op.grestore) def _draw_tex(self, gc, x, y, s, prop, angle): - # Rename to draw_tex to enable, but note the following: - # TODO: - # - font sizes other than 10pt - # - fonts other than the three ttf files included with matplotlib - # (will need to support Type-1 fonts and find them with kpsewhich) - # - encoding issues (e.g. \alpha doesn't work now) - # - overall robustness - # - ... + # Rename to draw_tex to enable, but it doesn't work at the moment + texmanager = self.get_texmanager() fontsize = prop.get_size_in_points() dvifile = texmanager.make_dvi(s, fontsize) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jo...@us...> - 2007-09-03 21:36:32
|
Revision: 3770 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3770&view=rev Author: jouni Date: 2007-09-03 14:36:17 -0700 (Mon, 03 Sep 2007) Log Message: ----------- Created new file type1font.py for supporting Type 1 fonts; quite preliminary for now. Started adding Type 1 support to PDF backend for purposes of usetex. Modified Paths: -------------- trunk/matplotlib/API_CHANGES trunk/matplotlib/CHANGELOG trunk/matplotlib/lib/matplotlib/afm.py trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py trunk/matplotlib/lib/matplotlib/dviread.py trunk/matplotlib/src/ft2font.cpp trunk/matplotlib/src/ft2font.h Added Paths: ----------- trunk/matplotlib/lib/matplotlib/type1font.py Modified: trunk/matplotlib/API_CHANGES =================================================================== --- trunk/matplotlib/API_CHANGES 2007-09-03 18:27:22 UTC (rev 3769) +++ trunk/matplotlib/API_CHANGES 2007-09-03 21:36:17 UTC (rev 3770) @@ -1,3 +1,18 @@ + The dviread.py file now has a parser for files like psfonts.map + and pdftex.map, to map TeX font names to external files. + + The file type1font.py contains a new class for Type 1 fonts. + Currently it simply reads pfa and pfb format files and stores the + data in pfa format, which is the format for embedding Type 1 fonts + in postscript and pdf files. In the future the class might + actually parse the font to allow e.g. subsetting. + + FT2Font now supports FT_Attach_File. In practice this can be used + to read an afm file in addition to a pfa/pfb file, to get metrics + and kerning information for a Type 1 font. + + The AFM class now supports querying CapHeight and stem widths. + Changed pcolor default to shading='flat'; but as noted now in the docstring, it is preferable to simply use the edgecolor kwarg. Modified: trunk/matplotlib/CHANGELOG =================================================================== --- trunk/matplotlib/CHANGELOG 2007-09-03 18:27:22 UTC (rev 3769) +++ trunk/matplotlib/CHANGELOG 2007-09-03 21:36:17 UTC (rev 3770) @@ -1,3 +1,9 @@ +2007-09-03 Created type1font.py, added features to AFM and FT2Font + (see API_CHANGES), started work on embedding Type 1 fonts + in pdf files. - JKS + +2007-09-02 Continued work on dviread.py. - JKS + 2007-08-16 Added a set_extent method to AxesImage, allow data extent to be modified after initial call to imshow - DSD Modified: trunk/matplotlib/lib/matplotlib/afm.py =================================================================== --- trunk/matplotlib/lib/matplotlib/afm.py 2007-09-03 18:27:22 UTC (rev 3769) +++ trunk/matplotlib/lib/matplotlib/afm.py 2007-09-03 21:36:17 UTC (rev 3770) @@ -103,7 +103,8 @@ 'Version': _to_str, 'Notice': _to_str, 'EncodingScheme': _to_str, - 'CapHeight': _to_float, + 'CapHeight': _to_float, # Is the second version a mistake, or + 'Capheight': _to_float, # do some AFM files contain 'Capheight'? -JKS 'XHeight': _to_float, 'Ascender': _to_float, 'Descender': _to_float, @@ -112,7 +113,6 @@ 'StartCharMetrics': _to_int, 'CharacterSet': _to_str, 'Characters': _to_int, - 'Capheight': _to_int, } d = {} @@ -446,6 +446,10 @@ "Return the fontangle as float" return self._header['ItalicAngle'] + def get_capheight(self): + "Return the cap height as float" + return self._header['CapHeight'] + def get_xheight(self): "Return the xheight as float" return self._header['XHeight'] @@ -453,6 +457,20 @@ def get_underline_thickness(self): "Return the underline thickness as float" return self._header['UnderlineThickness'] + + def get_horizontal_stem_width(self): + """ + Return the standard horizontal stem width as float, or None if + not specified in AFM file. + """ + return self._header.get('StdHW', None) + + def get_vertical_stem_width(self): + """ + Return the standard vertical stem width as float, or None if + not specified in AFM file. + """ + return self._header.get('StdVW', None) if __name__=='__main__': Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-03 18:27:22 UTC (rev 3769) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-03 21:36:17 UTC (rev 3770) @@ -26,7 +26,8 @@ from matplotlib.figure import Figure from matplotlib.font_manager import findfont from matplotlib.afm import AFM -from matplotlib.dviread import Dvi +import matplotlib.type1font as type1font +import matplotlib.dviread as dviread from matplotlib.ft2font import FT2Font, FIXED_WIDTH, ITALIC, LOAD_NO_SCALE, \ LOAD_NO_HINTING, KERNING_UNFITTED from matplotlib.mathtext import MathTextParser @@ -367,6 +368,7 @@ # self.fontNames maps filenames to internal font names self.fontNames = {} self.nextFont = 1 # next free internal font name + self.fontInfo = {} # information on fonts: metrics, encoding self.alphaStates = {} # maps alpha values to graphics state objects self.nextAlphaState = 1 @@ -438,6 +440,12 @@ self.currentstream = None def fontName(self, fontprop): + """ + Select a font based on fontprop and return a name suitable for + Op.selectfont. If fontprop is a string, it will be interpreted + as the filename of the font. + """ + if is_string_like(fontprop): filename = fontprop elif rcParams['pdf.use14corefonts']: @@ -458,6 +466,9 @@ for filename, Fx in self.fontNames.items(): if filename.endswith('.afm'): fontdictObject = self._write_afm_font(filename) + elif filename.endswith('.pfb') or filename.endswith('.pfa'): + # a Type 1 font; limited support for now + fontdictObject = self.embedType1(filename, self.fontInfo[Fx]) else: realpath, stat_key = get_realpath_and_stat(filename) chars = self.used_characters.get(stat_key) @@ -480,6 +491,97 @@ self.writeObject(fontdictObject, fontdict) return fontdictObject + def embedType1(self, filename, fontinfo): + fh = open(filename, 'rb') + try: + fontdata = fh.read() + finally: + fh.close() + + fh = open(fontinfo.afmfile, 'rb') + try: + afmdata = AFM(fh) + finally: + fh.close() + + font = FT2Font(filename) + font.attach_file(fontinfo.afmfile) + + widthsObject, fontdescObject, fontdictObject, fontfileObject = \ + [ self.reserveObject(n) for n in + ('font widths', 'font descriptor', + 'font dictionary', 'font file') ] + + _, _, fullname, familyname, weight, italic_angle, fixed_pitch, \ + ul_position, ul_thickness = font.get_ps_font_info() + + differencesArray = [ 0 ] + [ Name(ch) for ch in + dviread.Encoding(fontinfo.encoding) ] + + fontdict = { + 'Type': Name('Font'), + 'Subtype': Name('Type1'), + 'BaseFont': Name(font.postscript_name), + 'FirstChar': 0, + 'LastChar': len(differencesArray) - 2, + 'Widths': widthsObject, + 'FontDescriptor': fontdescObject, + 'Encoding': { 'Type': Name('Encoding'), + 'Differences': differencesArray }, + } + + flags = 0 + if fixed_pitch: flags |= 1 << 0 # fixed width + if 0: flags |= 1 << 1 # TODO: serif + if 0: flags |= 1 << 2 # TODO: symbolic + else: flags |= 1 << 5 # non-symbolic + if italic_angle: flags |= 1 << 6 # italic + if 0: flags |= 1 << 16 # TODO: all caps + if 0: flags |= 1 << 17 # TODO: small caps + if 0: flags |= 1 << 18 # TODO: force bold + + descriptor = { + 'Type': Name('FontDescriptor'), + 'FontName': Name(font.postscript_name), + 'Flags': flags, + 'FontBBox': font.bbox, + 'ItalicAngle': italic_angle, + 'Ascent': font.ascender, + 'Descent': font.descender, + 'CapHeight': afmdata.get_capheight(), + 'XHeight': afmdata.get_xheight(), + 'FontFile': fontfileObject, + 'FontFamily': Name(familyname), + #'FontWeight': a number where 400 = Regular, 700 = Bold + } + + # StemV is obligatory in PDF font descriptors but optional in + # AFM files. The collection of AFM files in my TeX Live 2007 + # collection has values ranging from 22 to 219, with both + # median and mode 50, so if the AFM file is silent, I'm + # guessing 50. -JKS + StemV = afmdata.get_vertical_stem_width() + if StemV is None: StemV = 50 + descriptor['StemV'] = StemV + + # StemH is entirely optional: + StemH = afmdata.get_horizontal_stem_width() + if StemH is not None: + descriptor['StemH'] = StemH + + self.writeObject(fontdictObject, fontdict) + self.writeObject(widthsObject, widths) + self.writeObject(fontdescObject, descriptor) + + fontdata = type1font.Type1Font(filename) + len1, len2, len3 = fontdata.lenghts() + self.beginStream(fontfileObject.id, None, + { 'Length1': len1, + 'Length2': len2, + 'Length3': len3 }) + self.currentstream.write(fontdata.data) + self.endStream() + def _get_xobject_symbol_name(self, filename, symbol_name): return "%s-%s" % ( os.path.splitext(os.path.basename(filename))[0], @@ -1034,6 +1136,7 @@ self.encode_string = self.encode_string_type42 self.mathtext_parser = MathTextParser("Pdf") self.image_magnification = dpi/72.0 + self.tex_font_map = None def finalize(self): self.gc.finalize() @@ -1050,6 +1153,12 @@ # Restore gc to avoid unwanted side effects gc._fillcolor = orig_fill + def tex_font_mapping(self, texfont): + if self.tex_font_map is None: + self.tex_font_map = \ + dviread.PsfontsMap(dviread.find_tex_file('pdftex.map')) + return self.tex_font_map[texfont] + def track_characters(self, font, s): """Keeps track of which characters are required from each font.""" @@ -1288,9 +1397,8 @@ texmanager = self.get_texmanager() fontsize = prop.get_size_in_points() dvifile = texmanager.make_dvi(s, fontsize) - dvi = Dvi(dvifile, 72) + dvi = dviread.Dvi(dvifile, 72) text, boxes = iter(dvi).next() - fontdir = os.path.join(get_data_path(), 'fonts', 'ttf') if angle == 0: # avoid rounding errors in common case def mytrans(x1, y1): @@ -1303,14 +1411,17 @@ self.check_gc(gc, gc._rgb) self.file.output(Op.begin_text) - oldfont, oldx, oldy = None, 0, 0 - for x1, y1, font, glyph in text: - if font != oldfont: - fontname, fontsize = dvi.fontinfo(font) - fontfile = os.path.join(fontdir, fontname+'.ttf') - self.file.output(self.file.fontName(fontfile), - fontsize, Op.selectfont) - oldfont = font + oldfontnum, oldx, oldy = None, 0, 0 + for x1, y1, fontnum, glyph in text: + if fontnum != oldfontnum: + texname, fontsize = dvi.fontinfo(fontnum) + fontinfo = self.tex_font_mapping(texname) + pdfname = self.file.fontName(fontinfo.filename) + self.file.fontInfo[pdfname] = Bunch( + encodingfile=fontinfo.encoding, + afmfile=fontinfo.afm) + self.file.output(pdfname, fontsize, Op.selectfont) + oldfontnum = fontnum x1, y1 = mytrans(x1, y1) self._setup_textpos(x1, y1, angle, oldx, oldy) self.file.output(chr(glyph), Op.show) Modified: trunk/matplotlib/lib/matplotlib/dviread.py =================================================================== --- trunk/matplotlib/lib/matplotlib/dviread.py 2007-09-03 18:27:22 UTC (rev 3769) +++ trunk/matplotlib/lib/matplotlib/dviread.py 2007-09-03 21:36:17 UTC (rev 3770) @@ -410,11 +410,11 @@ def __getitem__(self, texname): result = self._font[texname] - if result.filename is not None \ - and not result.filename.startswith('/'): - result.filename = find_tex_file(result.filename) - if result.encoding is not None \ - and not result.encoding.startswith('/'): + fn, enc = result.filename, result.encoding + if fn is not None and not fn.startswith('/'): + result.filename = find_tex_file(fn) + result.afm = find_tex_file(fn[:-4] + '.afm') + if enc is not None and not enc.startswith('/'): result.encoding = find_tex_file(result.encoding) return result @@ -473,6 +473,51 @@ texname=texname, psname=psname, effects=effects, encoding=encoding, filename=filename) +class Encoding(object): + + def __init__(self, filename): + file = open(filename, 'rt') + try: + self.encoding = self._parse(file) + finally: + file.close() + + def __iter__(self): + for name in self.encoding: + yield name + + def _parse(self, file): + result = [] + + state = 0 + for line in file: + comment_start = line.find('%') + if comment_start > -1: + line = line[:comment_start] + line = line.strip() + + if state == 0: + # Expecting something like /FooEncoding [ + if '[' in line: + state = 1 + line = line[line.index('[')+1].strip() + + if state == 1: + words = line.split() + for w in words: + if w.startswith('/'): + # Allow for /abc/def/ghi + subwords = w.split('/') + result.extend(subwords[1:]) + else: + raise ValueError, "Broken name in encoding file: " + w + + # Expecting ] def + if ']' in line: + break + + return result + def find_tex_file(filename, format=None): """ Call kpsewhich to find a file in the texmf tree. Added: trunk/matplotlib/lib/matplotlib/type1font.py =================================================================== --- trunk/matplotlib/lib/matplotlib/type1font.py (rev 0) +++ trunk/matplotlib/lib/matplotlib/type1font.py 2007-09-03 21:36:17 UTC (rev 3770) @@ -0,0 +1,95 @@ +""" +A class representing a Type 1 font. + +This version merely allows reading in pfa and pfb files, and stores +the data in pfa format (which can be embedded in PostScript or PDF +files). A more complete class might support subsetting. + +Usage: font = Type1Font(filename) + somefile.write(font.data) # writes out font in pfa format + len1, len2, len3 = font.lengths() # needed for pdf embedding + +Source: Adobe Technical Note #5040, Supporting Downloadable PostScript +Language Fonts. + +If extending this class, see also: Adobe Type 1 Font Format, Adobe +Systems Incorporated, third printing, v1.1, 1993. ISBN 0-201-57044-0. +""" + +import struct + +class Type1Font(object): + + def __init__(self, filename): + file = open(filename, 'rb') + try: + self._read(file) + finally: + file.close() + + def _read(self, file): + rawdata = file.read() + if not rawdata.startswith(chr(128)): + self.data = rawdata + return + + self.data = '' + while len(rawdata) > 0: + if not rawdata.startswith(chr(128)): + raise RuntimeError, \ + 'Broken pfb file (expected byte 128, got %d)' % \ + ord(rawdata[0]) + type = ord(rawdata[1]) + if type in (1,2): + length, = struct.unpack('<i', rawdata[2:6]) + segment = rawdata[6:6+length] + rawdata = rawdata[6+length:] + + if type == 1: # ASCII text: include verbatim + self.data += segment + elif type == 2: # binary data: encode in hexadecimal + self.data += ''.join(['%02x' % ord(char) + for char in segment]) + elif type == 3: # end of file + break + else: + raise RuntimeError, \ + 'Unknown segment type %d in pfb file' % type + + def lengths(self): + """ + Compute the lengths of the three parts of a Type 1 font. + + The three parts are: (1) the cleartext part, which ends in a + eexec operator; (2) the encrypted part; (3) the fixed part, + which contains 512 ASCII zeros possibly divided on various + lines, a cleartomark operator, and possibly something else. + """ + + # Cleartext part: just find the eexec and skip the eol char(s) + idx = self.data.index('eexec') + idx += len('eexec') + while self.data[idx] in ('\n', '\r'): + idx += 1 + len1 = idx + + # Encrypted part: find the cleartomark operator and count + # zeros backward + idx = self.data.rindex('cleartomark') - 1 + zeros = 512 + while zeros and self.data[idx] in ('0', '\n', '\r'): + if self.data[idx] == '0': + zeros -= 1 + idx -= 1 + if zeros: + raise RuntimeError, 'Insufficiently many zeros in Type 1 font' + + len2 = idx - len1 + len3 = len(self.data) - idx + + return len1, len2, len3 + +if __name__ == '__main__': + import sys + font = Type1Font(sys.argv[1]) + sys.stdout.write(font.data) Modified: trunk/matplotlib/src/ft2font.cpp =================================================================== --- trunk/matplotlib/src/ft2font.cpp 2007-09-03 18:27:22 UTC (rev 3769) +++ trunk/matplotlib/src/ft2font.cpp 2007-09-03 21:36:17 UTC (rev 3770) @@ -1552,11 +1552,11 @@ } Py::Tuple info(9); - info[0] = Py::String(fontinfo.version); - info[1] = Py::String(fontinfo.notice); - info[2] = Py::String(fontinfo.full_name); - info[3] = Py::String(fontinfo.family_name); - info[4] = Py::String(fontinfo.weight); + info[0] = Py::String(fontinfo.version ? fontinfo.version : ""); + info[1] = Py::String(fontinfo.notice ? fontinfo.notice : ""); + info[2] = Py::String(fontinfo.full_name ? fontinfo.full_name : ""); + info[3] = Py::String(fontinfo.family_name ? fontinfo.family_name : ""); + info[4] = Py::String(fontinfo.weight ? fontinfo.weight : ""); info[5] = Py::Long(fontinfo.italic_angle); info[6] = Py::Int(fontinfo.is_fixed_pitch); info[7] = Py::Int(fontinfo.underline_position); @@ -1788,7 +1788,30 @@ return Py::asObject(image); } +char FT2Font::attach_file__doc__ [] = + "attach_file(filename)\n" + "\n" + "Attach a file with extra information on the font\n" + "(in practice, an AFM file with the metrics of a Type 1 font).\n" + "Throws an exception if unsuccessful.\n"; Py::Object +FT2Font::attach_file (const Py::Tuple &args) { + args.verify_length(1); + + std::string filename = Py::String(args[0]); + FT_Error error = + FT_Attach_File(face, filename.c_str()); + + if (error) { + std::ostringstream s; + s << "Could not attach file " << filename + << " (freetype error code " << error << ")" << std::endl; + throw Py::RuntimeError(s.str()); + } + return Py::Object(); +} + +Py::Object ft2font_module::new_ft2image (const Py::Tuple &args) { args.verify_length(2); @@ -1894,6 +1917,8 @@ FT2Font::get_sfnt_table__doc__); add_varargs_method("get_image", &FT2Font::get_image, FT2Font::get_image__doc__); + add_varargs_method("attach_file", &FT2Font::attach_file, + FT2Font::attach_file__doc__); behaviors().supportGetattr(); behaviors().supportSetattr(); @@ -1949,6 +1974,7 @@ " max_advance_height same for vertical layout\n" " underline_position vertical position of the underline bar\n" " underline_thickness vertical thickness of the underline\n" +" postscript_name PostScript name of the font\n" ; #if defined(_MSC_VER) Modified: trunk/matplotlib/src/ft2font.h =================================================================== --- trunk/matplotlib/src/ft2font.h 2007-09-03 18:27:22 UTC (rev 3769) +++ trunk/matplotlib/src/ft2font.h 2007-09-03 21:36:17 UTC (rev 3770) @@ -122,6 +122,7 @@ Py::Object get_ps_font_info(const Py::Tuple & args); Py::Object get_sfnt_table(const Py::Tuple & args); Py::Object get_image(const Py::Tuple & args); + Py::Object attach_file(const Py::Tuple & args); int setattr( const char *_name, const Py::Object &value ); Py::Object getattr( const char *_name ); FT2Image* image; @@ -163,6 +164,7 @@ static char get_ps_font_info__doc__[]; static char get_sfnt_table__doc__[]; static char get_image__doc__[]; + static char attach_file__doc__[]; }; // the extension module This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ef...@us...> - 2007-09-03 18:27:26
|
Revision: 3769 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3769&view=rev Author: efiring Date: 2007-09-03 11:27:22 -0700 (Mon, 03 Sep 2007) Log Message: ----------- Added example of a standalone colorbar. Added Paths: ----------- trunk/matplotlib/examples/colorbar_only.py Added: trunk/matplotlib/examples/colorbar_only.py =================================================================== --- trunk/matplotlib/examples/colorbar_only.py (rev 0) +++ trunk/matplotlib/examples/colorbar_only.py 2007-09-03 18:27:22 UTC (rev 3769) @@ -0,0 +1,28 @@ +''' +Make a colorbar as a separate figure. +''' + +import pylab +import matplotlib as mpl + +# Make a figure and axes with dimensions as desired. +fig = pylab.figure(figsize=(8,1.5)) +ax = fig.add_axes([0.05, 0.4, 0.9, 0.5]) + +# Set the colormap and norm to correspond to the data for which +# the colorbar will be used. +cmap = mpl.cm.cool +norm = mpl.colors.Normalize(vmin=5, vmax=10) + +# ColorbarBase derives from ScalarMappable and puts a colorbar +# in a specified axes, so it has everything needed for a +# standalone colorbar. There are many more kwargs, but the +# following gives a basic continuous colorbar with ticks +# and labels. +cb = mpl.colorbar.ColorbarBase(ax, cmap=cmap, + norm=norm, + orientation='horizontal') +cb.set_label('Some Units') + +pylab.show() + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jo...@us...> - 2007-09-03 16:29:59
|
Revision: 3768 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3768&view=rev Author: jouni Date: 2007-09-03 09:29:08 -0700 (Mon, 03 Sep 2007) Log Message: ----------- Fix buglet in get_text_width_height_descent of backend_agg when text.usetex is in effect. The descent returned is probably not correct, but it should be similar to the one returned by backend_ps. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-09-02 18:49:20 UTC (rev 3767) +++ trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-09-03 16:29:08 UTC (rev 3768) @@ -228,7 +228,8 @@ texmanager = self.get_texmanager() Z = texmanager.get_rgba(s, size, self.dpi.get(), rgb) m,n,tmp = Z.shape - return n,m + # TODO: descent of TeX text (I am imitating backend_ps here -JKS) + return n, m, m if ismath: ox, oy, width, height, descent, fonts, used_characters = \ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jo...@us...> - 2007-09-02 18:49:30
|
Revision: 3767 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3767&view=rev Author: jouni Date: 2007-09-02 11:49:20 -0700 (Sun, 02 Sep 2007) Log Message: ----------- Some refactoring of dviread, plus a reader for psfonts.map format files Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py trunk/matplotlib/lib/matplotlib/dviread.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-08-31 19:35:09 UTC (rev 3766) +++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2007-09-02 18:49:20 UTC (rev 3767) @@ -1288,9 +1288,8 @@ texmanager = self.get_texmanager() fontsize = prop.get_size_in_points() dvifile = texmanager.make_dvi(s, fontsize) - dvi = Dvi(dvifile) - dvi.read() - text, boxes = dvi.output(72) + dvi = Dvi(dvifile, 72) + text, boxes = iter(dvi).next() fontdir = os.path.join(get_data_path(), 'fonts', 'ttf') if angle == 0: # avoid rounding errors in common case Modified: trunk/matplotlib/lib/matplotlib/dviread.py =================================================================== --- trunk/matplotlib/lib/matplotlib/dviread.py 2007-08-31 19:35:09 UTC (rev 3766) +++ trunk/matplotlib/lib/matplotlib/dviread.py 2007-09-02 18:49:20 UTC (rev 3767) @@ -1,40 +1,78 @@ """ -An experimental module for reading single-page dvi files output by -TeX. Several limitations make this not (currently) useful as a -general-purpose dvi preprocessor. The idea is that the file has a -single page with only a single formula or other piece of text. +An experimental module for reading dvi files output by TeX. Several +limitations make this not (currently) useful as a general-purpose dvi +preprocessor. Interface: - dvi = Dvi(filename) - dvi.read() - text, boxes = dvi.output(72) - for x,y,font,glyph in text: - fontname, pointsize = dvi.fontinfo(font) - ... - for x,y,height,width in boxes: - ... + dvi = Dvi(filename, 72) + for text, boxes in dvi: # iterate over pages + text, boxes = dvi.output(72) + for x,y,font,glyph in text: + fontname, pointsize = dvi.fontinfo(font) + ... + for x,y,height,width in boxes: + ... """ -from matplotlib.cbook import Bunch +import matplotlib +import matplotlib.cbook as mpl_cbook import os import struct -dvistate = Bunch(pre=0, outer=1, inpage=2, post_post=3, finale=4) +_dvistate = mpl_cbook.Bunch(pre=0, outer=1, inpage=2, post_post=3, finale=4) class Dvi(object): + """ + A dvi ("device-independent") file, as produced by TeX. + The current implementation only reads the first page and does not + even attempt to verify the postamble. + """ - def __init__(self, filename): - self.filename = filename - self.text = [] # list of (x,y,fontnum,glyphnum) - self.boxes = [] # list of (x,y,width,height) + def __init__(self, filename, dpi): + """ + Initialize the object. This takes the filename as input and + opens the file; actually reading the file happens when + iterating through the pages of the file. + """ + self.file = open(filename, 'rb') + self.dpi = dpi self.fonts = {} + self.state = _dvistate.pre - def output(self, dpi): - """Return lists of text and box objects transformed into a standard - Cartesian coordinate system at the given dpi value. The coordinates - are floating point numbers, but otherwise precision is not lost and - coordinate values are not clipped to integers.""" + def __iter__(self): + """ + Iterate through the pages of the file. + + Returns (text, pages) pairs, where: + text is a list of (x, y, fontnum, glyphnum) tuples + boxes is a list of (x, y, height, width) tuples + + The coordinates are transformed into a standard Cartesian + coordinate system at the dpi value given when initializing. + The coordinates are floating point numbers, but otherwise + precision is not lost and coordinate values are not clipped to + integers. + """ + while True: + have_page = self._read() + if have_page: + yield self.text, self.boxes + else: + break + + def close(self): + """ + Close the underlying file if it is open. + """ + if not self.file.closed: + self.file.close() + + def _output(self): + """ + Output the text and boxes belonging to the most recent page. + text, boxes = dvi._output() + """ t0 = self.text[0] minx, miny, maxx, maxy = t0[0], t0[1], t0[0], t0[1] for x,y,_,_ in self.text + self.boxes: @@ -42,31 +80,43 @@ if y < miny: miny = y if x > maxx: maxx = x if y > maxy: maxy = y - d = dpi / (72.27 * 2**16) # from TeX's "scaled points" to dpi units + d = self.dpi / (72.27 * 2**16) # from TeX's "scaled points" to dpi units text = [ ((x-minx)*d, (maxy-y)*d, f, g) for (x,y,f,g) in self.text ] boxes = [ ((x-minx)*d, (maxy-y)*d, h*d, w*d) for (x,y,h,w) in self.boxes ] return text, boxes def fontinfo(self, f): - """Name and size in (Adobe) points.""" + """ + texname, pointsize = dvi.fontinfo(fontnum) + + Name and size in points (Adobe points, not TeX points). + """ return self.fonts[f].name, self.fonts[f].scale * (72.0 / (72.27 * 2**16)) - def read(self, debug=False): - self.file = open(self.filename, 'rb') - try: - self.state = dvistate.pre - while True: - byte = ord(self.file.read(1)) - if byte == '': - break # eof - self.dispatch(byte) - if debug and self.state == dvistate.inpage: - print self.h, self.v - if byte == 140: break # end of page; we only read a single page for now - finally: - self.file.close() + def _read(self): + """ + Read one page from the file. Return True if successful, + False if there were no more pages. + """ + while True: + byte = ord(self.file.read(1)) + self._dispatch(byte) + if self.state == _dvistate.inpage: + matplotlib.verbose.report( + 'Dvi._read: after %d at %f,%f' % + (byte, self.h, self.v), + 'debug-annoying') + if byte == 140: # end of page + return True + if self.state == _dvistate.post_post: # end of file + self.close() + return False - def arg(self, nbytes, signed=False): + def _arg(self, nbytes, signed=False): + """ + Read and return an integer argument "nbytes" long. + Signedness is determined by the "signed" keyword. + """ str = self.file.read(nbytes) value = ord(str[0]) if signed and value >= 0x80: @@ -75,76 +125,81 @@ value = 0x100*value + ord(str[i]) return value - def dispatch(self, byte): - if 0 <= byte <= 127: self.set_char(byte) - elif byte == 128: self.set_char(self.arg(1)) - elif byte == 129: self.set_char(self.arg(2)) - elif byte == 130: self.set_char(self.arg(3)) - elif byte == 131: self.set_char(self.arg(4, True)) - elif byte == 132: self.set_rule(self.arg(4, True), self.arg(4, True)) - elif byte == 133: self.put_char(self.arg(1)) - elif byte == 134: self.put_char(self.arg(2)) - elif byte == 135: self.put_char(self.arg(3)) - elif byte == 136: self.put_char(self.arg(4, True)) - elif byte == 137: self.put_rule(self.arg(4, True), self.arg(4, True)) - elif byte == 138: self.nop() - elif byte == 139: self.bop(*[self.arg(4, True) for i in range(11)]) - elif byte == 140: self.eop() - elif byte == 141: self.push() - elif byte == 142: self.pop() - elif byte == 143: self.right(self.arg(1, True)) - elif byte == 144: self.right(self.arg(2, True)) - elif byte == 145: self.right(self.arg(3, True)) - elif byte == 146: self.right(self.arg(4, True)) - elif byte == 147: self.right_w(None) - elif byte == 148: self.right_w(self.arg(1, True)) - elif byte == 149: self.right_w(self.arg(2, True)) - elif byte == 150: self.right_w(self.arg(3, True)) - elif byte == 151: self.right_w(self.arg(4, True)) - elif byte == 152: self.right_x(None) - elif byte == 153: self.right_x(self.arg(1, True)) - elif byte == 154: self.right_x(self.arg(2, True)) - elif byte == 155: self.right_x(self.arg(3, True)) - elif byte == 156: self.right_x(self.arg(4, True)) - elif byte == 157: self.down(self.arg(1, True)) - elif byte == 158: self.down(self.arg(2, True)) - elif byte == 159: self.down(self.arg(3, True)) - elif byte == 160: self.down(self.arg(4, True)) - elif byte == 161: self.down_y(None) - elif byte == 162: self.down_y(self.arg(1, True)) - elif byte == 163: self.down_y(self.arg(2, True)) - elif byte == 164: self.down_y(self.arg(3, True)) - elif byte == 165: self.down_y(self.arg(4, True)) - elif byte == 166: self.down_z(None) - elif byte == 167: self.down_z(self.arg(1, True)) - elif byte == 168: self.down_z(self.arg(2, True)) - elif byte == 169: self.down_z(self.arg(3, True)) - elif byte == 170: self.down_z(self.arg(4, True)) - elif 171 <= byte <= 234: self.fnt_num(byte-171) - elif byte == 235: self.fnt_num(self.arg(1)) - elif byte == 236: self.fnt_num(self.arg(2)) - elif byte == 237: self.fnt_num(self.arg(3)) - elif byte == 238: self.fnt_num(self.arg(4, True)) + def _dispatch(self, byte): + """ + Based on the opcode "byte", read the correct kinds of + arguments from the dvi file and call the method implementing + that opcode with those arguments. + """ + if 0 <= byte <= 127: self._set_char(byte) + elif byte == 128: self._set_char(self._arg(1)) + elif byte == 129: self._set_char(self._arg(2)) + elif byte == 130: self._set_char(self._arg(3)) + elif byte == 131: self._set_char(self._arg(4, True)) + elif byte == 132: self._set_rule(self._arg(4, True), self._arg(4, True)) + elif byte == 133: self._put_char(self._arg(1)) + elif byte == 134: self._put_char(self._arg(2)) + elif byte == 135: self._put_char(self._arg(3)) + elif byte == 136: self._put_char(self._arg(4, True)) + elif byte == 137: self._put_rule(self._arg(4, True), self._arg(4, True)) + elif byte == 138: self._nop() + elif byte == 139: self._bop(*[self._arg(4, True) for i in range(11)]) + elif byte == 140: self._eop() + elif byte == 141: self._push() + elif byte == 142: self._pop() + elif byte == 143: self._right(self._arg(1, True)) + elif byte == 144: self._right(self._arg(2, True)) + elif byte == 145: self._right(self._arg(3, True)) + elif byte == 146: self._right(self._arg(4, True)) + elif byte == 147: self._right_w(None) + elif byte == 148: self._right_w(self._arg(1, True)) + elif byte == 149: self._right_w(self._arg(2, True)) + elif byte == 150: self._right_w(self._arg(3, True)) + elif byte == 151: self._right_w(self._arg(4, True)) + elif byte == 152: self._right_x(None) + elif byte == 153: self._right_x(self._arg(1, True)) + elif byte == 154: self._right_x(self._arg(2, True)) + elif byte == 155: self._right_x(self._arg(3, True)) + elif byte == 156: self._right_x(self._arg(4, True)) + elif byte == 157: self._down(self._arg(1, True)) + elif byte == 158: self._down(self._arg(2, True)) + elif byte == 159: self._down(self._arg(3, True)) + elif byte == 160: self._down(self._arg(4, True)) + elif byte == 161: self._down_y(None) + elif byte == 162: self._down_y(self._arg(1, True)) + elif byte == 163: self._down_y(self._arg(2, True)) + elif byte == 164: self._down_y(self._arg(3, True)) + elif byte == 165: self._down_y(self._arg(4, True)) + elif byte == 166: self._down_z(None) + elif byte == 167: self._down_z(self._arg(1, True)) + elif byte == 168: self._down_z(self._arg(2, True)) + elif byte == 169: self._down_z(self._arg(3, True)) + elif byte == 170: self._down_z(self._arg(4, True)) + elif 171 <= byte <= 234: self._fnt_num(byte-171) + elif byte == 235: self._fnt_num(self._arg(1)) + elif byte == 236: self._fnt_num(self._arg(2)) + elif byte == 237: self._fnt_num(self._arg(3)) + elif byte == 238: self._fnt_num(self._arg(4, True)) elif 239 <= byte <= 242: - len = self.arg(byte-238) + len = self._arg(byte-238) special = self.file.read(len) - self.xxx(special) + self._xxx(special) elif 243 <= byte <= 246: - k = self.arg(byte-242, byte==246) - c, s, d, a, l = [ self.arg(x) for x in (4, 4, 4, 1, 1) ] + k = self._arg(byte-242, byte==246) + c, s, d, a, l = [ self._arg(x) for x in (4, 4, 4, 1, 1) ] n = self.file.read(a+l) - self.fnt_def(k, c, s, d, a, l, n) + self._fnt_def(k, c, s, d, a, l, n) elif byte == 247: - i, num, den, mag, k = [ self.arg(x) for x in (1, 4, 4, 4, 1) ] + i, num, den, mag, k = [ self._arg(x) for x in (1, 4, 4, 4, 1) ] x = self.file.read(k) - self.pre(i, num, den, mag, x) - elif byte == 248: self.post() - elif byte == 249: self.post_post() + self._pre(i, num, den, mag, x) + elif byte == 248: self._post() + elif byte == 249: self._post_post() else: raise ValueError, "unknown command: byte %d"%byte - def pre(self, i, num, den, mag, comment): - if self.state != dvistate.pre: + def _pre(self, i, num, den, mag, comment): + if self.state != _dvistate.pre: raise ValueError, "pre command in middle of dvi file" if i != 2: raise ValueError, "Unknown dvi format %d"%i @@ -159,111 +214,116 @@ raise ValueError, "nonstandard magnification in dvi file" # meaning: LaTeX seems to frown on setting \mag, so # I think we can assume this is constant - self.state = dvistate.outer + self.state = _dvistate.outer - def set_char(self, char): - if self.state != dvistate.inpage: + def _set_char(self, char): + if self.state != _dvistate.inpage: raise ValueError, "misplaced set_char in dvi file" - self.put_char(char) + self._put_char(char) font = self.fonts[self.f] width = font.tfm.width[char] width = (width * font.scale) >> 20 self.h += width - def set_rule(self, a, b): - if self.state != dvistate.inpage: + def _set_rule(self, a, b): + if self.state != _dvistate.inpage: raise ValueError, "misplaced set_rule in dvi file" - self.put_rule(a, b) + self._put_rule(a, b) self.h += b - def put_char(self, char): - if self.state != dvistate.inpage: + def _put_char(self, char): + if self.state != _dvistate.inpage: raise ValueError, "misplaced put_char in dvi file" self.text.append((self.h, self.v, self.f, char)) - def put_rule(self, a, b): - if self.state != dvistate.inpage: + def _put_rule(self, a, b): + if self.state != _dvistate.inpage: raise ValueError, "misplaced put_rule in dvi file" if a > 0 and b > 0: self.boxes.append((self.h, self.v, a, b)) - def nop(self): + def _nop(self): pass - def bop(self, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, p): - if self.state != dvistate.outer: + def _bop(self, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, p): + if self.state != _dvistate.outer: + print '+++', self.state raise ValueError, "misplaced bop in dvi file" - self.state = dvistate.inpage + self.state = _dvistate.inpage self.h, self.v, self.w, self.x, self.y, self.z = 0, 0, 0, 0, 0, 0 self.stack = [] + self.text = [] # list of (x,y,fontnum,glyphnum) + self.boxes = [] # list of (x,y,width,height) - def eop(self): - if self.state != dvistate.inpage: + def _eop(self): + if self.state != _dvistate.inpage: raise ValueError, "misplaced eop in dvi file" - self.state = dvistate.outer + self.state = _dvistate.outer del self.h, self.v, self.w, self.x, self.y, self.z, self.stack - def push(self): - if self.state != dvistate.inpage: + def _push(self): + if self.state != _dvistate.inpage: raise ValueError, "misplaced push in dvi file" self.stack.append((self.h, self.v, self.w, self.x, self.y, self.z)) - def pop(self): - if self.state != dvistate.inpage: + def _pop(self): + if self.state != _dvistate.inpage: raise ValueError, "misplaced pop in dvi file" self.h, self.v, self.w, self.x, self.y, self.z = self.stack.pop() - def right(self, b): - if self.state != dvistate.inpage: + def _right(self, b): + if self.state != _dvistate.inpage: raise ValueError, "misplaced right in dvi file" self.h += b - def right_w(self, new_w): - if self.state != dvistate.inpage: + def _right_w(self, new_w): + if self.state != _dvistate.inpage: raise ValueError, "misplaced w in dvi file" if new_w is not None: self.w = new_w self.h += self.w - def right_x(self, new_x): - if self.state != dvistate.inpage: + def _right_x(self, new_x): + if self.state != _dvistate.inpage: raise ValueError, "misplaced x in dvi file" if new_x is not None: self.x = new_x self.h += self.x - def down(self, a): - if self.state != dvistate.inpage: + def _down(self, a): + if self.state != _dvistate.inpage: raise ValueError, "misplaced down in dvi file" self.v += a - def down_y(self, new_y): - if self.state != dvistate.inpage: + def _down_y(self, new_y): + if self.state != _dvistate.inpage: raise ValueError, "misplaced y in dvi file" if new_y is not None: self.y = new_y self.v += self.y - def down_z(self, new_z): - if self.state != dvistate.inpage: + def _down_z(self, new_z): + if self.state != _dvistate.inpage: raise ValueError, "misplaced z in dvi file" if new_z is not None: self.z = new_z self.v += self.z - def fnt_num(self, k): - if self.state != dvistate.inpage: + def _fnt_num(self, k): + if self.state != _dvistate.inpage: raise ValueError, "misplaced fnt_num in dvi file" self.f = k - def xxx(self, special): - pass + def _xxx(self, special): + matplotlib.verbose.report( + 'Dvi._xxx: encountered special: %s' + % ''.join((32 <= ord(ch) < 127) and ch + or '<%02x>' % ord(ch) + for ch in special), + 'debug') - def fnt_def(self, k, c, s, d, a, l, n): - filename = n[-l:] + '.tfm' - pipe = os.popen('kpsewhich ' + filename, 'r') - filename = pipe.readline().rstrip() - pipe.close() + def _fnt_def(self, k, c, s, d, a, l, n): + filename = find_tex_file(n[-l:] + '.tfm') tfm = Tfm(filename) if c != 0 and tfm.checksum != 0 and c != tfm.checksum: raise ValueError, 'tfm checksum mismatch: %s'%n @@ -271,41 +331,186 @@ #if d != tfm.design_size: # raise ValueError, 'tfm design size mismatch: %d in dvi, %d in %s'%\ # (d, tfm.design_size, n) - self.fonts[k] = Bunch(scale=s, tfm=tfm, name=n) + self.fonts[k] = mpl_cbook.Bunch(scale=s, tfm=tfm, name=n) - def post(self): - raise NotImplementedError + def _post(self): + if self.state != _dvistate.outer: + raise ValueError, "misplaced post in dvi file" + self.state = _dvistate.post_post + # TODO: actually read the postamble and finale? + # currently post_post just triggers closing the file - def post_post(self): + def _post_post(self): raise NotImplementedError class Tfm(object): + """ + A TeX Font Metric file. This implementation covers only the bare + minimum needed by the Dvi class. + Attributes: + checksum: for verifying against dvi file + design_size: design size of the font (in what units?) + width[i]: width of character #i, needs to be scaled + by the factor specified in the dvi file + (this is a dict because indexing may not start from 0) + """ + def __init__(self, filename): file = open(filename, 'rb') - header1 = file.read(24) - lh, bc, ec, nw = \ - struct.unpack('!4H', header1[2:10]) - header2 = file.read(4*lh) - self.checksum, self.design_size = \ - struct.unpack('!2I', header2[:8]) - # plus encoding information etc. + try: + header1 = file.read(24) + lh, bc, ec, nw = \ + struct.unpack('!4H', header1[2:10]) + header2 = file.read(4*lh) + self.checksum, self.design_size = \ + struct.unpack('!2I', header2[:8]) + # there is also encoding information etc. + char_info = file.read(4*(ec-bc+1)) + widths = file.read(4*nw) + finally: + file.close() - char_info = file.read(4*(ec-bc+1)) - widths = file.read(4*nw) - - file.close() - widths = struct.unpack('!%dI' % nw, widths) self.width = {} for i in range(ec-bc): self.width[bc+i] = widths[ord(char_info[4*i])] +class PsfontsMap(object): + """ + A psfonts.map formatted file, mapping TeX fonts to PS fonts. + Usage: map = PsfontsMap('.../psfonts.map'); map['cmr10'] + + For historical reasons, TeX knows many Type-1 fonts by different + names than the outside world. (For one thing, the names have to + fit in eight characters.) Also, TeX's native fonts are not Type-1 + but Metafont, which is nontrivial to convert to PostScript except + as a bitmap. While high-quality conversions to Type-1 format exist + and are shipped with modern TeX distributions, we need to know + which Type-1 fonts are the counterparts of which native fonts. For + these reasons a mapping is needed from internal font names to font + file names. + + A texmf tree typically includes mapping files called e.g. + psfonts.map, pdftex.map, dvipdfm.map. psfonts.map is used by + dvips, pdftex.map by pdfTeX, and dvipdfm.map by dvipdfm. + psfonts.map might avoid embedding the 35 PostScript fonts, while + the pdf-related files perhaps only avoid the "Base 14" pdf fonts. + But the user may have configured these files differently. + """ + + def __init__(self, filename): + self._font = {} + file = open(filename, 'rt') + try: + self._parse(file) + finally: + file.close() + + def __getitem__(self, texname): + result = self._font[texname] + if result.filename is not None \ + and not result.filename.startswith('/'): + result.filename = find_tex_file(result.filename) + if result.encoding is not None \ + and not result.encoding.startswith('/'): + result.encoding = find_tex_file(result.encoding) + return result + + def _parse(self, file): + """Parse each line into words.""" + for line in file: + line = line.strip() + if line == '' or line.startswith('%'): + continue + words, pos = [], 0 + while pos < len(line): + if line[pos] == '"': # double quoted word + pos += 1 + end = line.index('"', pos) + words.append(line[pos:end]) + pos = end + 1 + else: # ordinary word + end = line.find(' ', pos+1) + if end == -1: end = len(line) + words.append(line[pos:end]) + pos = end + while pos < len(line) and line[pos] == ' ': + pos += 1 + self._register(words) + + def _register(self, words): + """Register a font described by "words". + + The format is, AFAIK: texname fontname [effects and filenames] + Effects are PostScript snippets like ".177 SlantFont", + filenames begin with one or two less-than signs. A filename + ending in enc is an encoding file, other filenames are font + files. This can be overridden with a left bracket: <[foobar + indicates an encoding file named foobar. + + There is some difference between <foo.pfb and <<bar.pfb in + subsetting, but I have no example of << in my TeX installation. + """ + texname, psname = words[:2] + effects, encoding, filename = [], None, None + for word in words[2:]: + if not word.startswith('<'): + effects.append(word) + else: + word = word.lstrip('<') + if word.startswith('['): + assert encoding is None + encoding = word[1:] + elif word.endswith('.enc'): + assert encoding is None + encoding = word + else: + assert filename is None + filename = word + self._font[texname] = mpl_cbook.Bunch( + texname=texname, psname=psname, effects=effects, + encoding=encoding, filename=filename) + +def find_tex_file(filename, format=None): + """ + Call kpsewhich to find a file in the texmf tree. + If format is not None, it is used as the value for the --format option. + See the kpathsea documentation for more information. + + Apparently most existing TeX distributions on Unix-like systems + use kpathsea. I hear MikTeX (a popular distribution on Windows) + doesn't use kpathsea, so what do we do? (TODO) + """ + + cmd = 'kpsewhich ' + if format is not None: + assert "'" not in format + cmd += "--format='" + format + "' " + assert "'" not in filename + cmd += "'" + filename + "'" + + pipe = os.popen(cmd, 'r') + result = pipe.readline().rstrip() + pipe.close() + + return result + if __name__ == '__main__': - dvi = Dvi('foo.dvi') - dvi.read(debug=True) - for x,y,f,c in dvi.text: - print x,y,c,chr(c),dvi.fonts[f].__dict__ - print dvi.output(72) + matplotlib.verbose.set_level('debug') + dvi = Dvi('foo.dvi', 72) + fontmap = PsfontsMap(find_tex_file('pdftex.map')) + for text,boxes in dvi: + print '=== new page ===' + fPrev = None + for x,y,f,c in text: + texname = dvi.fonts[f].name + print x,y,c,chr(c),texname + if f != fPrev: + print 'font', texname, '=', fontmap[texname].__dict__ + fPrev = f + for x,y,w,h in boxes: + print x,y,'BOX',w,h + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-31 19:35:12
|
Revision: 3766 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3766&view=rev Author: mdboom Date: 2007-08-31 12:35:09 -0700 (Fri, 31 Aug 2007) Log Message: ----------- Fix log expression. Modified Paths: -------------- trunk/matplotlib/examples/mathtext_wx.py Modified: trunk/matplotlib/examples/mathtext_wx.py =================================================================== --- trunk/matplotlib/examples/mathtext_wx.py 2007-08-31 19:25:34 UTC (rev 3765) +++ trunk/matplotlib/examples/mathtext_wx.py 2007-08-31 19:35:09 UTC (rev 3766) @@ -31,7 +31,7 @@ (r'$\sin(2 \pi x)$' , lambda x: sin(2*pi*x)), (r'$\frac{4}{3}\pi x^3$' , lambda x: (4.0 / 3.0) * pi * x**3), (r'$\cos(2 \pi x)$' , lambda x: cos(2*pi*x)), - (r'$\log x$' , lambda x: log(x)) + (r'$\log(x)$' , lambda x: log(x)) ] class CanvasFrame(wx.Frame): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-31 19:25:36
|
Revision: 3765 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3765&view=rev Author: mdboom Date: 2007-08-31 12:25:34 -0700 (Fri, 31 Aug 2007) Log Message: ----------- Render all the fonts in each mathtext expression to a single image buffer (memory and time savings). Add support for getting raw image data for mathtext expressions. Add mathtext_wx.py example showing how to put mathtext expressions into controls. Added Paths: ----------- trunk/matplotlib/examples/mathtext_wx.py Added: trunk/matplotlib/examples/mathtext_wx.py =================================================================== --- trunk/matplotlib/examples/mathtext_wx.py (rev 0) +++ trunk/matplotlib/examples/mathtext_wx.py 2007-08-31 19:25:34 UTC (rev 3765) @@ -0,0 +1,124 @@ +""" +Demonstrates how to convert mathtext to a wx.Bitmap for display in various +controls on wxPython. +""" + +import matplotlib +matplotlib.use("WxAgg") +from matplotlib.numerix import arange, sin, pi, cos, log +from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas +from matplotlib.backends.backend_wx import NavigationToolbar2Wx +from matplotlib.figure import Figure + +import wx + +IS_GTK = 'wxGTK' in wx.PlatformInfo +IS_WIN = 'wxMSW' in wx.PlatformInfo +IS_MAC = 'wxMac' in wx.PlatformInfo + +############################################################ +# This is where the "magic" happens. +from matplotlib.mathtext import MathTextParser +mathtext_parser = MathTextParser("Bitmap") +def mathtext_to_wxbitmap(s): + ftimage = mathtext_parser.parse(s, 150) + return wx.BitmapFromBufferRGBA( + ftimage.get_width(), ftimage.get_height(), + ftimage.as_rgba_str()) +############################################################ + +functions = [ + (r'$\sin(2 \pi x)$' , lambda x: sin(2*pi*x)), + (r'$\frac{4}{3}\pi x^3$' , lambda x: (4.0 / 3.0) * pi * x**3), + (r'$\cos(2 \pi x)$' , lambda x: cos(2*pi*x)), + (r'$\log x$' , lambda x: log(x)) +] + +class CanvasFrame(wx.Frame): + def __init__(self, parent, title): + wx.Frame.__init__(self, parent, -1, title, size=(550, 350)) + self.SetBackgroundColour(wx.NamedColor("WHITE")) + + self.figure = Figure() + self.axes = self.figure.add_subplot(111) + self.change_plot(0) + + self.canvas = FigureCanvas(self, -1, self.figure) + + self.sizer = wx.BoxSizer(wx.VERTICAL) + self.add_buttonbar() + self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) + self.add_toolbar() # comment this out for no toolbar + + menuBar = wx.MenuBar() + + # File Menu + menu = wx.Menu() + menu.Append(wx.ID_EXIT, "E&xit\tAlt-X", "Exit this simple sample") + menuBar.Append(menu, "&File") + + if IS_GTK or IS_WIN: + # Equation Menu + menu = wx.Menu() + for i, (mt, func) in enumerate(functions): + bm = mathtext_to_wxbitmap(mt) + item = wx.MenuItem(menu, 1000 + i, "") + item.SetBitmap(bm) + menu.AppendItem(item) + self.Bind(wx.EVT_MENU, self.OnChangePlot, item) + menuBar.Append(menu, "&Functions") + + self.SetMenuBar(menuBar) + + self.SetSizer(self.sizer) + self.Fit() + + def add_buttonbar(self): + self.button_bar = wx.Panel(self) + self.button_bar_sizer = wx.BoxSizer(wx.HORIZONTAL) + self.sizer.Add(self.button_bar, 0, wx.LEFT | wx.TOP | wx.GROW) + + for i, (mt, func) in enumerate(functions): + bm = mathtext_to_wxbitmap(mt) + button = wx.BitmapButton(self.button_bar, 1000 + i, bm) + self.button_bar_sizer.Add(button, 1, wx.GROW) + self.Bind(wx.EVT_BUTTON, self.OnChangePlot, button) + + self.button_bar.SetSizer(self.button_bar_sizer) + + def add_toolbar(self): + """Copied verbatim from embedding_wx2.py""" + self.toolbar = NavigationToolbar2Wx(self.canvas) + self.toolbar.Realize() + if IS_MAC: + self.SetToolBar(self.toolbar) + else: + tw, th = self.toolbar.GetSizeTuple() + fw, fh = self.canvas.GetSizeTuple() + self.toolbar.SetSize(wx.Size(fw, th)) + self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND) + self.toolbar.update() + + def OnPaint(self, event): + self.canvas.draw() + + def OnChangePlot(self, event): + self.change_plot(event.GetId() - 1000) + + def change_plot(self, plot_number): + t = arange(1.0,3.0,0.01) + s = functions[plot_number][1](t) + self.axes.clear() + self.axes.plot(t, s) + self.Refresh() + +class MyApp(wx.App): + def OnInit(self): + frame = CanvasFrame(None, "wxPython mathtext demo app") + self.SetTopWindow(frame) + frame.Show(True) + return True + +app = MyApp() +app.MainLoop() + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <md...@us...> - 2007-08-31 19:25:20
|
Revision: 3764 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3764&view=rev Author: mdboom Date: 2007-08-31 12:25:17 -0700 (Fri, 31 Aug 2007) Log Message: ----------- Render all the fonts in each mathtext expression to a single image buffer (memory and time savings). Add support for getting raw image data for mathtext expressions. Add mathtext_wx.py example showing how to put mathtext expressions into controls. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py trunk/matplotlib/lib/matplotlib/backends/backend_gdk.py trunk/matplotlib/lib/matplotlib/mathtext.py trunk/matplotlib/src/_backend_agg.cpp trunk/matplotlib/src/_backend_agg.h trunk/matplotlib/src/ft2font.cpp trunk/matplotlib/src/ft2font.h trunk/matplotlib/unit/agg_memleak.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-08-31 17:23:32 UTC (rev 3763) +++ trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-08-31 19:25:17 UTC (rev 3764) @@ -172,7 +172,7 @@ """ if __debug__: verbose.report('RendererAgg.draw_mathtext', 'debug-annoying') - ox, oy, width, height, descent, fonts, used_characters = \ + ox, oy, width, height, descent, font_image, used_characters = \ self.mathtext_parser.parse(s, self.dpi.get(), prop) if angle == 90: @@ -180,13 +180,11 @@ ox, oy = oy, ox x = int(x) - width + ox y = int(y) - height + oy + font_image.rotate() else: x = int(x) + ox y = int(y) - height + oy - for font in fonts: - if angle == 90: - font.horiz_image_to_vert_image() # <-- Rotate - self._renderer.draw_text( font, x, y + 1, gc) + self._renderer.draw_text_image(font_image, x, y + 1, gc) if 0: self._renderer.draw_rectangle(gc, None, int(x), @@ -212,7 +210,7 @@ #print x, y, int(x), int(y) - self._renderer.draw_text(font, int(x), int(y) + 1, gc) + self._renderer.draw_text_image(font.get_image(), int(x), int(y) + 1, gc) def get_text_width_height_descent(self, s, prop, ismath, rgb=(0,0,0)): Modified: trunk/matplotlib/lib/matplotlib/backends/backend_gdk.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_gdk.py 2007-08-31 17:23:32 UTC (rev 3763) +++ trunk/matplotlib/lib/matplotlib/backends/backend_gdk.py 2007-08-31 19:25:17 UTC (rev 3764) @@ -215,7 +215,7 @@ for i, font in enumerate(fonts): if angle == 90: - font.horiz_image_to_vert_image() # <-- Rotate + font.get_image().rotate() # <-- Rotate imw, imh, image_str = font.image_as_str() Xall[:,i] = npy.fromstring(image_str, npy.uint8) Modified: trunk/matplotlib/lib/matplotlib/mathtext.py =================================================================== --- trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-31 17:23:32 UTC (rev 3763) +++ trunk/matplotlib/lib/matplotlib/mathtext.py 2007-08-31 19:25:17 UTC (rev 3764) @@ -143,7 +143,7 @@ from matplotlib.afm import AFM from matplotlib.cbook import enumerate, iterable, Bunch, get_realpath_and_stat, \ is_string_like -from matplotlib.ft2font import FT2Font, KERNING_DEFAULT, LOAD_DEFAULT, LOAD_NO_HINTING +from matplotlib.ft2font import FT2Font, FT2Image, KERNING_DEFAULT, LOAD_DEFAULT, LOAD_NO_HINTING from matplotlib.font_manager import findfont, FontProperties from matplotlib._mathtext_data import latex_to_bakoma, \ latex_to_standard, tex2uni, type12uni, tex2type1, uni2type1 @@ -288,20 +288,19 @@ def __init__(self): self.ox = 0 self.oy = 0 + self.image = None MathtextBackend.__init__(self) def set_canvas_size(self, w, h, d): MathtextBackend.set_canvas_size(self, w, h, d) - for font in self.fonts_object.get_fonts(): - font.set_bitmap_size(int(w), int(h) + int(d)) + self.image = FT2Image(ceil(w), ceil(h + d)) def render_glyph(self, ox, oy, info): info.font.draw_glyph_to_bitmap( - ox, oy - info.metrics.ymax, info.glyph) + self.image, ox, oy - info.metrics.ymax, info.glyph) def render_rect_filled(self, x1, y1, x2, y2): - font = self.fonts_object.get_fonts()[0] - font.draw_rect_filled(x1, y1, x2, max(y2 - 1, y1)) + self.image.draw_rect_filled(x1, y1, x2, max(y2 - 1, y1)) def get_results(self, box): return (self.ox, @@ -309,7 +308,7 @@ self.width, self.height + self.depth, self.depth, - self.fonts_object.get_fonts(), + self.image, self.fonts_object.get_used_characters()) def get_hinting_type(self): @@ -318,6 +317,13 @@ def MathtextBackendAgg(): return MathtextBackendBbox(MathtextBackendAggRender()) +class MathtextBackendBitmapRender(MathtextBackendAggRender): + def get_results(self, box): + return self.image + +def MathtextBackendBitmap(): + return MathtextBackendBbox(MathtextBackendBitmapRender()) + class MathtextBackendPs(MathtextBackend): def __init__(self): self.pswriter = StringIO() @@ -2443,6 +2449,7 @@ _parser = None _backend_mapping = { + 'Bitmap': MathtextBackendBitmap, 'Agg' : MathtextBackendAgg, 'PS' : MathtextBackendPs, 'Pdf' : MathtextBackendPdf, @@ -2454,7 +2461,10 @@ self._output = output self._cache = {} - def parse(self, s, dpi, prop): + def parse(self, s, dpi = 72, prop = None): + if prop is None: + prop = FontProperties() + cacheKey = (s, dpi, hash(prop)) result = self._cache.get(cacheKey) if result is not None: Modified: trunk/matplotlib/src/_backend_agg.cpp =================================================================== --- trunk/matplotlib/src/_backend_agg.cpp 2007-08-31 17:23:32 UTC (rev 3763) +++ trunk/matplotlib/src/_backend_agg.cpp 2007-08-31 19:25:17 UTC (rev 3764) @@ -2106,14 +2106,15 @@ Py::Object -RendererAgg::draw_text(const Py::Tuple& args) { +RendererAgg::draw_text_image(const Py::Tuple& args) { _VERBOSE("RendererAgg::draw_text"); args.verify_length(4); + FT2Image *image = static_cast<FT2Image*>(args[0].ptr()); + if (!image->get_buffer()) + return Py::Object(); - FT2Font *font = static_cast<FT2Font*>(args[0].ptr()); - int x(0),y(0); try { x = Py::Int( args[1] ); @@ -2151,15 +2152,16 @@ t = b+h; } + const unsigned char* const buffer = image->get_buffer(); - for (size_t i=0; i<font->image.width; i++) { - for (size_t j=0; j<font->image.height; j++) { - thisx = i+x+font->image.offsetx; - thisy = j+y+font->image.offsety; + for (size_t i=0; i< image->get_width(); i++) { + for (size_t j=0; j< image->get_height(); j++) { + thisx = i+x+image->offsetx; + thisy = j+y+image->offsety; if (thisx<l || thisx>=r) continue; if (thisy<height-t || thisy>=height-b) continue; pixFmt->blend_pixel - (thisx, thisy, p, font->image.buffer[i + j*font->image.width]); + (thisx, thisy, p, buffer[i + j*image->get_width()]); } } @@ -2568,8 +2570,8 @@ "draw_markers(gc, path, x, y)\n"); add_varargs_method("draw_path", &RendererAgg::draw_path, "draw_path(gc, rgbFace, path, transform)\n"); - add_varargs_method("draw_text", &RendererAgg::draw_text, - "draw_text(font, x, y, r, g, b, a)\n"); + add_varargs_method("draw_text_image", &RendererAgg::draw_text_image, + "draw_text_image(font_image, x, y, r, g, b, a)\n"); add_varargs_method("draw_image", &RendererAgg::draw_image, "draw_image(x, y, im)"); add_varargs_method("write_rgba", &RendererAgg::write_rgba, Modified: trunk/matplotlib/src/_backend_agg.h =================================================================== --- trunk/matplotlib/src/_backend_agg.h 2007-08-31 17:23:32 UTC (rev 3763) +++ trunk/matplotlib/src/_backend_agg.h 2007-08-31 19:25:17 UTC (rev 3764) @@ -166,7 +166,7 @@ //Py::Object _draw_markers_nocache(const Py::Tuple & args); //Py::Object _draw_markers_cache(const Py::Tuple & args); Py::Object draw_markers(const Py::Tuple & args); - Py::Object draw_text(const Py::Tuple & args); + Py::Object draw_text_image(const Py::Tuple & args); Py::Object draw_image(const Py::Tuple & args); Py::Object write_rgba(const Py::Tuple & args); Modified: trunk/matplotlib/src/ft2font.cpp =================================================================== --- trunk/matplotlib/src/ft2font.cpp 2007-08-31 17:23:32 UTC (rev 3763) +++ trunk/matplotlib/src/ft2font.cpp 2007-08-31 19:25:17 UTC (rev 3764) @@ -42,9 +42,414 @@ FT_Library _ft2Library; -FT2Image::FT2Image() : bRotated(false), buffer(NULL) {} -FT2Image::~FT2Image() {delete [] buffer; buffer=NULL;} +FT2Image::FT2Image() : + offsetx(0), offsety(0), + _bRotated(false), + _isDirty(true), + _buffer(NULL), + _width(0), _height(0), + _rgbCopy(NULL), + _rgbaCopy(NULL) { + _VERBOSE("FT2Image::FT2Image"); +} +FT2Image::FT2Image(unsigned long width, unsigned long height) : + offsetx(0), offsety(0), + _bRotated(false), + _isDirty(true), + _buffer(NULL), + _width(0), _height(0), + _rgbCopy(NULL), + _rgbaCopy(NULL) { + _VERBOSE("FT2Image::FT2Image"); + resize(width, height); +} + +FT2Image::~FT2Image() { + _VERBOSE("FT2Image::~FT2Image"); + delete [] _buffer; + _buffer=NULL; +} + +void FT2Image::resize(unsigned long width, unsigned long height) { + size_t numBytes = width*height; + + if (_width != width || _height != height) { + _width = width; + _height = height; + + delete [] _buffer; + _buffer = new unsigned char [numBytes]; + } + + for (size_t n=0; n<numBytes; n++) + _buffer[n] = 0; + + _bRotated = false; + _isDirty = true; +} + +char FT2Image::resize__doc__[] = +"resize(width, height)\n" +"\n" +"Resize the dimensions of the image (it is cleared in the process).\n" +; +Py::Object +FT2Image::py_resize(const Py::Tuple & args) { + _VERBOSE("FT2Image::resize"); + + args.verify_length(2); + + long x0 = Py::Int(args[0]); + long y0 = Py::Int(args[1]); + + resize(x0, y0); + + return Py::Object(); +} + +void FT2Image::clear() { + _VERBOSE("FT2Image::clear"); + + _width = 0; + _height = 0; + offsetx = 0; + offsety = 0; + _isDirty = true; + _bRotated = false; + delete [] _buffer; + _buffer = NULL; + if (_rgbCopy) { + delete _rgbCopy; + _rgbCopy = NULL; + } + if (_rgbaCopy) { + delete _rgbaCopy; + _rgbaCopy = NULL; + } +} +char FT2Image::clear__doc__[] = +"clear()\n" +"\n" +"Clear the contents of the image.\n" +; +Py::Object +FT2Image::py_clear(const Py::Tuple & args) { + args.verify_length(0); + + clear(); + + return Py::Object(); +} + +void FT2Image::rotate() { + // If we have already rotated, just return. + if (_bRotated) + return; + + unsigned long width = _width; + unsigned long height = _height; + + unsigned long newWidth = _height; + unsigned long newHeight = _width; + + unsigned long numBytes = _width * _height; + + unsigned char * buffer = new unsigned char [numBytes]; + + unsigned long i, j, k, offset, nhMinusOne; + + nhMinusOne = newHeight - 1; + + unsigned char * read_it = _buffer; + + for (i=0; i<height; i++) { + offset = i*width; + for (j=0; j<width; j++) { + k = nhMinusOne - j; + buffer[i + k*newWidth] = *(read_it++); + } + } + + delete [] _buffer; + _buffer = buffer; + _width = newWidth; + _height = newHeight; + _bRotated = true; + _isDirty = true; +} +char FT2Image::rotate__doc__[] = +"rotate()\n" +"\n" +"Rotates the image 90 degrees.\n" +; +Py::Object +FT2Image::py_rotate(const Py::Tuple & args) { + _VERBOSE("FT2Image::rotate"); + + args.verify_length(0); + + rotate(); + + return Py::Object(); +} + +void +FT2Image::draw_bitmap( FT_Bitmap* bitmap, + FT_Int x, + FT_Int y) { + _VERBOSE("FT2Image::draw_bitmap"); + FT_Int image_width = (FT_Int)_width; + FT_Int image_height = (FT_Int)_height; + FT_Int char_width = bitmap->width; + FT_Int char_height = bitmap->rows; + + FT_Int x1 = CLAMP(x, 0, image_width); + FT_Int y1 = CLAMP(y, 0, image_height); + FT_Int x2 = CLAMP(x + char_width, 0, image_width); + FT_Int y2 = CLAMP(y + char_height, 0, image_height); + + FT_Int x_start = MAX(0, -x); + FT_Int y_offset = y1 - MAX(0, -y); + + for ( FT_Int i = y1; i < y2; ++i ) { + unsigned char* dst = _buffer + (i * image_width + x1); + unsigned char* src = bitmap->buffer + (((i - y_offset) * bitmap->pitch) + x_start); + for ( FT_Int j = x1; j < x2; ++j, ++dst, ++src ) + *dst |= *src; + } + + _isDirty = true; +} + +void FT2Image::write_bitmap(const char* filename) const { + FILE *fh = fopen(filename, "w"); + + for ( size_t i = 0; i< _height; i++) { + for ( size_t j = 0; j < _width; ++j) { + if (_buffer[j + i*_width]) + fputc('#', fh); + else + fputc(' ', fh); + } + fputc('\n', fh); + } + + fclose(fh); +} + +char FT2Image::write_bitmap__doc__[] = +"write_bitmap(fname)\n" +"\n" +"Write the bitmap to file fname\n" +; +Py::Object +FT2Image::py_write_bitmap(const Py::Tuple & args) { + _VERBOSE("FT2Image::write_bitmap"); + + args.verify_length(1); + + std::string filename = Py::String(args[0]); + + write_bitmap(filename.c_str()); + + return Py::Object(); +} + +void +FT2Image::draw_rect(unsigned long x0, unsigned long y0, + unsigned long x1, unsigned long y1) { + if ( x0<0 || y0<0 || x1<0 || y1<0 || + x0>_width || x1>_width || + y0>_height || y1>_height ) + throw Py::ValueError("Rect coords outside image bounds"); + + size_t top = y0*_width; + size_t bottom = y1*_width; + for (size_t i=x0; i<x1+1; ++i) { + _buffer[i + top] = 255; + _buffer[i + bottom] = 255; + } + + for (size_t j=y0+1; j<y1; ++j) { + _buffer[x0 + j*_width] = 255; + _buffer[x1 + j*_width] = 255; + } + + _isDirty = true; +} + +char FT2Image::draw_rect__doc__[] = +"draw_rect(x0, y0, x1, y1)\n" +"\n" +"Draw a rect to the image.\n" +"\n" +; +Py::Object +FT2Image::py_draw_rect(const Py::Tuple & args) { + _VERBOSE("FT2Image::draw_rect"); + + args.verify_length(4); + + long x0 = Py::Int(args[0]); + long y0 = Py::Int(args[1]); + long x1 = Py::Int(args[2]); + long y1 = Py::Int(args[3]); + + draw_rect(x0, y0, x1, y1); + + return Py::Object(); +} + +void FT2Image::draw_rect_filled(unsigned long x0, unsigned long y0, + unsigned long x1, unsigned long y1) { + x0 = CLAMP(x0, 0, _width); + y0 = CLAMP(y0, 0, _height); + x1 = CLAMP(x1, 0, _width); + y1 = CLAMP(y1, 0, _height); + + for (size_t j=y0; j<y1+1; j++) { + for (size_t i=x0; i<x1+1; i++) { + _buffer[i + j*_width] = 255; + } + } + + _isDirty = true; +} + +char FT2Image::draw_rect_filled__doc__[] = +"draw_rect_filled(x0, y0, x1, y1)\n" +"\n" +"Draw a filled rect to the image.\n" +"\n" +; +Py::Object +FT2Image::py_draw_rect_filled(const Py::Tuple & args) { + _VERBOSE("FT2Image::draw_rect_filled"); + + args.verify_length(4); + + long x0 = Py::Int(args[0]); + long y0 = Py::Int(args[1]); + long x1 = Py::Int(args[2]); + long y1 = Py::Int(args[3]); + + draw_rect_filled(x0, y0, x1, y1); + + return Py::Object(); +} + +char FT2Image::as_str__doc__[] = +"width, height, s = image_as_str()\n" +"\n" +"Return the image buffer as a string\n" +"\n" +; +Py::Object +FT2Image::py_as_str(const Py::Tuple & args) { + _VERBOSE("FT2Image::as_str"); + args.verify_length(0); + + return Py::asObject(PyString_FromStringAndSize((const char *)_buffer, _width*_height)); +} + +void FT2Image::makeRgbCopy() { + if (!_isDirty) + return; + + if (!_rgbCopy) { + _rgbCopy = new FT2Image(_width * 3, _height); + } else { + _rgbCopy->resize(_width * 3, _height); + } + unsigned char *src = _buffer; + unsigned char *src_end = src + (_width * _height); + unsigned char *dst = _rgbCopy->_buffer; + + unsigned char tmp; + while (src != src_end) { + tmp = 255 - *src++; + *dst++ = tmp; + *dst++ = tmp; + *dst++ = tmp; + } +} + +char FT2Image::as_rgb_str__doc__[] = +"width, height, s = image_as_rgb_str()\n" +"\n" +"Return the image buffer as a 24-bit RGB string.\n" +"\n" +; +Py::Object +FT2Image::py_as_rgb_str(const Py::Tuple & args) { + _VERBOSE("FT2Image::as_str_rgb"); + args.verify_length(0); + + makeRgbCopy(); + + return _rgbCopy->py_as_str(args); +} + +void FT2Image::makeRgbaCopy() { + if (!_isDirty) + return; + + if (!_rgbaCopy) { + _rgbaCopy = new FT2Image(_width * 4, _height); + } else { + _rgbaCopy->resize(_width * 4, _height); + } + unsigned char *src = _buffer; + unsigned char *src_end = src + (_width * _height); + unsigned char *dst = _rgbaCopy->_buffer; + + // This pre-multiplies the alpha, which apparently shouldn't + // be necessary for wxGTK, but it sure as heck seems to be. + unsigned int c; + unsigned int tmp; + while (src != src_end) { + c = *src++; + tmp = ((255 - c) * c) >> 8; + *dst++ = tmp; + *dst++ = tmp; + *dst++ = tmp; + *dst++ = c; + } +} + +char FT2Image::as_rgba_str__doc__[] = +"width, height, s = image_as_rgb_str()\n" +"\n" +"Return the image buffer as a 32-bit RGBA string.\n" +"\n" +; +Py::Object +FT2Image::py_as_rgba_str(const Py::Tuple & args) { + _VERBOSE("FT2Image::as_str_rgba"); + args.verify_length(0); + + makeRgbaCopy(); + + return _rgbaCopy->py_as_str(args); +} + +Py::Object +FT2Image::py_get_width(const Py::Tuple & args) { + _VERBOSE("FT2Image::get_width"); + args.verify_length(0); + + return Py::Int((long)get_width()); +} + +Py::Object +FT2Image::py_get_height(const Py::Tuple & args) { + _VERBOSE("FT2Image::get_height"); + args.verify_length(0); + + return Py::Int((long)get_height()); +} + Glyph::Glyph( const FT_Face& face, const FT_Glyph& glyph, size_t ind) : glyphInd(ind) { _VERBOSE("Glyph::Glyph"); @@ -105,7 +510,6 @@ //get the glyph as a path, a list of (COMMAND, *args) as desribed in matplotlib.path // this code is from agg's decompose_ft_outline with minor modifications - enum {MOVETO, LINETO, CURVE3, CURVE4, ENDPOLY}; FT_Outline& outline = face->glyph->outline; Py::List path; @@ -345,12 +749,12 @@ } -FT2Font::FT2Font(std::string facefile) +FT2Font::FT2Font(std::string facefile) : + image(NULL) { _VERBOSE(Printf("FT2Font::FT2Font %s", facefile.c_str()).str()); clear(Py::Tuple(0)); - int error = FT_New_Face( _ft2Library, facefile.c_str(), 0, &face ); @@ -447,75 +851,20 @@ FT2Font::~FT2Font() { _VERBOSE("FT2Font::~FT2Font"); + + if(image) + Py::_XDECREF(image); FT_Done_Face ( face ); - delete [] image.buffer ; - image.buffer = NULL; - for (size_t i=0; i<glyphs.size(); i++) { FT_Done_Glyph( glyphs[i] ); } + for (size_t i=0; i<gms.size(); i++) { Py_DECREF(gms[i]); } } - -char FT2Font::horiz_image_to_vert_image__doc__[] = -"horiz_image_to_vert_image()\n" -"\n" -"Copies the horizontal image (w, h) into a\n" -"new image of size (h,w)\n" -"This is equivalent to rotating the original image\n" -"by 90 degrees ccw\n" -; - -Py::Object -FT2Font::horiz_image_to_vert_image(const Py::Tuple & args) { - - // If we have already rotated, just return. - - if (image.bRotated) - return Py::Object(); - - - long width = image.width, height = image.height; - - long newWidth = image.height; - long newHeight = image.width; - - long numBytes = image.width * image.height; - - unsigned char * buffer = new unsigned char [numBytes]; - - long i, j, k, offset, nhMinusOne; - - nhMinusOne = newHeight-1; - - for (i=0; i<height; i++) { - - offset = i*width; - - for (j=0; j<width; j++) { - - k = nhMinusOne - j; - - buffer[i + k*newWidth] = image.buffer[j + offset]; - - } - - } - - delete [] image.buffer; - image.buffer = buffer; - image.width = newWidth; - image.height = newHeight; - image.bRotated = true; - - return Py::Object(); - -} - int FT2Font::setattr( const char *name, const Py::Object &value ) { _VERBOSE("FT2Font::setattr"); @@ -530,34 +879,6 @@ else return getattr_default( name ); } -char FT2Font::set_bitmap_size__doc__[] = -"set_bitmap_size(w, h)\n" -"\n" -"Manually set the bitmap size to render the glyps to. This is useful" -"in cases where you want to render several different glyphs to the bitmap" -; - -Py::Object -FT2Font::set_bitmap_size(const Py::Tuple & args) { - _VERBOSE("FT2Font::set_bitmap_size"); - args.verify_length(2); - - long width = Py::Int(args[0]); - long height = Py::Int(args[1]); - - image.width = (unsigned)width; - image.height = (unsigned)height; - - long numBytes = image.width * image.height; - - delete [] image.buffer; - image.buffer = new unsigned char [numBytes]; - for (long n=0; n<numBytes; n++) - image.buffer[n] = 0; - - return Py::Object(); -} - char FT2Font::clear__doc__[] = "clear()\n" "\n" @@ -569,13 +890,8 @@ _VERBOSE("FT2Font::clear"); args.verify_length(0); - //todo: move to image method? - delete [] image.buffer ; - image.buffer = NULL; - image.width = 0; - image.height = 0; - image.offsetx = 0; - image.offsety = 0; + if (image) + image->clear(); angle = 0.0; @@ -904,8 +1220,6 @@ _VERBOSE("FT2Font::get_width_height"); args.verify_length(0); - - FT_BBox bbox = compute_string_bbox(); Py::Tuple ret(2); @@ -930,152 +1244,6 @@ return Py::Int(- bbox.yMin);; } -void -FT2Font::draw_bitmap( FT_Bitmap* bitmap, - FT_Int x, - FT_Int y) { - _VERBOSE("FT2Font::draw_bitmap"); - FT_Int image_width = (FT_Int)image.width; - FT_Int image_height = (FT_Int)image.height; - FT_Int char_width = bitmap->width; - FT_Int char_height = bitmap->rows; - - FT_Int x1 = CLAMP(x, 0, image_width); - FT_Int y1 = CLAMP(y, 0, image_height); - FT_Int x2 = CLAMP(x + char_width, 0, image_width); - FT_Int y2 = CLAMP(y + char_height, 0, image_height); - - FT_Int x_start = MAX(0, -x); - FT_Int y_offset = y1 - MAX(0, -y); - - for ( FT_Int i = y1; i < y2; ++i ) { - unsigned char* dst = image.buffer + (i * image_width + x1); - unsigned char* src = bitmap->buffer + (((i - y_offset) * bitmap->pitch) + x_start); - for ( FT_Int j = x1; j < x2; ++j, ++dst, ++src ) - *dst |= *src; - } -} - -char FT2Font::write_bitmap__doc__[] = -"write_bitmap(fname)\n" -"\n" -"Write the bitmap to file fname\n" -; -Py::Object -FT2Font::write_bitmap(const Py::Tuple & args) { - _VERBOSE("FT2Font::write_bitmap"); - - args.verify_length(1); - - FT_Int i, j; - - std::string filename = Py::String(args[0]); - - FILE *fh = fopen(filename.c_str(), "w"); - FT_Int width = (FT_Int)image.width; - FT_Int height = (FT_Int)image.height; - - for ( i = 0; i< height; i++) - for ( j = 0; j < width; ++j) - fputc(image.buffer[j + i*width], fh); - - fclose(fh); - - return Py::Object(); -} - -char FT2Font::draw_rect__doc__[] = -"draw_rect(x0, y0, x1, y1)\n" -"\n" -"Draw a rect to the image. It is your responsibility to set the dimensions\n" -"of the image, eg, with set_bitmap_size\n" -"\n" -; -Py::Object -FT2Font::draw_rect(const Py::Tuple & args) { - _VERBOSE("FT2Font::draw_rect"); - - args.verify_length(4); - - long x0 = Py::Int(args[0]); - long y0 = Py::Int(args[1]); - long x1 = Py::Int(args[2]); - long y1 = Py::Int(args[3]); - - FT_Int iwidth = (FT_Int)image.width; - FT_Int iheight = (FT_Int)image.height; - - if ( x0<0 || y0<0 || x1<0 || y1<0 || - x0>iwidth || x1>iwidth || - y0>iheight || y1>iheight ) - throw Py::ValueError("Rect coords outside image bounds"); - - for (long i=x0; i<x1+1; ++i) { - image.buffer[i + y0*iwidth] = 255; - image.buffer[i + y1*iwidth] = 255; - } - - for (long j=y0+1; j<y1; ++j) { - image.buffer[x0 + j*iwidth] = 255; - image.buffer[x1 + j*iwidth] = 255; - } - return Py::Object(); -} - -char FT2Font::draw_rect_filled__doc__[] = -"draw_rect_filled(x0, y0, x1, y1)\n" -"\n" -"Draw a filled rect to the image. It is your responsibility to set the\n" -"dimensions of the image, eg, with set_bitmap_size\n" -"\n" -; -Py::Object -FT2Font::draw_rect_filled(const Py::Tuple & args) { - _VERBOSE("FT2Font::draw_rect_filled"); - - args.verify_length(4); - - long x0 = Py::Int(args[0]); - long y0 = Py::Int(args[1]); - long x1 = Py::Int(args[2]); - long y1 = Py::Int(args[3]); - - FT_Int iwidth = (FT_Int)image.width; - FT_Int iheight = (FT_Int)image.height; - - x0 = CLAMP(x0, 0, iwidth); - y0 = CLAMP(y0, 0, iheight); - x1 = CLAMP(x1, 0, iwidth); - y1 = CLAMP(y1, 0, iheight); - - for (long j=y0; j<y1+1; j++) { - for (long i=x0; i<x1+1; i++) { - image.buffer[i + j*iwidth] = 255; - } - } - return Py::Object(); -} - -char FT2Font::image_as_str__doc__[] = -"width, height, s = image_as_str()\n" -"\n" -"Return the image buffer as a string\n" -"\n" -; -Py::Object -FT2Font::image_as_str(const Py::Tuple & args) { - _VERBOSE("FT2Font::image_as_str"); - args.verify_length(0); - - return Py::asObject( - Py_BuildValue("lls#", - image.width, - image.height, - image.buffer, - image.width*image.height) - ); -} - char FT2Font::draw_glyphs_to_bitmap__doc__[] = "draw_glyphs_to_bitmap()\n" "\n" @@ -1089,22 +1257,21 @@ args.verify_length(0); FT_BBox string_bbox = compute_string_bbox(); + size_t width = (string_bbox.xMax-string_bbox.xMin) / 64 + 2; + size_t height = (string_bbox.yMax-string_bbox.yMin) / 64 + 2; - image.width = (string_bbox.xMax-string_bbox.xMin) / 64 + 2; - image.height = (string_bbox.yMax-string_bbox.yMin) / 64 + 2; + if (!image) { + image = new FT2Image(width, height); + } else { + image->resize(width, height); + } - image.offsetx = (int)(string_bbox.xMin / 64.0); + image->offsetx = (int)(string_bbox.xMin / 64.0); if (angle==0) - image.offsety = -image.height; + image->offsety = -image->get_height(); else - image.offsety = (int)(-string_bbox.yMax/64.0); + image->offsety = (int)(-string_bbox.yMax/64.0); - size_t numBytes = image.width*image.height; - delete [] image.buffer; - image.buffer = new unsigned char [numBytes]; - for (size_t n=0; n<numBytes; n++) - image.buffer[n] = 0; - for ( size_t n = 0; n < glyphs.size(); n++ ) { FT_BBox bbox; @@ -1113,8 +1280,7 @@ error = FT_Glyph_To_Bitmap(&glyphs[n], ft_render_mode_normal, 0, - //&pos[n], - 1 //destroy image; + 1 ); if (error) throw Py::RuntimeError("Could not convert glyph to bitmap"); @@ -1126,7 +1292,7 @@ FT_Int x = (FT_Int)(bitmap->left - (string_bbox.xMin / 64.)); FT_Int y = (FT_Int)((string_bbox.yMax / 64.) - bitmap->top + 1); - draw_bitmap( &bitmap->bitmap, x, y); + image->draw_bitmap( &bitmap->bitmap, x, y); } return Py::Object(); @@ -1156,8 +1322,7 @@ error = FT_Glyph_To_Bitmap(&glyphs[n], ft_render_mode_normal, 0, - //&pos[n], - 1 //destroy image; + 1 ); if (error) throw Py::RuntimeError("Could not convert glyph to bitmap"); @@ -1181,7 +1346,7 @@ } char FT2Font::draw_glyph_to_bitmap__doc__[] = -"draw_glyph_to_bitmap(x, y, glyph)\n" +"draw_glyph_to_bitmap(bitmap, x, y, glyph)\n" "\n" "Draw a single glyph to the bitmap at pixel locations x,y\n" "Note it is your responsibility to set up the bitmap manually\n" @@ -1195,16 +1360,17 @@ Py::Object FT2Font::draw_glyph_to_bitmap(const Py::Tuple & args) { _VERBOSE("FT2Font::draw_glyph_to_bitmap"); - args.verify_length(3); + args.verify_length(4); - if (image.width==0 || image.height==0) - throw Py::RuntimeError("You must first set the size of the bitmap with set_bitmap_size"); + if (!FT2Image::check(args[0].ptr())) + throw Py::TypeError("Usage: draw_glyph_to_bitmap(bitmap, x,y,glyph)"); + FT2Image* im = static_cast<FT2Image*>(args[0].ptr()); - long x = Py::Int(args[0]); - long y = Py::Int(args[1]); - if (!Glyph::check(args[2].ptr())) - throw Py::TypeError("Usage: draw_glyph_to_bitmap(x,y,glyph)"); - Glyph* glyph = static_cast<Glyph*>(args[2].ptr()); + long x = Py::Int(args[1]); + long y = Py::Int(args[2]); + if (!Glyph::check(args[3].ptr())) + throw Py::TypeError("Usage: draw_glyph_to_bitmap(bitmap, x,y,glyph)"); + Glyph* glyph = static_cast<Glyph*>(args[3].ptr()); if ((size_t)glyph->glyphInd >= glyphs.size()) throw Py::ValueError("glyph num is out of range"); @@ -1219,7 +1385,7 @@ FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyphs[glyph->glyphInd]; - draw_bitmap( &bitmap->bitmap, x + bitmap->left, y); + im->draw_bitmap( &bitmap->bitmap, x + bitmap->left, y); return Py::Object(); } @@ -1611,7 +1777,28 @@ } } +char FT2Font::get_image__doc__ [] = + "get_image()\n" + "\n" + "Returns the underlying image buffer for this font object.\n"; Py::Object +FT2Font::get_image (const Py::Tuple &args) { + args.verify_length(0); + Py_INCREF(image); + return Py::asObject(image); +} + +Py::Object +ft2font_module::new_ft2image (const Py::Tuple &args) { + args.verify_length(2); + + int width = Py::Int(args[0]); + int height = Py::Int(args[1]); + + return Py::asObject( new FT2Image(width, height) ); +} + +Py::Object ft2font_module::new_ft2font (const Py::Tuple &args) { _VERBOSE("ft2font_module::new_ft2font "); args.verify_length(1); @@ -1621,6 +1808,36 @@ } void +FT2Image::init_type() { + _VERBOSE("FT2Image::init_type"); + behaviors().name("FT2Image"); + behaviors().doc("FT2Image"); + + add_varargs_method("clear", &FT2Image::py_clear, + FT2Image::clear__doc__); + add_varargs_method("resize", &FT2Image::py_resize, + FT2Image::resize__doc__); + add_varargs_method("rotate", &FT2Image::py_rotate, + FT2Image::rotate__doc__); + add_varargs_method("write_bitmap", &FT2Image::py_write_bitmap, + FT2Image::write_bitmap__doc__); + add_varargs_method("draw_rect", &FT2Image::py_draw_rect, + FT2Image::draw_rect__doc__); + add_varargs_method("draw_rect_filled", &FT2Image::py_draw_rect_filled, + FT2Image::draw_rect_filled__doc__); + add_varargs_method("as_str", &FT2Image::py_as_str, + FT2Image::as_str__doc__); + add_varargs_method("as_rgb_str", &FT2Image::py_as_rgb_str, + FT2Image::as_rgb_str__doc__); + add_varargs_method("as_rgba_str", &FT2Image::py_as_rgba_str, + FT2Image::as_rgba_str__doc__); + add_varargs_method("get_width", &FT2Image::py_get_width, + "Returns the width of the image"); + add_varargs_method("get_height", &FT2Image::py_get_height, + "Returns the height of the image"); +} + +void Glyph::init_type() { _VERBOSE("Glyph::init_type"); behaviors().name("Glyph"); @@ -1637,14 +1854,6 @@ add_varargs_method("clear", &FT2Font::clear, FT2Font::clear__doc__); - add_varargs_method("write_bitmap", &FT2Font::write_bitmap, - FT2Font::write_bitmap__doc__); - add_varargs_method("set_bitmap_size", &FT2Font::set_bitmap_size, - FT2Font::load_char__doc__); - add_varargs_method("draw_rect",&FT2Font::draw_rect, - FT2Font::draw_rect__doc__); - add_varargs_method("draw_rect_filled",&FT2Font::draw_rect_filled, - FT2Font::draw_rect_filled__doc__); add_varargs_method("draw_glyph_to_bitmap", &FT2Font::draw_glyph_to_bitmap, FT2Font::draw_glyph_to_bitmap__doc__); add_varargs_method("draw_glyphs_to_bitmap", &FT2Font::draw_glyphs_to_bitmap, @@ -1656,8 +1865,6 @@ FT2Font::get_glyph__doc__); add_varargs_method("get_num_glyphs", &FT2Font::get_num_glyphs, FT2Font::get_num_glyphs__doc__); - add_varargs_method("image_as_str", &FT2Font::image_as_str, - FT2Font::image_as_str__doc__); add_keyword_method("load_char", &FT2Font::load_char, FT2Font::load_char__doc__); add_keyword_method("set_text", &FT2Font::set_text, @@ -1685,9 +1892,8 @@ FT2Font::get_ps_font_info__doc__); add_varargs_method("get_sfnt_table", &FT2Font::get_sfnt_table, FT2Font::get_sfnt_table__doc__); - add_varargs_method("horiz_image_to_vert_image", - &FT2Font::horiz_image_to_vert_image, - FT2Font::horiz_image_to_vert_image__doc__); + add_varargs_method("get_image", &FT2Font::get_image, + FT2Font::get_image__doc__); behaviors().supportGetattr(); behaviors().supportSetattr(); Modified: trunk/matplotlib/src/ft2font.h =================================================================== --- trunk/matplotlib/src/ft2font.h 2007-08-31 17:23:32 UTC (rev 3763) +++ trunk/matplotlib/src/ft2font.h 2007-08-31 19:25:17 UTC (rev 3764) @@ -20,15 +20,64 @@ // the freetype string rendered into a width, height buffer -class FT2Image { +class FT2Image : public Py::PythonExtension<FT2Image> { public: FT2Image(); + FT2Image(unsigned long width, unsigned long height); ~FT2Image(); - bool bRotated; - unsigned char *buffer; - unsigned long width; - unsigned long height; - int offsetx, offsety; + + static void init_type(); + + void resize(unsigned long width, unsigned long height); + void clear(); + void rotate(); + void draw_bitmap(FT_Bitmap* bitmap, FT_Int x, FT_Int y); + void write_bitmap(const char* filename) const; + void draw_rect(unsigned long x0, unsigned long y0, + unsigned long x1, unsigned long y1); + void draw_rect_filled(unsigned long x0, unsigned long y0, + unsigned long x1, unsigned long y1); + + unsigned int get_width() const { return _width; }; + unsigned int get_height() const { return _height; }; + const unsigned char *const get_buffer() const { return _buffer; }; + + static char clear__doc__ []; + Py::Object py_clear(const Py::Tuple & args); + static char resize__doc__ []; + Py::Object py_resize(const Py::Tuple & args); + static char rotate__doc__ []; + Py::Object py_rotate(const Py::Tuple & args); + static char write_bitmap__doc__ []; + Py::Object py_write_bitmap(const Py::Tuple & args); + static char draw_rect__doc__ []; + Py::Object py_draw_rect(const Py::Tuple & args); + static char draw_rect_filled__doc__ []; + Py::Object py_draw_rect_filled(const Py::Tuple & args); + static char as_str__doc__ []; + Py::Object py_as_str(const Py::Tuple & args); + static char as_rgb_str__doc__ []; + Py::Object py_as_rgb_str(const Py::Tuple & args); + static char as_rgba_str__doc__ []; + Py::Object py_as_rgba_str(const Py::Tuple & args); + + Py::Object py_get_width(const Py::Tuple & args); + Py::Object py_get_height(const Py::Tuple & args); + + unsigned long offsetx; + unsigned long offsety; + + private: + bool _bRotated; + bool _isDirty; + unsigned char *_buffer; + unsigned long _width; + unsigned long _height; + FT2Image* _rgbCopy; + FT2Image* _rgbaCopy; + + void makeRgbCopy(); + void makeRgbaCopy(); }; @@ -52,7 +101,6 @@ FT2Font(std::string); ~FT2Font(); static void init_type(void); - Py::Object set_bitmap_size(const Py::Tuple & args); Py::Object clear(const Py::Tuple & args); Py::Object set_size(const Py::Tuple & args); Py::Object set_charmap(const Py::Tuple & args); @@ -63,10 +111,7 @@ Py::Object load_char(const Py::Tuple & args, const Py::Dict & kws); Py::Object get_width_height(const Py::Tuple & args); Py::Object get_descent(const Py::Tuple & args); - Py::Object write_bitmap(const Py::Tuple & args); - Py::Object draw_rect(const Py::Tuple & args); Py::Object draw_rect_filled(const Py::Tuple & args); - Py::Object image_as_str(const Py::Tuple & args); Py::Object get_xys(const Py::Tuple & args); Py::Object draw_glyphs_to_bitmap(const Py::Tuple & args); Py::Object draw_glyph_to_bitmap(const Py::Tuple & args); @@ -76,10 +121,10 @@ Py::Object get_name_index(const Py::Tuple & args); Py::Object get_ps_font_info(const Py::Tuple & args); Py::Object get_sfnt_table(const Py::Tuple & args); - Py::Object horiz_image_to_vert_image(const Py::Tuple & args); + Py::Object get_image(const Py::Tuple & args); int setattr( const char *_name, const Py::Object &value ); Py::Object getattr( const char *_name ); - FT2Image image; + FT2Image* image; private: Py::Dict __dict__; @@ -96,10 +141,8 @@ FT_BBox compute_string_bbox(); - void draw_bitmap( FT_Bitmap* bitmap, FT_Int x, FT_Int y); void set_scalable_attributes(); - static char set_bitmap_size__doc__ []; static char clear__doc__ []; static char set_size__doc__ []; static char set_charmap__doc__ []; @@ -110,10 +153,6 @@ static char get_width_height__doc__ []; static char get_descent__doc__ []; static char get_kerning__doc__ []; - static char write_bitmap__doc__ []; - static char draw_rect__doc__ []; - static char draw_rect_filled__doc__ []; - static char image_as_str__doc__ []; static char draw_glyphs_to_bitmap__doc__ []; static char get_xys__doc__ []; static char draw_glyph_to_bitmap__doc__ []; @@ -123,7 +162,7 @@ static char get_name_index__doc__[]; static char get_ps_font_info__doc__[]; static char get_sfnt_table__doc__[]; - static char horiz_image_to_vert_image__doc__[]; + static char get_image__doc__[]; }; // the extension module @@ -134,11 +173,14 @@ ft2font_module() : Py::ExtensionModule<ft2font_module>( "ft2font" ) { + FT2Image::init_type(); Glyph::init_type(); FT2Font::init_type(); add_varargs_method("FT2Font", &ft2font_module::new_ft2font, "FT2Font"); + add_varargs_method("FT2Image", &ft2font_module::new_ft2image, + "FT2Image"); initialize( "The ft2font module" ); } @@ -148,6 +190,7 @@ private: Py::Object new_ft2font (const Py::Tuple &args); + Py::Object new_ft2image (const Py::Tuple &args); }; Modified: trunk/matplotlib/unit/agg_memleak.py =================================================================== --- trunk/matplotlib/unit/agg_memleak.py 2007-08-31 17:23:32 UTC (rev 3763) +++ trunk/matplotlib/unit/agg_memleak.py 2007-08-31 19:25:17 UTC (rev 3764) @@ -41,7 +41,7 @@ font.clear() font.set_text('hi mom', 60) font.set_size(12, 72) - o.draw_text( font, 30, 40, gc) + o.draw_text_image(font.get_image(), 30, 40, gc) o.write_png('aggtest%d.png'%i) val = report_memory(i) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <js...@us...> - 2007-08-31 17:23:35
|
Revision: 3763 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3763&view=rev Author: jswhit Date: 2007-08-31 10:23:32 -0700 (Fri, 31 Aug 2007) Log Message: ----------- regenerate with Cython 0.9.6.5 Modified Paths: -------------- trunk/toolkits/basemap/src/_geod.c trunk/toolkits/basemap/src/_proj.c trunk/toolkits/basemap/src/_pyproj.pxi Modified: trunk/toolkits/basemap/src/_geod.c =================================================================== --- trunk/toolkits/basemap/src/_geod.c 2007-08-31 15:40:42 UTC (rev 3762) +++ trunk/toolkits/basemap/src/_geod.c 2007-08-31 17:23:32 UTC (rev 3763) @@ -1,10 +1,18 @@ -/* Generated by Pyrex 0.9.5.1 on Sun May 20 08:32:09 2007 */ +/* Generated by Pyrex 0.9.6.3 on Fri Aug 31 08:42:50 2007 */ +#define PY_SSIZE_T_CLEAN #include "Python.h" #include "structmember.h" #ifndef PY_LONG_LONG #define PY_LONG_LONG LONG_LONG #endif +#if PY_VERSION_HEX < 0x02050000 + typedef int Py_ssize_t; + #define PY_SSIZE_T_MAX INT_MAX + #define PY_SSIZE_T_MIN INT_MIN + #define PyInt_FromSsize_t(z) PyInt_FromLong(z) + #define PyInt_AsSsize_t(o) PyInt_AsLong(o) +#endif #ifdef __cplusplus #define __PYX_EXTERN_C extern "C" #else @@ -15,12 +23,36 @@ #include "math.h" #include "geodesic.h" #include "proj_api.h" -#include "pycompat.h" +#ifdef __GNUC__ +#define INLINE __inline__ +#elif _WIN32 +#define INLINE __inline +#else +#define INLINE +#endif + +typedef struct {const char *s; const void **p;} __Pyx_CApiTabEntry; /*proto*/ typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/ typedef struct {PyObject **p; char *s; long n;} __Pyx_StringTabEntry; /*proto*/ +#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False)) +static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + if (x == Py_True) return 1; + else if (x == Py_False) return 0; + else return PyObject_IsTrue(x); +} + + +#ifdef __GNUC__ +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) +#else /* __GNUC__ */ +#define likely(x) (x) +#define unlikely(x) (x) +#endif /* __GNUC__ */ + static PyObject *__pyx_m; static PyObject *__pyx_b; static int __pyx_lineno; @@ -70,13 +102,11 @@ static PyObject *__pyx_n___version__; static PyObject *__pyx_n_radians; static PyObject *__pyx_n_degrees; -static PyObject *__pyx_n_False; static PyObject *__pyx_k2p; static PyObject *__pyx_n_iteritems; static PyObject *__pyx_n_append; -static PyObject *__pyx_n_str; static PyObject *__pyx_n_join; static PyObject *__pyx_n_RuntimeError; @@ -85,6 +115,8 @@ static PyObject *__pyx_k8p; static PyObject *__pyx_k9p; +static PyObject *__pyx_builtin_RuntimeError; + static char (__pyx_k6[]) = "+"; static char (__pyx_k7[]) = "="; static char (__pyx_k8[]) = " "; @@ -99,119 +131,187 @@ PyObject *__pyx_v_value; int __pyx_r; PyObject *__pyx_1 = 0; - PyObject *__pyx_2 = 0; + Py_ssize_t __pyx_2; PyObject *__pyx_3 = 0; PyObject *__pyx_4 = 0; PyObject *__pyx_5 = 0; PyObject *__pyx_6 = 0; int __pyx_7; static char *__pyx_argnames[] = {"geodparams",0}; - if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O", __pyx_argnames, &__pyx_v_geodparams)) return -1; + if (unlikely(!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O", __pyx_argnames, &__pyx_v_geodparams))) return -1; Py_INCREF(__pyx_v_self); Py_INCREF(__pyx_v_geodparams); __pyx_v_geodargs = Py_None; Py_INCREF(Py_None); __pyx_v_key = Py_None; Py_INCREF(Py_None); __pyx_v_value = Py_None; Py_INCREF(Py_None); - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":13 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":13 + * def __new__(self, geodparams): + * cdef GEODESIC_T GEOD_T + * self.geodparams = geodparams # <<<<<<<<<<<<<< + * # setup proj initialization string. + * geodargs = [] + */ Py_INCREF(__pyx_v_geodparams); Py_DECREF(((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodparams); ((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodparams = __pyx_v_geodparams; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":15 */ - __pyx_1 = PyList_New(0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; goto __pyx_L1;} + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":15 + * self.geodparams = geodparams + * # setup proj initialization string. + * geodargs = [] # <<<<<<<<<<<<<< + * for key,value in geodparams.iteritems(): + * geodargs.append('+'+key+"="+str(value)+' ') + */ + __pyx_1 = PyList_New(0); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; goto __pyx_L1;} Py_DECREF(__pyx_v_geodargs); __pyx_v_geodargs = __pyx_1; __pyx_1 = 0; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":16 */ - __pyx_1 = PyObject_GetAttr(__pyx_v_geodparams, __pyx_n_iteritems); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; goto __pyx_L1;} - __pyx_2 = PyObject_CallObject(__pyx_1, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; goto __pyx_L1;} + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":16 + * # setup proj initialization string. + * geodargs = [] + * for key,value in geodparams.iteritems(): # <<<<<<<<<<<<<< + * geodargs.append('+'+key+"="+str(value)+' ') + * self.geodinitstring = PyString_AsString(''.join(geodargs)) + */ + __pyx_1 = PyObject_GetAttr(__pyx_v_geodparams, __pyx_n_iteritems); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; goto __pyx_L1;} + __pyx_3 = PyObject_CallObject(__pyx_1, 0); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; goto __pyx_L1;} Py_DECREF(__pyx_1); __pyx_1 = 0; - __pyx_1 = PyObject_GetIter(__pyx_2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; goto __pyx_L1;} - Py_DECREF(__pyx_2); __pyx_2 = 0; + if (PyList_CheckExact(__pyx_3)) { __pyx_2 = 0; __pyx_1 = __pyx_3; Py_INCREF(__pyx_1); } + else { __pyx_1 = PyObject_GetIter(__pyx_3); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; goto __pyx_L1;} } + Py_DECREF(__pyx_3); __pyx_3 = 0; for (;;) { - __pyx_2 = PyIter_Next(__pyx_1); - if (!__pyx_2) { - if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; goto __pyx_L1;} - break; + if (PyList_CheckExact(__pyx_1)) { if (__pyx_2 >= PyList_GET_SIZE(__pyx_1)) break; __pyx_3 = PyList_GET_ITEM(__pyx_1, __pyx_2++); Py_INCREF(__pyx_3); } + else { + __pyx_3 = PyIter_Next(__pyx_1); + if (!__pyx_3) { + break; + } } - __pyx_3 = PyObject_GetIter(__pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; goto __pyx_L1;} - Py_DECREF(__pyx_2); __pyx_2 = 0; - __pyx_2 = __Pyx_UnpackItem(__pyx_3); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; goto __pyx_L1;} - Py_DECREF(__pyx_v_key); - __pyx_v_key = __pyx_2; - __pyx_2 = 0; - __pyx_2 = __Pyx_UnpackItem(__pyx_3); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; goto __pyx_L1;} - Py_DECREF(__pyx_v_value); - __pyx_v_value = __pyx_2; - __pyx_2 = 0; - if (__Pyx_EndUnpack(__pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; goto __pyx_L1;} - Py_DECREF(__pyx_3); __pyx_3 = 0; + if (PyTuple_CheckExact(__pyx_3) && PyTuple_GET_SIZE(__pyx_3) == 2) { + __pyx_5 = PyTuple_GET_ITEM(__pyx_3, 0); + Py_INCREF(__pyx_5); + Py_DECREF(__pyx_v_key); + __pyx_v_key = __pyx_5; + __pyx_5 = 0; + __pyx_5 = PyTuple_GET_ITEM(__pyx_3, 1); + Py_INCREF(__pyx_5); + Py_DECREF(__pyx_v_value); + __pyx_v_value = __pyx_5; + __pyx_5 = 0; + Py_DECREF(__pyx_3); __pyx_3 = 0; + } + else { + __pyx_4 = PyObject_GetIter(__pyx_3); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; goto __pyx_L1;} + Py_DECREF(__pyx_3); __pyx_3 = 0; + __pyx_5 = __Pyx_UnpackItem(__pyx_4); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; goto __pyx_L1;} + Py_DECREF(__pyx_v_key); + __pyx_v_key = __pyx_5; + __pyx_5 = 0; + __pyx_5 = __Pyx_UnpackItem(__pyx_4); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; goto __pyx_L1;} + Py_DECREF(__pyx_v_value); + __pyx_v_value = __pyx_5; + __pyx_5 = 0; + if (__Pyx_EndUnpack(__pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; goto __pyx_L1;} + Py_DECREF(__pyx_4); __pyx_4 = 0; + } - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":17 */ - __pyx_2 = PyObject_GetAttr(__pyx_v_geodargs, __pyx_n_append); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} - __pyx_3 = PyNumber_Add(__pyx_k6p, __pyx_v_key); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} - __pyx_4 = PyNumber_Add(__pyx_3, __pyx_k7p); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":17 + * geodargs = [] + * for key,value in geodparams.iteritems(): + * geodargs.append('+'+key+"="+str(value)+' ') # <<<<<<<<<<<<<< + * self.geodinitstring = PyString_AsString(''.join(geodargs)) + * # initialize projection + */ + __pyx_5 = PyObject_GetAttr(__pyx_v_geodargs, __pyx_n_append); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} + __pyx_3 = PyNumber_Add(__pyx_k6p, __pyx_v_key); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} + __pyx_4 = PyNumber_Add(__pyx_3, __pyx_k7p); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} Py_DECREF(__pyx_3); __pyx_3 = 0; - __pyx_3 = __Pyx_GetName(__pyx_b, __pyx_n_str); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} - __pyx_5 = PyTuple_New(1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} + __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} Py_INCREF(__pyx_v_value); - PyTuple_SET_ITEM(__pyx_5, 0, __pyx_v_value); - __pyx_6 = PyObject_CallObject(__pyx_3, __pyx_5); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} + PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_value); + __pyx_6 = PyObject_CallObject(((PyObject*)&PyString_Type), __pyx_3); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} Py_DECREF(__pyx_3); __pyx_3 = 0; - Py_DECREF(__pyx_5); __pyx_5 = 0; - __pyx_3 = PyNumber_Add(__pyx_4, __pyx_6); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} + __pyx_3 = PyNumber_Add(__pyx_4, __pyx_6); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} Py_DECREF(__pyx_4); __pyx_4 = 0; Py_DECREF(__pyx_6); __pyx_6 = 0; - __pyx_5 = PyNumber_Add(__pyx_3, __pyx_k8p); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} + __pyx_4 = PyNumber_Add(__pyx_3, __pyx_k8p); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} Py_DECREF(__pyx_3); __pyx_3 = 0; - __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} - PyTuple_SET_ITEM(__pyx_4, 0, __pyx_5); - __pyx_5 = 0; - __pyx_6 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} - Py_DECREF(__pyx_2); __pyx_2 = 0; - Py_DECREF(__pyx_4); __pyx_4 = 0; + __pyx_6 = PyTuple_New(1); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} + PyTuple_SET_ITEM(__pyx_6, 0, __pyx_4); + __pyx_4 = 0; + __pyx_3 = PyObject_CallObject(__pyx_5, __pyx_6); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; goto __pyx_L1;} + Py_DECREF(__pyx_5); __pyx_5 = 0; Py_DECREF(__pyx_6); __pyx_6 = 0; + Py_DECREF(__pyx_3); __pyx_3 = 0; } Py_DECREF(__pyx_1); __pyx_1 = 0; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":18 */ - __pyx_3 = PyObject_GetAttr(__pyx_k9p, __pyx_n_join); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; goto __pyx_L1;} - __pyx_5 = PyTuple_New(1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; goto __pyx_L1;} + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":18 + * for key,value in geodparams.iteritems(): + * geodargs.append('+'+key+"="+str(value)+' ') + * self.geodinitstring = PyString_AsString(''.join(geodargs)) # <<<<<<<<<<<<<< + * # initialize projection + * self.geodesic_t = GEOD_init_plus(self.geodinitstring, &GEOD_T)[0] + */ + __pyx_4 = PyObject_GetAttr(__pyx_k9p, __pyx_n_join); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; goto __pyx_L1;} + __pyx_5 = PyTuple_New(1); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; goto __pyx_L1;} Py_INCREF(__pyx_v_geodargs); PyTuple_SET_ITEM(__pyx_5, 0, __pyx_v_geodargs); - __pyx_2 = PyObject_CallObject(__pyx_3, __pyx_5); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; goto __pyx_L1;} - Py_DECREF(__pyx_3); __pyx_3 = 0; + __pyx_6 = PyObject_CallObject(__pyx_4, __pyx_5); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; goto __pyx_L1;} + Py_DECREF(__pyx_4); __pyx_4 = 0; Py_DECREF(__pyx_5); __pyx_5 = 0; - ((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodinitstring = PyString_AsString(__pyx_2); - Py_DECREF(__pyx_2); __pyx_2 = 0; + ((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodinitstring = PyString_AsString(__pyx_6); + Py_DECREF(__pyx_6); __pyx_6 = 0; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":20 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":20 + * self.geodinitstring = PyString_AsString(''.join(geodargs)) + * # initialize projection + * self.geodesic_t = GEOD_init_plus(self.geodinitstring, &GEOD_T)[0] # <<<<<<<<<<<<<< + * if pj_errno != 0: + * raise RuntimeError(pj_strerrno(pj_errno)) + */ ((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t = (GEOD_init_plus(((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodinitstring,(&__pyx_v_GEOD_T))[0]); - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":21 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":21 + * # initialize projection + * self.geodesic_t = GEOD_init_plus(self.geodinitstring, &GEOD_T)[0] + * if pj_errno != 0: # <<<<<<<<<<<<<< + * raise RuntimeError(pj_strerrno(pj_errno)) + * self.proj_version = PJ_VERSION/100. + */ __pyx_7 = (pj_errno != 0); if (__pyx_7) { - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":22 */ - __pyx_4 = __Pyx_GetName(__pyx_b, __pyx_n_RuntimeError); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;} - __pyx_6 = PyString_FromString(pj_strerrno(pj_errno)); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;} - __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;} - PyTuple_SET_ITEM(__pyx_1, 0, __pyx_6); - __pyx_6 = 0; - __pyx_3 = PyObject_CallObject(__pyx_4, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;} + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":22 + * self.geodesic_t = GEOD_init_plus(self.geodinitstring, &GEOD_T)[0] + * if pj_errno != 0: + * raise RuntimeError(pj_strerrno(pj_errno)) # <<<<<<<<<<<<<< + * self.proj_version = PJ_VERSION/100. + * + */ + __pyx_3 = PyString_FromString(pj_strerrno(pj_errno)); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;} + __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;} + PyTuple_SET_ITEM(__pyx_1, 0, __pyx_3); + __pyx_3 = 0; + __pyx_4 = PyObject_CallObject(__pyx_builtin_RuntimeError, __pyx_1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;} + Py_DECREF(__pyx_1); __pyx_1 = 0; + __Pyx_Raise(__pyx_4, 0, 0); Py_DECREF(__pyx_4); __pyx_4 = 0; - Py_DECREF(__pyx_1); __pyx_1 = 0; - __Pyx_Raise(__pyx_3, 0, 0); - Py_DECREF(__pyx_3); __pyx_3 = 0; {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;} goto __pyx_L4; } __pyx_L4:; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":23 */ - __pyx_5 = PyFloat_FromDouble((PJ_VERSION / 100.)); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; goto __pyx_L1;} + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":23 + * if pj_errno != 0: + * raise RuntimeError(pj_strerrno(pj_errno)) + * self.proj_version = PJ_VERSION/100. # <<<<<<<<<<<<<< + * + * def __reduce__(self): + */ + __pyx_5 = PyFloat_FromDouble((PJ_VERSION / 100.)); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; goto __pyx_L1;} Py_DECREF(((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->proj_version); ((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->proj_version = __pyx_5; __pyx_5 = 0; @@ -220,7 +320,6 @@ goto __pyx_L0; __pyx_L1:; Py_XDECREF(__pyx_1); - Py_XDECREF(__pyx_2); Py_XDECREF(__pyx_3); Py_XDECREF(__pyx_4); Py_XDECREF(__pyx_5); @@ -246,15 +345,21 @@ PyObject *__pyx_2 = 0; PyObject *__pyx_3 = 0; static char *__pyx_argnames[] = {0}; - if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "", __pyx_argnames)) return 0; + if (unlikely(!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "", __pyx_argnames))) return 0; Py_INCREF(__pyx_v_self); - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":27 */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n___class__); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; goto __pyx_L1;} - __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; goto __pyx_L1;} + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":27 + * def __reduce__(self): + * """special method that allows pyproj.Geod instance to be pickled""" + * return (self.__class__,(self.geodparams,)) # <<<<<<<<<<<<<< + * + * def _fwd(self, object lons, object lats, object az, object dist, radians=False): + */ + __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_n___class__); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; goto __pyx_L1;} + __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; goto __pyx_L1;} Py_INCREF(((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodparams); PyTuple_SET_ITEM(__pyx_2, 0, ((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodparams); - __pyx_3 = PyTuple_New(2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; goto __pyx_L1;} + __pyx_3 = PyTuple_New(2); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; goto __pyx_L1;} PyTuple_SET_ITEM(__pyx_3, 0, __pyx_1); PyTuple_SET_ITEM(__pyx_3, 1, __pyx_2); __pyx_1 = 0; @@ -281,6 +386,8 @@ static PyObject *__pyx_k10p; static PyObject *__pyx_k11p; +static PyObject *__pyx_builtin_ValueError; + static char (__pyx_k10[]) = "Buffer lengths not the same"; static char (__pyx_k11[]) = "undefined forward geodesic (may be an equatorial arc)"; @@ -308,15 +415,15 @@ void (*__pyx_v_distdat); PyObject *__pyx_r; int __pyx_1; - PyObject *__pyx_2 = 0; - int __pyx_3; + int __pyx_2; + PyObject *__pyx_3 = 0; PyObject *__pyx_4 = 0; PyObject *__pyx_5 = 0; Py_ssize_t __pyx_6; double __pyx_7; static char *__pyx_argnames[] = {"lons","lats","az","dist","radians",0}; __pyx_v_radians = __pyx_k3; - if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OOOO|O", __pyx_argnames, &__pyx_v_lons, &__pyx_v_lats, &__pyx_v_az, &__pyx_v_dist, &__pyx_v_radians)) return 0; + if (unlikely(!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OOOO|O", __pyx_argnames, &__pyx_v_lons, &__pyx_v_lats, &__pyx_v_az, &__pyx_v_dist, &__pyx_v_radians))) return 0; Py_INCREF(__pyx_v_self); Py_INCREF(__pyx_v_lons); Py_INCREF(__pyx_v_lats); @@ -324,59 +431,105 @@ Py_INCREF(__pyx_v_dist); Py_INCREF(__pyx_v_radians); - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":40 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":40 + * cdef void *londata, *latdata, *azdat, *distdat + * # if buffer api is supported, get pointer to data buffers. + * if PyObject_AsWriteBuffer(lons, &londata, &buflenlons) <> 0: # <<<<<<<<<<<<<< + * raise RuntimeError + * if PyObject_AsWriteBuffer(lats, &latdata, &buflenlats) <> 0: + */ __pyx_1 = (PyObject_AsWriteBuffer(__pyx_v_lons,(&__pyx_v_londata),(&__pyx_v_buflenlons)) != 0); if (__pyx_1) { - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":41 */ - __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_RuntimeError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; goto __pyx_L1;} - __Pyx_Raise(__pyx_2, 0, 0); - Py_DECREF(__pyx_2); __pyx_2 = 0; + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":41 + * # if buffer api is supported, get pointer to data buffers. + * if PyObject_AsWriteBuffer(lons, &londata, &buflenlons) <> 0: + * raise RuntimeError # <<<<<<<<<<<<<< + * if PyObject_AsWriteBuffer(lats, &latdata, &buflenlats) <> 0: + * raise RuntimeError + */ + __Pyx_Raise(__pyx_builtin_RuntimeError, 0, 0); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; goto __pyx_L1;} goto __pyx_L2; } __pyx_L2:; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":42 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":42 + * if PyObject_AsWriteBuffer(lons, &londata, &buflenlons) <> 0: + * raise RuntimeError + * if PyObject_AsWriteBuffer(lats, &latdata, &buflenlats) <> 0: # <<<<<<<<<<<<<< + * raise RuntimeError + * if PyObject_AsWriteBuffer(az, &azdat, &buflenaz) <> 0: + */ __pyx_1 = (PyObject_AsWriteBuffer(__pyx_v_lats,(&__pyx_v_latdata),(&__pyx_v_buflenlats)) != 0); if (__pyx_1) { - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":43 */ - __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_RuntimeError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; goto __pyx_L1;} - __Pyx_Raise(__pyx_2, 0, 0); - Py_DECREF(__pyx_2); __pyx_2 = 0; + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":43 + * raise RuntimeError + * if PyObject_AsWriteBuffer(lats, &latdata, &buflenlats) <> 0: + * raise RuntimeError # <<<<<<<<<<<<<< + * if PyObject_AsWriteBuffer(az, &azdat, &buflenaz) <> 0: + * raise RuntimeError + */ + __Pyx_Raise(__pyx_builtin_RuntimeError, 0, 0); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; goto __pyx_L1;} goto __pyx_L3; } __pyx_L3:; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":44 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":44 + * if PyObject_AsWriteBuffer(lats, &latdata, &buflenlats) <> 0: + * raise RuntimeError + * if PyObject_AsWriteBuffer(az, &azdat, &buflenaz) <> 0: # <<<<<<<<<<<<<< + * raise RuntimeError + * if PyObject_AsWriteBuffer(dist, &distdat, &buflend) <> 0: + */ __pyx_1 = (PyObject_AsWriteBuffer(__pyx_v_az,(&__pyx_v_azdat),(&__pyx_v_buflenaz)) != 0); if (__pyx_1) { - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":45 */ - __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_RuntimeError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; goto __pyx_L1;} - __Pyx_Raise(__pyx_2, 0, 0); - Py_DECREF(__pyx_2); __pyx_2 = 0; + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":45 + * raise RuntimeError + * if PyObject_AsWriteBuffer(az, &azdat, &buflenaz) <> 0: + * raise RuntimeError # <<<<<<<<<<<<<< + * if PyObject_AsWriteBuffer(dist, &distdat, &buflend) <> 0: + * raise RuntimeError + */ + __Pyx_Raise(__pyx_builtin_RuntimeError, 0, 0); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; goto __pyx_L1;} goto __pyx_L4; } __pyx_L4:; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":46 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":46 + * if PyObject_AsWriteBuffer(az, &azdat, &buflenaz) <> 0: + * raise RuntimeError + * if PyObject_AsWriteBuffer(dist, &distdat, &buflend) <> 0: # <<<<<<<<<<<<<< + * raise RuntimeError + * # process data in buffer + */ __pyx_1 = (PyObject_AsWriteBuffer(__pyx_v_dist,(&__pyx_v_distdat),(&__pyx_v_buflend)) != 0); if (__pyx_1) { - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":47 */ - __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_RuntimeError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; goto __pyx_L1;} - __Pyx_Raise(__pyx_2, 0, 0); - Py_DECREF(__pyx_2); __pyx_2 = 0; + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":47 + * raise RuntimeError + * if PyObject_AsWriteBuffer(dist, &distdat, &buflend) <> 0: + * raise RuntimeError # <<<<<<<<<<<<<< + * # process data in buffer + * if not buflenlons == buflenlats == buflenaz == buflend: + */ + __Pyx_Raise(__pyx_builtin_RuntimeError, 0, 0); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; goto __pyx_L1;} goto __pyx_L5; } __pyx_L5:; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":49 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":49 + * raise RuntimeError + * # process data in buffer + * if not buflenlons == buflenlats == buflenaz == buflend: # <<<<<<<<<<<<<< + * raise RuntimeError("Buffer lengths not the same") + * ndim = buflenlons/_doublesize + */ __pyx_1 = __pyx_v_buflenlons == __pyx_v_buflenlats; if (__pyx_1) { __pyx_1 = __pyx_v_buflenlats == __pyx_v_buflenaz; @@ -384,141 +537,267 @@ __pyx_1 = __pyx_v_buflenaz == __pyx_v_buflend; } } - __pyx_3 = (!__pyx_1); - if (__pyx_3) { + __pyx_2 = (!__pyx_1); + if (__pyx_2) { - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":50 */ - __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_RuntimeError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; goto __pyx_L1;} - __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; goto __pyx_L1;} + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":50 + * # process data in buffer + * if not buflenlons == buflenlats == buflenaz == buflend: + * raise RuntimeError("Buffer lengths not the same") # <<<<<<<<<<<<<< + * ndim = buflenlons/_doublesize + * lonsdata = <double *>londata + */ + __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; goto __pyx_L1;} Py_INCREF(__pyx_k10p); - PyTuple_SET_ITEM(__pyx_4, 0, __pyx_k10p); - __pyx_5 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; goto __pyx_L1;} - Py_DECREF(__pyx_2); __pyx_2 = 0; + PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k10p); + __pyx_4 = PyObject_CallObject(__pyx_builtin_RuntimeError, __pyx_3); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; goto __pyx_L1;} + Py_DECREF(__pyx_3); __pyx_3 = 0; + __Pyx_Raise(__pyx_4, 0, 0); Py_DECREF(__pyx_4); __pyx_4 = 0; - __Pyx_Raise(__pyx_5, 0, 0); - Py_DECREF(__pyx_5); __pyx_5 = 0; {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; goto __pyx_L1;} goto __pyx_L6; } __pyx_L6:; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":51 */ - __pyx_2 = PyInt_FromLong(__pyx_v_buflenlons); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; goto __pyx_L1;} - __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_n__doublesize); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; goto __pyx_L1;} - __pyx_5 = PyNumber_Divide(__pyx_2, __pyx_4); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; goto __pyx_L1;} - Py_DECREF(__pyx_2); __pyx_2 = 0; + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":51 + * if not buflenlons == buflenlats == buflenaz == buflend: + * raise RuntimeError("Buffer lengths not the same") + * ndim = buflenlons/_doublesize # <<<<<<<<<<<<<< + * lonsdata = <double *>londata + * latsdata = <double *>latdata + */ + __pyx_3 = PyInt_FromSsize_t(__pyx_v_buflenlons); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; goto __pyx_L1;} + __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_n__doublesize); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; goto __pyx_L1;} + __pyx_5 = PyNumber_Divide(__pyx_3, __pyx_4); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; goto __pyx_L1;} + Py_DECREF(__pyx_3); __pyx_3 = 0; Py_DECREF(__pyx_4); __pyx_4 = 0; - __pyx_6 = PyInt_AsLong(__pyx_5); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; goto __pyx_L1;} + __pyx_6 = PyInt_AsSsize_t(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; goto __pyx_L1;} Py_DECREF(__pyx_5); __pyx_5 = 0; __pyx_v_ndim = __pyx_6; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":52 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":52 + * raise RuntimeError("Buffer lengths not the same") + * ndim = buflenlons/_doublesize + * lonsdata = <double *>londata # <<<<<<<<<<<<<< + * latsdata = <double *>latdata + * azdata = <double *>azdat + */ __pyx_v_lonsdata = ((double (*))__pyx_v_londata); - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":53 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":53 + * ndim = buflenlons/_doublesize + * lonsdata = <double *>londata + * latsdata = <double *>latdata # <<<<<<<<<<<<<< + * azdata = <double *>azdat + * distdata = <double *>distdat + */ __pyx_v_latsdata = ((double (*))__pyx_v_latdata); - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":54 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":54 + * lonsdata = <double *>londata + * latsdata = <double *>latdata + * azdata = <double *>azdat # <<<<<<<<<<<<<< + * distdata = <double *>distdat + * for i from 0 <= i < ndim: + */ __pyx_v_azdata = ((double (*))__pyx_v_azdat); - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":55 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":55 + * latsdata = <double *>latdata + * azdata = <double *>azdat + * distdata = <double *>distdat # <<<<<<<<<<<<<< + * for i from 0 <= i < ndim: + * if radians: + */ __pyx_v_distdata = ((double (*))__pyx_v_distdat); - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":56 */ - for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_ndim; ++__pyx_v_i) { + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":56 + * azdata = <double *>azdat + * distdata = <double *>distdat + * for i from 0 <= i < ndim: # <<<<<<<<<<<<<< + * if radians: + * self.geodesic_t.p1.v = lonsdata[i] + */ + for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_ndim; __pyx_v_i++) { - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":57 */ - __pyx_1 = PyObject_IsTrue(__pyx_v_radians); if (__pyx_1 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; goto __pyx_L1;} + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":57 + * distdata = <double *>distdat + * for i from 0 <= i < ndim: + * if radians: # <<<<<<<<<<<<<< + * self.geodesic_t.p1.v = lonsdata[i] + * self.geodesic_t.p1.u = latsdata[i] + */ + __pyx_1 = PyObject_IsTrue(__pyx_v_radians); if (unlikely(__pyx_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; goto __pyx_L1;} if (__pyx_1) { - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":58 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":58 + * for i from 0 <= i < ndim: + * if radians: + * self.geodesic_t.p1.v = lonsdata[i] # <<<<<<<<<<<<<< + * self.geodesic_t.p1.u = latsdata[i] + * self.geodesic_t.ALPHA12 = azdata[i] + */ ((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.p1.v = (__pyx_v_lonsdata[__pyx_v_i]); - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":59 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":59 + * if radians: + * self.geodesic_t.p1.v = lonsdata[i] + * self.geodesic_t.p1.u = latsdata[i] # <<<<<<<<<<<<<< + * self.geodesic_t.ALPHA12 = azdata[i] + * self.geodesic_t.DIST = distdata[i] + */ ((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.p1.u = (__pyx_v_latsdata[__pyx_v_i]); - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":60 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":60 + * self.geodesic_t.p1.v = lonsdata[i] + * self.geodesic_t.p1.u = latsdata[i] + * self.geodesic_t.ALPHA12 = azdata[i] # <<<<<<<<<<<<<< + * self.geodesic_t.DIST = distdata[i] + * else: + */ ((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.ALPHA12 = (__pyx_v_azdata[__pyx_v_i]); - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":61 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":61 + * self.geodesic_t.p1.u = latsdata[i] + * self.geodesic_t.ALPHA12 = azdata[i] + * self.geodesic_t.DIST = distdata[i] # <<<<<<<<<<<<<< + * else: + * self.geodesic_t.p1.v = _dg2rad*lonsdata[i] + */ ((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.DIST = (__pyx_v_distdata[__pyx_v_i]); goto __pyx_L9; } /*else*/ { - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":63 */ - __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n__dg2rad); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; goto __pyx_L1;} - __pyx_4 = PyFloat_FromDouble((__pyx_v_lonsdata[__pyx_v_i])); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; goto __pyx_L1;} - __pyx_5 = PyNumber_Multiply(__pyx_2, __pyx_4); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; goto __pyx_L1;} - Py_DECREF(__pyx_2); __pyx_2 = 0; + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":63 + * self.geodesic_t.DIST = distdata[i] + * else: + * self.geodesic_t.p1.v = _dg2rad*lonsdata[i] # <<<<<<<<<<<<<< + * self.geodesic_t.p1.u = _dg2rad*latsdata[i] + * self.geodesic_t.ALPHA12 = _dg2rad*azdata[i] + */ + __pyx_3 = __Pyx_GetName(__pyx_m, __pyx_n__dg2rad); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; goto __pyx_L1;} + __pyx_4 = PyFloat_FromDouble((__pyx_v_lonsdata[__pyx_v_i])); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; goto __pyx_L1;} + __pyx_5 = PyNumber_Multiply(__pyx_3, __pyx_4); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; goto __pyx_L1;} + Py_DECREF(__pyx_3); __pyx_3 = 0; Py_DECREF(__pyx_4); __pyx_4 = 0; - __pyx_7 = PyFloat_AsDouble(__pyx_5); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; goto __pyx_L1;} + __pyx_7 = PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; goto __pyx_L1;} Py_DECREF(__pyx_5); __pyx_5 = 0; ((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.p1.v = __pyx_7; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":64 */ - __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n__dg2rad); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; goto __pyx_L1;} - __pyx_4 = PyFloat_FromDouble((__pyx_v_latsdata[__pyx_v_i])); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; goto __pyx_L1;} - __pyx_5 = PyNumber_Multiply(__pyx_2, __pyx_4); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; goto __pyx_L1;} - Py_DECREF(__pyx_2); __pyx_2 = 0; + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":64 + * else: + * self.geodesic_t.p1.v = _dg2rad*lonsdata[i] + * self.geodesic_t.p1.u = _dg2rad*latsdata[i] # <<<<<<<<<<<<<< + * self.geodesic_t.ALPHA12 = _dg2rad*azdata[i] + * self.geodesic_t.DIST = distdata[i] + */ + __pyx_3 = __Pyx_GetName(__pyx_m, __pyx_n__dg2rad); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; goto __pyx_L1;} + __pyx_4 = PyFloat_FromDouble((__pyx_v_latsdata[__pyx_v_i])); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; goto __pyx_L1;} + __pyx_5 = PyNumber_Multiply(__pyx_3, __pyx_4); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; goto __pyx_L1;} + Py_DECREF(__pyx_3); __pyx_3 = 0; Py_DECREF(__pyx_4); __pyx_4 = 0; - __pyx_7 = PyFloat_AsDouble(__pyx_5); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; goto __pyx_L1;} + __pyx_7 = PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; goto __pyx_L1;} Py_DECREF(__pyx_5); __pyx_5 = 0; ((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.p1.u = __pyx_7; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":65 */ - __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n__dg2rad); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;} - __pyx_4 = PyFloat_FromDouble((__pyx_v_azdata[__pyx_v_i])); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;} - __pyx_5 = PyNumber_Multiply(__pyx_2, __pyx_4); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;} - Py_DECREF(__pyx_2); __pyx_2 = 0; + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":65 + * self.geodesic_t.p1.v = _dg2rad*lonsdata[i] + * self.geodesic_t.p1.u = _dg2rad*latsdata[i] + * self.geodesic_t.ALPHA12 = _dg2rad*azdata[i] # <<<<<<<<<<<<<< + * self.geodesic_t.DIST = distdata[i] + * geod_pre(&self.geodesic_t) + */ + __pyx_3 = __Pyx_GetName(__pyx_m, __pyx_n__dg2rad); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;} + __pyx_4 = PyFloat_FromDouble((__pyx_v_azdata[__pyx_v_i])); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;} + __pyx_5 = PyNumber_Multiply(__pyx_3, __pyx_4); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;} + Py_DECREF(__pyx_3); __pyx_3 = 0; Py_DECREF(__pyx_4); __pyx_4 = 0; - __pyx_7 = PyFloat_AsDouble(__pyx_5); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;} + __pyx_7 = PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;} Py_DECREF(__pyx_5); __pyx_5 = 0; ((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.ALPHA12 = __pyx_7; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":66 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":66 + * self.geodesic_t.p1.u = _dg2rad*latsdata[i] + * self.geodesic_t.ALPHA12 = _dg2rad*azdata[i] + * self.geodesic_t.DIST = distdata[i] # <<<<<<<<<<<<<< + * geod_pre(&self.geodesic_t) + * if pj_errno != 0: + */ ((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.DIST = (__pyx_v_distdata[__pyx_v_i]); } __pyx_L9:; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":67 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":67 + * self.geodesic_t.ALPHA12 = _dg2rad*azdata[i] + * self.geodesic_t.DIST = distdata[i] + * geod_pre(&self.geodesic_t) # <<<<<<<<<<<<<< + * if pj_errno != 0: + * raise RuntimeError(pj_strerrno(pj_errno)) + */ geod_pre((&((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t)); - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":68 */ - __pyx_3 = (pj_errno != 0); - if (__pyx_3) { + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":68 + * self.geodesic_t.DIST = distdata[i] + * geod_pre(&self.geodesic_t) + * if pj_errno != 0: # <<<<<<<<<<<<<< + * raise RuntimeError(pj_strerrno(pj_errno)) + * geod_for(&self.geodesic_t) + */ + __pyx_2 = (pj_errno != 0); + if (__pyx_2) { - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":69 */ - __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_RuntimeError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; goto __pyx_L1;} - __pyx_4 = PyString_FromString(pj_strerrno(pj_errno)); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; goto __pyx_L1;} - __pyx_5 = PyTuple_New(1); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; goto __pyx_L1;} - PyTuple_SET_ITEM(__pyx_5, 0, __pyx_4); - __pyx_4 = 0; - __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_5); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; goto __pyx_L1;} - Py_DECREF(__pyx_2); __pyx_2 = 0; + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":69 + * geod_pre(&self.geodesic_t) + * if pj_errno != 0: + * raise RuntimeError(pj_strerrno(pj_errno)) # <<<<<<<<<<<<<< + * geod_for(&self.geodesic_t) + * if pj_errno != 0: + */ + __pyx_3 = PyString_FromString(pj_strerrno(pj_errno)); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; goto __pyx_L1;} + __pyx_4 = PyTuple_New(1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; goto __pyx_L1;} + PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3); + __pyx_3 = 0; + __pyx_5 = PyObject_CallObject(__pyx_builtin_RuntimeError, __pyx_4); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; goto __pyx_L1;} + Py_DECREF(__pyx_4); __pyx_4 = 0; + __Pyx_Raise(__pyx_5, 0, 0); Py_DECREF(__pyx_5); __pyx_5 = 0; - __Pyx_Raise(__pyx_4, 0, 0); - Py_DECREF(__pyx_4); __pyx_4 = 0; {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; goto __pyx_L1;} goto __pyx_L10; } __pyx_L10:; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":70 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":70 + * if pj_errno != 0: + * raise RuntimeError(pj_strerrno(pj_errno)) + * geod_for(&self.geodesic_t) # <<<<<<<<<<<<<< + * if pj_errno != 0: + * raise RuntimeError(pj_strerrno(pj_errno)) + */ geod_for((&((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t)); - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":71 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":71 + * raise RuntimeError(pj_strerrno(pj_errno)) + * geod_for(&self.geodesic_t) + * if pj_errno != 0: # <<<<<<<<<<<<<< + * raise RuntimeError(pj_strerrno(pj_errno)) + * if isnan(self.geodesic_t.ALPHA21) == FP_NAN: + */ __pyx_1 = (pj_errno != 0); if (__pyx_1) { - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":72 */ - __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_RuntimeError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; goto __pyx_L1;} - __pyx_5 = PyString_FromString(pj_strerrno(pj_errno)); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; goto __pyx_L1;} - __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; goto __pyx_L1;} - PyTuple_SET_ITEM(__pyx_4, 0, __pyx_5); - __pyx_5 = 0; - __pyx_5 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; goto __pyx_L1;} - Py_DECREF(__pyx_2); __pyx_2 = 0; + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":72 + * geod_for(&self.geodesic_t) + * if pj_errno != 0: + * raise RuntimeError(pj_strerrno(pj_errno)) # <<<<<<<<<<<<<< + * if isnan(self.geodesic_t.ALPHA21) == FP_NAN: + * raise ValueError('undefined forward geodesic (may be an equatorial arc)') + */ + __pyx_3 = PyString_FromString(pj_strerrno(pj_errno)); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; goto __pyx_L1;} + __pyx_4 = PyTuple_New(1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; goto __pyx_L1;} + PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3); + __pyx_3 = 0; + __pyx_5 = PyObject_CallObject(__pyx_builtin_RuntimeError, __pyx_4); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; goto __pyx_L1;} Py_DECREF(__pyx_4); __pyx_4 = 0; __Pyx_Raise(__pyx_5, 0, 0); Py_DECREF(__pyx_5); __pyx_5 = 0; @@ -527,69 +806,121 @@ } __pyx_L11:; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":73 */ - __pyx_3 = (isnan(((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.ALPHA21) == FP_NAN); - if (__pyx_3) { + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":73 + * if pj_errno != 0: + * raise RuntimeError(pj_strerrno(pj_errno)) + * if isnan(self.geodesic_t.ALPHA21) == FP_NAN: # <<<<<<<<<<<<<< + * raise ValueError('undefined forward geodesic (may be an equatorial arc)') + * if radians: + */ + __pyx_2 = (isnan(((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.ALPHA21) == FP_NAN); + if (__pyx_2) { - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":74 */ - __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; goto __pyx_L1;} - __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; goto __pyx_L1;} + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":74 + * raise RuntimeError(pj_strerrno(pj_errno)) + * if isnan(self.geodesic_t.ALPHA21) == FP_NAN: + * raise ValueError('undefined forward geodesic (may be an equatorial arc)') # <<<<<<<<<<<<<< + * if radians: + * lonsdata[i] = self.geodesic_t.p2.v + */ + __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; goto __pyx_L1;} Py_INCREF(__pyx_k11p); - PyTuple_SET_ITEM(__pyx_4, 0, __pyx_k11p); - __pyx_5 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; goto __pyx_L1;} - Py_DECREF(__pyx_2); __pyx_2 = 0; + PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k11p); + __pyx_4 = PyObject_CallObject(__pyx_builtin_ValueError, __pyx_3); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; goto __pyx_L1;} + Py_DECREF(__pyx_3); __pyx_3 = 0; + __Pyx_Raise(__pyx_4, 0, 0); Py_DECREF(__pyx_4); __pyx_4 = 0; - __Pyx_Raise(__pyx_5, 0, 0); - Py_DECREF(__pyx_5); __pyx_5 = 0; {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; goto __pyx_L1;} goto __pyx_L12; } __pyx_L12:; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":75 */ - __pyx_1 = PyObject_IsTrue(__pyx_v_radians); if (__pyx_1 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; goto __pyx_L1;} + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":75 + * if isnan(self.geodesic_t.ALPHA21) == FP_NAN: + * raise ValueError('undefined forward geodesic (may be an equatorial arc)') + * if radians: # <<<<<<<<<<<<<< + * lonsdata[i] = self.geodesic_t.p2.v + * latsdata[i] = self.geodesic_t.p2.u + */ + __pyx_1 = PyObject_IsTrue(__pyx_v_radians); if (unlikely(__pyx_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; goto __pyx_L1;} if (__pyx_1) { - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":76 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":76 + * raise ValueError('undefined forward geodesic (may be an equatorial arc)') + * if radians: + * lonsdata[i] = self.geodesic_t.p2.v # <<<<<<<<<<<<<< + * latsdata[i] = self.geodesic_t.p2.u + * azdata[i] = self.geodesic_t.ALPHA21 + */ (__pyx_v_lonsdata[__pyx_v_i]) = ((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.p2.v; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":77 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":77 + * if radians: + * lonsdata[i] = self.geodesic_t.p2.v + * latsdata[i] = self.geodesic_t.p2.u # <<<<<<<<<<<<<< + * azdata[i] = self.geodesic_t.ALPHA21 + * else: + */ (__pyx_v_latsdata[__pyx_v_i]) = ((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.p2.u; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":78 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":78 + * lonsdata[i] = self.geodesic_t.p2.v + * latsdata[i] = self.geodesic_t.p2.u + * azdata[i] = self.geodesic_t.ALPHA21 # <<<<<<<<<<<<<< + * else: + * lonsdata[i] = _rad2dg*self.geodesic_t.p2.v + */ (__pyx_v_azdata[__pyx_v_i]) = ((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.ALPHA21; goto __pyx_L13; } /*else*/ { - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":80 */ - __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n__rad2dg); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; goto __pyx_L1;} - __pyx_4 = PyFloat_FromDouble(((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.p2.v); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; goto __pyx_L1;} - __pyx_5 = PyNumber_Multiply(__pyx_2, __pyx_4); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; goto __pyx_L1;} - Py_DECREF(__pyx_2); __pyx_2 = 0; + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":80 + * azdata[i] = self.geodesic_t.ALPHA21 + * else: + * lonsdata[i] = _rad2dg*self.geodesic_t.p2.v # <<<<<<<<<<<<<< + * latsdata[i] = _rad2dg*self.geodesic_t.p2.u + * azdata[i] = _rad2dg*self.geodesic_t.ALPHA21 + */ + __pyx_5 = __Pyx_GetName(__pyx_m, __pyx_n__rad2dg); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; goto __pyx_L1;} + __pyx_3 = PyFloat_FromDouble(((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.p2.v); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; goto __pyx_L1;} + __pyx_4 = PyNumber_Multiply(__pyx_5, __pyx_3); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; goto __pyx_L1;} + Py_DECREF(__pyx_5); __pyx_5 = 0; + Py_DECREF(__pyx_3); __pyx_3 = 0; + __pyx_7 = PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; goto __pyx_L1;} Py_DECREF(__pyx_4); __pyx_4 = 0; - __pyx_7 = PyFloat_AsDouble(__pyx_5); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; goto __pyx_L1;} - Py_DECREF(__pyx_5); __pyx_5 = 0; (__pyx_v_lonsdata[__pyx_v_i]) = __pyx_7; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":81 */ - __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n__rad2dg); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; goto __pyx_L1;} - __pyx_4 = PyFloat_FromDouble(((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.p2.u); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; goto __pyx_L1;} - __pyx_5 = PyNumber_Multiply(__pyx_2, __pyx_4); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; goto __pyx_L1;} - Py_DECREF(__pyx_2); __pyx_2 = 0; + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":81 + * else: + * lonsdata[i] = _rad2dg*self.geodesic_t.p2.v + * latsdata[i] = _rad2dg*self.geodesic_t.p2.u # <<<<<<<<<<<<<< + * azdata[i] = _rad2dg*self.geodesic_t.ALPHA21 + * + */ + __pyx_5 = __Pyx_GetName(__pyx_m, __pyx_n__rad2dg); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; goto __pyx_L1;} + __pyx_3 = PyFloat_FromDouble(((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.p2.u); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; goto __pyx_L1;} + __pyx_4 = PyNumber_Multiply(__pyx_5, __pyx_3); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; goto __pyx_L1;} + Py_DECREF(__pyx_5); __pyx_5 = 0; + Py_DECREF(__pyx_3); __pyx_3 = 0; + __pyx_7 = PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; goto __pyx_L1;} Py_DECREF(__pyx_4); __pyx_4 = 0; - __pyx_7 = PyFloat_AsDouble(__pyx_5); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; goto __pyx_L1;} - Py_DECREF(__pyx_5); __pyx_5 = 0; (__pyx_v_latsdata[__pyx_v_i]) = __pyx_7; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":82 */ - __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n__rad2dg); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; goto __pyx_L1;} - __pyx_4 = PyFloat_FromDouble(((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.ALPHA21); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; goto __pyx_L1;} - __pyx_5 = PyNumber_Multiply(__pyx_2, __pyx_4); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; goto __pyx_L1;} - Py_DECREF(__pyx_2); __pyx_2 = 0; + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":82 + * lonsdata[i] = _rad2dg*self.geodesic_t.p2.v + * latsdata[i] = _rad2dg*self.geodesic_t.p2.u + * azdata[i] = _rad2dg*self.geodesic_t.ALPHA21 # <<<<<<<<<<<<<< + * + * def _inv(self, object lons1, object lats1, object lons2, object lats2, radians=False): + */ + __pyx_5 = __Pyx_GetName(__pyx_m, __pyx_n__rad2dg); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; goto __pyx_L1;} + __pyx_3 = PyFloat_FromDouble(((struct __pyx_obj_5_geod_Geod *)__pyx_v_self)->geodesic_t.ALPHA21); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; goto __pyx_L1;} + __pyx_4 = PyNumber_Multiply(__pyx_5, __pyx_3); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; goto __pyx_L1;} + Py_DECREF(__pyx_5); __pyx_5 = 0; + Py_DECREF(__pyx_3); __pyx_3 = 0; + __pyx_7 = PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; goto __pyx_L1;} Py_DECREF(__pyx_4); __pyx_4 = 0; - __pyx_7 = PyFloat_AsDouble(__pyx_5); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; goto __pyx_L1;} - Py_DECREF(__pyx_5); __pyx_5 = 0; (__pyx_v_azdata[__pyx_v_i]) = __pyx_7; } __pyx_L13:; @@ -598,7 +929,7 @@ __pyx_r = Py_None; Py_INCREF(Py_None); goto __pyx_L0; __pyx_L1:; - Py_XDECREF(__pyx_2); + Py_XDECREF(__pyx_3); Py_XDECREF(__pyx_4); Py_XDECREF(__pyx_5); __Pyx_AddTraceback("_geod.Geod._fwd"); @@ -643,15 +974,15 @@ void (*__pyx_v_distdat); PyObject *__pyx_r; int __pyx_1; - PyObject *__pyx_2 = 0; - int __pyx_3; + int __pyx_2; + PyObject *__pyx_3 = 0; PyObject *__pyx_4 = 0; PyObject *__pyx_5 = 0; Py_ssize_t __pyx_6; double __pyx_7; static char *__pyx_argnames[] = {"lons1","lats1","lons2","lats2","radians",0}; __pyx_v_radians = __pyx_k4; - if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OOOO|O", __pyx_argnames, &__pyx_v_lons1, &__pyx_v_lats1, &__pyx_v_lons2, &__pyx_v_lats2, &__pyx_v_radians)) return 0; + if (unlikely(!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OOOO|O", __pyx_argnames, &__pyx_v_lons1, &__pyx_v_lats1, &__pyx_v_lons2, &__pyx_v_lats2, &__pyx_v_radians))) return 0; Py_INCREF(__pyx_v_self); Py_INCREF(__pyx_v_lons1); Py_INCREF(__pyx_v_lats1); @@ -659,59 +990,105 @@ Py_INCREF(__pyx_v_lats2); Py_INCREF(__pyx_v_radians); - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":94 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":94 + * cdef void *londata, *latdata, *azdat, *distdat + * # if buffer api is supported, get pointer to data buffers. + * if PyObject_AsWriteBuffer(lons1, &londata, &buflenlons) <> 0: # <<<<<<<<<<<<<< + * raise RuntimeError + * if PyObject_AsWriteBuffer(lats1, &latdata, &buflenlats) <> 0: + */ __pyx_1 = (PyObject_AsWriteBuffer(__pyx_v_lons1,(&__pyx_v_londata),(&__pyx_v_buflenlons)) != 0); if (__pyx_1) { - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":95 */ - __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_RuntimeError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; goto __pyx_L1;} - __Pyx_Raise(__pyx_2, 0, 0); - Py_DECREF(__pyx_2); __pyx_2 = 0; + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":95 + * # if buffer api is supported, get pointer to data buffers. + * if PyObject_AsWriteBuffer(lons1, &londata, &buflenlons) <> 0: + * raise RuntimeError # <<<<<<<<<<<<<< + * if PyObject_AsWriteBuffer(lats1, &latdata, &buflenlats) <> 0: + * raise RuntimeError + */ + __Pyx_Raise(__pyx_builtin_RuntimeError, 0, 0); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; goto __pyx_L1;} goto __pyx_L2; } __pyx_L2:; - /* "/Users/jsw/python/matplotlib/trunk/toolkits/basemap/src/_geod.pyx":96 */ + /* "/Volumes/User/jwhitaker/python/pyproj/_geod.pyx":96 + * if PyObject_AsWriteBuffer(lons1, &londata, &buflenlons) <> 0: + * raise RuntimeError + * if PyObject_AsWriteBuffer(lats1, &latdata, &buflenlats) <> 0: # <<<<<<<<<<<<<< + * raise RuntimeError + * if PyObject_AsWriteBuffer(lons2, &azdat, &buflenaz) <> 0: + */ __pyx_1 = (PyObject_AsWriteBuffer(__pyx_v_... [truncated message content] |
From: <md...@us...> - 2007-08-31 15:40:46
|
Revision: 3762 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3762&view=rev Author: mdboom Date: 2007-08-31 08:40:42 -0700 (Fri, 31 Aug 2007) Log Message: ----------- Oops in last commit. Modified Paths: -------------- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg.py =================================================================== --- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-08-31 15:09:27 UTC (rev 3761) +++ trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2007-08-31 15:40:42 UTC (rev 3762) @@ -172,7 +172,7 @@ """ if __debug__: verbose.report('RendererAgg.draw_mathtext', 'debug-annoying') - ox, oy, width, height, descent, font_image, used_characters = \ + ox, oy, width, height, descent, fonts, used_characters = \ self.mathtext_parser.parse(s, self.dpi.get(), prop) if angle == 90: @@ -183,9 +183,10 @@ else: x = int(x) + ox y = int(y) - height + oy - if angle == 90: - font_image.rotate() # <-- Rotate 90 deg - self._renderer.draw_text_image(font_image, x, y + 1, gc) + for font in fonts: + if angle == 90: + font.horiz_image_to_vert_image() # <-- Rotate + self._renderer.draw_text( font, x, y + 1, gc) if 0: self._renderer.draw_rectangle(gc, None, int(x), @@ -211,7 +212,7 @@ #print x, y, int(x), int(y) - self._renderer.draw_text_image(font.get_image(), int(x), int(y) + 1, gc) + self._renderer.draw_text(font, int(x), int(y) + 1, gc) def get_text_width_height_descent(self, s, prop, ismath, rgb=(0,0,0)): @@ -232,7 +233,7 @@ return n,m if ismath: - ox, oy, width, height, descent, font_image, used_characters = \ + ox, oy, width, height, descent, fonts, used_characters = \ self.mathtext_parser.parse(s, self.dpi.get(), prop) return width, height, descent font = self._get_agg_font(prop) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |