@@ -112,14 +112,18 @@ def __init__(
112112 anchored_position = None ,
113113 save_text = True , # can reduce memory use if save_text = False
114114 scale = 1 ,
115+ ** kwargs ,
115116 ):
116117
117118 # instance the Group
118- # self Group will contain a single local_group which contains one TileGrid which contains
119- # the text bitmap
119+ # self Group will contain a single local_group which contains a Group (self.local_group)
120+ # which contains a TileGrid (self.tilegrid) which contains the text bitmap (self.bitmap)
120121 super ().__init__ (
121- max_size = 1 , x = x , y = y ,
122- ) # this will include any arguments, including scale
122+ max_size = 1 , x = x , y = y , scale = 1 , ** kwargs ,
123+ )
124+ # the self group scale should always remain at 1, the self.local_group will
125+ # be used to set the scale
126+ # **kwargs will pass any additional arguments provided to the Label
123127
124128 self .local_group = displayio .Group (
125129 max_size = 1 , scale = scale
@@ -418,18 +422,14 @@ def _place_text(
418422 yposition ,
419423 text_palette_index = 1 ,
420424 background_palette_index = 0 ,
421- print_only_pixels = True , # print_only_pixels = True: only update the bitmap where the glyph
422- # pixel color is > 0. This is especially useful for script fonts where glyph
423- # bounding boxes overlap
424- # Set `print_only_pixels=False` to write all pixels
425+ skip_index = 0 , # set to None to write all pixels, other wise skip this palette index
426+ # when copying glyph bitmaps (this is important for slanted text
427+ # where rectangulary glyph boxes overlap)
425428 ):
426429 # placeText - Writes text into a bitmap at the specified location.
427430 #
428431 # Note: scale is pushed up to Group level
429432
430- bitmap_width = bitmap .width
431- bitmap_height = bitmap .height
432-
433433 x_start = xposition # starting x position (left margin)
434434 y_start = yposition
435435
@@ -472,58 +472,94 @@ def _place_text(
472472 ) # for type BuiltinFont, this creates the x-offset in the glyph bitmap.
473473 # for BDF loaded fonts, this should equal 0
474474
475- try :
476- bitmap .blit (
477- xposition + my_glyph .dx ,
478- yposition - my_glyph .height - my_glyph .dy ,
479- my_glyph .bitmap ,
480- x1 = glyph_offset_x ,
481- y1 = 0 ,
482- x2 = glyph_offset_x + my_glyph .width ,
483- y2 = 0 + my_glyph .height ,
484- skip_index = 0 , # do not copy over any 0 background pixels
485- )
486-
487- except AttributeError :
488- for y in range (my_glyph .height ):
489- for x in range (my_glyph .width ):
490- x_placement = x + xposition + my_glyph .dx
491- y_placement = (
492- y + yposition - my_glyph .height - my_glyph .dy
493- )
494-
495- if (bitmap_width > x_placement >= 0 ) and (
496- bitmap_height > y_placement >= 0
497- ):
498-
499- # Allows for remapping the bitmap indexes using paletteIndex
500- # for background and text.
501- palette_indexes = (
502- background_palette_index ,
503- text_palette_index ,
504- )
505-
506- this_pixel_color = palette_indexes [
507- my_glyph .bitmap [
508- y * my_glyph .bitmap .width
509- + x
510- + glyph_offset_x
511- ]
512- ]
513-
514- if not print_only_pixels or this_pixel_color > 0 :
515- # write all characters if printOnlyPixels = False,
516- # or if thisPixelColor is > 0
517- bitmap [
518- y_placement * bitmap_width + x_placement
519- ] = this_pixel_color
520- elif y_placement > bitmap_height :
521- break
475+ self ._blit (
476+ bitmap ,
477+ xposition + my_glyph .dx ,
478+ yposition - my_glyph .height - my_glyph .dy ,
479+ my_glyph .bitmap ,
480+ x_1 = glyph_offset_x ,
481+ y_1 = 0 ,
482+ x_2 = glyph_offset_x + my_glyph .width ,
483+ y_2 = 0 + my_glyph .height ,
484+ skip_index = skip_index , # do not copy over any 0 background pixels
485+ )
522486
523487 xposition = xposition + my_glyph .shift_x
524488
525489 return (left , top , right - left , bottom - top ) # bounding_box
526490
491+ def _blit (
492+ self ,
493+ bitmap , # target bitmap
494+ x , # target x upper left corner
495+ y , # target y upper left corner
496+ source_bitmap , # source bitmap
497+ x_1 = 0 , # source x start
498+ y_1 = 0 , # source y start
499+ x_2 = None , # source x end
500+ y_2 = None , # source y end
501+ skip_index = None , # palette index that will not be copied
502+ # (for example: the background color of a glyph)
503+ ):
504+
505+ if hasattr (bitmap , "blit" ): # if bitmap has a built-in blit function, call it
506+ # this function should perform its own input checks
507+ bitmap .blit (
508+ x ,
509+ y ,
510+ source_bitmap ,
511+ x1 = x_1 ,
512+ y1 = y_1 ,
513+ x2 = x_2 ,
514+ y2 = y_2 ,
515+ skip_index = skip_index ,
516+ )
517+
518+ else : # perform pixel by pixel copy of the bitmap
519+
520+ # Perform input checks
521+
522+ if x_2 is None :
523+ x_2 = source_bitmap .width
524+ if y_2 is None :
525+ y_2 = source_bitmap .height
526+
527+ # Rearrange so that x_1 < x_2 and y1 < y2
528+ if x_1 > x_2 :
529+ x_1 , x_2 = x_2 , x_1
530+ if y_1 > y_2 :
531+ y_1 , y_2 = y_2 , y_1
532+
533+ # Ensure that x2 and y2 are within source bitmap size
534+ x_2 = min (x_2 , source_bitmap .width )
535+ y_2 = min (y_2 , source_bitmap .height )
536+
537+ for y_count in range (y_2 - y_1 ):
538+ for x_count in range (x_2 - x_1 ):
539+ x_placement = x + x_count
540+ y_placement = y + y_count
541+
542+ if (bitmap .width > x_placement >= 0 ) and (
543+ bitmap .height > y_placement >= 0
544+ ): # ensure placement is within target bitmap
545+
546+ # get the palette index from the source bitmap
547+ this_pixel_color = source_bitmap [
548+ y_1
549+ + (
550+ y_count * source_bitmap .width
551+ ) # Direct index into a bitmap array is speedier than [x,y] tuple
552+ + x_1
553+ + x_count
554+ ]
555+
556+ if (skip_index is None ) or (this_pixel_color != skip_index ):
557+ bitmap [ # Direct index into a bitmap array is speedier than [x,y] tuple
558+ y_placement * bitmap .width + x_placement
559+ ] = this_pixel_color
560+ elif y_placement > bitmap .height :
561+ break
562+
527563 @property
528564 def bounding_box (self ):
529565 """An (x, y, w, h) tuple that completely covers all glyphs. The
@@ -532,7 +568,7 @@ def bounding_box(self):
532568
533569 @property
534570 def scale (self ):
535- """Set the scaling of the label"""
571+ """Set the scaling of the label, in integer values """
536572 return self ._scale
537573
538574 @scale .setter
0 commit comments