@@ -77,6 +77,8 @@ def __init__(
7777 padding_bottom = 0 ,
7878 padding_left = 0 ,
7979 padding_right = 0 ,
80+ anchor_point = None ,
81+ anchored_position = None ,
8082 ** kwargs
8183 ):
8284 if "scale" in kwargs .keys ():
@@ -93,7 +95,10 @@ def __init__(
9395 self .width = max_glyphs
9496 self ._font = font
9597 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
97102 self .x = x
98103 self .y = y
99104
@@ -112,11 +117,7 @@ def __init__(
112117
113118 self ._background_color = background_color
114119 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
120121
121122 self ._padding_top = padding_top
122123 self ._padding_bottom = padding_bottom
@@ -125,6 +126,8 @@ def __init__(
125126
126127 if text is not None :
127128 self ._update_text (str (text ))
129+ if anchored_position is not None :
130+ self .anchored_position = anchored_position
128131
129132 def _create_background_box (self , lines , y_offset ):
130133
@@ -160,7 +163,6 @@ def _create_background_box(self, lines, y_offset):
160163 )
161164 y_box_offset = - ascender_max + y_offset - self ._padding_top
162165
163- self ._update_background_color (self ._background_color )
164166 box_width = max (0 , box_width ) # remove any negative values
165167 box_height = max (0 , box_height ) # remove any negative values
166168
@@ -178,16 +180,66 @@ def _update_background_color(self, new_color):
178180
179181 if new_color is None :
180182 self ._background_palette .make_transparent (0 )
183+ if self ._added_background_tilegrid :
184+ self .pop (0 )
185+ self ._added_background_tilegrid = False
181186 else :
182187 self ._background_palette .make_opaque (0 )
183188 self ._background_palette [0 ] = new_color
184189 self ._background_color = new_color
185190
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
187236 x = 0
188237 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
191243 y_offset = int (
192244 (
193245 self ._font .get_glyph (ord ("M" )).height
@@ -212,11 +264,7 @@ def _update_text(self, new_text): # pylint: disable=too-many-locals
212264 bottom = max (bottom , y - glyph .dy + y_offset )
213265 position_y = y - glyph .height - glyph .dy + y_offset
214266 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 :
220268 try :
221269 # pylint: disable=unexpected-keyword-arg
222270 face = displayio .TileGrid (
@@ -237,38 +285,21 @@ def _update_text(self, new_text): # pylint: disable=too-many-locals
237285 x = position_x ,
238286 y = position_y ,
239287 )
240- if i < len (self ):
241- self [i ] = face
288+ if tilegrid_count < len (self ):
289+ self [tilegrid_count ] = face
242290 else :
243291 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
252293 x += glyph .shift_x
253- # TODO skip this for control sequences or non-printables.
254294 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
266295 # Remove the rest
267- while len (self ) > i :
296+
297+ while len (self ) > tilegrid_count : # i:
268298 self .pop ()
269299 self ._text = new_text
270300 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 )
272303
273304 @property
274305 def bounding_box (self ):
@@ -351,15 +382,11 @@ def anchored_position(self):
351382 """Position relative to the anchor_point. Tuple containing x,y
352383 pixel coordinates."""
353384 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 )),
359386 int (
360387 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 )
363390 ),
364391 )
365392
@@ -369,11 +396,10 @@ def anchored_position(self, new_position):
369396 new_position [0 ]
370397 - self ._anchor_point [0 ] * (self ._boundingbox [2 ] * self ._scale )
371398 )
372- new_y = self . y = int (
399+ new_y = int (
373400 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 )
376403 )
377- self ._boundingbox = (new_x , new_y , self ._boundingbox [2 ], self ._boundingbox [3 ])
378404 self .x = new_x
379405 self .y = new_y
0 commit comments