Browse Source

split text drawing interface into multiple methods.

Thomas Buck 1 year ago
parent
commit
d8943ab606
5 changed files with 114 additions and 60 deletions
  1. 49
    25
      bdf.py
  2. 40
    22
      pico.py
  3. 2
    1
      qr.py
  4. 3
    2
      scroll.py
  5. 20
    10
      tetris.py

+ 49
- 25
bdf.py View File

55
 
55
 
56
             # center vertically, in case of
56
             # center vertically, in case of
57
             # multiple stacked panels
57
             # multiple stacked panels
58
-            # TODO hard-coded offsets assume 32x32 panels
59
-            if self.gui.height > 32:
60
-                offset += 16
58
+            if self.gui.height > self.gui.panelH:
59
+                offset += int(self.gui.panelH / 2)
61
 
60
 
62
             font = Font(os.path.join(fontDir, filename))
61
             font = Font(os.path.join(fontDir, filename))
63
             data = (font, offset, {}, spacing)
62
             data = (font, offset, {}, spacing)
64
             self.fonts[filename[:-4]] = data
63
             self.fonts[filename[:-4]] = data
65
 
64
 
65
+    # internal
66
     def getGlyph(self, c, font):
66
     def getGlyph(self, c, font):
67
         if not isinstance(font, str):
67
         if not isinstance(font, str):
68
             # fall-back to first available font
68
             # fall-back to first available font
91
 
91
 
92
         return (cache[c], offset, spacing)
92
         return (cache[c], offset, spacing)
93
 
93
 
94
+    # internal
94
     def drawGlyph(self, g, xOff, yOff, spacing):
95
     def drawGlyph(self, g, xOff, yOff, spacing):
95
-        if xOff >= self.gui.width:
96
-            return
97
-
98
-        for x in range(0, g.width):
96
+        for x in range(0, g.width + spacing):
99
             for y in range(0, g.height):
97
             for y in range(0, g.height):
100
-                xTarget = xOff + x
101
-                if (xTarget < 0) or (xTarget >= self.gui.width):
102
-                    continue
103
-
104
-                p = g.getpixel((x, y))
105
-                self.gui.set_pixel(xTarget, yOff + y, p)
98
+                pos = (xOff + x, yOff + y)
99
+                if x >= g.width:
100
+                    self.image.putpixel(pos, self.bg)
101
+                else:
102
+                    p = g.getpixel((x, y))
103
+                    self.image.putpixel(pos, p)
104
+
105
+    # text drawing API
106
+    def setText(self, s, f):
107
+        # calculate length of whole text
108
+        w = 0
109
+        h = 0
110
+        for c in s:
111
+            g, y, spacing = self.getGlyph(c, f)
112
+            w += g.width + spacing
113
+            if h < g.height:
114
+                h = g.height
106
 
115
 
107
-        for x in range(0, spacing):
108
-            for y in range(0, g.height):
109
-                self.gui.set_pixel(xOff + x + g.width, yOff + y, self.bg)
116
+        # create new blank image buffer
117
+        self.image = Image.new('RGBA', (w, h))
110
 
118
 
111
-    def text(self, s, f, offset = 0, earlyAbort = True, yOff = 0):
119
+        # render glyphs into image
112
         w = 0
120
         w = 0
113
         for c in s:
121
         for c in s:
114
-            xOff = -offset + w
115
-            if earlyAbort:
116
-                if xOff >= self.gui.width:
117
-                    break
118
-
119
             g, y, spacing = self.getGlyph(c, f)
122
             g, y, spacing = self.getGlyph(c, f)
123
+            self.drawGlyph(g, w, 0, spacing)
120
             w += g.width + spacing
124
             w += g.width + spacing
125
+            self.yOffset = y
126
+
127
+    # text drawing API
128
+    def getDimensions(self):
129
+        return (self.image.width, self.image.height)
130
+
131
+    # text drawing API
132
+    def draw(self, xOff = 0, yOff = 0):
133
+        for x in range(0, self.image.width):
134
+            xTarget = -xOff + x
135
+            if xTarget < 0:
136
+                continue
137
+            if xTarget >= self.gui.width:
138
+                break
139
+
140
+            for y in range(0, self.image.height):
141
+                yTarget = yOff + y + self.yOffset
142
+                if yTarget < 0:
143
+                    continue
144
+                if yTarget >= self.gui.height:
145
+                    break
121
 
146
 
122
-            if xOff >= -16: # some wiggle room so chars dont disappear
123
-                self.drawGlyph(g, xOff, y + yOff, spacing)
124
-        return w
147
+                p = self.image.getpixel((x, y))
148
+                self.gui.set_pixel(xTarget, yTarget, p)

+ 40
- 22
pico.py View File

177
         self.bg = bg
177
         self.bg = bg
178
         self.color = c
178
         self.color = c
179
 
179
 
180
-    def text(self, s, f, offset = 0, earlyAbort = True, yOff = 0, compat = True):
181
-        if not earlyAbort:
182
-            self.gui.matrix.display.set_font(f)
183
-            return self.gui.matrix.display.measure_text(s, scale=1)
184
-
180
+    # text drawing API
181
+    def setText(self, s, f):
182
+        self.text = s
183
+        self.font = f
184
+
185
+    # text drawing API
186
+    def getDimensions(self):
187
+        self.gui.matrix.display.set_font(self.font)
188
+        w = self.gui.matrix.display.measure_text(self.text, scale=1)
189
+        return (w, 42) # TODO wrong height
190
+
191
+    # text drawing API
192
+    def draw(self, xOff = 0, yOff = 0, compat = True):
185
         color = self.fg
193
         color = self.fg
186
         if isinstance(self.gui, MapperReduceBrightness):
194
         if isinstance(self.gui, MapperReduceBrightness):
187
             color = self.gui.adjust(color)
195
             color = self.gui.adjust(color)
189
         pen = self.gui.matrix.display.create_pen(color[0], color[1], color[2])
197
         pen = self.gui.matrix.display.create_pen(color[0], color[1], color[2])
190
         self.gui.matrix.display.set_pen(pen)
198
         self.gui.matrix.display.set_pen(pen)
191
 
199
 
192
-        self.gui.matrix.display.set_font(f)
200
+        self.gui.matrix.display.set_font(self.font)
193
 
201
 
194
         if not compat:
202
         if not compat:
195
             # absolute positioning
203
             # absolute positioning
196
-            x = offset
204
+            x = xOff
197
             y = yOff
205
             y = yOff
198
         else:
206
         else:
199
             # centered, like BDF DrawText implementation
207
             # centered, like BDF DrawText implementation
200
             fontOff = 0
208
             fontOff = 0
201
-            if f == "bitmap6":
209
+            if self.font == "bitmap6":
202
                 fontOff = 3
210
                 fontOff = 3
203
-            elif f == "bitmap8":
211
+            elif self.font == "bitmap8":
204
                 fontOff = 4
212
                 fontOff = 4
205
-            elif f == "bitmap14_outline":
213
+            elif self.font == "bitmap14_outline":
206
                 fontOff = 7
214
                 fontOff = 7
207
 
215
 
208
-            x = -offset
216
+            x = -xOff
209
             y = int(self.gui.height / 2 - fontOff + yOff)
217
             y = int(self.gui.height / 2 - fontOff + yOff)
210
 
218
 
211
-        self.gui.matrix.display.text(s, x, y, scale=1)
219
+        self.gui.matrix.display.text(self.text, x, y, scale=1)
212
 
220
 
213
 class PicoBatt:
221
 class PicoBatt:
214
     def __init__(self, g, ti = 5.0, tt = 5.0):
222
     def __init__(self, g, ti = 5.0, tt = 5.0):
230
         c = batt_to_color(batt)
238
         c = batt_to_color(batt)
231
 
239
 
232
         self.text.fg = (255, 255, 255)
240
         self.text.fg = (255, 255, 255)
233
-        self.text.text(                  "Batt:", "bitmap8", 0, True, 8 * 0, False)
241
+        self.text.setText(                  "Batt:", "bitmap8")
242
+        self.text.draw(0, 8 * 0, False)
234
 
243
 
235
         self.text.fg = c
244
         self.text.fg = c
236
-        self.text.text("{:.2f}%".format(batt[0]), "bitmap8", 0, True, 8 * 1, False)
237
-        self.text.text("{:.2f}V".format(batt[1]), "bitmap8", 0, True, 8 * 2, False)
238
-        self.text.text("{:.2f}V".format(batt[2]), "bitmap8", 0, True, 8 * 3, False)
245
+        self.text.setText("{:.2f}%".format(batt[0]), "bitmap8")
246
+        self.text.draw(0, 8 * 1, False)
247
+        self.text.setText("{:.2f}V".format(batt[1]), "bitmap8")
248
+        self.text.draw(0, 8 * 2, False)
249
+        self.text.setText("{:.2f}V".format(batt[2]), "bitmap8")
250
+        self.text.draw(0, 8 * 3, False)
239
 
251
 
240
     def drawImage(self, refresh = False):
252
     def drawImage(self, refresh = False):
241
         x_off = const(1)
253
         x_off = const(1)
251
         fill_w = int(batt[0] / 100.0 * (w - nub_w))
263
         fill_w = int(batt[0] / 100.0 * (w - nub_w))
252
 
264
 
253
         s = "{:.0f}%".format(batt[0])
265
         s = "{:.0f}%".format(batt[0])
254
-        s_w = self.text.text(s, "bitmap14_outline", 0, False)
266
+        self.text.setText(s, "bitmap14_outline")
267
+        s_w = self.text.getDimensions()[0]
255
         self.text.fg = (255, 255, 255)
268
         self.text.fg = (255, 255, 255)
256
-        self.text.text(s, "bitmap14_outline", int((self.gui.width - s_w) / 2), True, 1, False)
269
+        self.text.draw(int((self.gui.width - s_w) / 2), 1, False)
257
 
270
 
258
         for x in range(0, w - nub_w):
271
         for x in range(0, w - nub_w):
259
             for y in range(0, h):
272
             for y in range(0, h):
273
 
286
 
274
 if __name__ == "__main__":
287
 if __name__ == "__main__":
275
     import time
288
     import time
289
+    import util
276
 
290
 
277
     t = PicoMatrix(32, 32)
291
     t = PicoMatrix(32, 32)
278
     s = PicoText(t)
292
     s = PicoText(t)
294
             b.draw(True)
308
             b.draw(True)
295
             time.sleep(1.0)
309
             time.sleep(1.0)
296
         elif i == 4:
310
         elif i == 4:
297
-            s.text("Abgj6", "bitmap6", 0, True, 0, False)
298
-            s.text("Abdgj8", "bitmap8", 0, True, 6 + 2, False)
299
-            s.text("Ag14", "bitmap14_outline", 0, True, 6 + 2 + 8 + 1, False)
311
+            s.setText("Abgj6", "bitmap6")
312
+            s.draw(0, 0, False)
313
+            s.setText("Abdgj8", "bitmap8")
314
+            s.draw(0, 6 + 2, False)
315
+            s.setText("Ag14", "bitmap14_outline")
316
+            s.draw(0, 6 + 2 + 8 + 1, False)
300
         else:
317
         else:
301
-            s.text("Drinks:", "bitmap8", 0)
318
+            s.setText("Drinks:", "bitmap8")
319
+            s.draw()
302
 
320
 
303
     util.loop(t, helper)
321
     util.loop(t, helper)

+ 2
- 1
qr.py View File

63
         if self.heading != None:
63
         if self.heading != None:
64
             DrawText = util.getTextDrawer()
64
             DrawText = util.getTextDrawer()
65
             self.text = DrawText(self.gui, self.c1, self.c2)
65
             self.text = DrawText(self.gui, self.c1, self.c2)
66
+            self.text.setText(self.heading, self.font)
66
             self.yOff = self.gui.height - self.image.height
67
             self.yOff = self.gui.height - self.image.height
67
         else:
68
         else:
68
             self.yOff = int((self.gui.height - self.image.height) / 2)
69
             self.yOff = int((self.gui.height - self.image.height) / 2)
98
             elif self.font == "tom-thumb":
99
             elif self.font == "tom-thumb":
99
                 off = -11
100
                 off = -11
100
 
101
 
101
-            self.text.text(self.heading, self.font, 0, True, off)
102
+            self.text.draw(0, off)
102
 
103
 
103
         for x in range(0, self.image.width):
104
         for x in range(0, self.image.width):
104
             for y in range(0, self.image.height):
105
             for y in range(0, self.image.height):

+ 3
- 2
scroll.py View File

32
     def setText(self, t, f):
32
     def setText(self, t, f):
33
         self.text = t
33
         self.text = t
34
         self.font = f
34
         self.font = f
35
-        self.width = self.drawer.text(self.text, self.font, 0, False)
35
+        self.drawer.setText(t, f)
36
+        self.width, height = self.drawer.getDimensions()
36
 
37
 
37
     def restart(self):
38
     def restart(self):
38
         self.offset = -self.gui.width
39
         self.offset = -self.gui.width
52
                 self.offset = -self.gui.width
53
                 self.offset = -self.gui.width
53
                 self.count += 1
54
                 self.count += 1
54
 
55
 
55
-        self.drawer.text(self.text, self.font, self.offset, True)
56
+        self.drawer.draw(self.offset)
56
 
57
 
57
 if __name__ == "__main__":
58
 if __name__ == "__main__":
58
     import util
59
     import util

+ 20
- 10
tetris.py View File

41
 
41
 
42
         DrawText = util.getTextDrawer()
42
         DrawText = util.getTextDrawer()
43
         self.text = []
43
         self.text = []
44
-        self.text.append(DrawText(self.gui, self.colors[1]))
45
-        self.text.append(DrawText(self.gui, self.colors[0]))
46
-        self.text.append(DrawText(self.gui, self.colors[4]))
47
-        self.text.append(DrawText(self.gui, self.colors[5]))
44
+        self.text.append(DrawText(self.gui, self.colors[1])) # Green, "Score"
45
+        self.text.append(DrawText(self.gui, self.colors[0])) # Pink, Score Number
46
+        self.text.append(DrawText(self.gui, self.colors[4])) # Yellow, "Paused"
47
+        self.text.append(DrawText(self.gui, self.colors[5])) # Blue, "next"
48
+        self.text.append(DrawText(self.gui, self.colors[0])) # Pink, "Tetris"
49
+        self.text.append(DrawText(self.gui, self.colors[5])) # Blue, "up"
50
+        self.text[0].setText("Score:", "tom-thumb")
51
+        self.text[1].setText("0", "tom-thumb")
52
+        self.text[2].setText("Paused", "tom-thumb")
53
+        self.text[3].setText("next", "tom-thumb")
54
+        self.text[4].setText("Tetris", "tom-thumb")
55
+        self.text[5].setText("up", "tom-thumb")
48
 
56
 
49
         # all [y][x] sub-lists must be the same length
57
         # all [y][x] sub-lists must be the same length
50
         self.pieces = [
58
         self.pieces = [
119
         self.last = time.time()
127
         self.last = time.time()
120
         self.button = None
128
         self.button = None
121
         self.score = 0
129
         self.score = 0
130
+        self.text[1].setText(str(self.score), "tom-thumb")
122
         self.done = False
131
         self.done = False
123
         self.data = [[self.bg for y in range(self.height)] for x in range(self.width)]
132
         self.data = [[self.bg for y in range(self.height)] for x in range(self.width)]
124
         self.piece = None
133
         self.piece = None
206
 
215
 
207
             if had_data and line_full:
216
             if had_data and line_full:
208
                 self.score += 1
217
                 self.score += 1
218
+                self.text[1].setText(str(self.score), "tom-thumb")
209
 
219
 
210
                 # move stuff above into this line
220
                 # move stuff above into this line
211
                 for y2 in reversed(range(1, y + 1)):
221
                 for y2 in reversed(range(1, y + 1)):
336
     def draw_stats(self, off):
346
     def draw_stats(self, off):
337
         x_off, y_off = off
347
         x_off, y_off = off
338
 
348
 
339
-        self.text[0].text("Score:", "tom-thumb", -x_off - 2, True, y_off - 11)
340
-        self.text[1].text(str(self.score), "tom-thumb", -x_off - 2, True, y_off - 5)
349
+        self.text[0].draw(-x_off - 2, y_off - 11)
350
+        self.text[1].draw(-x_off - 2, y_off - 5)
341
 
351
 
342
         if self.pause:
352
         if self.pause:
343
-            self.text[2].text("Paused", "tom-thumb", -x_off - 2, True, -y_off + 11)
353
+            self.text[2].draw(-x_off - 2, -y_off + 11)
344
 
354
 
345
     def draw(self):
355
     def draw(self):
346
         if self.input != None:
356
         if self.input != None:
370
                 self.endText.restart()
380
                 self.endText.restart()
371
 
381
 
372
         # static text
382
         # static text
373
-        self.text[1].text("Tetris", "tom-thumb", -2, True, -11)
374
-        self.text[3].text("next", "tom-thumb", -14, True, 5)
375
-        self.text[3].text("up", "tom-thumb", -14, True, 12)
383
+        self.text[4].draw(-2, -11)
384
+        self.text[3].draw(-14, 5)
385
+        self.text[5].draw(-14, 12)
376
 
386
 
377
         # draw play area and border
387
         # draw play area and border
378
         for x in range(-1, self.width + 1):
388
         for x in range(-1, self.width + 1):

Loading…
Cancel
Save