Skip to content

Commit

Permalink
Merge pull request #167 from kevinjwalters/kjw-efficient-text-updates
Browse files Browse the repository at this point in the history
Improved memory efficiency for some text updates to bitmap_label.Label
  • Loading branch information
FoamyGuy authored Mar 13, 2022
2 parents 144cbf9 + 161b99b commit 35b6410
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 41 deletions.
4 changes: 2 additions & 2 deletions adafruit_display_text/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ def __init__(
self._y_offset = self._ascent // 2

def _get_ascent_descent(self) -> Tuple[int, int]:
""" Private function to calculate ascent and descent font values """
"""Private function to calculate ascent and descent font values"""
if hasattr(self.font, "ascent") and hasattr(self.font, "descent"):
return self.font.ascent, self.font.descent

Expand Down Expand Up @@ -462,4 +462,4 @@ def label_direction(self, new_label_direction: str) -> None:
self._set_label_direction(new_label_direction)

def _replace_tabs(self, text: str) -> str:
return self._tab_text.join(text.split("\t"))
return text if text.find("\t") < 0 else self._tab_text.join(text.split("\t"))
94 changes: 55 additions & 39 deletions adafruit_display_text/bitmap_label.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

from adafruit_display_text import LabelBase


# pylint: disable=too-many-instance-attributes
class Label(LabelBase):
"""A label displaying a string of text that is stored in a bitmap.
Note: This ``bitmap_label.py`` library utilizes a :py:class:`~displayio.Bitmap`
Expand Down Expand Up @@ -84,20 +84,28 @@ class Label(LabelBase):
configurations possibles ``LTR``-Left-To-Right ``RTL``-Right-To-Left
``UPD``-Upside Down ``UPR``-Upwards ``DWR``-Downwards. It defaults to ``LTR``"""

# This maps label_direction to TileGrid's transpose_xy, flip_x, flip_y
_DIR_MAP = {
"UPR": (True, True, False),
"DWR": (True, False, True),
"UPD": (False, True, True),
"LTR": (False, False, False),
"RTL": (False, False, False),
}

def __init__(
self, font: Union[BuiltinFont, BDF, PCF], save_text: bool = True, **kwargs
) -> None:

self._bitmap = None
self._tilegrid = None
self._prev_label_direction = None

super().__init__(font, **kwargs)

self._save_text = save_text
self._text = self._replace_tabs(self._text)

if self._label_direction == "RTL":
self._text = "".join(reversed(self._text))

# call the text updater with all the arguments.
self._reset_text(
font=font,
Expand All @@ -113,7 +121,7 @@ def _reset_text(
line_spacing: Optional[float] = None,
scale: Optional[int] = None,
) -> None:
# pylint: disable=too-many-branches, too-many-statements
# pylint: disable=too-many-branches, too-many-statements, too-many-locals

# Store all the instance variables
if font is not None:
Expand All @@ -127,8 +135,6 @@ def _reset_text(

if self._save_text: # text string will be saved
self._text = self._replace_tabs(text)
if self._label_direction == "RTL":
self._text = "".join(reversed(self._text))
else:
self._text = None # save a None value since text string is not saved

Expand Down Expand Up @@ -179,13 +185,24 @@ def _reset_text(
box_x = box_x + self._padding_left + self._padding_right
box_y = box_y + self._padding_top + self._padding_bottom

# Create the bitmap and TileGrid
self._bitmap = displayio.Bitmap(box_x, box_y, len(self._palette))
# Create the Bitmap unless it can be reused
new_bitmap = None
if (
self._bitmap is None
or self._bitmap.width != box_x
or self._bitmap.height != box_y
):
new_bitmap = displayio.Bitmap(box_x, box_y, len(self._palette))
self._bitmap = new_bitmap
else:
self._bitmap.fill(0)

# Place the text into the Bitmap
self._place_text(
self._bitmap,
text,
text
if self._label_direction != "RTL"
else "".join(reversed(self._text)),
self._font,
self._padding_left - x_offset,
self._padding_top + y_offset,
Expand All @@ -196,35 +213,33 @@ def _reset_text(
else:
label_position_yoffset = self._ascent // 2

self._tilegrid = displayio.TileGrid(
self._bitmap,
pixel_shader=self._palette,
width=1,
height=1,
tile_width=box_x,
tile_height=box_y,
default_tile=0,
x=-self._padding_left + x_offset,
y=label_position_yoffset - y_offset - self._padding_top,
)

if self._label_direction == "UPR":
self._tilegrid.transpose_xy = True
self._tilegrid.flip_x = True
if self._label_direction == "DWR":
self._tilegrid.transpose_xy = True
self._tilegrid.flip_y = True
if self._label_direction == "UPD":
self._tilegrid.flip_x = True
self._tilegrid.flip_y = True

# Clear out any items in the local_group Group, in case this is an update to
# the bitmap_label
for _ in self._local_group:
self._local_group.pop(0)
self._local_group.append(
self._tilegrid
) # add the bitmap's tilegrid to the group
# Create the TileGrid if not created bitmap unchanged
if self._tilegrid is None or new_bitmap:
self._tilegrid = displayio.TileGrid(
self._bitmap,
pixel_shader=self._palette,
width=1,
height=1,
tile_width=box_x,
tile_height=box_y,
default_tile=0,
x=-self._padding_left + x_offset,
y=label_position_yoffset - y_offset - self._padding_top,
)
# Clear out any items in the local_group Group, in case this is an update to
# the bitmap_label
for _ in self._local_group:
self._local_group.pop(0)
self._local_group.append(
self._tilegrid
) # add the bitmap's tilegrid to the group

# Set TileGrid properties based on label_direction
if self._label_direction != self._prev_label_direction:
tg1 = self._tilegrid
tg1.transpose_xy, tg1.flip_x, tg1.flip_y = self._DIR_MAP[
self._label_direction
]

# Update bounding_box values. Note: To be consistent with label.py,
# this is the bounding box for the text only, not including the background.
Expand Down Expand Up @@ -537,6 +552,7 @@ def _set_background_color(self, new_color: Optional[int]):
self._palette.make_transparent(0)

def _set_label_direction(self, new_label_direction: str) -> None:
self._prev_label_direction = self._label_direction
self._label_direction = new_label_direction
self._reset_text(text=str(self._text)) # Force a recalculation

Expand Down

0 comments on commit 35b6410

Please sign in to comment.