5
5
"""
6
6
Display Text module helper functions
7
7
"""
8
+ from displayio import Group , Palette
8
9
9
10
10
11
def wrap_text_to_pixels (string , max_width , font = None , indent0 = "" , indent1 = "" ):
@@ -141,3 +142,169 @@ def chunks(lst, n):
141
142
if the_lines [0 ][0 ] == " " :
142
143
the_lines [0 ] = the_lines [0 ][1 :]
143
144
return the_lines
145
+
146
+
147
+ class LabelBase (Group ):
148
+ def __init__ (
149
+ self ,
150
+ font ,
151
+ x = 0 ,
152
+ y = 0 ,
153
+ text = "" ,
154
+ max_glyphs = None , # This input parameter is ignored, only present for compatibility
155
+ # with label.py
156
+ color = 0xFFFFFF ,
157
+ background_color = None ,
158
+ line_spacing = 1.25 ,
159
+ background_tight = False ,
160
+ padding_top = 0 ,
161
+ padding_bottom = 0 ,
162
+ padding_left = 0 ,
163
+ padding_right = 0 ,
164
+ anchor_point = None ,
165
+ anchored_position = None ,
166
+ save_text = True , # can reduce memory use if save_text = False
167
+ scale = 1 ,
168
+ base_alignment = False ,
169
+ ** kwargs ,
170
+ ):
171
+ super ().__init__ (max_size = 1 , x = x , y = y , scale = 1 )
172
+
173
+ self ._font = font
174
+ self .palette = Palette (2 )
175
+ self ._color = color
176
+ self ._background_color = background_color
177
+
178
+ self ._bounding_box = None
179
+ self ._anchor_point = anchor_point
180
+ self ._anchored_position = anchored_position
181
+
182
+ self .local_group = None
183
+
184
+ self ._text = text
185
+
186
+ def _get_ascent_descent (self ):
187
+ """ Private function to calculate ascent and descent font values """
188
+ if hasattr (self .font , "ascent" ):
189
+ return self .font .ascent , self .font .descent
190
+
191
+ # check a few glyphs for maximum ascender and descender height
192
+ glyphs = "M j'" # choose glyphs with highest ascender and lowest
193
+ try :
194
+ self ._font .load_glyphs (glyphs )
195
+ except AttributeError :
196
+ # Builtin font doesn't have or need load_glyphs
197
+ pass
198
+ # descender, will depend upon font used
199
+ ascender_max = descender_max = 0
200
+ for char in glyphs :
201
+ this_glyph = self ._font .get_glyph (ord (char ))
202
+ if this_glyph :
203
+ ascender_max = max (ascender_max , this_glyph .height + this_glyph .dy )
204
+ descender_max = max (descender_max , - this_glyph .dy )
205
+ return ascender_max , descender_max
206
+
207
+ def _get_ascent (self ):
208
+ return self ._get_ascent_descent ()[0 ]
209
+
210
+ @property
211
+ def font (self ):
212
+ """Font to use for text display."""
213
+ return self ._font
214
+
215
+ def _set_font (self , new_font ):
216
+ # subclasses should override this
217
+ pass
218
+
219
+ @font .setter
220
+ def font (self , new_font ):
221
+ self ._set_font (new_font )
222
+
223
+ @property
224
+ def color (self ):
225
+ """Color of the text as an RGB hex number."""
226
+ return self ._color
227
+
228
+ @color .setter
229
+ def color (self , new_color ):
230
+ self ._color = new_color
231
+ if new_color is not None :
232
+ self .palette [1 ] = new_color
233
+ self .palette .make_opaque (1 )
234
+ else :
235
+ self .palette [1 ] = 0
236
+ self .palette .make_transparent (1 )
237
+
238
+ @property
239
+ def background_color (self ):
240
+ """Color of the background as an RGB hex number."""
241
+ return self ._background_color
242
+
243
+ @background_color .setter
244
+ def background_color (self , new_color ):
245
+ self ._background_color = new_color
246
+ if new_color is not None :
247
+ self .palette [0 ] = new_color
248
+ self .palette .make_opaque (0 )
249
+ else :
250
+ self .palette [0 ] = 0
251
+ self .palette .make_transparent (0 )
252
+
253
+ @property
254
+ def anchor_point (self ):
255
+ """Point that anchored_position moves relative to.
256
+ Tuple with decimal percentage of width and height.
257
+ (E.g. (0,0) is top left, (1.0, 0.5): is middle right.)"""
258
+ return self ._anchor_point
259
+
260
+ @anchor_point .setter
261
+ def anchor_point (self , new_anchor_point ):
262
+ self ._anchor_point = new_anchor_point
263
+ self .anchored_position = (
264
+ self ._anchored_position
265
+ ) # update the anchored_position using setter
266
+
267
+ @property
268
+ def anchored_position (self ):
269
+ """Position relative to the anchor_point. Tuple containing x,y
270
+ pixel coordinates."""
271
+ return self ._anchored_position
272
+
273
+ @anchored_position .setter
274
+ def anchored_position (self , new_position ):
275
+ self ._anchored_position = new_position
276
+ # Set anchored_position
277
+ if (self ._anchor_point is not None ) and (self ._anchored_position is not None ):
278
+ self .x = int (
279
+ new_position [0 ]
280
+ - (self ._bounding_box [0 ] * self .scale )
281
+ - round (self ._anchor_point [0 ] * (self ._bounding_box [2 ] * self .scale ))
282
+ )
283
+ self .y = int (
284
+ new_position [1 ]
285
+ - (self ._bounding_box [1 ] * self .scale )
286
+ - round (self ._anchor_point [1 ] * self ._bounding_box [3 ] * self .scale )
287
+ )
288
+
289
+ @property
290
+ def scale (self ):
291
+ """Set the scaling of the label, in integer values"""
292
+ return self .local_group .scale
293
+
294
+ @scale .setter
295
+ def scale (self , new_scale ):
296
+ self .local_group .scale = new_scale
297
+ self .anchored_position = self ._anchored_position # update the anchored_position
298
+
299
+ def _reset_text (self , text , scale ):
300
+ # subclasses should override this
301
+ pass
302
+
303
+ @property
304
+ def text (self ):
305
+ """Text to be displayed."""
306
+ return self ._text
307
+
308
+ @text .setter # Cannot set color or background color with text setter, use separate setter
309
+ def text (self , new_text ):
310
+ self ._reset_text (text = new_text , scale = self .scale )
0 commit comments