SourceForge logo
SourceForge logo
Menu

matplotlib-checkins — Commit notification. DO NOT POST to this list, just subscribe to it.

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
S M T W T F S






1
2
(1)
3
(4)
4
(9)
5
(14)
6
(8)
7
(14)
8
(1)
9
(2)
10
(9)
11
(5)
12
(11)
13
(4)
14
(4)
15
(1)
16
17
(1)
18
(2)
19
(4)
20
(10)
21
(3)
22
(3)
23
(2)
24
(8)
25
(6)
26
(5)
27
28
(3)
29
30
(3)






Showing results of 137

<< < 1 .. 4 5 6 (Page 6 of 6)
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 (2007年9月04日)
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 (2007年9月04日)
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 (2007年9月04日)
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 (2007年9月04日)
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 (2007年9月04日)
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 (2007年9月03日)
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 (2007年9月03日)
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.
Revision: 3771
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3771&view=rev
Author: jouni
Date: 2007年09月03日 15:16:19 -0700 (2007年9月03日)
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 (2007年9月03日)
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 (2007年9月03日)
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.
Revision: 3768
 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=3768&view=rev
Author: jouni
Date: 2007年09月03日 09:29:08 -0700 (2007年9月03日)
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 (2007年9月02日)
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.

Showing results of 137

<< < 1 .. 4 5 6 (Page 6 of 6)
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.
Thanks for helping keep SourceForge clean.
X





Briefly describe the problem (required):
Upload screenshot of ad (required):
Select a file, or drag & drop file here.
Screenshot instructions:

Click URL instructions:
Right-click on the ad, choose "Copy Link", then paste here →
(This may not be possible with some types of ads)

More information about our ad policies

Ad destination/click URL:

AltStyle によって変換されたページ (->オリジナル) /