1
1
# -*- coding: utf-8 -*-
2
2
3
3
from __future__ import print_function
4
-
4
+ import warnings
5
5
import urllib
6
- from matplotlib .path import Path
7
- import matplotlib .font_manager as font_manager
8
6
9
- from matplotlib . ft2font import FT2Font , KERNING_DEFAULT , LOAD_NO_HINTING , LOAD_TARGET_LIGHT
7
+ import numpy as np
10
8
9
+ from matplotlib .path import Path
10
+ from matplotlib import rcParams
11
+ import matplotlib .font_manager as font_manager
12
+ from matplotlib .ft2font import FT2Font , KERNING_DEFAULT , LOAD_NO_HINTING
13
+ from matplotlib .ft2font import LOAD_TARGET_LIGHT
11
14
from matplotlib .mathtext import MathTextParser
12
-
13
15
import matplotlib .dviread as dviread
16
+ from matplotlib .font_manager import FontProperties
17
+ from matplotlib .transforms import Affine2D
14
18
15
- import numpy as np
16
-
17
- import warnings
18
19
19
20
class TextToPath (object ):
20
21
"""
@@ -38,7 +39,6 @@ def __init__(self):
38
39
39
40
self ._adobe_standard_encoding = None
40
41
41
-
42
42
def _get_adobe_standard_encoding (self ):
43
43
enc_name = dviread .find_tex_file ('8a.enc' )
44
44
enc = dviread .Encoding (enc_name )
@@ -61,7 +61,7 @@ def _get_char_id(self, font, ccode):
61
61
"""
62
62
Return a unique id for the given font and character-code set.
63
63
"""
64
- ps_name = font .get_sfnt ()[(1 ,0 , 0 , 6 )]
64
+ ps_name = font .get_sfnt ()[(1 , 0 , 0 , 6 )]
65
65
char_id = urllib .quote ('%s-%x' % (ps_name , ccode ))
66
66
return char_id
67
67
@@ -73,14 +73,13 @@ def _get_char_id_ps(self, font, ccode):
73
73
char_id = urllib .quote ('%s-%d' % (ps_name , ccode ))
74
74
return char_id
75
75
76
-
77
76
def glyph_to_path (self , font , currx = 0. ):
78
77
"""
79
78
convert the ft2font glyph to vertices and codes.
80
79
"""
81
80
verts , codes = font .get_path ()
82
81
if currx != 0.0 :
83
- verts [:,0 ] += currx
82
+ verts [:, 0 ] += currx
84
83
return verts , codes
85
84
86
85
def get_text_width_height_descent (self , s , prop , ismath ):
@@ -113,7 +112,8 @@ def get_text_width_height_descent(self, s, prop, ismath):
113
112
114
113
def get_text_path (self , prop , s , ismath = False , usetex = False ):
115
114
"""
116
- convert text *s* to path (a tuple of vertices and codes for matplotlib.math.Path).
115
+ convert text *s* to path (a tuple of vertices and codes for
116
+ matplotlib.path.Path).
117
117
118
118
*prop*
119
119
font property
@@ -129,12 +129,14 @@ def get_text_path(self, prop, s, ismath=False, usetex=False):
129
129
130
130
131
131
"""
132
- if usetex == False :
133
- if ismath == False :
132
+ if not usetex :
133
+ if not ismath :
134
134
font = self ._get_font (prop )
135
- glyph_info , glyph_map , rects = self .get_glyphs_with_font (font , s )
135
+ glyph_info , glyph_map , rects = self .get_glyphs_with_font (
136
+ font , s )
136
137
else :
137
- glyph_info , glyph_map , rects = self .get_glyphs_mathtext (prop , s )
138
+ glyph_info , glyph_map , rects = self .get_glyphs_mathtext (
139
+ prop , s )
138
140
else :
139
141
glyph_info , glyph_map , rects = self .get_glyphs_tex (prop , s )
140
142
@@ -143,7 +145,7 @@ def get_text_path(self, prop, s, ismath=False, usetex=False):
143
145
for glyph_id , xposition , yposition , scale in glyph_info :
144
146
verts1 , codes1 = glyph_map [glyph_id ]
145
147
if len (verts1 ):
146
- verts1 = np .array (verts1 )* scale + [xposition , yposition ]
148
+ verts1 = np .array (verts1 ) * scale + [xposition , yposition ]
147
149
verts .extend (verts1 )
148
150
codes .extend (codes1 )
149
151
@@ -153,7 +155,6 @@ def get_text_path(self, prop, s, ismath=False, usetex=False):
153
155
154
156
return verts , codes
155
157
156
-
157
158
def get_glyphs_with_font (self , font , s , glyph_map = None ,
158
159
return_new_glyphs_only = False ):
159
160
"""
@@ -213,12 +214,14 @@ def get_glyphs_with_font(self, font, s, glyph_map=None,
213
214
214
215
rects = []
215
216
216
- return zip (glyph_ids , xpositions , ypositions , sizes ), glyph_map_new , rects
217
+ return (zip (glyph_ids , xpositions , ypositions , sizes ),
218
+ glyph_map_new , rects )
217
219
218
220
def get_glyphs_mathtext (self , prop , s , glyph_map = None ,
219
221
return_new_glyphs_only = False ):
220
222
"""
221
- convert the string *s* to vertices and codes by parsing it with mathtext.
223
+ convert the string *s* to vertices and codes by parsing it with
224
+ mathtext.
222
225
"""
223
226
224
227
prop = prop .copy ()
@@ -227,8 +230,7 @@ def get_glyphs_mathtext(self, prop, s, glyph_map=None,
227
230
width , height , descent , glyphs , rects = self .mathtext_parser .parse (
228
231
s , self .DPI , prop )
229
232
230
-
231
- if glyph_map is None :
233
+ if not glyph_map :
232
234
glyph_map = dict ()
233
235
234
236
if return_new_glyphs_only :
@@ -258,14 +260,15 @@ def get_glyphs_mathtext(self, prop, s, glyph_map=None,
258
260
259
261
myrects = []
260
262
for ox , oy , w , h in rects :
261
- vert1 = [(ox , oy ), (ox , oy + h ), (ox + w , oy + h ), (ox + w , oy ), (ox , oy ), (0 ,0 )]
263
+ vert1 = [(ox , oy ), (ox , oy + h ), (ox + w , oy + h ),
264
+ (ox + w , oy ), (ox , oy ), (0 , 0 )]
262
265
code1 = [Path .MOVETO ,
263
266
Path .LINETO , Path .LINETO , Path .LINETO , Path .LINETO ,
264
267
Path .CLOSEPOLY ]
265
268
myrects .append ((vert1 , code1 ))
266
269
267
-
268
- return zip ( glyph_ids , xpositions , ypositions , sizes ), glyph_map_new , myrects
270
+ return ( zip ( glyph_ids , xpositions , ypositions , sizes ),
271
+ glyph_map_new , myrects )
269
272
270
273
def get_texmanager (self ):
271
274
"""
@@ -279,21 +282,23 @@ def get_texmanager(self):
279
282
def get_glyphs_tex (self , prop , s , glyph_map = None ,
280
283
return_new_glyphs_only = False ):
281
284
"""
282
- convert the string *s* to vertices and codes using matplotlib's usetex mode.
285
+ convert the string *s* to vertices and codes using matplotlib's usetex
286
+ mode.
283
287
"""
284
288
285
289
# codes are modstly borrowed from pdf backend.
286
290
287
291
texmanager = self .get_texmanager ()
288
292
289
293
if self .tex_font_map is None :
290
- self .tex_font_map = dviread .PsfontsMap (dviread .find_tex_file ('pdftex.map' ))
294
+ self .tex_font_map = dviread .PsfontsMap (
295
+ dviread .find_tex_file ('pdftex.map' ))
291
296
292
297
if self ._adobe_standard_encoding is None :
293
298
self ._adobe_standard_encoding = self ._get_adobe_standard_encoding ()
294
299
295
300
fontsize = prop .get_size_in_points ()
296
- if hasattr (texmanager , "get_dvi" ): #
301
+ if hasattr (texmanager , "get_dvi" ):
297
302
dvifilelike = texmanager .get_dvi (s , self .FONT_SCALE )
298
303
dvi = dviread .DviFromFileLike (dvifilelike , self .DPI )
299
304
else :
@@ -304,7 +309,6 @@ def get_glyphs_tex(self, prop, s, glyph_map=None,
304
309
finally :
305
310
dvi .close ()
306
311
307
-
308
312
if glyph_map is None :
309
313
glyph_map = dict ()
310
314
@@ -313,21 +317,22 @@ def get_glyphs_tex(self, prop, s, glyph_map=None,
313
317
else :
314
318
glyph_map_new = glyph_map
315
319
316
-
317
320
glyph_ids , xpositions , ypositions , sizes = [], [], [], []
318
321
319
322
# Gather font information and do some setup for combining
320
323
# characters into strings.
321
- #oldfont, seq = None, []
324
+ # oldfont, seq = None, []
322
325
for x1 , y1 , dvifont , glyph , width in page .text :
323
326
font_and_encoding = self ._ps_fontd .get (dvifont .texname )
324
- font_bunch = self .tex_font_map [dvifont .texname ]
327
+ font_bunch = self .tex_font_map [dvifont .texname ]
325
328
326
329
if font_and_encoding is None :
327
330
font = FT2Font (str (font_bunch .filename ))
328
331
329
- for charmap_name , charmap_code in [("ADOBE_CUSTOM" , 1094992451 ),
330
- ("ADOBE_STANDARD" , 1094995778 )]:
332
+ for charmap_name , charmap_code in [("ADOBE_CUSTOM" ,
333
+ 1094992451 ),
334
+ ("ADOBE_STANDARD" ,
335
+ 1094995778 )]:
331
336
try :
332
337
font .select_charmap (charmap_code )
333
338
except ValueError :
@@ -336,12 +341,13 @@ def get_glyphs_tex(self, prop, s, glyph_map=None,
336
341
break
337
342
else :
338
343
charmap_name = ""
339
- warnings .warn ("No supported encoding in font (%s)." % font_bunch .filename )
344
+ warnings .warn ("No supported encoding in font (%s)." %
345
+ font_bunch .filename )
340
346
341
347
if charmap_name == "ADOBE_STANDARD" and font_bunch .encoding :
342
348
enc0 = dviread .Encoding (font_bunch .encoding )
343
- enc = dict ([(i , self ._adobe_standard_encoding .get (c , None )) \
344
- for i , c in enumerate (enc0 .encoding )])
349
+ enc = dict ([(i , self ._adobe_standard_encoding .get (c , None ))
350
+ for i , c in enumerate (enc0 .encoding )])
345
351
else :
346
352
enc = dict ()
347
353
self ._ps_fontd [dvifont .texname ] = font , enc
@@ -356,48 +362,44 @@ def get_glyphs_tex(self, prop, s, glyph_map=None,
356
362
if not char_id in glyph_map :
357
363
font .clear ()
358
364
font .set_size (self .FONT_SCALE , self .DPI )
359
- if enc : charcode = enc .get (glyph , None )
360
- else : charcode = glyph
365
+ if enc :
366
+ charcode = enc .get (glyph , None )
367
+ else :
368
+ charcode = glyph
361
369
362
370
if charcode is not None :
363
371
glyph0 = font .load_char (charcode , flags = ft2font_flag )
364
372
else :
365
- warnings .warn ("The glyph (%d) of font (%s) cannot be converted with the encoding. Glyph may be wrong" % (glyph , font_bunch .filename ))
373
+ warnings .warn ("The glyph (%d) of font (%s) cannot be "
374
+ "converted with the encoding. Glyph may "
375
+ "be wrong" % (glyph , font_bunch .filename ))
366
376
367
377
glyph0 = font .load_char (glyph , flags = ft2font_flag )
368
378
369
379
glyph_map_new [char_id ] = self .glyph_to_path (font )
370
380
371
-
372
381
glyph_ids .append (char_id )
373
382
xpositions .append (x1 )
374
383
ypositions .append (y1 )
375
- sizes .append (dvifont .size / self .FONT_SCALE )
384
+ sizes .append (dvifont .size / self .FONT_SCALE )
376
385
377
386
myrects = []
378
387
379
388
for ox , oy , h , w in page .boxes :
380
- vert1 = [(ox , oy ), (ox + w , oy ), (ox + w , oy + h ), (ox , oy + h ), (ox , oy ), (0 ,0 )]
389
+ vert1 = [(ox , oy ), (ox + w , oy ), (ox + w , oy + h ),
390
+ (ox , oy + h ), (ox , oy ), (0 , 0 )]
381
391
code1 = [Path .MOVETO ,
382
392
Path .LINETO , Path .LINETO , Path .LINETO , Path .LINETO ,
383
393
Path .CLOSEPOLY ]
384
394
myrects .append ((vert1 , code1 ))
385
395
386
-
387
- return zip (glyph_ids , xpositions , ypositions , sizes ), \
388
- glyph_map_new , myrects
389
-
390
-
396
+ return (zip (glyph_ids , xpositions , ypositions , sizes ),
397
+ glyph_map_new , myrects )
391
398
392
399
393
-
394
-
395
- from matplotlib .font_manager import FontProperties
396
- from matplotlib import rcParams
397
- from matplotlib .transforms import Affine2D
398
-
399
400
text_to_path = TextToPath ()
400
401
402
+
401
403
class TextPath (Path ):
402
404
"""
403
405
Create a path from the text.
@@ -418,27 +420,26 @@ def __init__(self, xy, s, size=None, prop=None,
418
420
prop : font property
419
421
"""
420
422
421
-
422
423
if prop is None :
423
424
prop = FontProperties ()
424
425
425
426
if size is None :
426
427
size = prop .get_size_in_points ()
427
428
428
-
429
429
self ._xy = xy
430
430
self .set_size (size )
431
431
432
432
self ._cached_vertices = None
433
433
434
- self ._vertices , self ._codes = self .text_get_vertices_codes (prop , s , usetex = usetex )
434
+ self ._vertices , self ._codes = self .text_get_vertices_codes (
435
+ prop , s ,
436
+ usetex = usetex )
435
437
436
438
self .should_simplify = False
437
439
self .simplify_threshold = rcParams ['path.simplify_threshold' ]
438
440
self .has_nonfinite = False
439
441
self ._interpolation_steps = _interpolation_steps
440
442
441
-
442
443
def set_size (self , size ):
443
444
"""
444
445
set the size of the text
@@ -477,14 +478,14 @@ def _revalidate_path(self):
477
478
necessary.
478
479
479
480
"""
480
- if self ._invalid or \
481
- (self ._cached_vertices is None ):
482
- tr = Affine2D ().scale (self ._size / text_to_path .FONT_SCALE ,
483
- self ._size / text_to_path .FONT_SCALE ).translate (* self ._xy )
481
+ if (self ._invalid or
482
+ (self ._cached_vertices is None )):
483
+ tr = Affine2D ().scale (
484
+ self ._size / text_to_path .FONT_SCALE ,
485
+ self ._size / text_to_path .FONT_SCALE ).translate (* self ._xy )
484
486
self ._cached_vertices = tr .transform (self ._vertices )
485
487
self ._invalid = False
486
488
487
-
488
489
def is_math_text (self , s ):
489
490
"""
490
491
Returns True if the given string *s* contains any mathtext.
@@ -515,10 +516,7 @@ def text_get_vertices_codes(self, prop, s, usetex):
515
516
verts , codes = text_to_path .get_text_path (prop , s , usetex = True )
516
517
else :
517
518
clean_line , ismath = self .is_math_text (s )
518
- verts , codes = text_to_path .get_text_path (prop , clean_line , ismath = ismath )
519
+ verts , codes = text_to_path .get_text_path (prop , clean_line ,
520
+ ismath = ismath )
519
521
520
522
return verts , codes
521
-
522
-
523
-
524
-
0 commit comments