@@ -172,41 +172,41 @@ def draw_path(self, gc, path, transform, rgbFace=None):
172172
173173 raise OverflowError (msg ) from None
174174
175- def draw_mathtext (self , gc , x , y , s , prop , angle ):
176- """Draw mathtext using :mod:`matplotlib.mathtext`."""
175+ def _draw_text_glyphs_and_boxes (self , gc , x , y , angle , glyphs , boxes ):
177176 # y is downwards.
178- parse = self .mathtext_parser .parse (
179- s , self .dpi , prop , antialiased = gc .get_antialiased ())
180177 cos = math .cos (math .radians (angle ))
181178 sin = math .sin (math .radians (angle ))
182- for font , size , _char , glyph_index , dx , dy in parse .glyphs : # dy is upwards.
179+ load_flags = get_hinting_flag ()
180+ for font , size , glyph_index , slant , extend , dx , dy in glyphs : # dy is upwards.
183181 font .set_size (size , self .dpi )
184182 hf = font ._hinting_factor
185183 font ._set_transform (
186- [[round (0x10000 * cos / hf ), round (0x10000 * - sin )],
187- [round (0x10000 * sin / hf ), round (0x10000 * cos )]],
184+ (0x10000 * np .array ([[cos , - sin ], [sin , cos ]])
185+ @ [[extend , extend * slant ], [0 , 1 ]]
186+ @ [[1 / hf , 0 ], [0 , 1 ]]).round ().astype (int ),
188187 [round (0x40 * (x + dx * cos - dy * sin )),
189188 # FreeType's y is upwards.
190189 round (0x40 * (self .height - y + dx * sin + dy * cos ))]
191190 )
192191 bitmap = font ._render_glyph (
193- glyph_index , get_hinting_flag () ,
192+ glyph_index , load_flags ,
194193 RenderMode .NORMAL if gc .get_antialiased () else RenderMode .MONO )
195- buffer = np . asarray ( bitmap .buffer )
194+ buffer = bitmap .buffer
196195 if not gc .get_antialiased ():
197196 buffer *= 0xff
198197 # draw_text_image's y is downwards & the bitmap bottom side.
199198 self ._renderer .draw_text_image (
200199 buffer ,
201200 bitmap .left , int (self .height ) - bitmap .top + buffer .shape [0 ],
202201 0 , gc )
202+
203203 rgba = gc .get_rgb ()
204204 if len (rgba ) == 3 or gc .get_forced_alpha ():
205205 rgba = rgba [:3 ] + (gc .get_alpha (),)
206206 gc1 = self .new_gc ()
207207 gc1 .set_linewidth (0 )
208208 gc1 .set_snap (gc .get_snap ())
209- for dx , dy , w , h in parse . rects : # dy is upwards.
209+ for dx , dy , w , h in boxes : # dy is upwards.
210210 if gc1 .get_snap () in [None , True ]:
211211 # Prevent thin bars from disappearing by growing symmetrically.
212212 if w < 1 :
@@ -224,25 +224,31 @@ def draw_mathtext(self, gc, x, y, s, prop, angle):
224224 rgba )
225225 gc1 .restore ()
226226
227+ def draw_mathtext (self , gc , x , y , s , prop , angle ):
228+ """Draw mathtext using :mod:`matplotlib.mathtext`."""
229+ parse = self .mathtext_parser .parse (
230+ s , self .dpi , prop , antialiased = gc .get_antialiased ())
231+ self ._draw_text_glyphs_and_boxes (
232+ gc , x , y , angle ,
233+ ((font , size , glyph_index , 0 , 1 , dx , dy )
234+ for font , size , _char , glyph_index , dx , dy in parse .glyphs ),
235+ parse .rects )
236+
227237 def draw_text (self , gc , x , y , s , prop , angle , ismath = False , mtext = None ):
228238 # docstring inherited
229239 if ismath :
230240 return self .draw_mathtext (gc , x , y , s , prop , angle )
231241 font = self ._prepare_font (prop )
232- font .set_text (s , angle , flags = get_hinting_flag (),
233- features = mtext .get_fontfeatures () if mtext is not None else None ,
234- language = mtext .get_language () if mtext is not None else None )
235- for bitmap in font ._render_glyphs (
236- x , self .height - y ,
237- RenderMode .NORMAL if gc .get_antialiased () else RenderMode .MONO ,
238- ):
239- buffer = bitmap .buffer
240- if not gc .get_antialiased ():
241- buffer *= 0xff
242- self ._renderer .draw_text_image (
243- buffer ,
244- bitmap .left , int (self .height ) - bitmap .top + buffer .shape [0 ],
245- 0 , gc )
242+ items = font ._layout (
243+ s , flags = get_hinting_flag (),
244+ features = mtext .get_fontfeatures () if mtext is not None else None ,
245+ language = mtext .get_language () if mtext is not None else None )
246+ size = prop .get_size_in_points ()
247+ self ._draw_text_glyphs_and_boxes (
248+ gc , x , y , angle ,
249+ ((item .ft_object , size , item .glyph_index , 0 , 1 , item .x , item .y )
250+ for item in items ),
251+ [])
246252
247253 def get_text_width_height_descent (self , s , prop , ismath ):
248254 # docstring inherited
@@ -285,66 +291,13 @@ def draw_tex(self, gc, x, y, s, prop, angle, *, mtext=None):
285291 with Dvi (dvifile , self .dpi ) as dvi :
286292 page , = dvi
287293
288- cos = math .cos (math .radians (angle ))
289- sin = math .sin (math .radians (angle ))
290-
291- for text in page .text :
292- hf = mpl .rcParams ["text.hinting_factor" ]
293- # Resolving text.index will implicitly call get_font(), which
294- # resets the font transform, so it has to be done before explicitly
295- # setting the font transform below.
296- index = text .index
297- font = get_font (text .font_path )
298- font .set_size (text .font_size , self .dpi )
299- slant = text .font_effects .get ("slant" , 0 )
300- extend = text .font_effects .get ("extend" , 1 )
301- font ._set_transform (
302- (0x10000 * np .array ([[cos , - sin ], [sin , cos ]])
303- @ [[extend , extend * slant ], [0 , 1 ]]
304- @ [[1 / hf , 0 ], [0 , 1 ]]).round ().astype (int ),
305- [round (0x40 * (x + text .x * cos - text .y * sin )),
306- # FreeType's y is upwards.
307- round (0x40 * (self .height - y + text .x * sin + text .y * cos ))]
308- )
309- bitmap = font ._render_glyph (
310- index , get_hinting_flag (),
311- RenderMode .NORMAL if gc .get_antialiased () else RenderMode .MONO )
312- buffer = np .asarray (bitmap .buffer )
313- if not gc .get_antialiased ():
314- buffer *= 0xff
315- # draw_text_image's y is downwards & the bitmap bottom side.
316- self ._renderer .draw_text_image (
317- buffer ,
318- bitmap .left , int (self .height ) - bitmap .top + buffer .shape [0 ],
319- 0 , gc )
320-
321- rgba = gc .get_rgb ()
322- if len (rgba ) == 3 or gc .get_forced_alpha ():
323- rgba = rgba [:3 ] + (gc .get_alpha (),)
324- gc1 = self .new_gc ()
325- gc1 .set_linewidth (0 )
326- gc1 .set_snap (gc .get_snap ())
327- for box in page .boxes :
328- bx = box .x
329- by = box .y
330- bw = box .width
331- bh = box .height
332- if gc1 .get_snap () in [None , True ]:
333- # Prevent thin bars from disappearing by growing symmetrically.
334- if bw < 1 :
335- bx -= (1 - bw ) / 2
336- bw = 1
337- if bh < 1 :
338- by -= (1 - bh ) / 2
339- bh = 1
340- path = Path ._create_closed ([
341- (bx , by ), (bx + bw , by ), (bx + bw , by + bh ), (bx , by + bh )])
342- self ._renderer .draw_path (
343- gc1 , path ,
344- mpl .transforms .Affine2D ()
345- .rotate_deg (angle ).translate (x , self .height - y ),
346- rgba )
347- gc1 .restore ()
294+ self ._draw_text_glyphs_and_boxes (
295+ gc , x , y , angle ,
296+ ((get_font (text .font_path ), text .font_size , text .index ,
297+ text .font_effects .get ('slant' , 0 ), text .font_effects .get ('extend' , 1 ),
298+ text .x , text .y )
299+ for text in page .text ),
300+ ((box .x , box .y , box .width , box .height ) for box in page .boxes ))
348301
349302 def get_canvas_width_height (self ):
350303 # docstring inherited
0 commit comments