You can subscribe to this list here.
| 2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(115) |
Aug
(120) |
Sep
(137) |
Oct
(170) |
Nov
(461) |
Dec
(263) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2008 |
Jan
(120) |
Feb
(74) |
Mar
(35) |
Apr
(74) |
May
(245) |
Jun
(356) |
Jul
(240) |
Aug
(115) |
Sep
(78) |
Oct
(225) |
Nov
(98) |
Dec
(271) |
| 2009 |
Jan
(132) |
Feb
(84) |
Mar
(74) |
Apr
(56) |
May
(90) |
Jun
(79) |
Jul
(83) |
Aug
(296) |
Sep
(214) |
Oct
(76) |
Nov
(82) |
Dec
(66) |
| 2010 |
Jan
(46) |
Feb
(58) |
Mar
(51) |
Apr
(77) |
May
(58) |
Jun
(126) |
Jul
(128) |
Aug
(64) |
Sep
(50) |
Oct
(44) |
Nov
(48) |
Dec
(54) |
| 2011 |
Jan
(68) |
Feb
(52) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
| 2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <jo...@us...> - 2009-01-05 17:48:05
|
Revision: 6737
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6737&view=rev
Author: jouni
Date: 2009-01-05 17:48:01 +0000 (Mon, 05 Jan 2009)
Log Message:
-----------
Fix a bug in pdf usetex: allow using non-embedded fonts
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2009-01-05 14:47:08 UTC (rev 6736)
+++ trunk/matplotlib/CHANGELOG 2009-01-05 17:48:01 UTC (rev 6737)
@@ -1,3 +1,5 @@
+2009-01-05 Fix a bug in pdf usetex: allow using non-embedded fonts. - JKS
+
2009-01-05 optional use of preview.sty in usetex mode. - JJL
2009-01-02 Allow multipage pdf files. - JKS
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2009-01-05 14:47:08 UTC (rev 6736)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2009-01-05 17:48:01 UTC (rev 6737)
@@ -88,11 +88,9 @@
# * the alpha channel of images
# * image compression could be improved (PDF supports png-like compression)
# * encoding of fonts, including mathtext fonts and unicode support
-# * Type 1 font support (i.e., "pdf.use_afm")
# * TTF support has lots of small TODOs, e.g. how do you know if a font
# is serif/sans-serif, or symbolic/non-symbolic?
# * draw_markers, draw_line_collection, etc.
-# * use_tex
def fill(strings, linelen=75):
"""Make one string from sequence of strings, with whitespace
@@ -518,7 +516,7 @@
elif self.dviFontInfo.has_key(filename):
# a Type 1 font from a dvi file; the filename is really the TeX name
matplotlib.verbose.report('Writing Type-1 font', 'debug')
- fontdictObject = self.embedType1(filename, self.dviFontInfo[filename])
+ fontdictObject = self.embedTeXFont(filename, self.dviFontInfo[filename])
else:
# a normal TrueType font
matplotlib.verbose.report('Writing TrueType font', 'debug')
@@ -542,53 +540,62 @@
self.writeObject(fontdictObject, fontdict)
return fontdictObject
- def embedType1(self, texname, fontinfo):
+ def embedTeXFont(self, texname, fontinfo):
matplotlib.verbose.report(
- 'Embedding ' + texname +
- ' which is the Type 1 font ' + (fontinfo.fontfile or '(none)') +
- ' with encoding ' + (fontinfo.encodingfile or '(none)') +
- ' and effects ' + `fontinfo.effects`,
+ 'Embedding TeX font ' + texname + ' - fontinfo=' + `fontinfo.__dict__`,
'debug')
- t1font = type1font.Type1Font(fontinfo.fontfile)
- if fontinfo.effects:
- t1font = t1font.transform(fontinfo.effects)
-
- # Font descriptors may be shared between differently encoded
- # Type-1 fonts, so only create a new descriptor if there is no
- # existing descriptor for this font.
- effects = (fontinfo.effects.get('slant', 0.0), fontinfo.effects.get('extend', 1.0))
- fontdesc = self.type1Descriptors.get((fontinfo.fontfile, effects))
- if fontdesc is None:
- fontdesc = self.createType1Descriptor(t1font, fontinfo.fontfile)
- self.type1Descriptors[(fontinfo.fontfile, effects)] = fontdesc
-
# Widths
widthsObject = self.reserveObject('font widths')
- self.writeObject(widthsObject, fontinfo.widths)
+ self.writeObject(widthsObject, fontinfo.dvifont.widths)
# Font dictionary
fontdictObject = self.reserveObject('font dictionary')
fontdict = {
- 'Type': Name('Font'),
- 'Subtype': Name('Type1'),
- 'BaseFont': Name(t1font.prop['FontName']),
- 'FirstChar': 0,
- 'LastChar': len(fontinfo.widths) - 1,
- 'Widths': widthsObject,
- 'FontDescriptor': fontdesc,
- }
+ 'Type': Name('Font'),
+ 'Subtype': Name('Type1'),
+ 'FirstChar': 0,
+ 'LastChar': len(fontinfo.dvifont.widths) - 1,
+ 'Widths': widthsObject,
+ }
# Encoding (if needed)
if fontinfo.encodingfile is not None:
enc = dviread.Encoding(fontinfo.encodingfile)
differencesArray = [ Name(ch) for ch in enc ]
differencesArray = [ 0 ] + differencesArray
- fontdict.update({
- 'Encoding': { 'Type': Name('Encoding'),
- 'Differences': differencesArray },
- })
+ fontdict['Encoding'] = \
+ { 'Type': Name('Encoding'),
+ 'Differences': differencesArray }
+ # If no file is specified, stop short
+ if fontinfo.fontfile is None:
+ warnings.warn(
+ 'Because of TeX configuration (pdftex.map, see updmap ' +
+ 'option pdftexDownloadBase14) the font %s ' % fontinfo.basefont +
+ 'is not embedded. This is deprecated as of PDF 1.5 ' +
+ 'and it may cause the consumer application to show something ' +
+ 'that was not intended.')
+ fontdict['BaseFont'] = Name(fontinfo.basefont)
+ self.writeObject(fontdictObject, fontdict)
+ return fontdictObject
+
+ # We have a font file to embed - read it in and apply any effects
+ t1font = type1font.Type1Font(fontinfo.fontfile)
+ if fontinfo.effects:
+ t1font = t1font.transform(fontinfo.effects)
+ fontdict['BaseFont'] = Name(t1font.prop['FontName'])
+
+ # Font descriptors may be shared between differently encoded
+ # Type-1 fonts, so only create a new descriptor if there is no
+ # existing descriptor for this font.
+ effects = (fontinfo.effects.get('slant', 0.0), fontinfo.effects.get('extend', 1.0))
+ fontdesc = self.type1Descriptors.get((fontinfo.fontfile, effects))
+ if fontdesc is None:
+ fontdesc = self.createType1Descriptor(t1font, fontinfo.fontfile)
+ self.type1Descriptors[(fontinfo.fontfile, effects)] = fontdesc
+ fontdict['FontDescriptor'] = fontdesc
+
self.writeObject(fontdictObject, fontdict)
return fontdictObject
@@ -1389,11 +1396,12 @@
pdfname = self.file.fontName(dvifont.texname)
if not self.file.dviFontInfo.has_key(dvifont.texname):
psfont = self.tex_font_mapping(dvifont.texname)
+ fontfile = psfont.filename
self.file.dviFontInfo[dvifont.texname] = Bunch(
fontfile=psfont.filename,
+ basefont=psfont.psname,
encodingfile=psfont.encoding,
effects=psfont.effects,
- widths=dvifont.widths,
dvifont=dvifont)
seq += [['font', pdfname, dvifont.size]]
oldfont = dvifont
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2009-01-05 14:47:13
|
Revision: 6736
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6736&view=rev
Author: mdboom
Date: 2009-01-05 14:47:08 +0000 (Mon, 05 Jan 2009)
Log Message:
-----------
Fix crash rendering verbose message
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 2009-01-05 14:46:33 UTC (rev 6735)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2009-01-05 14:47:08 UTC (rev 6736)
@@ -545,7 +545,7 @@
def embedType1(self, texname, fontinfo):
matplotlib.verbose.report(
'Embedding ' + texname +
- ' which is the Type 1 font ' + fontinfo.fontfile +
+ ' which is the Type 1 font ' + (fontinfo.fontfile or '(none)') +
' with encoding ' + (fontinfo.encodingfile or '(none)') +
' and effects ' + `fontinfo.effects`,
'debug')
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2009-01-05 14:46:40
|
Revision: 6735
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6735&view=rev
Author: mdboom
Date: 2009-01-05 14:46:33 +0000 (Mon, 05 Jan 2009)
Log Message:
-----------
Add some comments for clarification
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/path.py
Modified: trunk/matplotlib/lib/matplotlib/path.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/path.py 2009-01-05 05:28:57 UTC (rev 6734)
+++ trunk/matplotlib/lib/matplotlib/path.py 2009-01-05 14:46:33 UTC (rev 6735)
@@ -603,6 +603,7 @@
cursor = 0
+ # - horizontal
if counts[0]:
vertices_chunk = vertices[cursor:cursor + counts[0] * 2]
cursor += counts[0] * 2
@@ -612,6 +613,7 @@
vertices_chunk[1::2, 0] = size
vertices_chunk[1::2, 1] = steps
+ # / ne
if counts[1]:
vertices_chunk = vertices[cursor:cursor + counts[1] * 4]
cursor += counts[1] * 4
@@ -625,6 +627,7 @@
vertices_chunk[3::4, 0] = size
vertices_chunk[3::4, 1] = steps
+ # | vertical
if counts[2]:
vertices_chunk = vertices[cursor:cursor + counts[2] * 2]
cursor += counts[2] * 2
@@ -634,6 +637,7 @@
vertices_chunk[1::2, 0] = steps
vertices_chunk[1::2, 1] = size
+ # \ se
if counts[3]:
vertices_chunk = vertices[cursor:cursor + counts[3] * 4]
cursor += counts[3] * 4
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <lee...@us...> - 2009-01-05 05:29:01
|
Revision: 6734
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6734&view=rev
Author: leejjoon
Date: 2009-01-05 05:28:57 +0000 (Mon, 05 Jan 2009)
Log Message:
-----------
optional use of preview.sty in usetex mode
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/backends/backend_agg.py
trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py
trunk/matplotlib/lib/matplotlib/backends/backend_ps.py
trunk/matplotlib/lib/matplotlib/mpl-data/matplotlib.conf.template
trunk/matplotlib/lib/matplotlib/rcsetup.py
trunk/matplotlib/lib/matplotlib/texmanager.py
Added Paths:
-----------
trunk/matplotlib/examples/pylab_examples/usetex_baseline_test.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2009-01-02 17:56:15 UTC (rev 6733)
+++ trunk/matplotlib/CHANGELOG 2009-01-05 05:28:57 UTC (rev 6734)
@@ -1,3 +1,5 @@
+2009-01-05 optional use of preview.sty in usetex mode. - JJL
+
2009-01-02 Allow multipage pdf files. - JKS
2008-12-31 Improve pdf usetex by adding support for font effects
Added: trunk/matplotlib/examples/pylab_examples/usetex_baseline_test.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/usetex_baseline_test.py (rev 0)
+++ trunk/matplotlib/examples/pylab_examples/usetex_baseline_test.py 2009-01-05 05:28:57 UTC (rev 6734)
@@ -0,0 +1,76 @@
+
+import matplotlib
+import matplotlib.pyplot as plt
+import matplotlib.axes as maxes
+
+class Axes(maxes.Axes):
+ """
+ A hackish way to simultaneously draw texts w/ usetex=True and
+ usetex=False in the same figure. It does not work in the ps backend.
+ """
+ def __init__(self, *kl, **kw):
+ self.usetex = kw.pop("usetex", "False")
+ self.preview = kw.pop("preview", "False")
+
+ maxes.Axes.__init__(self, *kl, **kw)
+
+ def draw(self, renderer):
+ usetex = plt.rcParams["text.usetex"]
+ preview = plt.rcParams["text.latex.preview"]
+ plt.rcParams["text.usetex"] = self.usetex
+ plt.rcParams["text.latex.preview"] = self.preview
+
+ maxes.Axes.draw(self, renderer)
+
+ plt.rcParams["text.usetex"] = usetex
+ plt.rcParams["text.latex.preview"] = preview
+
+Subplot = maxes.subplot_class_factory(Axes)
+
+
+def test_window_extent(ax, usetex, preview):
+
+ va = "baseline"
+ ax.xaxis.set_visible(False)
+ ax.yaxis.set_visible(False)
+
+
+ #t = ax.text(0., 0., r"mlp", va="baseline", size=150)
+ text_kw = dict(va=va,
+ size=50,
+ bbox=dict(pad=0., ec="k", fc="none"))
+
+
+ test_strings = ["lg", r"$\frac{1}{2}\pi$",
+ r"$p^{3^A}$", r"$p_{3_2}$"]
+
+ ax.axvline(0, color="r")
+
+ for i, s in enumerate(test_strings):
+
+ ax.axhline(i, color="r")
+ ax.text(0., 3-i, s, **text_kw)
+
+ ax.set_xlim(-0.1,1.1)
+ ax.set_ylim(-.8,3.9)
+
+
+ ax.set_title("usetex=%s\npreview=%s" % (str(usetex), str(preview)))
+
+
+
+F = plt.figure(figsize=(2.*3,6.5))
+
+for i, usetex, preview in [[0, False, False],
+ [1, True, False],
+ [2, True, True]]:
+ ax = Subplot(F, 1, 3, i+1, usetex=usetex, preview=preview)
+ F.add_subplot(ax)
+ F.subplots_adjust(top=0.85)
+
+ test_window_extent(ax, usetex=usetex, preview=preview)
+
+
+plt.draw()
+plt.show()
+
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_agg.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2009-01-02 17:56:15 UTC (rev 6733)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_agg.py 2009-01-05 05:28:57 UTC (rev 6734)
@@ -146,10 +146,10 @@
# todo: handle props
size = prop.get_size_in_points()
texmanager = self.get_texmanager()
- Z = texmanager.get_grey(s, size, self.dpi)
- m,n = Z.shape
- # TODO: descent of TeX text (I am imitating backend_ps here -JKS)
- return n, m, 0
+ fontsize = prop.get_size_in_points()
+ w, h, d = texmanager.get_text_width_height_descent(s, fontsize,
+ renderer=self)
+ return w, h, d
if ismath:
ox, oy, width, height, descent, fonts, used_characters = \
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2009-01-02 17:56:15 UTC (rev 6733)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2009-01-05 05:28:57 UTC (rev 6734)
@@ -612,7 +612,7 @@
if 0: flags |= 1 << 18 # TODO: force bold
ft2font = FT2Font(fontfile)
-
+
descriptor = {
'Type': Name('FontDescriptor'),
'FontName': Name(t1font.prop['FontName']),
@@ -1602,12 +1602,10 @@
if rcParams['text.usetex']:
texmanager = self.get_texmanager()
fontsize = prop.get_size_in_points()
- dvifile = texmanager.make_dvi(s, fontsize)
- dvi = dviread.Dvi(dvifile, 72)
- page = iter(dvi).next()
- dvi.close()
- # A total height (including the descent) needs to be returned.
- return page.width, page.height+page.descent, page.descent
+ w, h, d = texmanager.get_text_width_height_descent(s, fontsize,
+ renderer=self)
+ return w, h, d
+
if ismath:
w, h, d, glyphs, rects, used_characters = \
self.mathtext_parser.parse(s, 72, prop)
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_ps.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2009-01-02 17:56:15 UTC (rev 6733)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2009-01-05 05:28:57 UTC (rev 6734)
@@ -274,12 +274,9 @@
if rcParams['text.usetex']:
texmanager = self.get_texmanager()
fontsize = prop.get_size_in_points()
- l,b,r,t = texmanager.get_ps_bbox(s, fontsize)
- w = (r-l)
- h = (t-b)
- # TODO: We need a way to get a good baseline from
- # text.usetex
- return w, h, 0
+ w, h, d = texmanager.get_text_width_height_descent(s, fontsize,
+ renderer=self)
+ return w, h, d
if ismath:
width, height, descent, pswriter, used_characters = \
Modified: trunk/matplotlib/lib/matplotlib/mpl-data/matplotlib.conf.template
===================================================================
--- trunk/matplotlib/lib/matplotlib/mpl-data/matplotlib.conf.template 2009-01-02 17:56:15 UTC (rev 6733)
+++ trunk/matplotlib/lib/matplotlib/mpl-data/matplotlib.conf.template 2009-01-05 05:28:57 UTC (rev 6734)
@@ -357,6 +357,8 @@
preamble = []
# a boolean
unicode = False
+ # a boolean
+ preview = False
[verbose]
# a file name or 'sys.stdout'
Modified: trunk/matplotlib/lib/matplotlib/rcsetup.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/rcsetup.py 2009-01-02 17:56:15 UTC (rev 6733)
+++ trunk/matplotlib/lib/matplotlib/rcsetup.py 2009-01-05 05:28:57 UTC (rev 6734)
@@ -386,6 +386,7 @@
'text.usetex' : [False, validate_bool],
'text.latex.unicode' : [False, validate_bool],
'text.latex.preamble' : [[''], validate_stringlist],
+ 'text.latex.preview' : [False, validate_bool],
'text.dvipnghack' : [None, validate_bool_maybe_none],
'text.fontstyle' : ['normal', str],
'text.fontangle' : ['normal', str],
Modified: trunk/matplotlib/lib/matplotlib/texmanager.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/texmanager.py 2009-01-02 17:56:15 UTC (rev 6733)
+++ trunk/matplotlib/lib/matplotlib/texmanager.py 2009-01-05 05:28:57 UTC (rev 6734)
@@ -45,6 +45,8 @@
import matplotlib as mpl
from matplotlib import rcParams
from matplotlib._png import read_png
+import matplotlib.dviread as dviread
+import re
DEBUG = False
@@ -262,12 +264,83 @@
return texfile
+
+ _re_vbox = re.compile(r"MatplotlibBox:\(([\d.]+)pt\+([\d.]+)pt\)x([\d.]+)pt")
+
+ def make_tex_preview(self, tex, fontsize):
+ """
+ Generate a tex file to render the tex string at a specific
+ font size. It uses the preview.sty to determin the dimension
+ (width, height, descent) of the output.
+
+ returns the file name
+ """
+ basefile = self.get_basefile(tex, fontsize)
+ texfile = '%s.tex'%basefile
+ fh = file(texfile, 'w')
+ custom_preamble = self.get_custom_preamble()
+ fontcmd = {'sans-serif' : r'{\sffamily %s}',
+ 'monospace' : r'{\ttfamily %s}'}.get(self.font_family,
+ r'{\rmfamily %s}')
+ tex = fontcmd % tex
+
+ if rcParams['text.latex.unicode']:
+ unicode_preamble = """\usepackage{ucs}
+\usepackage[utf8x]{inputenc}"""
+ else:
+ unicode_preamble = ''
+
+
+
+ # newbox, setbox, immediate, etc. are used to find the box
+ # extent of the rendered text.
+
+
+ s = r"""\documentclass{article}
+%s
+%s
+%s
+\usepackage[active,showbox,tightpage]{preview}
+%%\usepackage[papersize={72in,72in}, body={70in,70in}, margin={1in,1in}]{geometry}
+
+%% we override the default showbox as it is treated as an error and makes
+%% the exit status not zero
+\def\showbox#1{\immediate\write16{MatplotlibBox:(\the\ht#1+\the\dp#1)x\the\wd#1}}
+
+\begin{document}
+\begin{preview}
+{\fontsize{%f}{%f}%s}
+\end{preview}
+\end{document}
+""" % (self._font_preamble, unicode_preamble, custom_preamble,
+ fontsize, fontsize*1.25, tex)
+ if rcParams['text.latex.unicode']:
+ fh.write(s.encode('utf8'))
+ else:
+ try:
+ fh.write(s)
+ except UnicodeEncodeError, err:
+ mpl.verbose.report("You are using unicode and latex, but have "
+ "not enabled the matplotlib 'text.latex.unicode' "
+ "rcParam.", 'helpful')
+ raise
+
+ fh.close()
+
+ return texfile
+
+
def make_dvi(self, tex, fontsize):
"""
generates a dvi file containing latex's layout of tex string
returns the file name
"""
+
+
+ if rcParams['text.latex.preview']:
+ return self.make_dvi_preview(tex, fontsize)
+
basefile = self.get_basefile(tex, fontsize)
dvifile = '%s.dvi'% basefile
@@ -298,6 +371,55 @@
return dvifile
+
+ def make_dvi_preview(self, tex, fontsize):
+ """
+ generates a dvi file containing latex's layout of tex
+ string. It calls make_tex_preview() method and store the size
+ information (width, height, descent) in a separte file.
+
+ returns the file name
+ """
+ basefile = self.get_basefile(tex, fontsize)
+ dvifile = '%s.dvi'% basefile
+ baselinefile = '%s.baseline'% basefile
+
+ if DEBUG or not os.path.exists(dvifile) or \
+ not os.path.exists(baselinefile):
+ texfile = self.make_tex_preview(tex, fontsize)
+ outfile = basefile+'.output'
+ command = self._get_shell_cmd('cd "%s"'% self.texcache,
+ 'latex -interaction=nonstopmode %s > "%s"'\
+ %(os.path.split(texfile)[-1], outfile))
+ mpl.verbose.report(command, 'debug')
+ exit_status = os.system(command)
+ try:
+ fh = file(outfile)
+ report = fh.read()
+ fh.close()
+
+ except IOError:
+ report = 'No latex error report available.'
+ if exit_status:
+ raise RuntimeError(('LaTeX was not able to process the following \
+string:\n%s\nHere is the full report generated by LaTeX: \n\n'% repr(tex)) + report)
+ else: mpl.verbose.report(report, 'debug')
+
+ # find the box extent information in the latex output
+ # file and store them in ".baseline" file
+ m = TexManager._re_vbox.search(report)
+ open(basefile+'.baseline',"w").write(" ".join(m.groups()))
+
+ for fname in glob.glob(basefile+'*'):
+ if fname.endswith('dvi'): pass
+ elif fname.endswith('tex'): pass
+ elif fname.endswith('baseline'): pass
+ else:
+ try: os.remove(fname)
+ except OSError: pass
+
+ return dvifile
+
def make_png(self, tex, fontsize, dpi):
"""
generates a png file containing latex's rendering of tex string
@@ -441,3 +563,37 @@
self.rgba_arrayd[key] = Z
return Z
+
+
+ def get_text_width_height_descent(self, tex, fontsize, renderer=None):
+ """
+ return width, heigth and descent of the text.
+ """
+
+ if renderer:
+ dpi_fraction = renderer.points_to_pixels(1.)
+ else:
+ dpi_fraction = 1.
+
+ if rcParams['text.latex.preview']:
+ # use preview.sty
+ basefile = self.get_basefile(tex, fontsize)
+ baselinefile = '%s.baseline'% basefile
+
+
+ if DEBUG or not os.path.exists(baselinefile):
+ dvifile = self.make_dvi_preview(tex, fontsize)
+
+ l = open(baselinefile).read().split()
+ height, depth, width = [float(l1)*dpi_fraction for l1 in l]
+ return width, height+depth, depth
+
+ else:
+ # use dviread. It sometimes returns a wrong descent.
+ dvifile = self.make_dvi(tex, fontsize)
+ dvi = dviread.Dvi(dvifile, 72*dpi_fraction)
+ page = iter(dvi).next()
+ dvi.close()
+ # A total height (including the descent) needs to be returned.
+ return page.width, page.height+page.descent, page.descent
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2009-01-02 17:56:26
|
Revision: 6733
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6733&view=rev
Author: mdboom
Date: 2009-01-02 17:56:15 +0000 (Fri, 02 Jan 2009)
Log Message:
-----------
Merged revisions 6717,6732 via svnmerge from
https://matplotlib.svn.sf.net/svnroot/matplotlib/branches/v0_98_5_maint
........
r6717 | jdh2358 | 2008-12-30 11:06:59 -0500 (Tue, 30 Dec 2008) | 1 line
added rcparams import to path
........
r6732 | efiring | 2009-01-02 12:13:37 -0500 (Fri, 02 Jan 2009) | 2 lines
Backport r6731 polar fixes from trunk.
........
Property Changed:
----------------
trunk/matplotlib/
trunk/matplotlib/doc/pyplots/README
trunk/matplotlib/doc/sphinxext/gen_gallery.py
trunk/matplotlib/doc/sphinxext/gen_rst.py
Property changes on: trunk/matplotlib
___________________________________________________________________
Modified: svnmerge-integrated
- /branches/v0_91_maint:1-6428 /branches/v0_98_5_maint:1-6715
+ /branches/v0_91_maint:1-6428 /branches/v0_98_5_maint:1-6732
Modified: svn:mergeinfo
- /branches/v0_91_maint:5753-5771
/branches/v0_98_5_maint:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673,6714-6715
+ /branches/v0_91_maint:5753-5771
/branches/v0_98_5_maint:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673,6714-6715,6717-6732
Property changes on: trunk/matplotlib/doc/pyplots/README
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/v0_98_5_maint/doc/pyplots/README:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673,6714-6715
+ /branches/v0_98_5_maint/doc/pyplots/README:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673,6714-6715,6717-6732
Property changes on: trunk/matplotlib/doc/sphinxext/gen_gallery.py
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/v0_91_maint/doc/_templates/gen_gallery.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_gallery.py:6660-6662,6672-6673,6714-6715
+ /branches/v0_91_maint/doc/_templates/gen_gallery.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_gallery.py:6660-6662,6672-6673,6714-6715,6717-6732
Property changes on: trunk/matplotlib/doc/sphinxext/gen_rst.py
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/v0_91_maint/doc/examples/gen_rst.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_rst.py:6714-6715
+ /branches/v0_91_maint/doc/examples/gen_rst.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_rst.py:6714-6715,6717-6732
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ef...@us...> - 2009-01-02 17:13:45
|
Revision: 6732
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6732&view=rev
Author: efiring
Date: 2009-01-02 17:13:37 +0000 (Fri, 02 Jan 2009)
Log Message:
-----------
Backport r6731 polar fixes from trunk.
Modified Paths:
--------------
branches/v0_98_5_maint/lib/matplotlib/projections/polar.py
Modified: branches/v0_98_5_maint/lib/matplotlib/projections/polar.py
===================================================================
--- branches/v0_98_5_maint/lib/matplotlib/projections/polar.py 2009-01-02 03:33:17 UTC (rev 6731)
+++ branches/v0_98_5_maint/lib/matplotlib/projections/polar.py 2009-01-02 17:13:37 UTC (rev 6732)
@@ -57,8 +57,6 @@
def transform_path(self, path):
vertices = path.vertices
- t = vertices[:, 0:1]
- t[t != (npy.pi * 2.0)] %= (npy.pi * 2.0)
if len(vertices) == 2 and vertices[0, 0] == vertices[1, 0]:
return Path(self.transform(vertices), path.codes)
ipath = path.interpolated(self._resolution)
@@ -174,6 +172,11 @@
def refresh(self):
return self.base.refresh()
+ def view_limits(self, vmin, vmax):
+ vmin, vmax = self.base.view_limits(vmin, vmax)
+ return 0, vmax
+
+
RESOLUTION = 75
def __init__(self, *args, **kwargs):
@@ -280,6 +283,7 @@
return Circle((0.5, 0.5), 0.5)
def set_rmax(self, rmax):
+ self.viewLim.y0 = 0
self.viewLim.y1 = rmax
angle = self._r_label1_position.to_values()[4]
self._r_label1_position.clear().translate(
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ef...@us...> - 2009-01-02 03:33:21
|
Revision: 6731
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6731&view=rev
Author: efiring
Date: 2009-01-02 03:33:17 +0000 (Fri, 02 Jan 2009)
Log Message:
-----------
Undo polar plotting bug introduced in 6106; improve r grid
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/projections/polar.py
Modified: trunk/matplotlib/lib/matplotlib/projections/polar.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/projections/polar.py 2009-01-01 22:23:57 UTC (rev 6730)
+++ trunk/matplotlib/lib/matplotlib/projections/polar.py 2009-01-02 03:33:17 UTC (rev 6731)
@@ -57,8 +57,6 @@
def transform_path(self, path):
vertices = path.vertices
- t = vertices[:, 0:1]
- t[t != (npy.pi * 2.0)] %= (npy.pi * 2.0)
if len(vertices) == 2 and vertices[0, 0] == vertices[1, 0]:
return Path(self.transform(vertices), path.codes)
ipath = path.interpolated(self._resolution)
@@ -174,6 +172,11 @@
def refresh(self):
return self.base.refresh()
+ def view_limits(self, vmin, vmax):
+ vmin, vmax = self.base.view_limits(vmin, vmax)
+ return 0, vmax
+
+
RESOLUTION = 75
def __init__(self, *args, **kwargs):
@@ -280,6 +283,7 @@
return Circle((0.5, 0.5), 0.5)
def set_rmax(self, rmax):
+ self.viewLim.y0 = 0
self.viewLim.y1 = rmax
angle = self._r_label1_position.to_values()[4]
self._r_label1_position.clear().translate(
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jo...@us...> - 2009-01-01 22:24:03
|
Revision: 6730
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6730&view=rev
Author: jouni
Date: 2009-01-01 22:23:57 +0000 (Thu, 01 Jan 2009)
Log Message:
-----------
Allow multipage pdf files
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py
Added Paths:
-----------
trunk/matplotlib/examples/pylab_examples/multipage_pdf.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-12-31 20:19:16 UTC (rev 6729)
+++ trunk/matplotlib/CHANGELOG 2009-01-01 22:23:57 UTC (rev 6730)
@@ -1,3 +1,5 @@
+2009-01-02 Allow multipage pdf files. - JKS
+
2008-12-31 Improve pdf usetex by adding support for font effects
(slanting and extending). - JKS
Added: trunk/matplotlib/examples/pylab_examples/multipage_pdf.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/multipage_pdf.py (rev 0)
+++ trunk/matplotlib/examples/pylab_examples/multipage_pdf.py 2009-01-01 22:23:57 UTC (rev 6730)
@@ -0,0 +1,29 @@
+import numpy as np
+import matplotlib
+from matplotlib.backends.backend_pdf import PdfFile
+from pylab import *
+
+pdf = PdfFile('multipage_pdf.pdf')
+
+figure(figsize=(3,3))
+plot(range(7), [3,1,4,1,5,9,2], 'r-o')
+title('Page One')
+savefig(pdf, format='pdf')
+close()
+
+rc('text', usetex=True)
+figure(figsize=(8,6))
+x = np.arange(0,5,0.1)
+plot(x, np.sin(x), 'b-')
+title('Page Two')
+savefig(pdf, format='pdf')
+close()
+
+rc('text', usetex=False)
+figure(figsize=(4,5))
+plot(x, x*x, 'ko')
+title('Page Three')
+savefig(pdf, format='pdf')
+close()
+
+pdf.close()
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2008-12-31 20:19:16 UTC (rev 6729)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2009-01-01 22:23:57 UTC (rev 6730)
@@ -219,6 +219,9 @@
def __repr__(self):
return "<Name %s>" % self.name
+ def __str__(self):
+ return '/' + self.name
+
@staticmethod
def hexify(match):
return '#%02x' % ord(match.group())
@@ -336,13 +339,7 @@
class PdfFile(object):
"""PDF file with one page."""
- def __init__(self, width, height, dpi, filename):
- self.width, self.height = width, height
- self.dpi = dpi
- if rcParams['path.simplify']:
- self.simplify = (width * dpi, height * dpi)
- else:
- self.simplify = None
+ def __init__(self, filename):
self.nextObject = 1 # next free object id
self.xrefTable = [ [0, 65535, 'the zero object'] ]
self.passed_in_file_object = False
@@ -364,17 +361,16 @@
self.rootObject = self.reserveObject('root')
self.infoObject = self.reserveObject('info')
- pagesObject = self.reserveObject('pages')
- thePageObject = self.reserveObject('page 0')
- contentObject = self.reserveObject('contents of page 0')
+ self.pagesObject = self.reserveObject('pages')
+ self.pageList = []
self.fontObject = self.reserveObject('fonts')
self.alphaStateObject = self.reserveObject('extended graphics states')
self.hatchObject = self.reserveObject('tiling patterns')
self.XObjectObject = self.reserveObject('external objects')
- resourceObject = self.reserveObject('resources')
+ self.resourceObject = self.reserveObject('resources')
root = { 'Type': Name('Catalog'),
- 'Pages': pagesObject }
+ 'Pages': self.pagesObject }
self.writeObject(self.rootObject, root)
info = { 'Creator': 'matplotlib ' + __version__ \
@@ -385,23 +381,12 @@
# Possible TODO: Title, Author, Subject, Keywords
self.writeObject(self.infoObject, info)
- pages = { 'Type': Name('Pages'),
- 'Kids': [ thePageObject ],
- 'Count': 1 }
- self.writeObject(pagesObject, pages)
-
- thePage = { 'Type': Name('Page'),
- 'Parent': pagesObject,
- 'Resources': resourceObject,
- 'MediaBox': [ 0, 0, dpi*width, dpi*height ],
- 'Contents': contentObject }
- self.writeObject(thePageObject, thePage)
-
self.fontNames = {} # maps filenames to internal font names
self.nextFont = 1 # next free internal font name
self.dviFontInfo = {} # information on dvi fonts
self.type1Descriptors = {} # differently encoded Type-1 fonts may
# share the same descriptor
+ self.used_characters = {}
self.alphaStates = {} # maps alpha values to graphics state objects
self.nextAlphaState = 1
@@ -426,16 +411,32 @@
'ExtGState': self.alphaStateObject,
'Pattern': self.hatchObject,
'ProcSet': procsets }
- self.writeObject(resourceObject, resources)
+ self.writeObject(self.resourceObject, resources)
- # Start the content stream of the page
+ def newPage(self, width, height):
+ self.endStream()
+
+ self.width, self.height = width, height
+ if rcParams['path.simplify']:
+ self.simplify = (width * 72, height * 72)
+ else:
+ self.simplify = None
+ contentObject = self.reserveObject('page contents')
+ thePage = { 'Type': Name('Page'),
+ 'Parent': self.pagesObject,
+ 'Resources': self.resourceObject,
+ 'MediaBox': [ 0, 0, 72*width, 72*height ],
+ 'Contents': contentObject }
+ pageObject = self.reserveObject('page')
+ self.writeObject(pageObject, thePage)
+ self.pageList.append(pageObject)
+
self.beginStream(contentObject.id,
self.reserveObject('length of content stream'))
def close(self):
- # End the content stream and write out the various deferred
- # objects
self.endStream()
+ # Write out the various deferred objects
self.writeFonts()
self.writeObject(self.alphaStateObject,
dict([(val[0], val[1])
@@ -449,6 +450,12 @@
self.writeObject(self.XObjectObject, xobjects)
self.writeImages()
self.writeMarkers()
+ self.writeObject(self.pagesObject,
+ { 'Type': Name('Pages'),
+ 'Kids': self.pageList,
+ 'Count': len(self.pageList) })
+
+ # Finalize the file
self.writeXref()
self.writeTrailer()
if self.passed_in_file_object:
@@ -471,8 +478,9 @@
self.currentstream = Stream(id, len, self, extra)
def endStream(self):
- self.currentstream.end()
- self.currentstream = None
+ if self.currentstream is not None:
+ self.currentstream.end()
+ self.currentstream = None
def fontName(self, fontprop):
"""
@@ -493,20 +501,27 @@
Fx = Name('F%d' % self.nextFont)
self.fontNames[filename] = Fx
self.nextFont += 1
+ matplotlib.verbose.report(
+ 'Assigning font %s = %s' % (Fx, filename),
+ 'debug')
return Fx
def writeFonts(self):
fonts = {}
for filename, Fx in self.fontNames.items():
+ matplotlib.verbose.report('Embedding font %s' % filename, 'debug')
if filename.endswith('.afm'):
# from pdf.use14corefonts
+ matplotlib.verbose.report('Writing AFM font', 'debug')
fontdictObject = self._write_afm_font(filename)
elif self.dviFontInfo.has_key(filename):
# a Type 1 font from a dvi file; the filename is really the TeX name
+ matplotlib.verbose.report('Writing Type-1 font', 'debug')
fontdictObject = self.embedType1(filename, self.dviFontInfo[filename])
else:
# a normal TrueType font
+ matplotlib.verbose.report('Writing TrueType font', 'debug')
realpath, stat_key = get_realpath_and_stat(filename)
chars = self.used_characters.get(stat_key)
if chars is not None and len(chars[1]):
@@ -1143,8 +1158,7 @@
return cmds
def writePath(self, path, transform):
- cmds = self.pathOperations(
- path, transform, self.simplify)
+ cmds = self.pathOperations(path, transform, self.simplify)
self.output(*cmds)
def reserveObject(self, name=''):
@@ -1198,13 +1212,11 @@
truetype_font_cache = maxdict(50)
afm_font_cache = maxdict(50)
- def __init__(self, file, dpi, image_dpi):
+ def __init__(self, file, image_dpi):
RendererBase.__init__(self)
self.file = file
self.gc = self.new_gc()
- self.file.used_characters = self.used_characters = {}
self.mathtext_parser = MathTextParser("Pdf")
- self.dpi = dpi
self.image_dpi = image_dpi
self.tex_font_map = None
@@ -1235,13 +1247,13 @@
else:
fname = font.fname
realpath, stat_key = get_realpath_and_stat(fname)
- used_characters = self.used_characters.setdefault(
+ used_characters = self.file.used_characters.setdefault(
stat_key, (realpath, set()))
used_characters[1].update([ord(x) for x in s])
def merge_used_characters(self, other):
for stat_key, (realpath, charset) in other.items():
- used_characters = self.used_characters.setdefault(
+ used_characters = self.file.used_characters.setdefault(
stat_key, (realpath, set()))
used_characters[1].update(charset)
@@ -1299,7 +1311,7 @@
def draw_mathtext(self, gc, x, y, s, prop, angle):
# TODO: fix positioning and encoding
width, height, descent, glyphs, rects, used_characters = \
- self.mathtext_parser.parse(s, self.dpi, prop)
+ self.mathtext_parser.parse(s, 72, prop)
self.merge_used_characters(used_characters)
# When using Type 3 fonts, we can't use character codes higher
@@ -1327,7 +1339,6 @@
self._setup_textpos(ox, oy, 0, 0, oldx, oldy)
oldx, oldy = ox, oy
if (fontname, fontsize) != prev_font:
- fontsize *= self.dpi/72.0
self.file.output(self.file.fontName(fontname), fontsize,
Op.selectfont)
prev_font = fontname, fontsize
@@ -1338,7 +1349,6 @@
# as XObjects using the 'Do' command.
if global_fonttype == 3:
for ox, oy, fontname, fontsize, num, symbol_name in glyphs:
- fontsize *= self.dpi/72.0
if is_opentype_cff_font(fontname):
fonttype = 42
else:
@@ -1367,7 +1377,7 @@
texmanager = self.get_texmanager()
fontsize = prop.get_size_in_points()
dvifile = texmanager.make_dvi(s, fontsize)
- dvi = dviread.Dvi(dvifile, self.dpi)
+ dvi = dviread.Dvi(dvifile, 72)
page = iter(dvi).next()
dvi.close()
@@ -1463,7 +1473,7 @@
self.check_gc(gc, gc._rgb)
if ismath: return self.draw_mathtext(gc, x, y, s, prop, angle)
- fontsize = prop.get_size_in_points() * self.dpi/72.0
+ fontsize = prop.get_size_in_points()
if rcParams['pdf.use14corefonts']:
font = self._get_font_afm(prop)
@@ -1593,14 +1603,14 @@
texmanager = self.get_texmanager()
fontsize = prop.get_size_in_points()
dvifile = texmanager.make_dvi(s, fontsize)
- dvi = dviread.Dvi(dvifile, self.dpi)
+ dvi = dviread.Dvi(dvifile, 72)
page = iter(dvi).next()
dvi.close()
# A total height (including the descent) needs to be returned.
return page.width, page.height+page.descent, page.descent
if ismath:
w, h, d, glyphs, rects, used_characters = \
- self.mathtext_parser.parse(s, self.dpi, prop)
+ self.mathtext_parser.parse(s, 72, prop)
elif rcParams['pdf.use14corefonts']:
font = self._get_font_afm(prop)
@@ -1645,14 +1655,14 @@
self.truetype_font_cache[filename] = font
self.truetype_font_cache[key] = font
font.clear()
- font.set_size(prop.get_size_in_points(), self.dpi)
+ font.set_size(prop.get_size_in_points(), 72)
return font
def flipy(self):
return False
def get_canvas_width_height(self):
- return self.file.width / self.dpi, self.file.height / self.dpi
+ return self.file.width / 72.0, self.file.height / 72.0
def new_gc(self):
return GraphicsContextPdf(self.file)
@@ -1887,16 +1897,22 @@
return 'pdf'
def print_pdf(self, filename, **kwargs):
- ppi = 72 # Postscript points in an inch
image_dpi = kwargs.get('dpi', 72) # dpi to use for images
- self.figure.set_dpi(ppi)
+ self.figure.set_dpi(72) # there are 72 pdf points to an inch
width, height = self.figure.get_size_inches()
- file = PdfFile(width, height, ppi, filename)
+ if isinstance(filename, PdfFile):
+ file = filename
+ else:
+ file = PdfFile(filename)
+ file.newPage(width, height)
renderer = MixedModeRenderer(
- width, height, ppi, RendererPdf(file, ppi, image_dpi))
+ width, height, 72, RendererPdf(file, image_dpi))
self.figure.draw(renderer)
renderer.finalize()
- file.close()
+ if file != filename: # we opened the file
+ file.close()
+ else: # multipage file; just finish off the page
+ file.endStream()
class FigureManagerPdf(FigureManagerBase):
pass
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <js...@us...> - 2008-12-31 20:19:20
|
Revision: 6729
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6729&view=rev
Author: jswhit
Date: 2008-12-31 20:19:16 +0000 (Wed, 31 Dec 2008)
Log Message:
-----------
fix small bug in land-sea mask lat/lon definitions
Modified Paths:
--------------
trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py
Modified: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py
===================================================================
--- trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py 2008-12-31 19:56:55 UTC (rev 6728)
+++ trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py 2008-12-31 20:19:16 UTC (rev 6729)
@@ -3110,9 +3110,16 @@
lsmaskf = open(os.path.join(basemap_datadir,'5minmask.bin'),'rb')
nlons = 4320; nlats = nlons/2
delta = 360./float(nlons)
- lsmask_lons = np.arange(-180+0.5*delta,180.,delta)
- lsmask_lats = np.arange(-90.+0.5*delta,90.,delta)
lsmask = np.reshape(np.fromstring(lsmaskf.read(),np.uint8),(nlats,nlons))
+ lsmask_lons = np.arange(-180,180.,delta)
+ lsmask_lats = np.arange(-90.,90+0.5*delta,delta)
+ # add cyclic point in longitude
+ lsmask, lsmask_lons = addcyclic(lsmask, lsmask_lons)
+ nlons = nlons + 1; nlats = nlats + 1
+ # add North Pole point (assumed water)
+ tmparr = np.zeros((nlats,nlons),lsmask.dtype)
+ tmparr[0:nlats-1,0:nlons] = lsmask
+ lsmask = tmparr
lsmaskf.close()
# instance variable lsmask is set on first invocation,
# it contains the land-sea mask interpolated to the native
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jo...@us...> - 2008-12-31 19:57:00
|
Revision: 6728
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6728&view=rev
Author: jouni
Date: 2008-12-31 19:56:55 +0000 (Wed, 31 Dec 2008)
Log Message:
-----------
Don't crash with Microsoft fonts such as Tahoma
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 2008-12-31 19:42:44 UTC (rev 6727)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2008-12-31 19:56:55 UTC (rev 6728)
@@ -333,7 +333,7 @@
self.file.write(compressed)
self.compressobj = None
-class PdfFile:
+class PdfFile(object):
"""PDF file with one page."""
def __init__(self, width, height, dpi, filename):
@@ -900,7 +900,14 @@
# Beginning of main embedTTF function...
# You are lost in a maze of TrueType tables, all different...
- ps_name = Name(font.get_sfnt()[(1,0,0,6)])
+ sfnt = font.get_sfnt()
+ try:
+ ps_name = sfnt[(1,0,0,6)] # Macintosh scheme
+ except KeyError:
+ # Microsoft scheme:
+ ps_name = sfnt[(3,1,0x0409,6)].decode('utf-16be').encode('ascii','replace')
+ # (see freetype/ttnameid.h)
+ ps_name = Name(ps_name)
pclt = font.get_sfnt_table('pclt') \
or { 'capHeight': 0, 'xHeight': 0 }
post = font.get_sfnt_table('post') \
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jo...@us...> - 2008-12-31 19:42:48
|
Revision: 6727
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6727&view=rev
Author: jouni
Date: 2008-12-31 19:42:44 +0000 (Wed, 31 Dec 2008)
Log Message:
-----------
Modernize a little since we can assume Python 2.4
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 2008-12-31 19:01:41 UTC (rev 6726)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2008-12-31 19:42:44 UTC (rev 6727)
@@ -185,7 +185,7 @@
"Don't know a PDF representation for %s objects." \
% type(obj)
-class Reference:
+class Reference(object):
"""PDF reference object.
Use PdfFile.reserveObject() to create References.
"""
@@ -205,8 +205,9 @@
write(pdfRepr(contents))
write("\nendobj\n")
-class Name:
+class Name(object):
"""PDF name object."""
+ __slots__ = ('name',)
_regex = re.compile(r'[^!-~]')
def __init__(self, name):
@@ -218,15 +219,16 @@
def __repr__(self):
return "<Name %s>" % self.name
+ @staticmethod
def hexify(match):
return '#%02x' % ord(match.group())
- hexify = staticmethod(hexify)
def pdfRepr(self):
return '/' + self.name
-class Operator:
+class Operator(object):
"""PDF operator object."""
+ __slots__ = ('op',)
def __init__(self, op):
self.op = op
@@ -257,12 +259,13 @@
Op = Bunch(**dict([(name, Operator(value))
for name, value in _pdfops.items()]))
-class Stream:
+class Stream(object):
"""PDF stream object.
This has no pdfRepr method. Instead, call begin(), then output the
contents of the stream by calling write(), and finally call end().
"""
+ __slots__ = ('id', 'len', 'pdfFile', 'file', 'compressobj', 'extra', 'pos')
def __init__(self, id, len, file, extra=None):
"""id: object id of stream; len: an unused Reference object for the
@@ -1107,7 +1110,7 @@
self.output(Op.stroke)
self.endStream()
- #@staticmethod
+ @staticmethod
def pathOperations(path, transform, simplify=None):
tpath = transform.transform_path(path)
@@ -1131,7 +1134,6 @@
cmds.append(Op.closepath)
last_points = points
return cmds
- pathOperations = staticmethod(pathOperations)
def writePath(self, path, transform):
cmds = self.pathOperations(
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <js...@us...> - 2008-12-31 19:01:44
|
Revision: 6726
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6726&view=rev
Author: jswhit
Date: 2008-12-31 19:01:41 +0000 (Wed, 31 Dec 2008)
Log Message:
-----------
add comment
Modified Paths:
--------------
trunk/toolkits/basemap/examples/garp.py
Modified: trunk/toolkits/basemap/examples/garp.py
===================================================================
--- trunk/toolkits/basemap/examples/garp.py 2008-12-31 19:00:19 UTC (rev 6725)
+++ trunk/toolkits/basemap/examples/garp.py 2008-12-31 19:01:41 UTC (rev 6726)
@@ -16,6 +16,8 @@
lat_0 = float(raw_input('input reference lat (degrees):'))
location = raw_input('name of location:')
+# no width/height or lat/lon corners specified, so whole world
+# is plotted in a circle.
m = Basemap(resolution='c',projection='aeqd',lat_0=lat_0,lon_0=lon_0)
# draw coastlines and fill continents.
@@ -27,8 +29,8 @@
#m.drawmapboundary(fill_color='white')
#m.drawcoastlines(linewidth=0.5)
#m.fillcontinents(color='black',lake_color='white')
-#m.drawparallels(np.arange(-80,81,20))
-#m.drawmeridians(np.arange(-180,180,20))
+#m.drawparallels(np.arange(-80,81,20),color='0.7')
+#m.drawmeridians(np.arange(-180,180,20),color='0.7')
# draw lsmask instead of drawing continents (slower, but more robust).
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <js...@us...> - 2008-12-31 19:00:24
|
Revision: 6725
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6725&view=rev
Author: jswhit
Date: 2008-12-31 19:00:19 +0000 (Wed, 31 Dec 2008)
Log Message:
-----------
make graticule gray show the lines show up over continents.
Modified Paths:
--------------
trunk/toolkits/basemap/examples/garp.py
Modified: trunk/toolkits/basemap/examples/garp.py
===================================================================
--- trunk/toolkits/basemap/examples/garp.py 2008-12-31 18:49:07 UTC (rev 6724)
+++ trunk/toolkits/basemap/examples/garp.py 2008-12-31 19:00:19 UTC (rev 6725)
@@ -33,8 +33,8 @@
# draw lsmask instead of drawing continents (slower, but more robust).
m.drawlsmask(land_color='black',ocean_color='white',lakes=True)
-m.drawparallels(np.arange(-80,81,20))
-m.drawmeridians(np.arange(-180,180,20))
+m.drawparallels(np.arange(-80,81,20),color='0.7')
+m.drawmeridians(np.arange(-180,180,20),color='0.7')
m.drawmapboundary()
# blue marble background (pretty, but slow).
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <js...@us...> - 2008-12-31 18:49:12
|
Revision: 6724
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6724&view=rev
Author: jswhit
Date: 2008-12-31 18:49:07 +0000 (Wed, 31 Dec 2008)
Log Message:
-----------
fix bluemarble for full-disk aeqd, update garp.py example.
Modified Paths:
--------------
trunk/toolkits/basemap/examples/garp.py
trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py
Modified: trunk/toolkits/basemap/examples/garp.py
===================================================================
--- trunk/toolkits/basemap/examples/garp.py 2008-12-31 17:10:51 UTC (rev 6723)
+++ trunk/toolkits/basemap/examples/garp.py 2008-12-31 18:49:07 UTC (rev 6724)
@@ -17,17 +17,38 @@
location = raw_input('name of location:')
m = Basemap(resolution='c',projection='aeqd',lat_0=lat_0,lon_0=lon_0)
-# fill background.
-m.drawmapboundary(fill_color='aqua')
-# draw coasts and fill continents.
-m.drawcoastlines(linewidth=0.5)
-m.fillcontinents(color='coral',lake_color='aqua')
-# 20 degree graticule.
+
+# draw coastlines and fill continents.
+# **it's easy to make this fail with global aeqd plots.
+# For example, if the center point is at the North Pole,
+# the continent filling routines get confused and fills
+# the outside of Antartica instead of the inside**
+
+#m.drawmapboundary(fill_color='white')
+#m.drawcoastlines(linewidth=0.5)
+#m.fillcontinents(color='black',lake_color='white')
+#m.drawparallels(np.arange(-80,81,20))
+#m.drawmeridians(np.arange(-180,180,20))
+
+# draw lsmask instead of drawing continents (slower, but more robust).
+
+m.drawlsmask(land_color='black',ocean_color='white',lakes=True)
m.drawparallels(np.arange(-80,81,20))
m.drawmeridians(np.arange(-180,180,20))
-# draw a black dot at the center.
+m.drawmapboundary()
+
+# blue marble background (pretty, but slow).
+
+#m.bluemarble(scale=0.5)
+#m.drawparallels(np.arange(-80,81,20),color='0.5')
+#m.drawmeridians(np.arange(-180,180,20),color='0.5')
+#m.drawmapboundary(color='0.5')
+
+# draw a red dot at the center.
xpt, ypt = m(lon_0, lat_0)
-m.plot([xpt],[ypt],'ko')
+m.plot([xpt],[ypt],'ro')
+
# draw the title.
plt.title('The World According to Garp in '+location)
+
plt.show()
Modified: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py
===================================================================
--- trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py 2008-12-31 17:10:51 UTC (rev 6723)
+++ trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py 2008-12-31 18:49:07 UTC (rev 6724)
@@ -3317,7 +3317,8 @@
self.transform_scalar(self._bm_rgba[:,:,k],\
self._bm_lons,self._bm_lats,nx,ny,returnxy=True)
# for ortho,geos mask pixels outside projection limb.
- if self.projection in ['geos','ortho']:
+ if self.projection in ['geos','ortho'] or \
+ (self.projection == 'aeqd' and self._fulldisk):
lonsr,latsr = self(x,y,inverse=True)
mask = ma.zeros((ny,nx,4),np.int8)
mask[:,:,0] = np.logical_or(lonsr>1.e20,latsr>1.e30)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <js...@us...> - 2008-12-31 17:10:56
|
Revision: 6723
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6723&view=rev
Author: jswhit
Date: 2008-12-31 17:10:51 +0000 (Wed, 31 Dec 2008)
Log Message:
-----------
more comments added to document proj4 bug
Modified Paths:
--------------
trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py
Modified: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py
===================================================================
--- trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py 2008-12-31 17:00:34 UTC (rev 6722)
+++ trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py 2008-12-31 17:10:51 UTC (rev 6723)
@@ -99,7 +99,11 @@
# raise an exception for ellipsoids - there appears to be a bug
# in proj4 that causes the inverse transform to fail for points
# more than 90 degrees of arc away from center point for ellipsoids
- # (works fine for spheres)
+ # (works fine for spheres) - below is an example
+ #from pyproj import Proj
+ #p1 = Proj(proj='aeqd',a=6378137.00,b=6356752.3142,lat_0=0,lon_0=0)
+ #x,y= p1(91,0)
+ #lon,lat = p1(x,y,inverse=True) # lon is 89 instead of 91
if self.ellipsoid:
msg = dedent("""
full disk (whole world) Azimuthal Equidistant projection can
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <js...@us...> - 2008-12-31 17:00:46
|
Revision: 6722
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6722&view=rev
Author: jswhit
Date: 2008-12-31 17:00:34 +0000 (Wed, 31 Dec 2008)
Log Message:
-----------
add some comments
Modified Paths:
--------------
trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py
Modified: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py
===================================================================
--- trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py 2008-12-31 16:29:37 UTC (rev 6721)
+++ trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py 2008-12-31 17:00:34 UTC (rev 6722)
@@ -96,13 +96,17 @@
urcrnrlat == 90):
self._fulldisk = True
self._proj4 = pyproj.Proj(projparams)
+ # raise an exception for ellipsoids - there appears to be a bug
+ # in proj4 that causes the inverse transform to fail for points
+ # more than 90 degrees of arc away from center point for ellipsoids
+ # (works fine for spheres)
if self.ellipsoid:
msg = dedent("""
full disk (whole world) Azimuthal Equidistant projection can
only be drawn for a perfect sphere""")
raise ValueError(msg)
- llcrnrx = -np.pi*self.rminor
- llcrnry = -np.pi*self.rminor
+ llcrnrx = -np.pi*self.rmajor
+ llcrnry = -np.pi*self.rmajor
self._width = -llcrnrx
self._height = -llcrnry
urcrnrx = -llcrnrx
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <js...@us...> - 2008-12-31 16:29:42
|
Revision: 6721
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6721&view=rev
Author: jswhit
Date: 2008-12-31 16:29:37 +0000 (Wed, 31 Dec 2008)
Log Message:
-----------
fix typo
Modified Paths:
--------------
trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py
Modified: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py
===================================================================
--- trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py 2008-12-31 14:41:54 UTC (rev 6720)
+++ trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py 2008-12-31 16:29:37 UTC (rev 6721)
@@ -101,8 +101,8 @@
full disk (whole world) Azimuthal Equidistant projection can
only be drawn for a perfect sphere""")
raise ValueError(msg)
- llcrnrx = -0.5*(self.rmajor+self.rminor)
- llcrnry = -0.5*(self.rmajor+self.rminor)
+ llcrnrx = -np.pi*self.rminor
+ llcrnry = -np.pi*self.rminor
self._width = -llcrnrx
self._height = -llcrnry
urcrnrx = -llcrnrx
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <js...@us...> - 2008-12-31 14:42:07
|
Revision: 6720
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6720&view=rev
Author: jswhit
Date: 2008-12-31 14:41:54 +0000 (Wed, 31 Dec 2008)
Log Message:
-----------
fix bug in fulldisk aeqd, change garp.py example to plot whole disk
Modified Paths:
--------------
trunk/toolkits/basemap/examples/garp.py
Modified: trunk/toolkits/basemap/examples/garp.py
===================================================================
--- trunk/toolkits/basemap/examples/garp.py 2008-12-31 14:37:44 UTC (rev 6719)
+++ trunk/toolkits/basemap/examples/garp.py 2008-12-31 14:41:54 UTC (rev 6720)
@@ -11,20 +11,12 @@
# it will be to reach that destination.
# The specified point shows up as a red dot in the center of the map.
-# This example shows how to use the width and height keywords
-# to specify the map projection region (instead of specifying
-# the lat/lon of the upper right and lower left corners).
-
# user enters the lon/lat of the point, and it's name
lon_0 = float(raw_input('input reference lon (degrees):'))
lat_0 = float(raw_input('input reference lat (degrees):'))
location = raw_input('name of location:')
-# use these values to setup Basemap instance.
-width = 28000000
-m = Basemap(width=width,height=width,\
- resolution='c',projection='aeqd',\
- lat_0=lat_0,lon_0=lon_0)
+m = Basemap(resolution='c',projection='aeqd',lat_0=lat_0,lon_0=lon_0)
# fill background.
m.drawmapboundary(fill_color='aqua')
# draw coasts and fill continents.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <js...@us...> - 2008-12-31 14:37:48
|
Revision: 6719
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6719&view=rev
Author: jswhit
Date: 2008-12-31 14:37:44 +0000 (Wed, 31 Dec 2008)
Log Message:
-----------
whole world aeqd added
Modified Paths:
--------------
trunk/toolkits/basemap/Changelog
trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py
trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py
Modified: trunk/toolkits/basemap/Changelog
===================================================================
--- trunk/toolkits/basemap/Changelog 2008-12-31 13:20:50 UTC (rev 6718)
+++ trunk/toolkits/basemap/Changelog 2008-12-31 14:37:44 UTC (rev 6719)
@@ -1,4 +1,7 @@
version 0.99.3 (not yet released)
+ * if upper right/lower left corners nor width/height given for
+ azimuthal equidistant ('aeqd') the whole world is drawn in
+ a circle (only works for perfect spheres, not ellipsoids).
* have setup.py check for already installed pyshapelib (just
like it does for httplib2 and pydap).
* Basemap will now look for it's data in BASEMAPDATA.
Modified: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py
===================================================================
--- trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py 2008-12-31 13:20:50 UTC (rev 6718)
+++ trunk/toolkits/basemap/lib/mpl_toolkits/basemap/__init__.py 2008-12-31 14:37:44 UTC (rev 6719)
@@ -625,10 +625,17 @@
raise ValueError, 'must specify lat_0 and lon_0 for Azimuthal Equidistant basemap'
if not using_corners:
if width is None or height is None:
- raise ValueError, 'must either specify lat/lon values of corners (llcrnrlon,llcrnrlat,ucrnrlon,urcrnrlat) in degrees or width and height in meters'
+ self._fulldisk = True
+ llcrnrlon = -180.
+ llcrnrlat = -90.
+ urcrnrlon = 180
+ urcrnrlat = 90.
+ else:
+ self._fulldisk = False
if lon_0 is None or lat_0 is None:
raise ValueError, 'must specify lon_0 and lat_0 when using width, height to specify projection region'
- llcrnrlon,llcrnrlat,urcrnrlon,urcrnrlat = _choosecorners(width,height,**projparams)
+ if not self._fulldisk:
+ llcrnrlon,llcrnrlat,urcrnrlon,urcrnrlat = _choosecorners(width,height,**projparams)
self.llcrnrlon = llcrnrlon; self.llcrnrlat = llcrnrlat
self.urcrnrlon = urcrnrlon; self.urcrnrlat = urcrnrlat
elif projection in _cylproj:
@@ -1046,12 +1053,8 @@
if self.projection in ['ortho','geos']:
# circular region.
thetas = np.linspace(0.,2.*np.pi,2*nx*ny)[:-1]
- if self.projection == 'ortho':
- rminor = self.rmajor
- rmajor = self.rmajor
- else:
- rminor = self._height
- rmajor = self._width
+ rminor = self._height
+ rmajor = self._width
x = rmajor*np.cos(thetas) + rmajor
y = rminor*np.sin(thetas) + rminor
b = np.empty((len(x),2),np.float64)
@@ -1075,6 +1078,16 @@
projparms['x_0']=-llcrnrx
projparms['y_0']=-llcrnry
maptran = pyproj.Proj(projparms)
+ elif self.projection == 'aeqd' and self._fulldisk:
+ # circular region.
+ thetas = np.linspace(0.,2.*np.pi,2*nx*ny)[:-1]
+ rminor = self._height
+ rmajor = self._width
+ x = rmajor*np.cos(thetas) + rmajor
+ y = rminor*np.sin(thetas) + rminor
+ b = np.empty((len(x),2),np.float64)
+ b[:,0]=x; b[:,1]=y
+ boundaryxy = _geoslib.Polygon(b)
elif self.projection in _pseudocyl:
# quasi-elliptical region.
lon_0 = self.projparams['lon_0']
@@ -1188,11 +1201,10 @@
elif ax is None and self.ax is not None:
ax = self.ax
limb = None
- if self.projection == 'ortho':
- limb = Circle((self.rmajor,self.rmajor),self.rmajor)
- elif self.projection == 'geos':
+ if self.projection in ['ortho','geos'] or (self.projection=='aeqd' and\
+ self._fulldisk):
limb = Ellipse((self._width,self._height),2.*self._width,2.*self._height)
- if self.projection in ['ortho','geos'] and self._fulldisk:
+ if self.projection in ['ortho','geos','aeqd'] and self._fulldisk:
# elliptical region.
ax.add_patch(limb)
if fill_color is None:
@@ -1822,7 +1834,7 @@
linecolls[circ] = (lines,[])
# draw labels for parallels
# parallels not labelled for fulldisk orthographic or geostationary
- if self.projection in ['ortho','geos','vandg'] and max(labels):
+ if self.projection in ['ortho','geos','vandg','aeqd'] and max(labels):
if self.projection == 'vandg' or self._fulldisk:
print 'Warning: Cannot label parallels on %s basemap' % _projnames[self.projection]
labels = [0,0,0,0]
@@ -2068,9 +2080,12 @@
if self.projection in ['sinu','moll','vandg'] and max(labels):
print 'Warning: Cannot label meridians on %s basemap' % _projnames[self.projection]
labels = [0,0,0,0]
- if self.projection in ['ortho','geos'] and max(labels):
+ if self.projection in ['ortho','geos','aeqd'] and max(labels):
if self._fulldisk:
- print 'Warning: Cannot label meridians on full-disk Geostationary or Orthographic basemap'
+ print dedent(
+ """'Warning: Cannot label meridians on full-disk
+ Geostationary, Orthographic or Azimuthal equidistant basemap
+ """)
labels = [0,0,0,0]
# search along edges of map to see if parallels intersect.
# if so, find x,y location of intersection and draw a label there.
@@ -2535,7 +2550,7 @@
# turn off axes frame for non-rectangular projections.
if self.projection in _pseudocyl:
ax.set_frame_on(False)
- if self.projection in ['ortho','geos'] and self._fulldisk:
+ if self.projection in ['ortho','geos','aeqd'] and self._fulldisk:
ax.set_frame_on(False)
# make sure aspect ratio of map preserved.
# plot is re-centered in bounding rectangle.
Modified: trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py
===================================================================
--- trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py 2008-12-31 13:20:50 UTC (rev 6718)
+++ trunk/toolkits/basemap/lib/mpl_toolkits/basemap/proj.py 2008-12-31 14:37:44 UTC (rev 6719)
@@ -1,6 +1,7 @@
import numpy as np
import pyproj
import math
+from matplotlib.cbook import dedent
__version__ = '1.2.2'
_dg2rad = math.radians(1.)
@@ -70,19 +71,18 @@
self.esq = (self.rmajor**2 - self.rminor**2)/self.rmajor**2
self.llcrnrlon = llcrnrlon
self.llcrnrlat = llcrnrlat
- if self.projection not in ['ortho','geos','cyl'] + _pseudocyl:
- self._proj4 = pyproj.Proj(projparams)
- llcrnrx, llcrnry = self(llcrnrlon,llcrnrlat)
- elif self.projection == 'cyl':
+ if self.projection == 'cyl':
llcrnrx = llcrnrlon
llcrnry = llcrnrlat
- elif self.projection == 'ortho':
+ elif self.projection in 'ortho':
if (llcrnrlon == -180 and llcrnrlat == -90 and
urcrnrlon == 180 and urcrnrlat == 90):
self._fulldisk = True
self._proj4 = pyproj.Proj(projparams)
llcrnrx = -self.rmajor
llcrnry = -self.rmajor
+ self._width = 0.5*(self.rmajor+self.rminor)
+ self._height = 0.5*(self.rmajor+self.rminor)
urcrnrx = -llcrnrx
urcrnry = -llcrnry
else:
@@ -91,6 +91,22 @@
llcrnrx, llcrnry = self(llcrnrlon,llcrnrlat)
if llcrnrx > 1.e20 or llcrnry > 1.e20:
raise ValueError(_lower_left_out_of_bounds)
+ elif self.projection == 'aeqd' and\
+ (llcrnrlon == -180 and llcrnrlat == -90 and urcrnrlon == 180 and\
+ urcrnrlat == 90):
+ self._fulldisk = True
+ self._proj4 = pyproj.Proj(projparams)
+ if self.ellipsoid:
+ msg = dedent("""
+ full disk (whole world) Azimuthal Equidistant projection can
+ only be drawn for a perfect sphere""")
+ raise ValueError(msg)
+ llcrnrx = -0.5*(self.rmajor+self.rminor)
+ llcrnry = -0.5*(self.rmajor+self.rminor)
+ self._width = -llcrnrx
+ self._height = -llcrnry
+ urcrnrx = -llcrnrx
+ urcrnry = -llcrnry
elif self.projection == 'geos':
self._proj4 = pyproj.Proj(projparams)
# find major and minor axes of ellipse defining map proj region.
@@ -129,6 +145,10 @@
urcrnrx,xtmp = self(projparams['lon_0']+180.,0)
llcrnrx = -urcrnrx
llcrnry = -urcrnry
+ else:
+ self._proj4 = pyproj.Proj(projparams)
+ llcrnrx, llcrnry = self(llcrnrlon,llcrnrlat)
+ if self.projection == 'aeqd': self._fulldisk=False
# compute x_0, y_0 so ll corner of domain is x=0,y=0.
# note that for 'cyl' x,y == lon,lat
self.projparams['x_0']=-llcrnrx
@@ -144,18 +164,10 @@
if urcrnrislatlon:
self.urcrnrlon = urcrnrlon
self.urcrnrlat = urcrnrlat
- if self.projection not in ['ortho','geos'] + _pseudocyl:
+ if self.projection not in ['ortho','geos','aeqd'] + _pseudocyl:
urcrnrx,urcrnry = self(urcrnrlon,urcrnrlat)
- elif self.projection == 'ortho':
+ elif self.projection in ['ortho','geos','aeqd']:
if self._fulldisk:
- urcrnrx = 2.*self.rmajor
- urcrnry = 2.*self.rmajor
- else:
- urcrnrx,urcrnry = self(urcrnrlon,urcrnrlat)
- if urcrnrx > 1.e20 or urcrnry > 1.e20:
- raise ValueError(_upper_right_out_of_bounds)
- elif self.projection == 'geos':
- if self._fulldisk:
urcrnrx = 2.*self._width
urcrnry = 2.*self._height
else:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jo...@us...> - 2008-12-31 13:20:56
|
Revision: 6718
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6718&view=rev
Author: jouni
Date: 2008-12-31 13:20:50 +0000 (Wed, 31 Dec 2008)
Log Message:
-----------
Improve pdf usetex by adding support for font effects
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/doc/api/index_backend_api.rst
trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py
trunk/matplotlib/lib/matplotlib/dviread.py
trunk/matplotlib/lib/matplotlib/type1font.py
Added Paths:
-----------
trunk/matplotlib/doc/api/dviread.rst
trunk/matplotlib/doc/api/type1font.rst
trunk/matplotlib/examples/pylab_examples/usetex_fonteffects.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-12-30 16:06:59 UTC (rev 6717)
+++ trunk/matplotlib/CHANGELOG 2008-12-31 13:20:50 UTC (rev 6718)
@@ -1,3 +1,6 @@
+2008-12-31 Improve pdf usetex by adding support for font effects
+ (slanting and extending). - JKS
+
2008-12-29 Fix a bug in pdf usetex support, which occurred if the same
Type-1 font was used with different encodings, e.g. with
Minion Pro and MnSymbol. - JKS
Added: trunk/matplotlib/doc/api/dviread.rst
===================================================================
--- trunk/matplotlib/doc/api/dviread.rst (rev 0)
+++ trunk/matplotlib/doc/api/dviread.rst 2008-12-31 13:20:50 UTC (rev 6718)
@@ -0,0 +1,8 @@
+
+:mod:`matplotlib.dviread`
+=========================
+
+.. automodule:: matplotlib.dviread
+ :members:
+ :undoc-members:
+ :show-inheritance:
Modified: trunk/matplotlib/doc/api/index_backend_api.rst
===================================================================
--- trunk/matplotlib/doc/api/index_backend_api.rst 2008-12-30 16:06:59 UTC (rev 6717)
+++ trunk/matplotlib/doc/api/index_backend_api.rst 2008-12-31 13:20:50 UTC (rev 6718)
@@ -8,3 +8,5 @@
backend_gtkagg_api.rst
backend_qt4agg_api.rst
backend_wxagg_api.rst
+ dviread.rst
+ type1font.rst
Added: trunk/matplotlib/doc/api/type1font.rst
===================================================================
--- trunk/matplotlib/doc/api/type1font.rst (rev 0)
+++ trunk/matplotlib/doc/api/type1font.rst 2008-12-31 13:20:50 UTC (rev 6718)
@@ -0,0 +1,8 @@
+
+:mod:`matplotlib.type1font`
+===========================
+
+.. automodule:: matplotlib.type1font
+ :members:
+ :undoc-members:
+ :show-inheritance:
Added: trunk/matplotlib/examples/pylab_examples/usetex_fonteffects.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/usetex_fonteffects.py (rev 0)
+++ trunk/matplotlib/examples/pylab_examples/usetex_fonteffects.py 2008-12-31 13:20:50 UTC (rev 6718)
@@ -0,0 +1,22 @@
+# This script demonstrates that font effects specified in your pdftex.map
+# are now supported in pdf usetex.
+
+import matplotlib
+matplotlib.rc('text', usetex=True)
+import pylab
+
+def setfont(font):
+ return r'\font\a %s at 14pt\a ' % font
+
+for y, font, text in zip(range(5),
+ ['ptmr8r', 'ptmri8r', 'ptmro8r', 'ptmr8rn', 'ptmrr8re'],
+ ['Nimbus Roman No9 L ' + x for x in
+ ['', 'Italics (real italics for comparison)',
+ '(slanted)', '(condensed)', '(extended)']]):
+ pylab.text(0, y, setfont(font) + text)
+
+pylab.ylim(-1, 5)
+pylab.xlim(-0.2, 0.6)
+pylab.setp(pylab.gca(), frame_on=False, xticks=(), yticks=())
+pylab.title('Usetex font effects')
+pylab.savefig('usetex_fonteffects.pdf')
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2008-12-30 16:06:59 UTC (rev 6717)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2008-12-31 13:20:50 UTC (rev 6718)
@@ -500,7 +500,7 @@
# from pdf.use14corefonts
fontdictObject = self._write_afm_font(filename)
elif self.dviFontInfo.has_key(filename):
- # a Type 1 font from a dvi file
+ # a Type 1 font from a dvi file; the filename is really the TeX name
fontdictObject = self.embedType1(filename, self.dviFontInfo[filename])
else:
# a normal TrueType font
@@ -525,22 +525,25 @@
return fontdictObject
def embedType1(self, texname, fontinfo):
- # TODO: font effects such as SlantFont
matplotlib.verbose.report(
- 'Embedding Type 1 font ' + fontinfo.fontfile +
- ' with encoding ' + (fontinfo.encodingfile or '(none)'),
+ 'Embedding ' + texname +
+ ' which is the Type 1 font ' + fontinfo.fontfile +
+ ' with encoding ' + (fontinfo.encodingfile or '(none)') +
+ ' and effects ' + `fontinfo.effects`,
'debug')
- # Use FT2Font to get several font properties
- font = FT2Font(fontinfo.fontfile)
+ t1font = type1font.Type1Font(fontinfo.fontfile)
+ if fontinfo.effects:
+ t1font = t1font.transform(fontinfo.effects)
# Font descriptors may be shared between differently encoded
# Type-1 fonts, so only create a new descriptor if there is no
# existing descriptor for this font.
- fontdesc = self.type1Descriptors.get(fontinfo.fontfile)
+ effects = (fontinfo.effects.get('slant', 0.0), fontinfo.effects.get('extend', 1.0))
+ fontdesc = self.type1Descriptors.get((fontinfo.fontfile, effects))
if fontdesc is None:
- fontdesc = self.createType1Descriptor(font, fontinfo.fontfile)
- self.type1Descriptors[fontinfo.fontfile] = fontdesc
+ fontdesc = self.createType1Descriptor(t1font, fontinfo.fontfile)
+ self.type1Descriptors[(fontinfo.fontfile, effects)] = fontdesc
# Widths
widthsObject = self.reserveObject('font widths')
@@ -551,7 +554,7 @@
fontdict = {
'Type': Name('Font'),
'Subtype': Name('Type1'),
- 'BaseFont': Name(font.postscript_name),
+ 'BaseFont': Name(t1font.prop['FontName']),
'FirstChar': 0,
'LastChar': len(fontinfo.widths) - 1,
'Widths': widthsObject,
@@ -571,14 +574,14 @@
self.writeObject(fontdictObject, fontdict)
return fontdictObject
- def createType1Descriptor(self, font, fontfile):
+ def createType1Descriptor(self, t1font, fontfile):
# Create and write the font descriptor and the font file
# of a Type-1 font
fontdescObject = self.reserveObject('font descriptor')
fontfileObject = self.reserveObject('font file')
- _, _, fullname, familyname, weight, italic_angle, fixed_pitch, \
- ul_position, ul_thickness = font.get_ps_font_info()
+ italic_angle = t1font.prop['ItalicAngle']
+ fixed_pitch = t1font.prop['isFixedPitch']
flags = 0
if fixed_pitch: flags |= 1 << 0 # fixed width
@@ -590,18 +593,20 @@
if 0: flags |= 1 << 17 # TODO: small caps
if 0: flags |= 1 << 18 # TODO: force bold
+ ft2font = FT2Font(fontfile)
+
descriptor = {
'Type': Name('FontDescriptor'),
- 'FontName': Name(font.postscript_name),
+ 'FontName': Name(t1font.prop['FontName']),
'Flags': flags,
- 'FontBBox': font.bbox,
+ 'FontBBox': ft2font.bbox,
'ItalicAngle': italic_angle,
- 'Ascent': font.ascender,
- 'Descent': font.descender,
+ 'Ascent': ft2font.ascender,
+ 'Descent': ft2font.descender,
'CapHeight': 1000, # TODO: find this out
'XHeight': 500, # TODO: this one too
'FontFile': fontfileObject,
- 'FontFamily': familyname,
+ 'FontFamily': t1font.prop['FamilyName'],
'StemV': 50, # TODO
# (see also revision 3874; but not all TeX distros have AFM files!)
#'FontWeight': a number where 400 = Regular, 700 = Bold
@@ -609,7 +614,6 @@
self.writeObject(fontdescObject, descriptor)
- t1font = type1font.Type1Font(fontfile)
self.beginStream(fontfileObject.id, None,
{ 'Length1': len(t1font.parts[0]),
'Length2': len(t1font.parts[1]),
@@ -1369,14 +1373,14 @@
self.file.dviFontInfo[dvifont.texname] = Bunch(
fontfile=psfont.filename,
encodingfile=psfont.encoding,
+ effects=psfont.effects,
widths=dvifont.widths,
dvifont=dvifont)
- # TODO: font effects
seq += [['font', pdfname, dvifont.size]]
oldfont = dvifont
seq += [['text', x1, y1, [chr(glyph)], x1+width]]
- # Find consecutive text strings with constant x coordinate and
+ # Find consecutive text strings with constant y coordinate and
# combine into a sequence of strings and kerns, or just one
# string (if any kerns would be less than 0.1 points).
i, curx = 0, 0
Modified: trunk/matplotlib/lib/matplotlib/dviread.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/dviread.py 2008-12-30 16:06:59 UTC (rev 6717)
+++ trunk/matplotlib/lib/matplotlib/dviread.py 2008-12-31 13:20:50 UTC (rev 6718)
@@ -1,12 +1,14 @@
"""
An experimental module for reading dvi files output by TeX. Several
limitations make this not (currently) useful as a general-purpose dvi
-preprocessor.
+preprocessor, but it is currently used by the pdf backend for
+processing usetex text.
Interface::
dvi = Dvi(filename, 72)
- for page in dvi: # iterate over pages
+ # iterate over pages (but only one page is supported for now):
+ for page in dvi:
w, h, d = page.width, page.height, page.descent
for x,y,font,glyph,width in page.text:
fontname = font.texname
@@ -49,7 +51,7 @@
"""
Iterate through the pages of the file.
- Returns (text, pages) pairs, where:
+ Returns (text, boxes) pairs, where:
text is a list of (x, y, fontnum, glyphnum, width) tuples
boxes is a list of (x, y, height, width) tuples
@@ -131,8 +133,8 @@
def _arg(self, nbytes, signed=False):
"""
- Read and return an integer argument "nbytes" long.
- Signedness is determined by the "signed" keyword.
+ Read and return an integer argument *nbytes* long.
+ Signedness is determined by the *signed* keyword.
"""
str = self.file.read(nbytes)
value = ord(str[0])
@@ -144,7 +146,7 @@
def _dispatch(self, byte):
"""
- Based on the opcode "byte", read the correct kinds of
+ 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.
"""
@@ -385,9 +387,27 @@
Object that holds a font's texname and size, supports comparison,
and knows the widths of glyphs in the same units as the AFM file.
There are also internal attributes (for use by dviread.py) that
- are _not_ used for comparison.
+ are *not* used for comparison.
The size is in Adobe points (converted from TeX points).
+
+ .. attribute:: texname
+
+ Name of the font as used internally by TeX and friends. This
+ is usually very different from any external font names, and
+ :class:`dviread.PsfontsMap` can be used to find the external
+ name of the font.
+
+ .. attribute:: size
+
+ Size of the font in Adobe points, converted from the slightly
+ smaller TeX points.
+
+ .. attribute:: widths
+
+ Widths of glyphs in glyph-space units, typically 1/1000ths of
+ the point size.
+
"""
__slots__ = ('texname', 'size', 'widths', '_scale', '_vf', '_tfm')
@@ -532,17 +552,27 @@
A TeX Font Metric file. This implementation covers only the bare
minimum needed by the Dvi class.
- Attributes:
+ .. attribute:: checksum
- checksum: for verifying against dvi file
+ Used for verifying against the dvi file.
- design_size: design size of the font (in what units?)
+ .. attribute:: design_size
- 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)
+ Design size of the font (in what units?)
- height[i], depth[i]: height and depth of character \#i
+ .. attribute:: width
+
+ Width of each character, needs to be scaled by the factor
+ specified in the dvi file. This is a dict because indexing may
+ not start from 0.
+
+ .. attribute:: height
+
+ Height of each character.
+
+ .. attribute:: depth
+
+ Depth of each character.
"""
__slots__ = ('checksum', 'design_size', 'width', 'height', 'depth')
@@ -581,8 +611,20 @@
class PsfontsMap(object):
"""
A psfonts.map formatted file, mapping TeX fonts to PS fonts.
- Usage: map = PsfontsMap('.../psfonts.map'); map['cmr10']
+ Usage::
+ >>> map = PsfontsMap(find_tex_file('pdftex.map'))
+ >>> entry = map['ptmbo8r']
+ >>> entry.texname
+ 'ptmbo8r'
+ >>> entry.psname
+ 'Times-Bold'
+ >>> entry.encoding
+ '/usr/local/texlive/2008/texmf-dist/fonts/enc/dvips/base/8r.enc'
+ >>> entry.effects
+ {'slant': 0.16700000000000001}
+ >>> entry.filename
+
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
@@ -594,11 +636,12 @@
file names.
A texmf tree typically includes mapping files called e.g.
- psfonts.map, pdftex.map, dvipdfm.map. psfonts.map is used by
+ 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.
+ psfonts.map might avoid embedding the 35 PostScript fonts (i.e.,
+ have no filename for them, as in the Times-Bold example above),
+ while the pdf-related files perhaps only avoid the "Base 14" pdf
+ fonts. But the user may have configured these files differently.
"""
__slots__ = ('_font',)
@@ -655,10 +698,10 @@
subsetting, but I have no example of << in my TeX installation.
"""
texname, psname = words[:2]
- effects, encoding, filename = [], None, None
+ effects, encoding, filename = '', None, None
for word in words[2:]:
if not word.startswith('<'):
- effects.append(word)
+ effects = word
else:
word = word.lstrip('<')
if word.startswith('['):
@@ -670,6 +713,18 @@
else:
assert filename is None
filename = word
+
+ eff = effects.split()
+ effects = {}
+ try:
+ effects['slant'] = float(eff[eff.index('SlantFont')-1])
+ except ValueError:
+ pass
+ try:
+ effects['extend'] = float(eff[eff.index('ExtendFont')-1])
+ except ValueError:
+ pass
+
self._font[texname] = mpl_cbook.Bunch(
texname=texname, psname=psname, effects=effects,
encoding=encoding, filename=filename)
@@ -733,13 +788,18 @@
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.
+ Call :program:`kpsewhich` to find a file in the texmf tree. If
+ *format* is not None, it is used as the value for the
+ :option:`--format` option.
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)
+
+ .. seealso::
+
+ `Kpathsea documentation <http://www.tug.org/kpathsea/>`_
+ The library that :program:`kpsewhich` is part of.
"""
cmd = ['kpsewhich']
Modified: trunk/matplotlib/lib/matplotlib/type1font.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/type1font.py 2008-12-30 16:06:59 UTC (rev 6717)
+++ trunk/matplotlib/lib/matplotlib/type1font.py 2008-12-31 13:20:50 UTC (rev 6718)
@@ -1,37 +1,70 @@
"""
-A class representing a Type 1 font.
+This module contains a class representing a Type 1 font.
-This version merely reads pfa and pfb files and splits them for
-embedding in pdf files. There is no support yet for subsetting or
-anything like that.
+This version reads pfa and pfb files and splits them for embedding in
+pdf files. It also supports SlantFont and ExtendFont transformations,
+similarly to pdfTeX and friends. There is no support yet for
+subsetting.
-Usage (subject to change):
+Usage::
- font = Type1Font(filename)
- clear_part, encrypted_part, finale = font.parts
+ >>> font = Type1Font(filename)
+ >>> clear_part, encrypted_part, finale = font.parts
+ >>> slanted_font = font.transform({'slant': 0.167})
+ >>> extended_font = font.transform({'extend': 1.2})
-Source: Adobe Technical Note #5040, Supporting Downloadable PostScript
-Language Fonts.
+Sources:
-If extending this class, see also: Adobe Type 1 Font Format, Adobe
-Systems Incorporated, third printing, v1.1, 1993. ISBN 0-201-57044-0.
+* Adobe Technical Note #5040, Supporting Downloadable PostScript
+ Language Fonts.
+
+* Adobe Type 1 Font Format, Adobe Systems Incorporated, third printing,
+ v1.1, 1993. ISBN 0-201-57044-0.
"""
+import matplotlib.cbook as cbook
+import cStringIO
+import itertools
+import numpy as np
import re
import struct
class Type1Font(object):
+ """
+ A class representing a Type-1 font, for use by backends.
- def __init__(self, filename):
- file = open(filename, 'rb')
- try:
- data = self._read(file)
- finally:
- file.close()
- self.parts = self._split(data)
- #self._parse()
+ .. attribute:: parts
+ A 3-tuple of the cleartext part, the encrypted part, and the
+ finale of zeros.
+
+ .. attribute:: prop
+
+ A dictionary of font properties.
+ """
+ __slots__ = ('parts', 'prop')
+
+ def __init__(self, input):
+ """
+ Initialize a Type-1 font. *input* can be either the file name of
+ a pfb file or a 3-tuple of already-decoded Type-1 font parts.
+ """
+ if isinstance(input, tuple) and len(input) == 3:
+ self.parts = input
+ else:
+ file = open(input, 'rb')
+ try:
+ data = self._read(file)
+ finally:
+ file.close()
+ self.parts = self._split(data)
+
+ self._parse()
+
def _read(self, file):
+ """
+ Read the font from a file, decoding into usable parts.
+ """
rawdata = file.read()
if not rawdata.startswith(chr(128)):
return rawdata
@@ -100,85 +133,177 @@
return data[:len1], binary, data[idx:]
_whitespace = re.compile(r'[\0\t\r\014\n ]+')
- _delim = re.compile(r'[()<>[]{}/%]')
_token = re.compile(r'/{0,2}[^]\0\t\r\v\n ()<>{}/%[]+')
_comment = re.compile(r'%[^\r\n\v]*')
_instring = re.compile(r'[()\\]')
- def _parse(self):
+ @classmethod
+ def _tokens(cls, text):
"""
- A very limited kind of parsing to find the Encoding of the
- font.
+ A PostScript tokenizer. Yield (token, value) pairs such as
+ ('whitespace', ' ') or ('name', '/Foobar').
"""
- def tokens(text):
- """
- Yield pairs (position, token), ignoring comments and
- whitespace. Numbers count as tokens.
- """
- pos = 0
- while pos < len(text):
- match = self._comment.match(text[pos:]) or self._whitespace.match(text[pos:])
+ pos = 0
+ while pos < len(text):
+ match = cls._comment.match(text[pos:]) or cls._whitespace.match(text[pos:])
+ if match:
+ yield ('whitespace', match.group())
+ pos += match.end()
+ elif text[pos] == '(':
+ start = pos
+ pos += 1
+ depth = 1
+ while depth:
+ match = cls._instring.search(text[pos:])
+ if match is None: return
+ pos += match.end()
+ if match.group() == '(':
+ depth += 1
+ elif match.group() == ')':
+ depth -= 1
+ else: # a backslash - skip the next character
+ pos += 1
+ yield ('string', text[start:pos])
+ elif text[pos:pos+2] in ('<<', '>>'):
+ yield ('delimiter', text[pos:pos+2])
+ pos += 2
+ elif text[pos] == '<':
+ start = pos
+ pos += text[pos:].index('>')
+ yield ('string', text[start:pos])
+ else:
+ match = cls._token.match(text[pos:])
if match:
+ try:
+ float(match.group())
+ yield ('number', match.group())
+ except ValueError:
+ yield ('name', match.group())
pos += match.end()
- elif text[pos] == '(':
- start = pos
+ else:
+ yield ('delimiter', text[pos])
pos += 1
- depth = 1
- while depth:
- match = self._instring.search(text[pos:])
- if match is None: return
- if match.group() == '(':
- depth += 1
- pos += 1
- elif match.group() == ')':
- depth -= 1
- pos += 1
- else:
- pos += 2
- yield (start, text[start:pos])
- elif text[pos:pos+2] in ('<<', '>>'):
- yield (pos, text[pos:pos+2])
- pos += 2
- elif text[pos] == '<':
- start = pos
- pos += text[pos:].index('>')
- yield (start, text[start:pos])
- else:
- match = self._token.match(text[pos:])
- if match:
- yield (pos, match.group())
- pos += match.end()
+
+ def _parse(self):
+ """
+ Find the values of various font properties. This limited kind
+ of parsing is described in Chapter 10 "Adobe Type Manager
+ Compatibility" of the Type-1 spec.
+ """
+ # Start with reasonable defaults
+ prop = { 'weight': 'Regular', 'ItalicAngle': 0.0, 'isFixedPitch': False,
+ 'UnderlinePosition': -100, 'UnderlineThickness': 50 }
+ tokenizer = self._tokens(self.parts[0])
+ filtered = itertools.ifilter(lambda x: x[0] != 'whitespace', tokenizer)
+ for token, value in filtered:
+ if token == 'name' and value.startswith('/'):
+ key = value[1:]
+ token, value = filtered.next()
+ if token == 'name':
+ if value in ('true', 'false'):
+ value = value == 'true'
else:
- yield (pos, text[pos])
- pos += 1
+ value = value.lstrip('/')
+ elif token == 'string':
+ value = value.lstrip('(').rstrip(')')
+ elif token == 'number':
+ if '.' in value: value = float(value)
+ else: value = int(value)
+ else: # more complicated value such as an array
+ value = None
+ if key != 'FontInfo' and value is not None:
+ prop[key] = value
- enc_starts, enc_ends = None, None
- state = 0
- # State transitions:
- # 0 -> /Encoding -> 1
- # 1 -> StandardEncoding -> 2 -> def -> (ends)
- # 1 -> dup -> 4 -> put -> 5
- # 5 -> dup -> 4 -> put -> 5
- # 5 -> def -> (ends)
- for pos,token in tokens(self.parts[0]):
- if state == 0 and token == '/Encoding':
- enc_starts = pos
- state = 1
- elif state == 1 and token == 'StandardEncoding':
- state = 2
- elif state in (2,5) and token == 'def':
- enc_ends = pos+3
- break
- elif state in (1,5) and token == 'dup':
- state = 4
- elif state == 4 and token == 'put':
- state = 5
- self.enc_starts, self.enc_ends = enc_starts, enc_ends
+ # Fill in the various *Name properties
+ if not prop.has_key('FontName'):
+ prop['FontName'] = prop.get('FullName') or prop.get('FamilyName') or 'Unknown'
+ if not prop.has_key('FullName'):
+ prop['FullName'] = prop['FontName']
+ if not prop.has_key('FamilyName'):
+ extras = r'(?i)([ -](regular|plain|italic|oblique|(semi)?bold|(ultra)?light|extra|condensed))+$'
+ prop['FamilyName'] = re.sub(extras, '', prop['FullName'])
+ self.prop = prop
+
+ @classmethod
+ def _transformer(cls, tokens, slant, extend):
+ def fontname(name):
+ result = name
+ if slant: result += '_Slant_' + str(int(1000*slant))
+ if extend != 1.0: result += '_Extend_' + str(int(1000*extend))
+ return result
+
+ def italicangle(angle):
+ return str(float(angle) - np.arctan(slant)/np.pi*180)
+
+ def fontmatrix(array):
+ array = array.lstrip('[').rstrip(']').strip().split()
+ array = [ float(x) for x in array ]
+ oldmatrix = np.eye(3,3)
+ oldmatrix[0:3,0] = array[::2]
+ oldmatrix[0:3,1] = array[1::2]
+ modifier = np.array([[extend, 0, 0],
+ [slant, 1, 0],
+ [0, 0, 1]])
+ newmatrix = np.dot(modifier, oldmatrix)
+ array[::2] = newmatrix[0:3,0]
+ array[1::2] = newmatrix[0:3,1]
+ return '[' + ' '.join(str(x) for x in array) + ']'
+
+ def replace(fun):
+ def replacer(tokens):
+ token, value = tokens.next() # name, e.g. /FontMatrix
+ yield value
+ token, value = tokens.next() # possible whitespace
+ while token == 'whitespace':
+ yield value
+ token, value = tokens.next()
+ if value != '[': # name/number/etc.
+ yield fun(value)
+ else: # array, e.g. [1 2 3]
+ array = []
+ while value != ']':
+ array += value
+ token, value = tokens.next()
+ array += value
+ yield fun(''.join(array))
+ return replacer
+
+ def suppress(tokens):
+ for x in itertools.takewhile(lambda x: x[1] != 'def', tokens):
+ pass
+ yield ''
+
+ table = { '/FontName': replace(fontname),
+ '/ItalicAngle': replace(italicangle),
+ '/FontMatrix': replace(fontmatrix),
+ '/UniqueID': suppress }
+
+ while True:
+ token, value = tokens.next()
+ if token == 'name' and value in table:
+ for value in table[value](itertools.chain([(token, value)], tokens)):
+ yield value
+ else:
+ yield value
+
+ def transform(self, effects):
+ """
+ Transform the font by slanting or extending. *effects* should
+ be a dict where ``effects['slant']`` is the tangent of the
+ angle that the font is to be slanted to the right (so negative
+ values slant to the left) and ``effects['extend']`` is the
+ multiplier by which the font is to be extended (so values less
+ than 1.0 condense). Returns a new :class:`Type1Font` object.
+ """
+
+ buffer = cStringIO.StringIO()
+ tokenizer = self._tokens(self.parts[0])
+ for value in self._transformer(tokenizer,
+ slant=effects.get('slant', 0.0),
+ extend=effects.get('extend', 1.0)):
+ buffer.write(value)
+ result = buffer.getvalue()
+ buffer.close()
+
+ return Type1Font((result, self.parts[1], self.parts[2]))
-if __name__ == '__main__':
- import sys
- font = Type1Font(sys.argv[1])
- parts = font.parts
- print len(parts[0]), len(parts[1]), len(parts[2])
- #print parts[0][font.enc_starts:font.enc_ends]
-
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2008-12-30 16:07:06
|
Revision: 6717
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6717&view=rev
Author: jdh2358
Date: 2008-12-30 16:06:59 +0000 (Tue, 30 Dec 2008)
Log Message:
-----------
added rcparams import to path
Modified Paths:
--------------
branches/v0_98_5_maint/lib/matplotlib/path.py
Modified: branches/v0_98_5_maint/lib/matplotlib/path.py
===================================================================
--- branches/v0_98_5_maint/lib/matplotlib/path.py 2008-12-29 15:34:30 UTC (rev 6716)
+++ branches/v0_98_5_maint/lib/matplotlib/path.py 2008-12-30 16:06:59 UTC (rev 6717)
@@ -12,6 +12,7 @@
point_in_path_collection, get_path_collection_extents, \
path_in_path, path_intersects_path, convert_path_to_polygons
from matplotlib.cbook import simple_linear_interpolation
+from matplotlib import rcParams
class Path(object):
"""
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2008-12-29 15:34:33
|
Revision: 6716
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6716&view=rev
Author: mdboom
Date: 2008-12-29 15:34:30 +0000 (Mon, 29 Dec 2008)
Log Message:
-----------
Merged revisions 6714-6715 via svnmerge from
https://matplotlib.svn.sf.net/svnroot/matplotlib/branches/v0_98_5_maint
........
r6714 | mdboom | 2008-12-29 10:29:52 -0500 (Mon, 29 Dec 2008) | 2 lines
Handle path.simplify rcParam in all backends.
........
r6715 | mdboom | 2008-12-29 10:33:18 -0500 (Mon, 29 Dec 2008) | 2 lines
Handle path.simplify rcParam in all backends.
........
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/path.py
Property Changed:
----------------
trunk/matplotlib/
trunk/matplotlib/doc/pyplots/README
trunk/matplotlib/doc/sphinxext/gen_gallery.py
trunk/matplotlib/doc/sphinxext/gen_rst.py
Property changes on: trunk/matplotlib
___________________________________________________________________
Modified: svnmerge-integrated
- /branches/v0_91_maint:1-6428 /branches/v0_98_5_maint:1-6689
+ /branches/v0_91_maint:1-6428 /branches/v0_98_5_maint:1-6715
Modified: svn:mergeinfo
- /branches/v0_91_maint:5753-5771
/branches/v0_98_5_maint:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673
+ /branches/v0_91_maint:5753-5771
/branches/v0_98_5_maint:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673,6714-6715
Property changes on: trunk/matplotlib/doc/pyplots/README
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/v0_98_5_maint/doc/pyplots/README:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673
+ /branches/v0_98_5_maint/doc/pyplots/README:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673,6714-6715
Property changes on: trunk/matplotlib/doc/sphinxext/gen_gallery.py
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/v0_91_maint/doc/_templates/gen_gallery.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_gallery.py:6660-6662,6672-6673
+ /branches/v0_91_maint/doc/_templates/gen_gallery.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_gallery.py:6660-6662,6672-6673,6714-6715
Property changes on: trunk/matplotlib/doc/sphinxext/gen_rst.py
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/v0_91_maint/doc/examples/gen_rst.py:5753-5771
+ /branches/v0_91_maint/doc/examples/gen_rst.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_rst.py:6714-6715
Modified: trunk/matplotlib/lib/matplotlib/path.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/path.py 2008-12-29 15:33:18 UTC (rev 6715)
+++ trunk/matplotlib/lib/matplotlib/path.py 2008-12-29 15:34:30 UTC (rev 6716)
@@ -112,7 +112,7 @@
self.should_simplify = (rcParams['path.simplify'] and
(len(vertices) >= 128 and
- (codes is None or np.all(codes <= Path.LINETO))))
+ (codes is None or np.all(codes <= Path.LINETO))))
self.has_nonfinite = not np.isfinite(vertices).all()
self.codes = codes
self.vertices = vertices
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2008-12-29 15:33:24
|
Revision: 6715
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6715&view=rev
Author: mdboom
Date: 2008-12-29 15:33:18 +0000 (Mon, 29 Dec 2008)
Log Message:
-----------
Handle path.simplify rcParam in all backends.
Modified Paths:
--------------
branches/v0_98_5_maint/lib/matplotlib/path.py
Modified: branches/v0_98_5_maint/lib/matplotlib/path.py
===================================================================
--- branches/v0_98_5_maint/lib/matplotlib/path.py 2008-12-29 15:29:52 UTC (rev 6714)
+++ branches/v0_98_5_maint/lib/matplotlib/path.py 2008-12-29 15:33:18 UTC (rev 6715)
@@ -109,7 +109,7 @@
assert vertices.ndim == 2
assert vertices.shape[1] == 2
- self.should_simplify = (rcParam['path.simplify'] and
+ self.should_simplify = (rcParams['path.simplify'] and
(len(vertices) >= 128 and
(codes is None or np.all(codes <= Path.LINETO))))
self.has_nonfinite = not np.isfinite(vertices).all()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2008-12-29 15:29:56
|
Revision: 6714
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6714&view=rev
Author: mdboom
Date: 2008-12-29 15:29:52 +0000 (Mon, 29 Dec 2008)
Log Message:
-----------
Handle path.simplify rcParam in all backends.
Modified Paths:
--------------
branches/v0_98_5_maint/lib/matplotlib/path.py
Modified: branches/v0_98_5_maint/lib/matplotlib/path.py
===================================================================
--- branches/v0_98_5_maint/lib/matplotlib/path.py 2008-12-29 14:52:30 UTC (rev 6713)
+++ branches/v0_98_5_maint/lib/matplotlib/path.py 2008-12-29 15:29:52 UTC (rev 6714)
@@ -109,8 +109,9 @@
assert vertices.ndim == 2
assert vertices.shape[1] == 2
- self.should_simplify = (len(vertices) >= 128 and
- (codes is None or np.all(codes <= Path.LINETO)))
+ self.should_simplify = (rcParam['path.simplify'] and
+ (len(vertices) >= 128 and
+ (codes is None or np.all(codes <= Path.LINETO))))
self.has_nonfinite = not np.isfinite(vertices).all()
self.codes = codes
self.vertices = vertices
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jo...@us...> - 2008-12-29 14:52:33
|
Revision: 6713
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6713&view=rev
Author: jouni
Date: 2008-12-29 14:52:30 +0000 (Mon, 29 Dec 2008)
Log Message:
-----------
Fix buglet in path.py
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/path.py
Modified: trunk/matplotlib/lib/matplotlib/path.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/path.py 2008-12-29 14:42:20 UTC (rev 6712)
+++ trunk/matplotlib/lib/matplotlib/path.py 2008-12-29 14:52:30 UTC (rev 6713)
@@ -12,6 +12,7 @@
point_in_path_collection, get_path_collection_extents, \
path_in_path, path_intersects_path, convert_path_to_polygons
from matplotlib.cbook import simple_linear_interpolation, maxdict
+from matplotlib import rcParams
class Path(object):
"""
@@ -109,7 +110,7 @@
assert vertices.ndim == 2
assert vertices.shape[1] == 2
- self.should_simplify = (rcParam['path.simplify'] and
+ self.should_simplify = (rcParams['path.simplify'] and
(len(vertices) >= 128 and
(codes is None or np.all(codes <= Path.LINETO))))
self.has_nonfinite = not np.isfinite(vertices).all()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|