Skip to content

Commit e97e698

Browse files
authored
Merge pull request #134 from jposada202020/tab_replacement
Anchoring Point relative to the Baseline
2 parents f0a80b9 + bbe9e8c commit e97e698

File tree

3 files changed

+133
-108
lines changed

3 files changed

+133
-108
lines changed

adafruit_display_text/__init__.py

+71-52
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@
55
"""
66
Display Text module helper functions
77
"""
8+
try:
9+
from typing import Tuple
10+
except ImportError:
11+
pass
812
from 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

Comments
 (0)