@@ -44,44 +44,6 @@ def _rotate_point(angle, x, y):
4444 return (cos * x - sin * y , sin * x + cos * y )
4545
4646
47- def _get_textbox (text , renderer ):
48- """
49- Calculate the bounding box of the text.
50-
51- The bbox position takes text rotation into account, but the width and
52- height are those of the unrotated box (unlike `.Text.get_window_extent`).
53- """
54- # TODO : This function may move into the Text class as a method. As a
55- # matter of fact, the information from the _get_textbox function
56- # should be available during the Text._get_layout() call, which is
57- # called within the _get_textbox. So, it would be better to move this
58- # function as a method with some refactoring of _get_layout method.
59-
60- projected_xys = []
61-
62- theta = math .radians (text .get_rotation ())
63- tr = _rotate (- theta )
64-
65- _ , parts = text ._get_layout (renderer )
66-
67- for t , (w , a , d ), xy in parts :
68- xt , yt = tr .transform (xy )
69- projected_xys .extend ([
70- (xt , yt + a ),
71- (xt , yt - d ),
72- (xt + w , yt + a ),
73- (xt + w , yt - d ),
74- ])
75- projected_xs , projected_ys = zip (* projected_xys )
76-
77- xt_box , yt_box = min (projected_xs ), min (projected_ys )
78- w_box , h_box = max (projected_xs ) - xt_box , max (projected_ys ) - yt_box
79-
80- x_box , y_box = _rotate (theta ).transform ((xt_box , yt_box ))
81-
82- return x_box , y_box , w_box , h_box
83-
84-
8547def _get_text_metrics_with_cache (renderer , text , fontprop , ismath , dpi ):
8648 """Call ``renderer.get_text_width_height_descent``, caching the results."""
8749
@@ -455,8 +417,11 @@ def _get_layout(self, renderer):
455417 """
456418 Return
457419
458- - the (rotated) text bbox, and
459- - a list of ``(line, (width, ascent, descent), xy)`` tuples for each line.
420+ - the rotated, axis-aligned text bbox;
421+ - a list of ``(line, (width, ascent, descent), xy)`` tuples for each line;
422+ - a ``(xy, (width, height))` pair of the lower-left corner and size of the
423+ rotated, *text-aligned* text box (i.e. describing how to draw the
424+ text-surrounding box).
460425 """
461426 thisx , thisy = 0.0 , 0.0
462427 lines = self ._get_wrapped_text ().split ("\n " ) # Ensures lines is not empty.
@@ -529,7 +494,7 @@ def _get_layout(self, renderer):
529494
530495 # the corners of the unrotated bounding box
531496 corners_horiz = [(xmin , ymin ), (xmin , ymax ), (xmax , ymax ), (xmax , ymin )]
532-
497+ size_horiz = ( xmax - xmin , ymax - ymin )
533498 # now rotate the bbox
534499 angle = self .get_rotation ()
535500 rotate = functools .partial (_rotate_point , angle )
@@ -539,8 +504,8 @@ def _get_layout(self, renderer):
539504 xs , ys = zip (* corners_rotated )
540505 xmin , xmax = min (xs ), max (xs )
541506 ymin , ymax = min (ys ), max (ys )
542- width = xmax - xmin
543- height = ymax - ymin
507+ width_rot = xmax - xmin
508+ height_rot = ymax - ymin
544509
545510 # Now move the box to the target position offset the display
546511 # bbox by alignment
@@ -555,57 +520,47 @@ def _get_layout(self, renderer):
555520 valign = self ._va_for_angle (angle )
556521 # compute the text location in display coords and the offsets
557522 # necessary to align the bbox with that location
558- if halign == 'center' :
559- offsetx = (xmin + xmax ) / 2
560- elif halign == 'right' :
561- offsetx = xmax
562- else :
563- offsetx = xmin
564-
565- if valign == 'center' :
566- offsety = (ymin + ymax ) / 2
567- elif valign == 'top' :
568- offsety = ymax
569- elif valign == 'baseline' :
570- offsety = ymin + descent
571- elif valign == 'center_baseline' :
572- offsety = ymin + height - baseline / 2.0
573- else :
574- offsety = ymin
523+ offsetx = (
524+ xmin if halign == "left" else
525+ xmax if halign == "right" else
526+ (xmin + xmax ) / 2 # halign == "center"
527+ )
528+ offsety = (
529+ ymin if valign == "bottom" else
530+ ymax if valign == "top" else
531+ (ymin + ymax ) / 2 if valign == "center" else
532+ ymin + descent if valign == "baseline" else
533+ ymin + height_rot - baseline / 2 # valign == "center_baseline"
534+ )
575535 else :
576536 xmin1 , ymin1 = corners_horiz [0 ]
577537 xmax1 , ymax1 = corners_horiz [2 ]
578-
579- if halign == 'center' :
580- offsetx = (xmin1 + xmax1 ) / 2.0
581- elif halign == 'right' :
582- offsetx = xmax1
583- else :
584- offsetx = xmin1
585-
586- if valign == 'center' :
587- offsety = (ymin1 + ymax1 ) / 2.0
588- elif valign == 'top' :
589- offsety = ymax1
590- elif valign == 'baseline' :
591- offsety = ymax1 - baseline
592- elif valign == 'center_baseline' :
593- offsety = ymax1 - baseline / 2.0
594- else :
595- offsety = ymin1
596-
538+ offsetx = (
539+ xmin1 if halign == "left" else
540+ xmax1 if halign == "right" else
541+ (xmin1 + xmax1 ) / 2 # halign == "center"
542+ )
543+ offsety = (
544+ ymin1 if valign == "bottom" else
545+ ymax1 if valign == "top" else
546+ (ymin1 + ymax1 ) / 2 if valign == "center" else
547+ ymax1 - baseline if valign == "baseline" else
548+ ymax1 - baseline / 2 # valign == "center_baseline"
549+ )
597550 offsetx , offsety = rotate (offsetx , offsety )
598551
599552 xmin -= offsetx
600553 ymin -= offsety
601554
602- bbox = Bbox .from_bounds (xmin , ymin , width , height )
555+ bbox_rot = Bbox .from_bounds (xmin , ymin , width_rot , height_rot )
603556
604557 # now rotate the positions around the first (x, y) position
605558 xys = [(x - offsetx , y - offsety )
606559 for x , y in itertools .starmap (rotate , offset_layout )]
560+ x , y = corners_rotated [0 ]
561+ xy_corner = (x - offsetx , y - offsety )
607562
608- return bbox , list (zip (lines , wads , xys ))
563+ return bbox_rot , list (zip (lines , wads , xys )), ( xy_corner , size_horiz )
609564
610565 def set_bbox (self , rectprops ):
611566 """
@@ -677,7 +632,7 @@ def update_bbox_position_size(self, renderer):
677632 posy = float (self .convert_yunits (self ._y ))
678633 posx , posy = self .get_transform ().transform ((posx , posy ))
679634
680- x_box , y_box , w_box , h_box = _get_textbox ( self , renderer )
635+ _ , _ , (( x_box , y_box ), ( w_box , h_box )) = self . _get_layout ( renderer )
681636 self ._bbox_patch .set_bounds (0. , 0. , w_box , h_box )
682637 self ._bbox_patch .set_transform (
683638 Affine2D ()
@@ -857,7 +812,7 @@ def draw(self, renderer):
857812
858813 renderer .open_group ('text' , self .get_gid ())
859814
860- bbox , info = self ._get_layout (renderer )
815+ bbox , info , _ = self ._get_layout (renderer )
861816 trans = self .get_transform ()
862817
863818 # don't use self.get_position here, which refers to text
@@ -1080,7 +1035,7 @@ def get_window_extent(self, renderer=None, dpi=None):
10801035 "want to call 'figure.draw_without_rendering()' first." )
10811036
10821037 with cbook ._setattr_cm (fig , dpi = dpi ):
1083- bbox , _ = self ._get_layout (self ._renderer )
1038+ bbox , _ , _ = self ._get_layout (self ._renderer )
10841039 x , y = self .get_unitless_position ()
10851040 x , y = self .get_transform ().transform ((x , y ))
10861041 bbox = bbox .translated (x , y )
0 commit comments