@@ -88,6 +88,7 @@ class Label(displayio.Group):
8888 """
8989
9090 # pylint: disable=unused-argument, too-many-instance-attributes, too-many-locals, too-many-arguments
91+ # pylint: disable=too-many-branches, no-self-use
9192 # Note: max_glyphs parameter is unnecessary, this is used for direct
9293 # compatibility with label.py
9394
@@ -144,14 +145,20 @@ def __init__(
144145
145146 # Calculate tight box to provide bounding box dimensions to match label for
146147 # anchor_position calculations
147- (tight_box_x , tight_box_y , x_offset , tight_y_offset ) = self ._text_bounding_box (
148+ (
149+ tight_box_x ,
150+ tight_box_y ,
151+ tight_x_offset ,
152+ tight_y_offset ,
153+ ) = self ._text_bounding_box (
148154 text , font , self ._line_spacing , background_tight = True ,
149155 )
150156
151157 if background_tight :
152158 box_x = tight_box_x
153159 box_y = tight_box_y
154160 y_offset = tight_y_offset
161+ x_offset = tight_x_offset
155162
156163 else :
157164 (box_x , box_y , x_offset , y_offset ) = self ._text_bounding_box (
@@ -176,16 +183,12 @@ def __init__(
176183 text ,
177184 font ,
178185 self ._line_spacing ,
179- padding_left + x_offset ,
186+ padding_left - x_offset ,
180187 padding_top + y_offset ,
181188 )
182189
183190 label_position_yoffset = int ( # To calibrate with label.py positioning
184- (
185- font .get_glyph (ord ("M" )).height
186- - text .count ("\n " ) * font .get_bounding_box ()[1 ] * self ._line_spacing
187- )
188- / 2
191+ (font .get_glyph (ord ("M" )).height ) / 2
189192 )
190193
191194 self .tilegrid = displayio .TileGrid (
@@ -196,7 +199,7 @@ def __init__(
196199 tile_width = box_x ,
197200 tile_height = box_y ,
198201 default_tile = 0 ,
199- x = - padding_left ,
202+ x = - padding_left + x_offset ,
200203 y = label_position_yoffset - y_offset - padding_top ,
201204 )
202205
@@ -229,14 +232,19 @@ def _line_spacing_ypixels(font, line_spacing):
229232 return_value = int (line_spacing * font .get_bounding_box ()[1 ])
230233 return return_value
231234
232- def _text_bounding_box (
233- self , text , font , line_spacing , background_tight = False
234- ): # **** change default background_tight=False
235+ def _text_bounding_box (self , text , font , line_spacing , background_tight = False ):
235236
236237 # This empirical approach checks several glyphs for maximum ascender and descender height
237238 # (consistent with label.py)
238239 glyphs = "M j'" # choose glyphs with highest ascender and lowest
239240 # descender, will depend upon font used
241+
242+ try :
243+ self ._font .load_glyphs (text + glyphs )
244+ except AttributeError :
245+ # ignore if font does not have load_glyphs
246+ pass
247+
240248 ascender_max = descender_max = 0
241249 for char in glyphs :
242250 this_glyph = font .get_glyph (ord (char ))
@@ -246,19 +254,15 @@ def _text_bounding_box(
246254
247255 lines = 1
248256
249- xposition = x_start = 0 # starting x position (left margin)
250- yposition = y_start = 0
257+ xposition = (
258+ x_start
259+ ) = yposition = y_start = 0 # starting x and y position (left margin)
251260
252- left = right = x_start
261+ left = None
262+ right = x_start
253263 top = bottom = y_start
254264
255- y_offset_tight = int (
256- (
257- font .get_glyph (ord ("M" )).height
258- - text .count ("\n " ) * self ._line_spacing_ypixels (font , line_spacing )
259- )
260- / 2
261- )
265+ y_offset_tight = int ((font .get_glyph (ord ("M" )).height ) / 2 )
262266 # this needs to be reviewed (also in label.py), since it doesn't respond
263267 # properly to the number of newlines.
264268
@@ -283,37 +287,35 @@ def _text_bounding_box(
283287 font , line_spacing
284288 ) # Add a newline
285289 lines += 1
290+ if xposition == x_start :
291+ if left is None :
292+ left = my_glyph .dx
293+ else :
294+ left = min (left , my_glyph .dx )
295+ xright = xposition + my_glyph .width + my_glyph .dx
286296 xposition += my_glyph .shift_x
287- right = max (right , xposition )
297+
298+ right = max (right , xposition , xright )
288299
289300 if yposition == y_start : # first line, find the Ascender height
290301 top = min (top , - my_glyph .height - my_glyph .dy + y_offset_tight )
291302 bottom = max (bottom , yposition - my_glyph .dy + y_offset_tight )
292303
293- loose_height = (lines - 1 ) * self ._line_spacing_ypixels (font , line_spacing ) + (
294- ascender_max + descender_max
295- )
296-
297- label_calibration_offset = int (
298- (
299- font .get_glyph (ord ("M" )).height
300- - text .count ("\n " ) * self ._line_spacing_ypixels (font , line_spacing )
301- )
302- / 2
303- )
304-
305- y_offset_tight = - top + label_calibration_offset
304+ if left is None :
305+ left = 0
306306
307307 final_box_width = right - left
308308 if background_tight :
309309 final_box_height = bottom - top
310- final_y_offset = y_offset_tight
310+ final_y_offset = - top + y_offset_tight
311311
312312 else :
313- final_box_height = loose_height
313+ final_box_height = (lines - 1 ) * self ._line_spacing_ypixels (
314+ font , line_spacing
315+ ) + (ascender_max + descender_max )
314316 final_y_offset = ascender_max
315317
316- return (final_box_width , final_box_height , 0 , final_y_offset )
318+ return (final_box_width , final_box_height , left , final_y_offset )
317319
318320 # pylint: disable=too-many-nested-blocks
319321 def _place_text (
@@ -344,7 +346,8 @@ def _place_text(
344346 x_start = xposition # starting x position (left margin)
345347 y_start = yposition
346348
347- left = right = x_start
349+ left = None
350+ right = x_start
348351 top = bottom = y_start
349352
350353 for char in text :
@@ -362,8 +365,17 @@ def _place_text(
362365 if my_glyph is None : # Error checking: no glyph found
363366 print ("Glyph not found: {}" .format (repr (char )))
364367 else :
365-
366- right = max (right , xposition + my_glyph .shift_x )
368+ if xposition == x_start :
369+ if left is None :
370+ left = my_glyph .dx
371+ else :
372+ left = min (left , my_glyph .dx )
373+
374+ right = max (
375+ right ,
376+ xposition + my_glyph .shift_x ,
377+ xposition + my_glyph .width + my_glyph .dx ,
378+ )
367379 if yposition == y_start : # first line, find the Ascender height
368380 top = min (top , - my_glyph .height - my_glyph .dy )
369381 bottom = max (bottom , yposition - my_glyph .dy )
@@ -420,7 +432,6 @@ def line_spacing(self):
420432 bounding-box height. (E.g. 1.0 is the bounding-box height)"""
421433 return self ._line_spacing
422434
423- # pylint: disable=no-self-use
424435 @line_spacing .setter
425436 def line_spacing (self , new_line_spacing ):
426437 raise RuntimeError (
@@ -462,7 +473,6 @@ def text(self):
462473 """Text to displayed."""
463474 return self ._text
464475
465- # pylint: disable=no-self-use
466476 @text .setter
467477 def text (self , new_text ):
468478 raise RuntimeError (
@@ -474,7 +484,6 @@ def font(self):
474484 """Font to use for text display."""
475485 return self .font
476486
477- # pylint: disable=no-self-use
478487 @font .setter
479488 def font (self , new_font ):
480489 raise RuntimeError (
@@ -507,14 +516,13 @@ def anchored_position(self, new_position):
507516
508517 # Set anchored_position
509518 if (self ._anchor_point is not None ) and (self ._anchored_position is not None ):
510- new_x = int (
519+ self . x = int (
511520 new_position [0 ]
512- - self ._anchor_point [0 ] * (self ._bounding_box [2 ] * self ._scale )
521+ - (self ._bounding_box [0 ] * self ._scale )
522+ - round (self ._anchor_point [0 ] * (self ._bounding_box [2 ] * self ._scale ))
513523 )
514- new_y = int (
524+ self . y = int (
515525 new_position [1 ]
516- - (self ._anchor_point [1 ] * self ._bounding_box [ 3 ] * self . scale )
517- + round (( self ._bounding_box [ 3 ] * self .scale ) / 2.0 )
526+ - (self ._bounding_box [1 ] * self ._scale )
527+ - round (self ._anchor_point [ 1 ] * self ._bounding_box [ 3 ] * self . _scale )
518528 )
519- self .x = new_x
520- self .y = new_y
0 commit comments