2020# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2121# THE SOFTWARE.
2222"""
23- `adafruit_display_text.text_area `
23+ `adafruit_display_text.label `
2424====================================================
2525
26- Displays text using CircuitPython's displayio.
26+ Displays text labels using CircuitPython's displayio.
2727
2828* Author(s): Scott Shawcroft
2929
4444__version__ = "0.0.0-auto.0"
4545__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Display_Text.git"
4646
47- class TextArea (displayio .Group ):
48- """An area displaying a string of textself.
47+ class Label (displayio .Group ):
48+ """A label displaying a string of text. The origin point set by ``x`` and ``y``
49+ properties will be the left edge of the bounding box, and in the center of a M
50+ glyph (if its one line), or the (number of lines * linespacing + M)/2. That is,
51+ it will try to have it be center-left as close as possible.
4952
5053 :param Font font: A font class that has ``get_bounding_box`` and ``get_glyph``
5154 :param str text: Text to display
52- :param int width: Area width in characters
53- :param int height: Area height in characters
55+ :param int max_glyphs: The largest quantity of glyphs we will display
5456 :param int color: Color of all text in RGB hex"""
55- def __init__ (self , font , * , text = None , width = None , height = 1 , color = 0xffffff ):
56- if not width and not text :
57- raise RuntimeError ("Please provide a width " )
58- if not width :
59- width = len (text )
60- super ().__init__ (max_size = width * height )
61- self .width = width
57+ def __init__ (self , font , * , text = None , max_glyphs = None , color = 0xffffff , ** kwargs ):
58+ if not max_glyphs and not text :
59+ raise RuntimeError ("Please provide a max size, or initial text " )
60+ if not max_glyphs :
61+ max_glyphs = len (text )
62+ super ().__init__ (max_size = max_glyphs , ** kwargs )
63+ self .width = max_glyphs
6264 self .font = font
6365 self ._text = None
6466
@@ -68,36 +70,47 @@ def __init__(self, font, *, text=None, width=None, height=1, color=0xffffff):
6870
6971 bounds = self .font .get_bounding_box ()
7072 self .height = bounds [1 ]
73+ self ._line_spacing = 1.25
74+ self ._boundingbox = None
7175
7276 if text :
7377 self ._update_text (text )
7478
7579
76- def _update_text (self , new_text ):
80+ def _update_text (self , new_text ): # pylint: disable=too-many-locals
7781 x = 0
7882 y = 0
7983 i = 0
8084 old_c = 0
85+ y_offset = int ((self .font .get_glyph (ord ('M' )).height -
86+ new_text .count ('\n ' ) * self .height * self .line_spacing ) / 2 )
87+ #print("y offset from baseline", y_offset)
88+ left = right = top = bottom = 0
8189 for character in new_text :
8290 if character == '\n ' :
83- y += int (self .height * 1.25 )
91+ y += int (self .height * self . _line_spacing )
8492 x = 0
8593 continue
8694 glyph = self .font .get_glyph (ord (character ))
8795 if not glyph :
8896 continue
89- position_y = y + self .height - glyph .height - glyph .dy
97+ right = max (right , x + glyph .width )
98+ if y == 0 : # first line, find the Ascender height
99+ top = min (top , - glyph .height + y_offset )
100+ bottom = max (bottom , y - glyph .dy + y_offset )
101+ position_y = y - glyph .height - glyph .dy + y_offset
102+ position_x = x + glyph .dx
90103 if not self ._text or old_c >= len (self ._text ) or character != self ._text [old_c ]:
91104 face = displayio .TileGrid (glyph .bitmap , pixel_shader = self .palette ,
92105 default_tile = glyph .tile_index ,
93106 tile_width = glyph .width , tile_height = glyph .height ,
94- position = (x , position_y ))
107+ position = (position_x , position_y ))
95108 if i < len (self ):
96109 self [i ] = face
97110 else :
98111 self .append (face )
99112 elif self ._text and character == self ._text [old_c ]:
100- self [i ].position = (x , position_y )
113+ self [i ].position = (position_x , position_y )
101114
102115 x += glyph .shift_x
103116
@@ -112,6 +125,23 @@ def _update_text(self, new_text):
112125 while len (self ) > i :
113126 self .pop ()
114127 self ._text = new_text
128+ self ._boundingbox = (left , top , left + right , bottom - top )
129+
130+ @property
131+ def bounding_box (self ):
132+ """An (x, y, w, h) tuple that completely covers all glyphs. The
133+ first two numbers are offset from the x, y origin of this group"""
134+ return tuple (self ._boundingbox )
135+
136+ @property
137+ def line_spacing (self ):
138+ """The amount of space between lines of text, in multiples of the font's
139+ bounding-box height. (E.g. 1.0 is the bounding-box height)"""
140+ return self ._line_spacing
141+
142+ @line_spacing .setter
143+ def line_spacing (self , spacing ):
144+ self ._line_spacing = spacing
115145
116146 @property
117147 def color (self ):
0 commit comments