Skip to content

Commit 0d0be6f

Browse files
committed
outline functionality moved into bitmap_label
1 parent ad55877 commit 0d0be6f

File tree

4 files changed

+112
-203
lines changed

4 files changed

+112
-203
lines changed

adafruit_display_text/bitmap_label.py

Lines changed: 100 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
Text graphics handling for CircuitPython, including text boxes
1111
1212
13-
* Author(s): Kevin Matocha
13+
* Author(s): Kevin Matocha, Tim Cocks
1414
1515
Implementation Notes
1616
--------------------
@@ -114,29 +114,57 @@ def __init__(
114114
font: FontProtocol,
115115
save_text: bool = True,
116116
color_palette: Optional[displayio.Palette] = None,
117+
outline_color: Optional[int] = None,
118+
outline_size: int = 1,
117119
**kwargs,
118120
) -> None:
119121
self._bitmap = None
120122
self._tilegrid = None
121123
self._prev_label_direction = None
122124

125+
if "padding_top" not in kwargs:
126+
kwargs["padding_top"] = outline_size + 0
127+
if "padding_bottom" not in kwargs:
128+
kwargs["padding_bottom"] = outline_size + 2
129+
if "padding_left" not in kwargs:
130+
kwargs["padding_left"] = outline_size + 0
131+
if "padding_right" not in kwargs:
132+
kwargs["padding_right"] = outline_size + 0
133+
123134
super().__init__(font, **kwargs)
124135

125136
if color_palette is not None:
126-
if len(color_palette) <= 2:
137+
if len(color_palette) <= 3:
127138
raise ValueError(
128-
"color_palette should be at least 3 colors to "
129-
"provide enough for normal and accented text. "
139+
"color_palette should be at least 4 colors to "
140+
"provide enough for normal, accented, and outlined text. "
130141
"color_palette argument can be omitted if not "
131142
"using accents."
132143
)
133144
self._palette = color_palette
134145
self.color = self._color
135146
self.background_color = self._background_color
136-
147+
else:
148+
_background_color = self._palette[0]
149+
_foreground_color = self._palette[1]
150+
_background_is_transparent = self._palette.is_transparent(0)
151+
self._palette = displayio.Palette(3)
152+
self._palette[0] = _background_color
153+
self._palette[1] = _foreground_color
154+
self._palette[2] = outline_color if outline_color is not None else 0x999999
155+
if _background_is_transparent:
156+
self._palette.make_transparent(0)
157+
158+
# accent handling vars
137159
self._accent_ranges = []
138160
self._tmp_glyph_bitmap = None
139161

162+
# outline handling vars
163+
self._outline_size = outline_size
164+
self._outline_color = outline_color
165+
if self._outline_color is not None:
166+
self._init_outline_stamp(outline_size)
167+
140168
self._save_text = save_text
141169
self._text = self._replace_tabs(self._text)
142170

@@ -148,6 +176,11 @@ def __init__(
148176
scale=self.scale,
149177
)
150178

179+
def _init_outline_stamp(self, outline_size):
180+
self._outline_size = outline_size
181+
self._stamp_source = displayio.Bitmap((outline_size * 2) + 1, (outline_size * 2) + 1, 3)
182+
self._stamp_source.fill(2)
183+
151184
def _reset_text(
152185
self,
153186
font: Optional[FontProtocol] = None,
@@ -498,9 +531,36 @@ def _place_text(
498531

499532
xposition = xposition + my_glyph.shift_x
500533

534+
self._add_outline()
501535
# bounding_box
502536
return left, top, right - left, bottom - top
503537

538+
def _add_outline(self):
539+
"""
540+
Blit the outline into the labels Bitmap. Will blit self._stamp_source for each
541+
pixel of the foreground color but skip the foreground color when we blit,
542+
creating an outline.
543+
:return: None
544+
"""
545+
if self._outline_color is not None:
546+
for y in range(self.bitmap.height):
547+
for x in range(self.bitmap.width):
548+
if self.bitmap[x, y] == 1:
549+
try:
550+
bitmaptools.blit(
551+
self.bitmap,
552+
self._stamp_source,
553+
x - self._outline_size,
554+
y - self._outline_size,
555+
skip_dest_index=1,
556+
)
557+
except ValueError as value_error:
558+
raise ValueError(
559+
"Padding must be big enough to fit outline_size "
560+
"all the way around the text. "
561+
"Try using either larger padding sizes, or smaller outline_size."
562+
) from value_error
563+
504564
def _blit(
505565
self,
506566
bitmap: displayio.Bitmap, # target bitmap
@@ -627,6 +687,41 @@ def bitmap(self) -> displayio.Bitmap:
627687
"""
628688
return self._bitmap
629689

690+
@property
691+
def outline_color(self):
692+
"""Color of the outline to draw around the text. Or None for no outline."""
693+
694+
return self._palette[2] if self._outline_color is not None else None
695+
696+
@outline_color.setter
697+
def outline_color(self, new_outline_color):
698+
if new_outline_color is not None:
699+
self._palette[2] = new_outline_color
700+
else:
701+
self._outline_color = None
702+
703+
@property
704+
def outline_size(self):
705+
"""Stroke size of the outline to draw around the text."""
706+
return self._outline_size
707+
708+
@outline_size.setter
709+
def outline_size(self, new_outline_size):
710+
self._outline_size = new_outline_size
711+
712+
self._padding_top = new_outline_size + 0
713+
self._padding_bottom = new_outline_size + 2
714+
self._padding_left = new_outline_size + 0
715+
self._padding_right = new_outline_size + 0
716+
717+
self._init_outline_stamp(new_outline_size)
718+
self._reset_text(
719+
font=self._font,
720+
text=self._text,
721+
line_spacing=self._line_spacing,
722+
scale=self.scale,
723+
)
724+
630725
def add_accent_range(self, start, end, foreground_color, background_color):
631726
"""
632727
Set a range of text to get accented with the specified colors.

adafruit_display_text/outlined_label.py

Lines changed: 0 additions & 188 deletions
This file was deleted.

docs/examples.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ Simple test using scrolling_label to display text
2525
:caption: examples/display_text_scrolling_label.py
2626
:linenos:
2727

28-
OutlinedLabel Simple Test
29-
-------------------------
28+
Outline Example
29+
---------------
3030

31-
Simple test using outlined_label to display text with a stroke outline
31+
Basic example of outlined text
3232

33-
.. literalinclude:: ../examples/display_text_outlined_label_simpletest.py
34-
:caption: examples/display_text_outlined_label_simpletest.py
33+
.. literalinclude:: ../examples/display_text_outline_example.py
34+
:caption: examples/display_text_outline_example.py
3535
:linenos:
3636

3737
Label vs Bitmap_label Comparison

0 commit comments

Comments
 (0)