@@ -77,6 +77,8 @@ def __init__(
77
77
padding_bottom = 0 ,
78
78
padding_left = 0 ,
79
79
padding_right = 0 ,
80
+ anchor_point = None ,
81
+ anchored_position = None ,
80
82
** kwargs
81
83
):
82
84
if "scale" in kwargs .keys ():
@@ -93,7 +95,10 @@ def __init__(
93
95
self .width = max_glyphs
94
96
self ._font = font
95
97
self ._text = None
96
- self ._anchor_point = (0 , 0 )
98
+ if anchor_point is None :
99
+ self ._anchor_point = (0 , 0 )
100
+ else :
101
+ self ._anchor_point = anchor_point
97
102
self .x = x
98
103
self .y = y
99
104
@@ -112,11 +117,7 @@ def __init__(
112
117
113
118
self ._background_color = background_color
114
119
self ._background_palette = displayio .Palette (1 )
115
- self .append (
116
- displayio .TileGrid (
117
- displayio .Bitmap (0 , 0 , 1 ), pixel_shader = self ._background_palette
118
- )
119
- ) # initialize with a blank tilegrid placeholder for background
120
+ self ._added_background_tilegrid = False
120
121
121
122
self ._padding_top = padding_top
122
123
self ._padding_bottom = padding_bottom
@@ -125,6 +126,8 @@ def __init__(
125
126
126
127
if text is not None :
127
128
self ._update_text (str (text ))
129
+ if anchored_position is not None :
130
+ self .anchored_position = anchored_position
128
131
129
132
def _create_background_box (self , lines , y_offset ):
130
133
@@ -160,7 +163,6 @@ def _create_background_box(self, lines, y_offset):
160
163
)
161
164
y_box_offset = - ascender_max + y_offset - self ._padding_top
162
165
163
- self ._update_background_color (self ._background_color )
164
166
box_width = max (0 , box_width ) # remove any negative values
165
167
box_height = max (0 , box_height ) # remove any negative values
166
168
@@ -178,16 +180,66 @@ def _update_background_color(self, new_color):
178
180
179
181
if new_color is None :
180
182
self ._background_palette .make_transparent (0 )
183
+ if self ._added_background_tilegrid :
184
+ self .pop (0 )
185
+ self ._added_background_tilegrid = False
181
186
else :
182
187
self ._background_palette .make_opaque (0 )
183
188
self ._background_palette [0 ] = new_color
184
189
self ._background_color = new_color
185
190
186
- def _update_text (self , new_text ): # pylint: disable=too-many-locals
191
+ y_offset = int (
192
+ (
193
+ self ._font .get_glyph (ord ("M" )).height
194
+ - self .text .count ("\n " ) * self .height * self .line_spacing
195
+ )
196
+ / 2
197
+ )
198
+ lines = self .text .count ("\n " ) + 1
199
+
200
+ if not self ._added_background_tilegrid : # no bitmap is in the self Group
201
+ # add bitmap if text is present and bitmap sizes > 0 pixels
202
+ if (
203
+ (len (self ._text ) > 0 )
204
+ and (
205
+ self ._boundingbox [2 ] + self ._padding_left + self ._padding_right > 0
206
+ )
207
+ and (
208
+ self ._boundingbox [3 ] + self ._padding_top + self ._padding_bottom > 0
209
+ )
210
+ ):
211
+ if len (self ) > 0 :
212
+ self .insert (0 , self ._create_background_box (lines , y_offset ))
213
+ else :
214
+ self .append (self ._create_background_box (lines , y_offset ))
215
+ self ._added_background_tilegrid = True
216
+
217
+ else : # a bitmap is present in the self Group
218
+ # update bitmap if text is present and bitmap sizes > 0 pixels
219
+ if (
220
+ (len (self ._text ) > 0 )
221
+ and (
222
+ self ._boundingbox [2 ] + self ._padding_left + self ._padding_right > 0
223
+ )
224
+ and (
225
+ self ._boundingbox [3 ] + self ._padding_top + self ._padding_bottom > 0
226
+ )
227
+ ):
228
+ self [0 ] = self ._create_background_box (lines , y_offset )
229
+ else : # delete the existing bitmap
230
+ self .pop (0 )
231
+ self ._added_background_tilegrid = False
232
+
233
+ def _update_text (
234
+ self , new_text
235
+ ): # pylint: disable=too-many-locals ,too-many-branches, too-many-statements
187
236
x = 0
188
237
y = 0
189
- i = 1
190
- old_c = 0
238
+ if self ._added_background_tilegrid :
239
+ i = 1
240
+ else :
241
+ i = 0
242
+ tilegrid_count = i
191
243
y_offset = int (
192
244
(
193
245
self ._font .get_glyph (ord ("M" )).height
@@ -212,11 +264,7 @@ def _update_text(self, new_text): # pylint: disable=too-many-locals
212
264
bottom = max (bottom , y - glyph .dy + y_offset )
213
265
position_y = y - glyph .height - glyph .dy + y_offset
214
266
position_x = x + glyph .dx
215
- if (
216
- not self ._text
217
- or old_c >= len (self ._text )
218
- or character != self ._text [old_c ]
219
- ):
267
+ if glyph .width > 0 and glyph .height > 0 :
220
268
try :
221
269
# pylint: disable=unexpected-keyword-arg
222
270
face = displayio .TileGrid (
@@ -237,38 +285,21 @@ def _update_text(self, new_text): # pylint: disable=too-many-locals
237
285
x = position_x ,
238
286
y = position_y ,
239
287
)
240
- if i < len (self ):
241
- self [i ] = face
288
+ if tilegrid_count < len (self ):
289
+ self [tilegrid_count ] = face
242
290
else :
243
291
self .append (face )
244
- elif self ._text and character == self ._text [old_c ]:
245
-
246
- try :
247
- self [i ].position = (position_x , position_y )
248
- except AttributeError :
249
- self [i ].x = position_x
250
- self [i ].y = position_y
251
-
292
+ tilegrid_count += 1
252
293
x += glyph .shift_x
253
- # TODO skip this for control sequences or non-printables.
254
294
i += 1
255
- old_c += 1
256
- # skip all non-printables in the old string
257
- while (
258
- self ._text
259
- and old_c < len (self ._text )
260
- and (
261
- self ._text [old_c ] == "\n "
262
- or not self ._font .get_glyph (ord (self ._text [old_c ]))
263
- )
264
- ):
265
- old_c += 1
266
295
# Remove the rest
267
- while len (self ) > i :
296
+
297
+ while len (self ) > tilegrid_count : # i:
268
298
self .pop ()
269
299
self ._text = new_text
270
300
self ._boundingbox = (left , top , left + right , bottom - top )
271
- self [0 ] = self ._create_background_box (lines , y_offset )
301
+
302
+ self ._update_background_color (self ._background_color )
272
303
273
304
@property
274
305
def bounding_box (self ):
@@ -351,15 +382,11 @@ def anchored_position(self):
351
382
"""Position relative to the anchor_point. Tuple containing x,y
352
383
pixel coordinates."""
353
384
return (
354
- int (
355
- self .x
356
- + self ._boundingbox [0 ]
357
- + self ._anchor_point [0 ] * self ._boundingbox [2 ]
358
- ),
385
+ int (self .x + (self ._anchor_point [0 ] * self ._boundingbox [2 ] * self ._scale )),
359
386
int (
360
387
self .y
361
- + self ._boundingbox [1 ]
362
- + self ._anchor_point [ 1 ] * self ._boundingbox [ 3 ]
388
+ + ( self ._anchor_point [1 ] * self . _boundingbox [ 3 ] * self . _scale )
389
+ - round (( self ._boundingbox [ 3 ] * self ._scale ) / 2.0 )
363
390
),
364
391
)
365
392
@@ -369,11 +396,10 @@ def anchored_position(self, new_position):
369
396
new_position [0 ]
370
397
- self ._anchor_point [0 ] * (self ._boundingbox [2 ] * self ._scale )
371
398
)
372
- new_y = self . y = int (
399
+ new_y = int (
373
400
new_position [1 ]
374
- - self ._anchor_point [1 ] * ( self ._boundingbox [3 ] * self ._scale )
375
- + ( self ._boundingbox [3 ] * self ._scale ) / 2
401
+ - ( self ._anchor_point [1 ] * self ._boundingbox [3 ] * self ._scale )
402
+ + round (( self ._boundingbox [3 ] * self ._scale ) / 2.0 )
376
403
)
377
- self ._boundingbox = (new_x , new_y , self ._boundingbox [2 ], self ._boundingbox [3 ])
378
404
self .x = new_x
379
405
self .y = new_y
0 commit comments