Skip to content

Commit 55267ee

Browse files
committed
LabelBase created and bitmap_label using it. Starting on label
1 parent d91f5d3 commit 55267ee

File tree

3 files changed

+195
-220
lines changed

3 files changed

+195
-220
lines changed

adafruit_display_text/__init__.py

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"""
66
Display Text module helper functions
77
"""
8+
from displayio import Group, Palette
89

910

1011
def wrap_text_to_pixels(string, max_width, font=None, indent0="", indent1=""):
@@ -141,3 +142,169 @@ def chunks(lst, n):
141142
if the_lines[0][0] == " ":
142143
the_lines[0] = the_lines[0][1:]
143144
return the_lines
145+
146+
147+
class LabelBase(Group):
148+
def __init__(
149+
self,
150+
font,
151+
x=0,
152+
y=0,
153+
text="",
154+
max_glyphs=None, # This input parameter is ignored, only present for compatibility
155+
# with label.py
156+
color=0xFFFFFF,
157+
background_color=None,
158+
line_spacing=1.25,
159+
background_tight=False,
160+
padding_top=0,
161+
padding_bottom=0,
162+
padding_left=0,
163+
padding_right=0,
164+
anchor_point=None,
165+
anchored_position=None,
166+
save_text=True, # can reduce memory use if save_text = False
167+
scale=1,
168+
base_alignment=False,
169+
**kwargs,
170+
):
171+
super().__init__(max_size=1, x=x, y=y, scale=1)
172+
173+
self._font = font
174+
self.palette = Palette(2)
175+
self._color = color
176+
self._background_color = background_color
177+
178+
self._bounding_box = None
179+
self._anchor_point = anchor_point
180+
self._anchored_position = anchored_position
181+
182+
self.local_group = None
183+
184+
self._text = text
185+
186+
def _get_ascent_descent(self):
187+
""" Private function to calculate ascent and descent font values """
188+
if hasattr(self.font, "ascent"):
189+
return self.font.ascent, self.font.descent
190+
191+
# check a few glyphs for maximum ascender and descender height
192+
glyphs = "M j'" # choose glyphs with highest ascender and lowest
193+
try:
194+
self._font.load_glyphs(glyphs)
195+
except AttributeError:
196+
# Builtin font doesn't have or need load_glyphs
197+
pass
198+
# descender, will depend upon font used
199+
ascender_max = descender_max = 0
200+
for char in glyphs:
201+
this_glyph = self._font.get_glyph(ord(char))
202+
if this_glyph:
203+
ascender_max = max(ascender_max, this_glyph.height + this_glyph.dy)
204+
descender_max = max(descender_max, -this_glyph.dy)
205+
return ascender_max, descender_max
206+
207+
def _get_ascent(self):
208+
return self._get_ascent_descent()[0]
209+
210+
@property
211+
def font(self):
212+
"""Font to use for text display."""
213+
return self._font
214+
215+
def _set_font(self, new_font):
216+
# subclasses should override this
217+
pass
218+
219+
@font.setter
220+
def font(self, new_font):
221+
self._set_font(new_font)
222+
223+
@property
224+
def color(self):
225+
"""Color of the text as an RGB hex number."""
226+
return self._color
227+
228+
@color.setter
229+
def color(self, new_color):
230+
self._color = new_color
231+
if new_color is not None:
232+
self.palette[1] = new_color
233+
self.palette.make_opaque(1)
234+
else:
235+
self.palette[1] = 0
236+
self.palette.make_transparent(1)
237+
238+
@property
239+
def background_color(self):
240+
"""Color of the background as an RGB hex number."""
241+
return self._background_color
242+
243+
@background_color.setter
244+
def background_color(self, new_color):
245+
self._background_color = new_color
246+
if new_color is not None:
247+
self.palette[0] = new_color
248+
self.palette.make_opaque(0)
249+
else:
250+
self.palette[0] = 0
251+
self.palette.make_transparent(0)
252+
253+
@property
254+
def anchor_point(self):
255+
"""Point that anchored_position moves relative to.
256+
Tuple with decimal percentage of width and height.
257+
(E.g. (0,0) is top left, (1.0, 0.5): is middle right.)"""
258+
return self._anchor_point
259+
260+
@anchor_point.setter
261+
def anchor_point(self, new_anchor_point):
262+
self._anchor_point = new_anchor_point
263+
self.anchored_position = (
264+
self._anchored_position
265+
) # update the anchored_position using setter
266+
267+
@property
268+
def anchored_position(self):
269+
"""Position relative to the anchor_point. Tuple containing x,y
270+
pixel coordinates."""
271+
return self._anchored_position
272+
273+
@anchored_position.setter
274+
def anchored_position(self, new_position):
275+
self._anchored_position = new_position
276+
# Set anchored_position
277+
if (self._anchor_point is not None) and (self._anchored_position is not None):
278+
self.x = int(
279+
new_position[0]
280+
- (self._bounding_box[0] * self.scale)
281+
- round(self._anchor_point[0] * (self._bounding_box[2] * self.scale))
282+
)
283+
self.y = int(
284+
new_position[1]
285+
- (self._bounding_box[1] * self.scale)
286+
- round(self._anchor_point[1] * self._bounding_box[3] * self.scale)
287+
)
288+
289+
@property
290+
def scale(self):
291+
"""Set the scaling of the label, in integer values"""
292+
return self.local_group.scale
293+
294+
@scale.setter
295+
def scale(self, new_scale):
296+
self.local_group.scale = new_scale
297+
self.anchored_position = self._anchored_position # update the anchored_position
298+
299+
def _reset_text(self, text, scale):
300+
# subclasses should override this
301+
pass
302+
303+
@property
304+
def text(self):
305+
"""Text to be displayed."""
306+
return self._text
307+
308+
@text.setter # Cannot set color or background color with text setter, use separate setter
309+
def text(self, new_text):
310+
self._reset_text(text=new_text, scale=self.scale)

0 commit comments

Comments
 (0)