@@ -88,6 +88,7 @@ class Label(displayio.Group):
88
88
"""
89
89
90
90
# pylint: disable=unused-argument, too-many-instance-attributes, too-many-locals, too-many-arguments
91
+ # pylint: disable=too-many-branches, no-self-use
91
92
# Note: max_glyphs parameter is unnecessary, this is used for direct
92
93
# compatibility with label.py
93
94
@@ -144,14 +145,20 @@ def __init__(
144
145
145
146
# Calculate tight box to provide bounding box dimensions to match label for
146
147
# 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 (
148
154
text , font , self ._line_spacing , background_tight = True ,
149
155
)
150
156
151
157
if background_tight :
152
158
box_x = tight_box_x
153
159
box_y = tight_box_y
154
160
y_offset = tight_y_offset
161
+ x_offset = tight_x_offset
155
162
156
163
else :
157
164
(box_x , box_y , x_offset , y_offset ) = self ._text_bounding_box (
@@ -176,16 +183,12 @@ def __init__(
176
183
text ,
177
184
font ,
178
185
self ._line_spacing ,
179
- padding_left + x_offset ,
186
+ padding_left - x_offset ,
180
187
padding_top + y_offset ,
181
188
)
182
189
183
190
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
189
192
)
190
193
191
194
self .tilegrid = displayio .TileGrid (
@@ -196,7 +199,7 @@ def __init__(
196
199
tile_width = box_x ,
197
200
tile_height = box_y ,
198
201
default_tile = 0 ,
199
- x = - padding_left ,
202
+ x = - padding_left + x_offset ,
200
203
y = label_position_yoffset - y_offset - padding_top ,
201
204
)
202
205
@@ -229,14 +232,19 @@ def _line_spacing_ypixels(font, line_spacing):
229
232
return_value = int (line_spacing * font .get_bounding_box ()[1 ])
230
233
return return_value
231
234
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 ):
235
236
236
237
# This empirical approach checks several glyphs for maximum ascender and descender height
237
238
# (consistent with label.py)
238
239
glyphs = "M j'" # choose glyphs with highest ascender and lowest
239
240
# 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
+
240
248
ascender_max = descender_max = 0
241
249
for char in glyphs :
242
250
this_glyph = font .get_glyph (ord (char ))
@@ -246,19 +254,15 @@ def _text_bounding_box(
246
254
247
255
lines = 1
248
256
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)
251
260
252
- left = right = x_start
261
+ left = None
262
+ right = x_start
253
263
top = bottom = y_start
254
264
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 )
262
266
# this needs to be reviewed (also in label.py), since it doesn't respond
263
267
# properly to the number of newlines.
264
268
@@ -283,37 +287,35 @@ def _text_bounding_box(
283
287
font , line_spacing
284
288
) # Add a newline
285
289
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
286
296
xposition += my_glyph .shift_x
287
- right = max (right , xposition )
297
+
298
+ right = max (right , xposition , xright )
288
299
289
300
if yposition == y_start : # first line, find the Ascender height
290
301
top = min (top , - my_glyph .height - my_glyph .dy + y_offset_tight )
291
302
bottom = max (bottom , yposition - my_glyph .dy + y_offset_tight )
292
303
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
306
306
307
307
final_box_width = right - left
308
308
if background_tight :
309
309
final_box_height = bottom - top
310
- final_y_offset = y_offset_tight
310
+ final_y_offset = - top + y_offset_tight
311
311
312
312
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 )
314
316
final_y_offset = ascender_max
315
317
316
- return (final_box_width , final_box_height , 0 , final_y_offset )
318
+ return (final_box_width , final_box_height , left , final_y_offset )
317
319
318
320
# pylint: disable=too-many-nested-blocks
319
321
def _place_text (
@@ -344,7 +346,8 @@ def _place_text(
344
346
x_start = xposition # starting x position (left margin)
345
347
y_start = yposition
346
348
347
- left = right = x_start
349
+ left = None
350
+ right = x_start
348
351
top = bottom = y_start
349
352
350
353
for char in text :
@@ -362,8 +365,17 @@ def _place_text(
362
365
if my_glyph is None : # Error checking: no glyph found
363
366
print ("Glyph not found: {}" .format (repr (char )))
364
367
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
+ )
367
379
if yposition == y_start : # first line, find the Ascender height
368
380
top = min (top , - my_glyph .height - my_glyph .dy )
369
381
bottom = max (bottom , yposition - my_glyph .dy )
@@ -420,7 +432,6 @@ def line_spacing(self):
420
432
bounding-box height. (E.g. 1.0 is the bounding-box height)"""
421
433
return self ._line_spacing
422
434
423
- # pylint: disable=no-self-use
424
435
@line_spacing .setter
425
436
def line_spacing (self , new_line_spacing ):
426
437
raise RuntimeError (
@@ -462,7 +473,6 @@ def text(self):
462
473
"""Text to displayed."""
463
474
return self ._text
464
475
465
- # pylint: disable=no-self-use
466
476
@text .setter
467
477
def text (self , new_text ):
468
478
raise RuntimeError (
@@ -474,7 +484,6 @@ def font(self):
474
484
"""Font to use for text display."""
475
485
return self .font
476
486
477
- # pylint: disable=no-self-use
478
487
@font .setter
479
488
def font (self , new_font ):
480
489
raise RuntimeError (
@@ -507,14 +516,13 @@ def anchored_position(self, new_position):
507
516
508
517
# Set anchored_position
509
518
if (self ._anchor_point is not None ) and (self ._anchored_position is not None ):
510
- new_x = int (
519
+ self . x = int (
511
520
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 ))
513
523
)
514
- new_y = int (
524
+ self . y = int (
515
525
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 )
518
528
)
519
- self .x = new_x
520
- self .y = new_y
0 commit comments