Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d0a4cd0

Browse files
committed
Render all the fonts in each mathtext expression to a single image buffer
(memory and time savings). Add support for getting raw image data for mathtext expressions. Add mathtext_wx.py example showing how to put mathtext expressions into controls. svn path=/trunk/matplotlib/; revision=3764
1 parent eaded86 commit d0a4cd0

8 files changed

Lines changed: 591 additions & 332 deletions

File tree

lib/matplotlib/backends/backend_agg.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -172,21 +172,19 @@ def draw_mathtext(self, gc, x, y, s, prop, angle):
172172
"""
173173
if __debug__: verbose.report('RendererAgg.draw_mathtext',
174174
'debug-annoying')
175-
ox, oy, width, height, descent, fonts, used_characters = \
175+
ox, oy, width, height, descent, font_image, used_characters = \
176176
self.mathtext_parser.parse(s, self.dpi.get(), prop)
177177

178178
if angle == 90:
179179
width, height = height, width
180180
ox, oy = oy, ox
181181
x = int(x) - width + ox
182182
y = int(y) - height + oy
183+
font_image.rotate()
183184
else:
184185
x = int(x) + ox
185186
y = int(y) - height + oy
186-
for font in fonts:
187-
if angle == 90:
188-
font.horiz_image_to_vert_image() # <-- Rotate
189-
self._renderer.draw_text( font, x, y + 1, gc)
187+
self._renderer.draw_text_image(font_image, x, y + 1, gc)
190188
if 0:
191189
self._renderer.draw_rectangle(gc, None,
192190
int(x),
@@ -212,7 +210,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath):
212210

213211
#print x, y, int(x), int(y)
214212

215-
self._renderer.draw_text(font, int(x), int(y) + 1, gc)
213+
self._renderer.draw_text_image(font.get_image(), int(x), int(y) + 1, gc)
216214

217215

218216
def get_text_width_height_descent(self, s, prop, ismath, rgb=(0,0,0)):

lib/matplotlib/backends/backend_gdk.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ def _draw_mathtext(self, gc, x, y, s, prop, angle):
215215

216216
for i, font in enumerate(fonts):
217217
if angle == 90:
218-
font.horiz_image_to_vert_image() # <-- Rotate
218+
font.get_image().rotate() # <-- Rotate
219219
imw, imh, image_str = font.image_as_str()
220220
Xall[:,i] = npy.fromstring(image_str, npy.uint8)
221221

lib/matplotlib/mathtext.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@
143143
from matplotlib.afm import AFM
144144
from matplotlib.cbook import enumerate, iterable, Bunch, get_realpath_and_stat, \
145145
is_string_like
146-
from matplotlib.ft2font import FT2Font, KERNING_DEFAULT, LOAD_DEFAULT, LOAD_NO_HINTING
146+
from matplotlib.ft2font import FT2Font, FT2Image, KERNING_DEFAULT, LOAD_DEFAULT, LOAD_NO_HINTING
147147
from matplotlib.font_manager import findfont, FontProperties
148148
from matplotlib._mathtext_data import latex_to_bakoma, \
149149
latex_to_standard, tex2uni, type12uni, tex2type1, uni2type1
@@ -288,28 +288,27 @@ class MathtextBackendAggRender(MathtextBackend):
288288
def __init__(self):
289289
self.ox = 0
290290
self.oy = 0
291+
self.image = None
291292
MathtextBackend.__init__(self)
292293

293294
def set_canvas_size(self, w, h, d):
294295
MathtextBackend.set_canvas_size(self, w, h, d)
295-
for font in self.fonts_object.get_fonts():
296-
font.set_bitmap_size(int(w), int(h) + int(d))
296+
self.image = FT2Image(ceil(w), ceil(h + d))
297297

298298
def render_glyph(self, ox, oy, info):
299299
info.font.draw_glyph_to_bitmap(
300-
ox, oy - info.metrics.ymax, info.glyph)
300+
self.image, ox, oy - info.metrics.ymax, info.glyph)
301301

302302
def render_rect_filled(self, x1, y1, x2, y2):
303-
font = self.fonts_object.get_fonts()[0]
304-
font.draw_rect_filled(x1, y1, x2, max(y2 - 1, y1))
303+
self.image.draw_rect_filled(x1, y1, x2, max(y2 - 1, y1))
305304

306305
def get_results(self, box):
307306
return (self.ox,
308307
self.oy,
309308
self.width,
310309
self.height + self.depth,
311310
self.depth,
312-
self.fonts_object.get_fonts(),
311+
self.image,
313312
self.fonts_object.get_used_characters())
314313

315314
def get_hinting_type(self):
@@ -318,6 +317,13 @@ def get_hinting_type(self):
318317
def MathtextBackendAgg():
319318
return MathtextBackendBbox(MathtextBackendAggRender())
320319

320+
class MathtextBackendBitmapRender(MathtextBackendAggRender):
321+
def get_results(self, box):
322+
return self.image
323+
324+
def MathtextBackendBitmap():
325+
return MathtextBackendBbox(MathtextBackendBitmapRender())
326+
321327
class MathtextBackendPs(MathtextBackend):
322328
def __init__(self):
323329
self.pswriter = StringIO()
@@ -2443,6 +2449,7 @@ class MathTextParser(object):
24432449
_parser = None
24442450

24452451
_backend_mapping = {
2452+
'Bitmap': MathtextBackendBitmap,
24462453
'Agg' : MathtextBackendAgg,
24472454
'PS' : MathtextBackendPs,
24482455
'Pdf' : MathtextBackendPdf,
@@ -2454,7 +2461,10 @@ def __init__(self, output):
24542461
self._output = output
24552462
self._cache = {}
24562463

2457-
def parse(self, s, dpi, prop):
2464+
def parse(self, s, dpi = 72, prop = None):
2465+
if prop is None:
2466+
prop = FontProperties()
2467+
24582468
cacheKey = (s, dpi, hash(prop))
24592469
result = self._cache.get(cacheKey)
24602470
if result is not None:

src/_backend_agg.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2106,13 +2106,14 @@ RendererAgg::draw_path(const Py::Tuple& args) {
21062106

21072107

21082108
Py::Object
2109-
RendererAgg::draw_text(const Py::Tuple& args) {
2109+
RendererAgg::draw_text_image(const Py::Tuple& args) {
21102110
_VERBOSE("RendererAgg::draw_text");
21112111

21122112
args.verify_length(4);
21132113

2114-
2115-
FT2Font *font = static_cast<FT2Font*>(args[0].ptr());
2114+
FT2Image *image = static_cast<FT2Image*>(args[0].ptr());
2115+
if (!image->get_buffer())
2116+
return Py::Object();
21162117

21172118
int x(0),y(0);
21182119
try {
@@ -2151,15 +2152,16 @@ RendererAgg::draw_text(const Py::Tuple& args) {
21512152
t = b+h;
21522153
}
21532154

2155+
const unsigned char* const buffer = image->get_buffer();
21542156

2155-
for (size_t i=0; i<font->image.width; i++) {
2156-
for (size_t j=0; j<font->image.height; j++) {
2157-
thisx = i+x+font->image.offsetx;
2158-
thisy = j+y+font->image.offsety;
2157+
for (size_t i=0; i< image->get_width(); i++) {
2158+
for (size_t j=0; j< image->get_height(); j++) {
2159+
thisx = i+x+image->offsetx;
2160+
thisy = j+y+image->offsety;
21592161
if (thisx<l || thisx>=r) continue;
21602162
if (thisy<height-t || thisy>=height-b) continue;
21612163
pixFmt->blend_pixel
2162-
(thisx, thisy, p, font->image.buffer[i + j*font->image.width]);
2164+
(thisx, thisy, p, buffer[i + j*image->get_width()]);
21632165
}
21642166
}
21652167

@@ -2568,8 +2570,8 @@ void RendererAgg::init_type()
25682570
"draw_markers(gc, path, x, y)\n");
25692571
add_varargs_method("draw_path", &RendererAgg::draw_path,
25702572
"draw_path(gc, rgbFace, path, transform)\n");
2571-
add_varargs_method("draw_text", &RendererAgg::draw_text,
2572-
"draw_text(font, x, y, r, g, b, a)\n");
2573+
add_varargs_method("draw_text_image", &RendererAgg::draw_text_image,
2574+
"draw_text_image(font_image, x, y, r, g, b, a)\n");
25732575
add_varargs_method("draw_image", &RendererAgg::draw_image,
25742576
"draw_image(x, y, im)");
25752577
add_varargs_method("write_rgba", &RendererAgg::write_rgba,

src/_backend_agg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ class RendererAgg: public Py::PythonExtension<RendererAgg> {
166166
//Py::Object _draw_markers_nocache(const Py::Tuple & args);
167167
//Py::Object _draw_markers_cache(const Py::Tuple & args);
168168
Py::Object draw_markers(const Py::Tuple & args);
169-
Py::Object draw_text(const Py::Tuple & args);
169+
Py::Object draw_text_image(const Py::Tuple & args);
170170
Py::Object draw_image(const Py::Tuple & args);
171171

172172
Py::Object write_rgba(const Py::Tuple & args);

0 commit comments

Comments
 (0)