3333
3434**Hardware:**
3535
36- .. todo:: Add links to any specific hardware product page(s), or category page(s). Use
37- unordered list & hyperlink rST
38- inline format: "* `Link Text <url>`_"
39-
4036**Software and Dependencies:**
4137
4238* Adafruit CircuitPython firmware for the supported boards:
4339 https://github.com/adafruit/circuitpython/releases
4440
45- .. todo:: Uncomment or remove the Bus Device and/or the Register library dependencies based
46- on the library's use of either.
47-
48- # * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
49- # * Adafruit's Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register
5041"""
5142
5243import displayio
5647
5748
5849class Label (displayio .Group ):
59- """A label displaying a string of text. The origin point set by ``x`` and ``y``
50+ """A label displaying a string of text that is stored in a bitmap.
51+ Note: This ``bitmap_label.py`` library utilizes a bitmap to display the text.
52+ This method is memory-conserving relative to ``label.py``.
53+ For the bitmap_label library, the font, text, and line_spacing must be set at
54+ instancing and are immutable. The ``max_glyphs`` parameter is ignored and is present
55+ only for direct compatability with label.py.
56+ For use cases where text changes are required after the initial instancing, please
57+ use the `label.py` library.
58+ For further reduction in memory usage, set save_text to False (text string will not
59+ be stored).
60+
61+ The origin point set by ``x`` and ``y``
6062 properties will be the left edge of the bounding box, and in the center of a M
6163 glyph (if its one line), or the (number of lines * linespacing + M)/2. That is,
6264 it will try to have it be center-left as close as possible.
@@ -81,17 +83,14 @@ class Label(displayio.Group):
8183 :param (int,int) anchored_position: Position relative to the anchor_point. Tuple
8284 containing x,y pixel coordinates.
8385 :param int scale: Integer value of the pixel scaling
86+ :param bool save_text: Set True to save the text string as a constant in the
87+ label structure. Set False to reduce memory use.
8488 """
8589
8690 # pylint: disable=unused-argument, too-many-instance-attributes, too-many-locals, too-many-arguments
8791 # Note: max_glyphs parameter is unnecessary, this is used for direct
8892 # compatibility with label.py
8993
90- # Class variable
91- # To save memory, set Label._memory_saver=True and avoid storing the text string in the class.
92- # If set to False, the class saves the text string for future reference.
93- _memory_saver = True
94-
9594 def __init__ (
9695 self ,
9796 font ,
@@ -108,13 +107,18 @@ def __init__(
108107 padding_bottom = 0 ,
109108 padding_left = 0 ,
110109 padding_right = 0 ,
111- anchor_point = ( 0 , 0 ) ,
110+ anchor_point = None ,
112111 anchored_position = None ,
112+ save_text = True , # can reduce memory use if save_text = False
113113 ** kwargs
114114 ):
115115
116116 if text == "" :
117- raise RuntimeError ("Please provide text string" )
117+ raise RuntimeError (
118+ "Please provide text string, or use label.py for mutable text"
119+ )
120+
121+ self ._font = font
118122
119123 # Scale will be passed to Group using kwargs.
120124 if "scale" in kwargs .keys ():
@@ -123,11 +127,12 @@ def __init__(
123127 self ._scale = 1
124128
125129 self ._line_spacing = line_spacing
130+ self ._save_text = save_text
126131
127- if self ._memory_saver : # do not save the text in the instance
128- self ._text = None
132+ if self ._save_text : # text string will be saved
133+ self ._text = text
129134 else :
130- self ._text = text # text to be displayed
135+ self ._text = None # save a None value since text string is not saved
131136
132137 # limit padding to >= 0
133138 padding_top = max (0 , padding_top )
@@ -158,12 +163,9 @@ def __init__(
158163
159164 # Create the two-color palette
160165 self .palette = displayio .Palette (2 )
161- if background_color is not None :
162- self .palette [0 ] = background_color
163- else :
164- self .palette [0 ] = 0
165- self .palette .make_transparent (0 )
166- self .palette [1 ] = color
166+
167+ self .background_color = background_color
168+ self .color = color
167169
168170 # Create the bitmap and TileGrid
169171 self .bitmap = displayio .Bitmap (box_x , box_y , len (self .palette ))
@@ -208,7 +210,7 @@ def __init__(
208210 # Update bounding_box values. Note: To be consistent with label.py,
209211 # this is the bounding box for the text only, not including the background.
210212
211- self .bounding_box = (
213+ self ._bounding_box = (
212214 self .tilegrid .x ,
213215 self .tilegrid .y ,
214216 tight_box_x ,
@@ -406,6 +408,76 @@ def _place_text(
406408
407409 return (left , top , right - left , bottom - top ) # bounding_box
408410
411+ @property
412+ def bounding_box (self ):
413+ """An (x, y, w, h) tuple that completely covers all glyphs. The
414+ first two numbers are offset from the x, y origin of this group"""
415+ return self ._bounding_box
416+
417+ @property
418+ def line_spacing (self ):
419+ """The amount of space between lines of text, in multiples of the font's
420+ bounding-box height. (E.g. 1.0 is the bounding-box height)"""
421+ return self ._line_spacing
422+
423+ @line_spacing .setter
424+ def line_spacing (self , new_line_spacing ):
425+ raise RuntimeError (
426+ "line_spacing is immutable for bitmap_label.py; use label.py for mutable line_spacing"
427+ )
428+
429+ @property
430+ def color (self ):
431+ """Color of the text as an RGB hex number."""
432+ return self ._color
433+
434+ @color .setter
435+ def color (self , new_color ):
436+ self ._color = new_color
437+ if new_color is not None :
438+ self .palette [1 ] = new_color
439+ self .palette .make_opaque (1 )
440+ else :
441+ self .palette [1 ] = 0
442+ self .palette .make_transparent (1 )
443+
444+ @property
445+ def background_color (self ):
446+ """Color of the background as an RGB hex number."""
447+ return self ._background_color
448+
449+ @background_color .setter
450+ def background_color (self , new_color ):
451+ self ._background_color = new_color
452+ if new_color is not None :
453+ self .palette [0 ] = new_color
454+ self .palette .make_opaque (0 )
455+ else :
456+ self .palette [0 ] = 0
457+ self .palette .make_transparent (0 )
458+
459+ @property
460+ def text (self ):
461+ """Text to displayed."""
462+ return self ._text
463+
464+ @text .setter
465+ def text (self , new_text ):
466+ raise RuntimeError (
467+ "text is immutable for bitmap_label.py; use label.py library for mutable text"
468+ )
469+
470+ @property
471+ def font (self ):
472+ """Font to use for text display."""
473+ return self .font
474+
475+ @font .setter
476+ def font (self , new_font ):
477+ raise RuntimeError (
478+ "font is immutable for bitmap_label.py; use label.py library for mutable font"
479+ )
480+
409481 @property
410482 def anchor_point (self ):
411483 """Point that anchored_position moves relative to.
@@ -434,12 +506,12 @@ def anchored_position(self, new_position):
434506 if (self ._anchor_point is not None ) and (self ._anchored_position is not None ):
435507 new_x = int (
436508 new_position [0 ]
437- - self ._anchor_point [0 ] * (self .bounding_box [2 ] * self ._scale )
509+ - self ._anchor_point [0 ] * (self ._bounding_box [2 ] * self ._scale )
438510 )
439511 new_y = int (
440512 new_position [1 ]
441- - (self ._anchor_point [1 ] * self .bounding_box [3 ] * self .scale )
442- + round ((self .bounding_box [3 ] * self .scale ) / 2.0 )
513+ - (self ._anchor_point [1 ] * self ._bounding_box [3 ] * self .scale )
514+ + round ((self ._bounding_box [3 ] * self .scale ) / 2.0 )
443515 )
444516 self .x = new_x
445517 self .y = new_y
0 commit comments