55"""
66Display Text module helper functions
77"""
8+ try :
9+ from typing import Tuple
10+ except ImportError :
11+ pass
812from displayio import Group , Palette
913
1014
11- def wrap_text_to_pixels (string , max_width , font = None , indent0 = "" , indent1 = "" ):
15+ def wrap_text_to_pixels (
16+ string : str , max_width : int , font = None , indent0 : str = "" , indent1 : str = ""
17+ ) -> None :
1218 """wrap_text_to_pixels function
1319 A helper that will return a list of lines with word-break wrapping.
1420 Leading and trailing whitespace in your string will be removed. If
@@ -26,7 +32,7 @@ def wrap_text_to_pixels(string, max_width, font=None, indent0="", indent1=""):
2632 input text at max_width pixels size
2733
2834 """
29- # pylint: disable=too-many-locals too-many-branches
35+ # pylint: disable=too-many-locals, too-many-branches
3036 if font is None :
3137
3238 def measure (string ):
@@ -173,37 +179,36 @@ class LabelBase(Group):
173179 :param int scale: Integer value of the pixel scaling
174180 :param bool save_text: Set True to save the text string as a constant in the
175181 label structure. Set False to reduce memory use.
176- :param: bool base_alignment: when True allows to align text label to the baseline.
182+ :param bool base_alignment: when True allows to align text label to the baseline.
177183 This is helpful when two or more labels need to be aligned to the same baseline
178- :param: (int,str) tab_replacement: tuple with tab character replace information. When
184+ :param (int,str) tab_replacement: tuple with tab character replace information. When
179185 (4, " ") will indicate a tab replacement of 4 spaces, defaults to 4 spaces by
180186 tab character"""
181187
182188 # pylint: disable=unused-argument, too-many-instance-attributes, too-many-locals, too-many-arguments
183189 def __init__ (
184190 self ,
185191 font ,
186- x = 0 ,
187- y = 0 ,
188- text = "" ,
189- max_glyphs = None ,
190- # with label.py
191- color = 0xFFFFFF ,
192- background_color = None ,
193- line_spacing = 1.25 ,
194- background_tight = False ,
195- padding_top = 0 ,
196- padding_bottom = 0 ,
197- padding_left = 0 ,
198- padding_right = 0 ,
199- anchor_point = None ,
200- anchored_position = None ,
201- save_text = True , # can reduce memory use if save_text = False
202- scale = 1 ,
203- base_alignment = False ,
204- tab_replacement = (4 , " " ),
192+ x : int = 0 ,
193+ y : int = 0 ,
194+ text : str = "" ,
195+ max_glyphs : int = None ,
196+ color : int = 0xFFFFFF ,
197+ background_color : int = None ,
198+ line_spacing : float = 1.25 ,
199+ background_tight : bool = False ,
200+ padding_top : int = 0 ,
201+ padding_bottom : int = 0 ,
202+ padding_left : int = 0 ,
203+ padding_right : int = 0 ,
204+ anchor_point : Tuple [float , float ] = None ,
205+ anchored_position : Tuple [int , int ] = None ,
206+ save_text : bool = True , # can reduce memory use if save_text = False
207+ scale : int = 1 ,
208+ base_alignment : bool = False ,
209+ tab_replacement : Tuple [int , str ] = (4 , " " ),
205210 ** kwargs ,
206- ):
211+ ) -> None :
207212 super ().__init__ (max_size = 1 , x = x , y = y , scale = 1 )
208213
209214 self ._font = font
@@ -221,8 +226,16 @@ def __init__(
221226 self .local_group = None
222227
223228 self ._text = text
229+ self .baseline = - 1.0
224230
225- def _get_ascent_descent (self ):
231+ self .base_alignment = base_alignment
232+
233+ if self .base_alignment :
234+ self ._y_offset = 0
235+ else :
236+ self ._y_offset = self ._get_ascent () // 2
237+
238+ def _get_ascent_descent (self ) -> Tuple [int , int ]:
226239 """ Private function to calculate ascent and descent font values """
227240 if hasattr (self .font , "ascent" ):
228241 return self .font .ascent , self .font .descent
@@ -243,29 +256,29 @@ def _get_ascent_descent(self):
243256 descender_max = max (descender_max , - this_glyph .dy )
244257 return ascender_max , descender_max
245258
246- def _get_ascent (self ):
259+ def _get_ascent (self ) -> int :
247260 return self ._get_ascent_descent ()[0 ]
248261
249262 @property
250- def font (self ):
263+ def font (self ) -> None :
251264 """Font to use for text display."""
252265 return self ._font
253266
254- def _set_font (self , new_font ):
267+ def _set_font (self , new_font ) -> None :
255268 # subclasses should override this
256269 pass
257270
258271 @font .setter
259- def font (self , new_font ):
272+ def font (self , new_font ) -> None :
260273 self ._set_font (new_font )
261274
262275 @property
263- def color (self ):
276+ def color (self ) -> int :
264277 """Color of the text as an RGB hex number."""
265278 return self ._color
266279
267280 @color .setter
268- def color (self , new_color ):
281+ def color (self , new_color : int ):
269282 self ._color = new_color
270283 if new_color is not None :
271284 self .palette [1 ] = new_color
@@ -275,7 +288,7 @@ def color(self, new_color):
275288 self .palette .make_transparent (1 )
276289
277290 @property
278- def background_color (self ):
291+ def background_color (self ) -> int :
279292 """Color of the background as an RGB hex number."""
280293 return self ._background_color
281294
@@ -284,31 +297,34 @@ def _set_background_color(self, new_color):
284297 pass
285298
286299 @background_color .setter
287- def background_color (self , new_color ) :
300+ def background_color (self , new_color : int ) -> None :
288301 self ._set_background_color (new_color )
289302
290303 @property
291- def anchor_point (self ):
304+ def anchor_point (self ) -> Tuple [ float , float ] :
292305 """Point that anchored_position moves relative to.
293306 Tuple with decimal percentage of width and height.
294307 (E.g. (0,0) is top left, (1.0, 0.5): is middle right.)"""
295308 return self ._anchor_point
296309
297310 @anchor_point .setter
298- def anchor_point (self , new_anchor_point ):
299- self ._anchor_point = new_anchor_point
311+ def anchor_point (self , new_anchor_point : Tuple [float , float ]) -> None :
312+ if new_anchor_point [1 ] == self .baseline :
313+ self ._anchor_point = (new_anchor_point [0 ], - 1.0 )
314+ else :
315+ self ._anchor_point = new_anchor_point
300316 self .anchored_position = (
301317 self ._anchored_position
302318 ) # update the anchored_position using setter
303319
304320 @property
305- def anchored_position (self ):
321+ def anchored_position (self ) -> Tuple [ int , int ] :
306322 """Position relative to the anchor_point. Tuple containing x,y
307323 pixel coordinates."""
308324 return self ._anchored_position
309325
310326 @anchored_position .setter
311- def anchored_position (self , new_position ) :
327+ def anchored_position (self , new_position : Tuple [ int , int ]) -> None :
312328 self ._anchored_position = new_position
313329 # Set anchored_position
314330 if (self ._anchor_point is not None ) and (self ._anchored_position is not None ):
@@ -317,51 +333,54 @@ def anchored_position(self, new_position):
317333 - (self ._bounding_box [0 ] * self .scale )
318334 - round (self ._anchor_point [0 ] * (self ._bounding_box [2 ] * self .scale ))
319335 )
320- self .y = int (
321- new_position [1 ]
322- - (self ._bounding_box [1 ] * self .scale )
323- - round (self ._anchor_point [1 ] * self ._bounding_box [3 ] * self .scale )
324- )
336+ if self ._anchor_point [1 ] == self .baseline :
337+ self .y = int (new_position [1 ] - (self ._y_offset * self .scale ))
338+ else :
339+ self .y = int (
340+ new_position [1 ]
341+ - (self ._bounding_box [1 ] * self .scale )
342+ - round (self ._anchor_point [1 ] * self ._bounding_box [3 ] * self .scale )
343+ )
325344
326345 @property
327- def scale (self ):
346+ def scale (self ) -> int :
328347 """Set the scaling of the label, in integer values"""
329348 return self .local_group .scale
330349
331350 @scale .setter
332- def scale (self , new_scale ) :
351+ def scale (self , new_scale : int ) -> None :
333352 self .local_group .scale = new_scale
334353 self .anchored_position = self ._anchored_position # update the anchored_position
335354
336- def _set_text (self , new_text , scale ) :
355+ def _set_text (self , new_text : str , scale : int ) -> None :
337356 # subclasses should override this
338357 pass
339358
340359 @property
341- def text (self ):
360+ def text (self ) -> str :
342361 """Text to be displayed."""
343362 return self ._text
344363
345364 @text .setter # Cannot set color or background color with text setter, use separate setter
346- def text (self , new_text ) :
365+ def text (self , new_text : str ) -> None :
347366 self ._set_text (new_text , self .scale )
348367
349368 @property
350- def bounding_box (self ):
369+ def bounding_box (self ) -> Tuple [ int , int ] :
351370 """An (x, y, w, h) tuple that completely covers all glyphs. The
352371 first two numbers are offset from the x, y origin of this group"""
353372 return tuple (self ._bounding_box )
354373
355374 @property
356- def line_spacing (self ):
375+ def line_spacing (self ) -> float :
357376 """The amount of space between lines of text, in multiples of the font's
358377 bounding-box height. (E.g. 1.0 is the bounding-box height)"""
359378 return self ._line_spacing
360379
361- def _set_line_spacing (self , new_line_spacing ) :
380+ def _set_line_spacing (self , new_line_spacing : float ) -> None :
362381 # subclass should override this.
363382 pass
364383
365384 @line_spacing .setter
366- def line_spacing (self , new_line_spacing ) :
385+ def line_spacing (self , new_line_spacing : float ) -> None :
367386 self ._set_line_spacing (new_line_spacing )
0 commit comments