Skip to content

Commit 329158c

Browse files
authored
Merge pull request #5 from ladyada/master
Add line_spacing property and change (0,0) definition
2 parents 187bcae + 8673868 commit 329158c

File tree

5 files changed

+116
-23
lines changed

5 files changed

+116
-23
lines changed

README.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,12 @@ For a board with a built-in display.
3434
3535
import board
3636
import terminalio
37-
from adafruit_display_text import text_area
37+
from adafruit_display_text import label
3838
3939
text = "Hello world"
40-
text_area = text_area.TextArea(terminalio.FONT, text=text, width=len(text))
40+
text_area = label.Label(terminalio.FONT, text=text)
41+
text_area.x = 10
42+
text_area.y = 10
4143
board.DISPLAY.show(text_area)
4244
4345

adafruit_display_text/text_area.py renamed to adafruit_display_text/label.py

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
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
@@ -44,21 +44,23 @@
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):

docs/api.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
.. If your library file(s) are nested in a directory (e.g. /adafruit_foo/foo.py)
55
.. use this format as the module name: "adafruit_foo.foo"
66
7-
.. automodule:: adafruit_display_text.text_area
7+
.. automodule:: adafruit_display_text.label
88
:members:

examples/pyportal.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import displayio
77

88
from adafruit_bitmap_font import bitmap_font
9-
from adafruit_display_text.text_area import TextArea
9+
from adafruit_display_text.label import Label
1010

1111
backlight = pulseio.PWMOut(microcontroller.pin.PB21) #pylint: disable=no-member
1212

@@ -31,7 +31,7 @@
3131
for demo_text in demos:
3232
for font in fonts:
3333
print("Font load {}".format(font.name))
34-
area = TextArea(font, text=demo_text)
34+
area = Label(font, text=demo_text)
3535
area.y = y
3636
splash.append(area)
3737

examples/textarea_boundingbox.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import os
2+
import board
3+
import displayio
4+
from adafruit_display_text.label import Label
5+
from adafruit_bitmap_font import bitmap_font
6+
7+
# the current working directory (where this file is)
8+
cwd = ("/"+__file__).rsplit('/', 1)[0]
9+
fonts = [file for file in os.listdir(cwd+"/fonts/")
10+
if (file.endswith(".bdf") and not file.startswith("._"))]
11+
for i, filename in enumerate(fonts):
12+
fonts[i] = cwd+"/fonts/"+filename
13+
print(fonts)
14+
15+
##########################################################################
16+
THE_FONT = fonts[0]
17+
DISPLAY_STRING = "A multi-line-\nexample of\n font bounding!"
18+
WRAP_CHARS = 40
19+
20+
##########################################################################
21+
# Make the display context
22+
splash = displayio.Group()
23+
board.DISPLAY.show(splash)
24+
25+
# Make a background color fill
26+
color_bitmap = displayio.Bitmap(320, 240, 1)
27+
color_palette = displayio.Palette(1)
28+
color_palette[0] = 0xFFFFFF
29+
bg_sprite = displayio.TileGrid(color_bitmap,
30+
pixel_shader=color_palette,
31+
position=(0, 0))
32+
splash.append(bg_sprite)
33+
34+
# Load the font
35+
font = bitmap_font.load_font(THE_FONT)
36+
font.load_glyphs(DISPLAY_STRING.encode('utf-8'))
37+
38+
print(DISPLAY_STRING)
39+
40+
text = Label(font, text=DISPLAY_STRING)
41+
text.x = 20
42+
text.y = 100
43+
text.color = 0x0
44+
45+
# Make a background color fill
46+
dims = text.bounding_box
47+
print(dims)
48+
textbg_bitmap = displayio.Bitmap(dims[2], dims[3], 1)
49+
textbg_palette = displayio.Palette(1)
50+
textbg_palette[0] = 0xFF0000
51+
textbg_sprite = displayio.TileGrid(textbg_bitmap,
52+
pixel_shader=textbg_palette,
53+
position=(text.x+dims[0], text.y+dims[1]))
54+
splash.append(textbg_sprite)
55+
splash.append(text)
56+
board.DISPLAY.refresh_soon()
57+
board.DISPLAY.wait_for_frame()
58+
59+
60+
while True:
61+
pass

0 commit comments

Comments
 (0)