diff --git a/Adafruit_GFX/Adafruit_GFX.py b/Adafruit_GFX/Adafruit_GFX.py new file mode 100644 index 00000000..15e267a8 --- /dev/null +++ b/Adafruit_GFX/Adafruit_GFX.py @@ -0,0 +1,400 @@ +#!/usr/bin/python + +#/****************************************************************** +# This is the core graphics library for all our displays, providing +# basic graphics primitives (points, lines, circles, etc.). It needs +# to be paired with a hardware-specific library for each display +# device we carry (handling the lower-level functions). +# Adafruit invests time and resources providing this open +# source code, please support Adafruit and open-source hardware +# by purchasing products from Adafruit! +# Written by Limor Fried/Ladyada for Adafruit Industries. +# BSD license, check license.txt for more information. +# All text above must be included in any redistribution. +# +# Port of library from the C++ library for Arduino +# 6/6/2013 - R Heironimus (cameraready) +#******************************************************************/ + +#import time +from glcdfont import glcdfont + + +class Adafruit_GFX(object): + + def __init__(self, w, h): + self.WIDTH = w + self.HEIGHT = h + self._width = w + self._height = h + + self.rotation = 0 + self.cursor_x = 0 + self.cursor_y = 0 + + self.textsize = 1 + self.textcolor = 0xFFFF + self.textbgcolor = 0xFFFF + + self.wrap = True + self.font = glcdfont().getfont() + + # this must be defined by the subclass + def drawPixel(self, x, y, color): + pass + + def invertDisplay(self, i): + pass + + # bresenham's algorithm - thx wikpedia + def drawLine(self, x0, y0, x1, y1, color=1): + steep = abs(y1 - y0) > abs(x1 - x0) + if (steep): + x0, y0 = self.swap(x0, y0) + x1, y1 = self.swap(x1, y1) + + if (x0 > x1): + x0, x1 = self.swap(x0, x1) + y0, y1 = self.swap(y0, y1) + + dx = x1 - x0 + dy = abs(y1 - y0) + err = dx / 2 + + if (y0 < y1): + ystep = 1 + else: + ystep = -1 + + while (x0 <= x1): + if (steep): + self.drawPixel(y0, x0, color) + else: + self.drawPixel(x0, y0, color) + + err -= dy + if (err < 0): + y0 += ystep + err += dx + + x0 += 1 + + def drawFastVLine(self, x, y, h, color=1): + # stupidest version - update in subclasses if desired! + self.drawLine(x, y, x, y+h-1, color) + + def drawFastHLine(self, x, y, w, color=1): + #stupidest version - update in subclasses if desired! + self.drawLine(x, y, x+w-1, y, color) + + # draw a rectangle + def drawRect(self, x, y, w, h, color=1): + self.drawFastHLine(x, y, w, color) + self.drawFastHLine(x, y+h-1, w, color) + self.drawFastVLine(x, y, h, color) + self.drawFastVLine(x+w-1, y, h, color) + + def fillRect(self, x, y, w, h, color=1): + # stupidest version - update in subclasses if desired! + for i in range(x, x+w): + self.drawFastVLine(i, y, h, color) + + def fillScreen(self, color=1): + self.fillRect(0, 0, self._width, self._height, color) + + # draw a circle outline + def drawCircle(self, x0, y0, r, color=1): + f = 1 - r + ddF_x = 1 + ddF_y = -2 * r + x = 0 + y = r + + self.drawPixel(x0, y0+r, color); + self.drawPixel(x0, y0-r, color); + self.drawPixel(x0+r, y0, color); + self.drawPixel(x0-r, y0, color); + + while (x= 0): + y -= 1 + ddF_y += 2 + f += ddF_y + + x += 1 + ddF_x += 2 + f += ddF_x + + self.drawPixel(x0 + x, y0 + y, color) + self.drawPixel(x0 - x, y0 + y, color) + self.drawPixel(x0 + x, y0 - y, color) + self.drawPixel(x0 - x, y0 - y, color) + self.drawPixel(x0 + y, y0 + x, color) + self.drawPixel(x0 - y, y0 + x, color) + self.drawPixel(x0 + y, y0 - x, color) + self.drawPixel(x0 - y, y0 - x, color) + + def drawCircleHelper(self, x0, y0, r, cornername, color=1): + f = 1 - r + ddF_x = 1 + ddF_y = -2 * r + x = 0 + y = r + + while (x= 0): + y -= 1 + ddF_y += 2 + f += ddF_y + + x += 1 + ddF_x += 2 + f += ddF_x + if (cornername & 0x4): + self.drawPixel(x0 + x, y0 + y, color) + self.drawPixel(x0 + y, y0 + x, color) + + if (cornername & 0x2): + self.drawPixel(x0 + x, y0 - y, color) + self.drawPixel(x0 + y, y0 - x, color) + + if (cornername & 0x8): + self.drawPixel(x0 - y, y0 + x, color) + self.drawPixel(x0 - x, y0 + y, color) + + if (cornername & 0x1): + self.drawPixel(x0 - y, y0 - x, color) + self.drawPixel(x0 - x, y0 - y, color) + + def fillCircle(self, x0, y0, r, color=1): + self.drawFastVLine(x0, y0-r, 2*r+1, color) + self.fillCircleHelper(x0, y0, r, 3, 0, color) + + # used to do circles and roundrects! + def fillCircleHelper(self, x0, y0, r, cornername, delta, color=1): + f = 1 - r + ddF_x = 1 + ddF_y = -2 * r + x = 0 + y = r + + while (x= 0): + y -= 1 + ddF_y += 2 + f += ddF_y + + x += 1 + ddF_x += 2 + f += ddF_x + + if (cornername & 0x1): + self.drawFastVLine(x0+x, y0-y, 2*y+1+delta, color) + self.drawFastVLine(x0+y, y0-x, 2*x+1+delta, color) + + if (cornername & 0x2): + self.drawFastVLine(x0-x, y0-y, 2*y+1+delta, color) + self.drawFastVLine(x0-y, y0-x, 2*x+1+delta, color) + + # Draw a triangle! + def drawTriangle(self, x0, y0, x1, y1, x2, y2, color=1): + self.drawLine(x0, y0, x1, y1, color) + self.drawLine(x1, y1, x2, y2, color) + self.drawLine(x2, y2, x0, y0, color) + + # fill a triangle! + def fillTriangle(self, x0, y0, x1, y1, x2, y2, color=1): + # Sort coordinates by Y order (y2 >= y1 >= y0) + if (y0 > y1): + y0, y1 = self.swap(y0, y1) + x0, x1 = self.swap(x0, x1) + + if (y1 > y2): + y2, y1 = self.swap(y2, y1) + x2, x1 = self.swap(x2, x1) + + if (y0 > y1): + y0, y1 = self.swap(y0, y1) + x0, x1 = self.swap(x0, x1) + + if(y0 == y2): # Handle awkward all-on-same-line case as its own thing + a = x0 + b = x0 + if(x1 < a): + a = x1 + elif(x1 > b): + b = x1 + if(x2 < a): + a = x2 + elif(x2 > b): + b = x2 + self.drawFastHLine(a, y0, b-a+1, color) + return + + dx01 = x1 - x0 + dy01 = y1 - y0 + dx02 = x2 - x0 + dy02 = y2 - y0 + dx12 = x2 - x1 + dy12 = y2 - y1 + sa = 0 + sb = 0 + + # For upper part of triangle, find scanline crossings for segments + # 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 + # is included here (and second loop will be skipped, avoiding a /0 + # error there), otherwise scanline y1 is skipped here and handled + # in the second loop...which also avoids a /0 error here if y0=y1 + # (flat-topped triangle). + if(y1 == y2): # true + last = y1 # Include y1 scanline + else: + last = y1-1 # Skip it + + y = y0 + for y in range(y0, last+1): # 0, 8 (not skipped) + a = x0 + sa / dy01 + b = x0 + sb / dy02 + sa += dx01 + sb += dx02 + #/* longhand: + #a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); + #b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); + #*/ + if(a > b): + a,b = self.swap(a,b) + self.drawFastHLine(a, y, b-a+1, color) + + y += 1 # added this line since python for loops don't increment the variable on the last pass - RH + # For lower part of triangle, find scanline crossings for segments + # 0-2 and 1-2. This loop is skipped if y1=y2. + sa = dx12 * (y - y1) + sb = dx02 * (y - y0) + for y in range(y,y2+1): + a = x1 + sa / dy12 + b = x0 + sb / dy02 + sa += dx12 + sb += dx02 + #/* longhand: + #a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); + #b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); + #*/ + if(a > b): + a,b = self.swap(a,b) + self.drawFastHLine(a, y, b-a+1, color) + + # draw a rounded rectangle! + def drawRoundRect(self, x, y, w, h, r, color=1): + # smarter version + self.drawFastHLine(x+r , y , w-2*r, color) # Top + self.drawFastHLine(x+r , y+h-1, w-2*r, color) # Bottom + self.drawFastVLine( x , y+r , h-2*r, color) # Left + self.drawFastVLine( x+w-1, y+r , h-2*r, color) # Right + # draw four corners + self.drawCircleHelper(x+r , y+r , r, 1, color) + self.drawCircleHelper(x+w-r-1, y+r , r, 2, color) + self.drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color) + self.drawCircleHelper(x+r , y+h-r-1, r, 8, color) + + # fill a rounded rectangle! + def fillRoundRect(self, x, y, w, h, r, color=1): + # smarter version + self.fillRect(x+r, y, w-2*r, h, color) + + # draw four corners + self.fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color) + self.fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color) + + #def drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color): + + def write(self, c): + if (c == '\n'): + self.cursor_y += textsize*8 + self.cursor_x = 0 + elif (c == '\r'): + pass # skip em + else: + self.drawChar(self.cursor_x, self.cursor_y, c, self.textcolor, self.textbgcolor, self.textsize) + self.cursor_x += self.textsize*6 + if (self.wrap and (self.cursor_x > (self._width - self.textsize*6))): + self.cursor_y += self.textsize*8 + self.cursor_x = 0 + + # self.draw a character + def drawChar(self, x, y, c, color, bg, size): + if ((x >= self._width) or # Clip right \ + (y >= self._height) or # Clip bottom + ((x + 5 * size - 1) < 0) or # Clip left + ((y + 8 * size - 1) < 0)): # Clip top + return + + for i in range(0,6): #(i=0; i<6; i+=1) + if (i == 5): + line = 0x0 + else: + line = self.font[(ord(c)*5)+i] #pgm_read_byte(font+(c*5)+i) + for j in range(0,8): #(j = 0; j<8; j+=1) + if (line & 0x1): + if (size == 1): # default size + self.drawPixel(x+i, y+j, color) + else: # big size + self.fillRect(x+(i*size), y+(j*size), size, size, color) + elif (bg != color): + if (size == 1): # default size + self.drawPixel(x+i, y+j, bg) + else: # big size + self.fillRect(x+i*size, y+j*size, size, size, bg) + line >>= 1 + + def setCursor(self, x, y): + self.cursor_x = x + self.cursor_y = y + + def getCursor(self): + return ('' + str(self.cursor_x) + ',' + str(self.cursor_y)) + + def setTextSize(self, s): + if s > 0: + self.textsize = s + else: + self.textsize = 1 + + def getTextSize(self): + return self.textsize + + def setTextColor(self, c): + self.textcolor = c + self.textbgcolor = c + # for 'transparent' background, we'll set the bg + # to the same as fg instead of using a flag + + def setTextColor(self, c, b=None): + self.textcolor = c + self.textbgcolor = b + + def setTextWrap(self, w): + self.wrap = w + + def getRotation(self): + self.rotation %= 4 + return self.rotation + + def setRotation(self, x): + x %= 4 # cant be higher than 3 + self.rotation = x + if x == 0 or x == 2: + self._width = self.WIDTH + self._height = self.HEIGHT + elif x == 1 or x == 3: + self._width = self.HEIGHT + self._height = self.WIDTH + else: + return + + # return the size of the display which depends on the rotation! + def width(self): + return self._width + + def height(self): + return self._height + \ No newline at end of file diff --git a/Adafruit_LEDBackpack/Adafruit_8x8.py b/Adafruit_LEDBackpack/Adafruit_8x8.py index df966dc9..f1446d79 100644 --- a/Adafruit_LEDBackpack/Adafruit_8x8.py +++ b/Adafruit_LEDBackpack/Adafruit_8x8.py @@ -1,55 +1,80 @@ #!/usr/bin/python +# Updated to allow for scrolling text with the Adafruit_GFX.py library +# ColorEightByEight not updated yet. -import time -import datetime from Adafruit_LEDBackpack import LEDBackpack # =========================================================================== # 8x8 Pixel Display # =========================================================================== -class EightByEight: - disp = None +class EightByEight(LEDBackpack): + #disp = None + rotation = None # Constructor def __init__(self, address=0x70, debug=False): if (debug): print "Initializing a new instance of LEDBackpack at 0x%02X" % address - self.disp = LEDBackpack(address=address, debug=debug) + LEDBackpack.__init__(self, 8, 8, address, debug) + self.rotation = 0 def writeRowRaw(self, charNumber, value): - "Sets a row of pixels using a raw 16-bit value" + #"Sets a row of pixels using a raw 16-bit value" if (charNumber > 7): return # Set the appropriate row - self.disp.setBufferRow(charNumber, value) + self.setBufferRow(charNumber, value) def clearPixel(self, x, y): - "A wrapper function to clear pixels (purely cosmetic)" + #"A wrapper function to clear pixels (purely cosmetic)" self.setPixel(x, y, 0) - def setPixel(self, x, y, color=1): - "Sets a single pixel" - if (x >= 8): + def drawPixel(self, x, y, color=1): + #"Sets a single pixel" + if ((y < 0) or (y >= 8)): return - if (y >= 8): + if ((x < 0) or (x >= 8)): return + + # Added rotation code 4/16/13 - RH + if self.rotation == 1: + x, y = self.swap(x, y) + x = 8 - x - 1 + elif self.rotation == 2: + x = 8 - x - 1 + y = 8 - y - 1 + elif self.rotation == 3: + x, y = self.swap(x, y) + y = 8 - y - 1 + x += 7 # ATTN: This might be a bug? On the color matrix, this causes x=0 to draw on the last line instead of the first. x %= 8 # Set the appropriate pixel - buffer = self.disp.getBuffer() + buffer = self.getBuffer() if (color): - self.disp.setBufferRow(y, buffer[y] | 1 << x) - else: - self.disp.setBufferRow(y, buffer[y] & ~(1 << x)) + self.setBufferRow(y, buffer[y] | 1 << x, False) # disable update option to determine if writeDisplay() is called when + else: # writing a bunch of pixels. Speeds things up dramatically when scrolling + self.setBufferRow(y, buffer[y] & ~(1 << x), False) # text on multiple matrices. Call writeDisplay() after updating buffer. + + # Used to rotate display 4/16/13 - RH + # Corrected for dual output 6/5/13 - RH + def swap(self, x, y): + temp = x + x = y + y = temp + return (x, y) - def clear(self): - "Clears the entire display" - self.disp.clear() + # Added 6/3/13 - RH + def printMessage(self, text): + for letter in range(0, len(text)): + self.write(text[letter]) + if (self.debug): + print(text[letter]) class ColorEightByEight(EightByEight): def setPixel(self, x, y, color=1): - "Sets a single pixel" + #"Sets a single pixel" if (x >= 8): return if (y >= 8): diff --git a/Adafruit_LEDBackpack/Adafruit_GFX.py b/Adafruit_LEDBackpack/Adafruit_GFX.py new file mode 100644 index 00000000..15e267a8 --- /dev/null +++ b/Adafruit_LEDBackpack/Adafruit_GFX.py @@ -0,0 +1,400 @@ +#!/usr/bin/python + +#/****************************************************************** +# This is the core graphics library for all our displays, providing +# basic graphics primitives (points, lines, circles, etc.). It needs +# to be paired with a hardware-specific library for each display +# device we carry (handling the lower-level functions). +# Adafruit invests time and resources providing this open +# source code, please support Adafruit and open-source hardware +# by purchasing products from Adafruit! +# Written by Limor Fried/Ladyada for Adafruit Industries. +# BSD license, check license.txt for more information. +# All text above must be included in any redistribution. +# +# Port of library from the C++ library for Arduino +# 6/6/2013 - R Heironimus (cameraready) +#******************************************************************/ + +#import time +from glcdfont import glcdfont + + +class Adafruit_GFX(object): + + def __init__(self, w, h): + self.WIDTH = w + self.HEIGHT = h + self._width = w + self._height = h + + self.rotation = 0 + self.cursor_x = 0 + self.cursor_y = 0 + + self.textsize = 1 + self.textcolor = 0xFFFF + self.textbgcolor = 0xFFFF + + self.wrap = True + self.font = glcdfont().getfont() + + # this must be defined by the subclass + def drawPixel(self, x, y, color): + pass + + def invertDisplay(self, i): + pass + + # bresenham's algorithm - thx wikpedia + def drawLine(self, x0, y0, x1, y1, color=1): + steep = abs(y1 - y0) > abs(x1 - x0) + if (steep): + x0, y0 = self.swap(x0, y0) + x1, y1 = self.swap(x1, y1) + + if (x0 > x1): + x0, x1 = self.swap(x0, x1) + y0, y1 = self.swap(y0, y1) + + dx = x1 - x0 + dy = abs(y1 - y0) + err = dx / 2 + + if (y0 < y1): + ystep = 1 + else: + ystep = -1 + + while (x0 <= x1): + if (steep): + self.drawPixel(y0, x0, color) + else: + self.drawPixel(x0, y0, color) + + err -= dy + if (err < 0): + y0 += ystep + err += dx + + x0 += 1 + + def drawFastVLine(self, x, y, h, color=1): + # stupidest version - update in subclasses if desired! + self.drawLine(x, y, x, y+h-1, color) + + def drawFastHLine(self, x, y, w, color=1): + #stupidest version - update in subclasses if desired! + self.drawLine(x, y, x+w-1, y, color) + + # draw a rectangle + def drawRect(self, x, y, w, h, color=1): + self.drawFastHLine(x, y, w, color) + self.drawFastHLine(x, y+h-1, w, color) + self.drawFastVLine(x, y, h, color) + self.drawFastVLine(x+w-1, y, h, color) + + def fillRect(self, x, y, w, h, color=1): + # stupidest version - update in subclasses if desired! + for i in range(x, x+w): + self.drawFastVLine(i, y, h, color) + + def fillScreen(self, color=1): + self.fillRect(0, 0, self._width, self._height, color) + + # draw a circle outline + def drawCircle(self, x0, y0, r, color=1): + f = 1 - r + ddF_x = 1 + ddF_y = -2 * r + x = 0 + y = r + + self.drawPixel(x0, y0+r, color); + self.drawPixel(x0, y0-r, color); + self.drawPixel(x0+r, y0, color); + self.drawPixel(x0-r, y0, color); + + while (x= 0): + y -= 1 + ddF_y += 2 + f += ddF_y + + x += 1 + ddF_x += 2 + f += ddF_x + + self.drawPixel(x0 + x, y0 + y, color) + self.drawPixel(x0 - x, y0 + y, color) + self.drawPixel(x0 + x, y0 - y, color) + self.drawPixel(x0 - x, y0 - y, color) + self.drawPixel(x0 + y, y0 + x, color) + self.drawPixel(x0 - y, y0 + x, color) + self.drawPixel(x0 + y, y0 - x, color) + self.drawPixel(x0 - y, y0 - x, color) + + def drawCircleHelper(self, x0, y0, r, cornername, color=1): + f = 1 - r + ddF_x = 1 + ddF_y = -2 * r + x = 0 + y = r + + while (x= 0): + y -= 1 + ddF_y += 2 + f += ddF_y + + x += 1 + ddF_x += 2 + f += ddF_x + if (cornername & 0x4): + self.drawPixel(x0 + x, y0 + y, color) + self.drawPixel(x0 + y, y0 + x, color) + + if (cornername & 0x2): + self.drawPixel(x0 + x, y0 - y, color) + self.drawPixel(x0 + y, y0 - x, color) + + if (cornername & 0x8): + self.drawPixel(x0 - y, y0 + x, color) + self.drawPixel(x0 - x, y0 + y, color) + + if (cornername & 0x1): + self.drawPixel(x0 - y, y0 - x, color) + self.drawPixel(x0 - x, y0 - y, color) + + def fillCircle(self, x0, y0, r, color=1): + self.drawFastVLine(x0, y0-r, 2*r+1, color) + self.fillCircleHelper(x0, y0, r, 3, 0, color) + + # used to do circles and roundrects! + def fillCircleHelper(self, x0, y0, r, cornername, delta, color=1): + f = 1 - r + ddF_x = 1 + ddF_y = -2 * r + x = 0 + y = r + + while (x= 0): + y -= 1 + ddF_y += 2 + f += ddF_y + + x += 1 + ddF_x += 2 + f += ddF_x + + if (cornername & 0x1): + self.drawFastVLine(x0+x, y0-y, 2*y+1+delta, color) + self.drawFastVLine(x0+y, y0-x, 2*x+1+delta, color) + + if (cornername & 0x2): + self.drawFastVLine(x0-x, y0-y, 2*y+1+delta, color) + self.drawFastVLine(x0-y, y0-x, 2*x+1+delta, color) + + # Draw a triangle! + def drawTriangle(self, x0, y0, x1, y1, x2, y2, color=1): + self.drawLine(x0, y0, x1, y1, color) + self.drawLine(x1, y1, x2, y2, color) + self.drawLine(x2, y2, x0, y0, color) + + # fill a triangle! + def fillTriangle(self, x0, y0, x1, y1, x2, y2, color=1): + # Sort coordinates by Y order (y2 >= y1 >= y0) + if (y0 > y1): + y0, y1 = self.swap(y0, y1) + x0, x1 = self.swap(x0, x1) + + if (y1 > y2): + y2, y1 = self.swap(y2, y1) + x2, x1 = self.swap(x2, x1) + + if (y0 > y1): + y0, y1 = self.swap(y0, y1) + x0, x1 = self.swap(x0, x1) + + if(y0 == y2): # Handle awkward all-on-same-line case as its own thing + a = x0 + b = x0 + if(x1 < a): + a = x1 + elif(x1 > b): + b = x1 + if(x2 < a): + a = x2 + elif(x2 > b): + b = x2 + self.drawFastHLine(a, y0, b-a+1, color) + return + + dx01 = x1 - x0 + dy01 = y1 - y0 + dx02 = x2 - x0 + dy02 = y2 - y0 + dx12 = x2 - x1 + dy12 = y2 - y1 + sa = 0 + sb = 0 + + # For upper part of triangle, find scanline crossings for segments + # 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 + # is included here (and second loop will be skipped, avoiding a /0 + # error there), otherwise scanline y1 is skipped here and handled + # in the second loop...which also avoids a /0 error here if y0=y1 + # (flat-topped triangle). + if(y1 == y2): # true + last = y1 # Include y1 scanline + else: + last = y1-1 # Skip it + + y = y0 + for y in range(y0, last+1): # 0, 8 (not skipped) + a = x0 + sa / dy01 + b = x0 + sb / dy02 + sa += dx01 + sb += dx02 + #/* longhand: + #a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); + #b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); + #*/ + if(a > b): + a,b = self.swap(a,b) + self.drawFastHLine(a, y, b-a+1, color) + + y += 1 # added this line since python for loops don't increment the variable on the last pass - RH + # For lower part of triangle, find scanline crossings for segments + # 0-2 and 1-2. This loop is skipped if y1=y2. + sa = dx12 * (y - y1) + sb = dx02 * (y - y0) + for y in range(y,y2+1): + a = x1 + sa / dy12 + b = x0 + sb / dy02 + sa += dx12 + sb += dx02 + #/* longhand: + #a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); + #b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); + #*/ + if(a > b): + a,b = self.swap(a,b) + self.drawFastHLine(a, y, b-a+1, color) + + # draw a rounded rectangle! + def drawRoundRect(self, x, y, w, h, r, color=1): + # smarter version + self.drawFastHLine(x+r , y , w-2*r, color) # Top + self.drawFastHLine(x+r , y+h-1, w-2*r, color) # Bottom + self.drawFastVLine( x , y+r , h-2*r, color) # Left + self.drawFastVLine( x+w-1, y+r , h-2*r, color) # Right + # draw four corners + self.drawCircleHelper(x+r , y+r , r, 1, color) + self.drawCircleHelper(x+w-r-1, y+r , r, 2, color) + self.drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color) + self.drawCircleHelper(x+r , y+h-r-1, r, 8, color) + + # fill a rounded rectangle! + def fillRoundRect(self, x, y, w, h, r, color=1): + # smarter version + self.fillRect(x+r, y, w-2*r, h, color) + + # draw four corners + self.fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color) + self.fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color) + + #def drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color): + + def write(self, c): + if (c == '\n'): + self.cursor_y += textsize*8 + self.cursor_x = 0 + elif (c == '\r'): + pass # skip em + else: + self.drawChar(self.cursor_x, self.cursor_y, c, self.textcolor, self.textbgcolor, self.textsize) + self.cursor_x += self.textsize*6 + if (self.wrap and (self.cursor_x > (self._width - self.textsize*6))): + self.cursor_y += self.textsize*8 + self.cursor_x = 0 + + # self.draw a character + def drawChar(self, x, y, c, color, bg, size): + if ((x >= self._width) or # Clip right \ + (y >= self._height) or # Clip bottom + ((x + 5 * size - 1) < 0) or # Clip left + ((y + 8 * size - 1) < 0)): # Clip top + return + + for i in range(0,6): #(i=0; i<6; i+=1) + if (i == 5): + line = 0x0 + else: + line = self.font[(ord(c)*5)+i] #pgm_read_byte(font+(c*5)+i) + for j in range(0,8): #(j = 0; j<8; j+=1) + if (line & 0x1): + if (size == 1): # default size + self.drawPixel(x+i, y+j, color) + else: # big size + self.fillRect(x+(i*size), y+(j*size), size, size, color) + elif (bg != color): + if (size == 1): # default size + self.drawPixel(x+i, y+j, bg) + else: # big size + self.fillRect(x+i*size, y+j*size, size, size, bg) + line >>= 1 + + def setCursor(self, x, y): + self.cursor_x = x + self.cursor_y = y + + def getCursor(self): + return ('' + str(self.cursor_x) + ',' + str(self.cursor_y)) + + def setTextSize(self, s): + if s > 0: + self.textsize = s + else: + self.textsize = 1 + + def getTextSize(self): + return self.textsize + + def setTextColor(self, c): + self.textcolor = c + self.textbgcolor = c + # for 'transparent' background, we'll set the bg + # to the same as fg instead of using a flag + + def setTextColor(self, c, b=None): + self.textcolor = c + self.textbgcolor = b + + def setTextWrap(self, w): + self.wrap = w + + def getRotation(self): + self.rotation %= 4 + return self.rotation + + def setRotation(self, x): + x %= 4 # cant be higher than 3 + self.rotation = x + if x == 0 or x == 2: + self._width = self.WIDTH + self._height = self.HEIGHT + elif x == 1 or x == 3: + self._width = self.HEIGHT + self._height = self.WIDTH + else: + return + + # return the size of the display which depends on the rotation! + def width(self): + return self._width + + def height(self): + return self._height + \ No newline at end of file diff --git a/Adafruit_LEDBackpack/Adafruit_LEDBackpack.py b/Adafruit_LEDBackpack/Adafruit_LEDBackpack.py index a0c58295..f7a11fd6 100644 --- a/Adafruit_LEDBackpack/Adafruit_LEDBackpack.py +++ b/Adafruit_LEDBackpack/Adafruit_LEDBackpack.py @@ -1,14 +1,15 @@ #!/usr/bin/python +# Updated to support the Adafruit_GFX library -import time from copy import copy from Adafruit_I2C import Adafruit_I2C +from Adafruit_GFX import Adafruit_GFX # ============================================================================ # LEDBackpack Class # ============================================================================ -class LEDBackpack: +class LEDBackpack(Adafruit_GFX): i2c = None # Registers @@ -27,7 +28,8 @@ class LEDBackpack: 0x0000, 0x0000, 0x0000, 0x0000 ] # Constructor - def __init__(self, address=0x70, debug=False): + def __init__(self, w, h, address=0x70, debug=False): + Adafruit_GFX.__init__(self, w, h) self.i2c = Adafruit_I2C(address) self.address = address self.debug = debug @@ -83,5 +85,5 @@ def clear(self, update=True): if (update): self.writeDisplay() -led = LEDBackpack(0x70) +led = LEDBackpack(8,8,0x70) diff --git a/Adafruit_LEDBackpack/ex_8x8_GFX_Debug.py b/Adafruit_LEDBackpack/ex_8x8_GFX_Debug.py new file mode 100644 index 00000000..b619c6e2 --- /dev/null +++ b/Adafruit_LEDBackpack/ex_8x8_GFX_Debug.py @@ -0,0 +1,119 @@ +#!/usr/bin/python +# A bunch of random tests for drawing GFX on the matrices + +import time +from glcdfont import glcdfont +from Adafruit_8x8 import EightByEight + +grid1 = EightByEight(address=0x70) +grid2 = EightByEight(address=0x71) +grid3 = EightByEight(address=0x72) +grid1.setBrightness(8) +grid2.setBrightness(8) +grid3.setBrightness(8) +font = glcdfont().getfont() + +#print(font) +grid1.fillScreen() +grid1.writeDisplay() +time.sleep(.25) +grid1.clear() + +grid2.fillScreen() +grid2.writeDisplay() +time.sleep(.25) +grid2.clear() + +grid3.fillScreen() +grid3.writeDisplay() +time.sleep(.25) +grid3.clear() + +for i in range (0, 24): + grid1.drawLine(7,7-i,0,-16+i) + grid2.drawLine(7,15-i,0,-8+i) + grid3.drawLine(7,23-i,0,0+i) + grid1.writeDisplay() + grid2.writeDisplay() + grid3.writeDisplay() + time.sleep(.05) + grid1.clear() + grid2.clear() + grid3.clear() + +for i in range (0, 16, 2): + grid1.drawCircle(4,4-8,i+1) + grid2.drawCircle(4,4,i+1) + grid3.drawCircle(4,4+8,i+1) + grid1.writeDisplay() + grid2.writeDisplay() + grid3.writeDisplay() + time.sleep(.05) +grid1.clear() +grid2.clear() +grid3.clear() + +for i in range (0,8): + grid1.drawCircle(4,4,i+1) + grid2.fillCircle(4,4,i+1) + grid3.drawPixel(i,0) + grid1.writeDisplay() + grid2.writeDisplay() + grid3.writeDisplay() + time.sleep(.05) + grid1.clear() + grid2.clear() + grid3.clear() + +for i in range (0,8): + grid1.drawPixel(0,i) + grid2.drawTriangle(0,0,7,i,0,7) + grid3.fillTriangle(7,7,0,i,7,0) + grid1.writeDisplay() + grid2.writeDisplay() + grid3.writeDisplay() + time.sleep(.05) + grid1.clear() + grid2.clear() + grid3.clear() + + +grid1.drawRoundRect(0,0,7,7,2) +grid2.fillRoundRect(0,0,8,8,2) +grid1.writeDisplay() +grid2.writeDisplay() +time.sleep(.5) +grid2.clear() +grid1.clear() + +for i in range (1,9): + grid2.drawRect(0,0,i,i) + grid2.writeDisplay() + time.sleep(.05) + grid2.clear() + +for i in range (1,9): + grid3.fillRect(0,0,i,i) + grid3.writeDisplay() + time.sleep(.05) + grid3.clear() + +while True: + #binary = 0b10101010 + #for k in range(0,8): + #print('binary = ' + str(bin(binary))) + #binary >>= 1 + #time.sleep(.01) + + for i in range(0,255,3): + #for i in range(0,10): + for j in range(0,5): + #print "printing i: " + str(i) + " j: " + str(j) + " char(i+j): " + str(i*5+j) + " " + bin(font[i*5+j]) + grid1.writeRowRaw(5-j, font[i*5+j]) + grid2.writeRowRaw(5-j, font[(i+1)*5+j]) + grid3.writeRowRaw(5-j, font[(i+2)*5+j]) + #print "Buffer: " + str(i) + "-" + str(j) + " " + str(bin(font[i*5+j])) + #grid.writeRowRaw(j, font[i*5+j]) + #print "Buffer: " + str(i) + "-" + str(j) + " " + str(bin(font[i*5+j])) + time.sleep(.25) + #grid.clear() \ No newline at end of file diff --git a/Adafruit_LEDBackpack/ex_8x8_Scroll_Text.py b/Adafruit_LEDBackpack/ex_8x8_Scroll_Text.py new file mode 100644 index 00000000..49bf1904 --- /dev/null +++ b/Adafruit_LEDBackpack/ex_8x8_Scroll_Text.py @@ -0,0 +1,45 @@ +#!/usr/bin/python +# Example code to test scrolling text across multiple 8x8 matrices. +# WARNING! Make sure to use a level shifter between the Raspberry Pi +# and matrices running at 5v to avoid overpowering the Pi. + +import time +from Adafruit_8x8 import EightByEight + +MATRICES = 3 +matrix = [] + +for i in range(0,MATRICES): + matrix.append(EightByEight(address=0x70+i)) + matrix[i].setTextWrap(False) # Allow text to run off edges + matrix[i].setRotation(3) + matrix[i].setBrightness(4) + matrix[i].setTextSize(1) + +#message = 'Hello World!!!' +message = '<-= Scrolling Text now with Python & Raspberry Pi! =->' + +# Horiz. position of text -- starts off right edge +x = 8 * MATRICES + +while True: + for i in range(0,MATRICES): + # Draw message in each matrix buffer, offseting each by 8 pixels + matrix[i].clear() + matrix[i].setCursor(x - i * 8, 0) + matrix[i].printMessage(message) + + # Write data to matrices in separate loop so it's less jumpy + for i in range(0,MATRICES): + matrix[i].writeDisplay() + + #print('Test') + + # Move text position left by 1 pixel. + # When it's completely gone off left edge, start over off right. + length = len(message) * 6 * matrix[i].getTextSize() + x -= 1 + if(x < -(length)): + x = 8 * MATRICES + + time.sleep(.025) \ No newline at end of file diff --git a/Adafruit_LEDBackpack/glcdfont.py b/Adafruit_LEDBackpack/glcdfont.py new file mode 100644 index 00000000..03046f4f --- /dev/null +++ b/Adafruit_LEDBackpack/glcdfont.py @@ -0,0 +1,265 @@ +#!/usr/bin/python + +#standard ascii 5x7 font +class glcdfont(object): + + def __init__(self): + self.font = [ \ + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, + 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, + 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, + 0x18, 0x3C, 0x7E, 0x3C, 0x18, + 0x1C, 0x57, 0x7D, 0x57, 0x1C, + 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, + 0x00, 0x18, 0x3C, 0x18, 0x00, + 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, + 0x00, 0x18, 0x24, 0x18, 0x00, + 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, + 0x30, 0x48, 0x3A, 0x06, 0x0E, + 0x26, 0x29, 0x79, 0x29, 0x26, + 0x40, 0x7F, 0x05, 0x05, 0x07, + 0x40, 0x7F, 0x05, 0x25, 0x3F, + 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, + 0x7F, 0x3E, 0x1C, 0x1C, 0x08, + 0x08, 0x1C, 0x1C, 0x3E, 0x7F, + 0x14, 0x22, 0x7F, 0x22, 0x14, + 0x5F, 0x5F, 0x00, 0x5F, 0x5F, + 0x06, 0x09, 0x7F, 0x01, 0x7F, + 0x00, 0x66, 0x89, 0x95, 0x6A, + 0x60, 0x60, 0x60, 0x60, 0x60, + 0x94, 0xA2, 0xFF, 0xA2, 0x94, + 0x08, 0x04, 0x7E, 0x04, 0x08, + 0x10, 0x20, 0x7E, 0x20, 0x10, + 0x08, 0x08, 0x2A, 0x1C, 0x08, + 0x08, 0x1C, 0x2A, 0x08, 0x08, + 0x1E, 0x10, 0x10, 0x10, 0x10, + 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, + 0x30, 0x38, 0x3E, 0x38, 0x30, + 0x06, 0x0E, 0x3E, 0x0E, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x5F, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x07, 0x00, + 0x14, 0x7F, 0x14, 0x7F, 0x14, + 0x24, 0x2A, 0x7F, 0x2A, 0x12, + 0x23, 0x13, 0x08, 0x64, 0x62, + 0x36, 0x49, 0x56, 0x20, 0x50, + 0x00, 0x08, 0x07, 0x03, 0x00, + 0x00, 0x1C, 0x22, 0x41, 0x00, + 0x00, 0x41, 0x22, 0x1C, 0x00, + 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, + 0x08, 0x08, 0x3E, 0x08, 0x08, + 0x00, 0x80, 0x70, 0x30, 0x00, + 0x08, 0x08, 0x08, 0x08, 0x08, + 0x00, 0x00, 0x60, 0x60, 0x00, + 0x20, 0x10, 0x08, 0x04, 0x02, + 0x3E, 0x51, 0x49, 0x45, 0x3E, + 0x00, 0x42, 0x7F, 0x40, 0x00, + 0x72, 0x49, 0x49, 0x49, 0x46, + 0x21, 0x41, 0x49, 0x4D, 0x33, + 0x18, 0x14, 0x12, 0x7F, 0x10, + 0x27, 0x45, 0x45, 0x45, 0x39, + 0x3C, 0x4A, 0x49, 0x49, 0x31, + 0x41, 0x21, 0x11, 0x09, 0x07, + 0x36, 0x49, 0x49, 0x49, 0x36, + 0x46, 0x49, 0x49, 0x29, 0x1E, + 0x00, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x40, 0x34, 0x00, 0x00, + 0x00, 0x08, 0x14, 0x22, 0x41, + 0x14, 0x14, 0x14, 0x14, 0x14, + 0x00, 0x41, 0x22, 0x14, 0x08, + 0x02, 0x01, 0x59, 0x09, 0x06, + 0x3E, 0x41, 0x5D, 0x59, 0x4E, + 0x7C, 0x12, 0x11, 0x12, 0x7C, + 0x7F, 0x49, 0x49, 0x49, 0x36, + 0x3E, 0x41, 0x41, 0x41, 0x22, + 0x7F, 0x41, 0x41, 0x41, 0x3E, + 0x7F, 0x49, 0x49, 0x49, 0x41, + 0x7F, 0x09, 0x09, 0x09, 0x01, + 0x3E, 0x41, 0x41, 0x51, 0x73, + 0x7F, 0x08, 0x08, 0x08, 0x7F, + 0x00, 0x41, 0x7F, 0x41, 0x00, + 0x20, 0x40, 0x41, 0x3F, 0x01, + 0x7F, 0x08, 0x14, 0x22, 0x41, + 0x7F, 0x40, 0x40, 0x40, 0x40, + 0x7F, 0x02, 0x1C, 0x02, 0x7F, + 0x7F, 0x04, 0x08, 0x10, 0x7F, + 0x3E, 0x41, 0x41, 0x41, 0x3E, + 0x7F, 0x09, 0x09, 0x09, 0x06, + 0x3E, 0x41, 0x51, 0x21, 0x5E, + 0x7F, 0x09, 0x19, 0x29, 0x46, + 0x26, 0x49, 0x49, 0x49, 0x32, + 0x03, 0x01, 0x7F, 0x01, 0x03, + 0x3F, 0x40, 0x40, 0x40, 0x3F, + 0x1F, 0x20, 0x40, 0x20, 0x1F, + 0x3F, 0x40, 0x38, 0x40, 0x3F, + 0x63, 0x14, 0x08, 0x14, 0x63, + 0x03, 0x04, 0x78, 0x04, 0x03, + 0x61, 0x59, 0x49, 0x4D, 0x43, + 0x00, 0x7F, 0x41, 0x41, 0x41, + 0x02, 0x04, 0x08, 0x10, 0x20, + 0x00, 0x41, 0x41, 0x41, 0x7F, + 0x04, 0x02, 0x01, 0x02, 0x04, + 0x40, 0x40, 0x40, 0x40, 0x40, + 0x00, 0x03, 0x07, 0x08, 0x00, + 0x20, 0x54, 0x54, 0x78, 0x40, + 0x7F, 0x28, 0x44, 0x44, 0x38, + 0x38, 0x44, 0x44, 0x44, 0x28, + 0x38, 0x44, 0x44, 0x28, 0x7F, + 0x38, 0x54, 0x54, 0x54, 0x18, + 0x00, 0x08, 0x7E, 0x09, 0x02, + 0x18, 0xA4, 0xA4, 0x9C, 0x78, + 0x7F, 0x08, 0x04, 0x04, 0x78, + 0x00, 0x44, 0x7D, 0x40, 0x00, + 0x20, 0x40, 0x40, 0x3D, 0x00, + 0x7F, 0x10, 0x28, 0x44, 0x00, + 0x00, 0x41, 0x7F, 0x40, 0x00, + 0x7C, 0x04, 0x78, 0x04, 0x78, + 0x7C, 0x08, 0x04, 0x04, 0x78, + 0x38, 0x44, 0x44, 0x44, 0x38, + 0xFC, 0x18, 0x24, 0x24, 0x18, + 0x18, 0x24, 0x24, 0x18, 0xFC, + 0x7C, 0x08, 0x04, 0x04, 0x08, + 0x48, 0x54, 0x54, 0x54, 0x24, + 0x04, 0x04, 0x3F, 0x44, 0x24, + 0x3C, 0x40, 0x40, 0x20, 0x7C, + 0x1C, 0x20, 0x40, 0x20, 0x1C, + 0x3C, 0x40, 0x30, 0x40, 0x3C, + 0x44, 0x28, 0x10, 0x28, 0x44, + 0x4C, 0x90, 0x90, 0x90, 0x7C, + 0x44, 0x64, 0x54, 0x4C, 0x44, + 0x00, 0x08, 0x36, 0x41, 0x00, + 0x00, 0x00, 0x77, 0x00, 0x00, + 0x00, 0x41, 0x36, 0x08, 0x00, + 0x02, 0x01, 0x02, 0x04, 0x02, + 0x3C, 0x26, 0x23, 0x26, 0x3C, + 0x1E, 0xA1, 0xA1, 0x61, 0x12, + 0x3A, 0x40, 0x40, 0x20, 0x7A, + 0x38, 0x54, 0x54, 0x55, 0x59, + 0x21, 0x55, 0x55, 0x79, 0x41, + 0x21, 0x54, 0x54, 0x78, 0x41, + 0x21, 0x55, 0x54, 0x78, 0x40, + 0x20, 0x54, 0x55, 0x79, 0x40, + 0x0C, 0x1E, 0x52, 0x72, 0x12, + 0x39, 0x55, 0x55, 0x55, 0x59, + 0x39, 0x54, 0x54, 0x54, 0x59, + 0x39, 0x55, 0x54, 0x54, 0x58, + 0x00, 0x00, 0x45, 0x7C, 0x41, + 0x00, 0x02, 0x45, 0x7D, 0x42, + 0x00, 0x01, 0x45, 0x7C, 0x40, + 0xF0, 0x29, 0x24, 0x29, 0xF0, + 0xF0, 0x28, 0x25, 0x28, 0xF0, + 0x7C, 0x54, 0x55, 0x45, 0x00, + 0x20, 0x54, 0x54, 0x7C, 0x54, + 0x7C, 0x0A, 0x09, 0x7F, 0x49, + 0x32, 0x49, 0x49, 0x49, 0x32, + 0x32, 0x48, 0x48, 0x48, 0x32, + 0x32, 0x4A, 0x48, 0x48, 0x30, + 0x3A, 0x41, 0x41, 0x21, 0x7A, + 0x3A, 0x42, 0x40, 0x20, 0x78, + 0x00, 0x9D, 0xA0, 0xA0, 0x7D, + 0x39, 0x44, 0x44, 0x44, 0x39, + 0x3D, 0x40, 0x40, 0x40, 0x3D, + 0x3C, 0x24, 0xFF, 0x24, 0x24, + 0x48, 0x7E, 0x49, 0x43, 0x66, + 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, + 0xFF, 0x09, 0x29, 0xF6, 0x20, + 0xC0, 0x88, 0x7E, 0x09, 0x03, + 0x20, 0x54, 0x54, 0x79, 0x41, + 0x00, 0x00, 0x44, 0x7D, 0x41, + 0x30, 0x48, 0x48, 0x4A, 0x32, + 0x38, 0x40, 0x40, 0x22, 0x7A, + 0x00, 0x7A, 0x0A, 0x0A, 0x72, + 0x7D, 0x0D, 0x19, 0x31, 0x7D, + 0x26, 0x29, 0x29, 0x2F, 0x28, + 0x26, 0x29, 0x29, 0x29, 0x26, + 0x30, 0x48, 0x4D, 0x40, 0x20, + 0x38, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x38, + 0x2F, 0x10, 0xC8, 0xAC, 0xBA, + 0x2F, 0x10, 0x28, 0x34, 0xFA, + 0x00, 0x00, 0x7B, 0x00, 0x00, + 0x08, 0x14, 0x2A, 0x14, 0x22, + 0x22, 0x14, 0x2A, 0x14, 0x08, + 0xAA, 0x00, 0x55, 0x00, 0xAA, + 0xAA, 0x55, 0xAA, 0x55, 0xAA, + 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x10, 0x10, 0x10, 0xFF, 0x00, + 0x14, 0x14, 0x14, 0xFF, 0x00, + 0x10, 0x10, 0xFF, 0x00, 0xFF, + 0x10, 0x10, 0xF0, 0x10, 0xF0, + 0x14, 0x14, 0x14, 0xFC, 0x00, + 0x14, 0x14, 0xF7, 0x00, 0xFF, + 0x00, 0x00, 0xFF, 0x00, 0xFF, + 0x14, 0x14, 0xF4, 0x04, 0xFC, + 0x14, 0x14, 0x17, 0x10, 0x1F, + 0x10, 0x10, 0x1F, 0x10, 0x1F, + 0x14, 0x14, 0x14, 0x1F, 0x00, + 0x10, 0x10, 0x10, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0x10, + 0x10, 0x10, 0x10, 0x1F, 0x10, + 0x10, 0x10, 0x10, 0xF0, 0x10, + 0x00, 0x00, 0x00, 0xFF, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0xFF, 0x10, + 0x00, 0x00, 0x00, 0xFF, 0x14, + 0x00, 0x00, 0xFF, 0x00, 0xFF, + 0x00, 0x00, 0x1F, 0x10, 0x17, + 0x00, 0x00, 0xFC, 0x04, 0xF4, + 0x14, 0x14, 0x17, 0x10, 0x17, + 0x14, 0x14, 0xF4, 0x04, 0xF4, + 0x00, 0x00, 0xFF, 0x00, 0xF7, + 0x14, 0x14, 0x14, 0x14, 0x14, + 0x14, 0x14, 0xF7, 0x00, 0xF7, + 0x14, 0x14, 0x14, 0x17, 0x14, + 0x10, 0x10, 0x1F, 0x10, 0x1F, + 0x14, 0x14, 0x14, 0xF4, 0x14, + 0x10, 0x10, 0xF0, 0x10, 0xF0, + 0x00, 0x00, 0x1F, 0x10, 0x1F, + 0x00, 0x00, 0x00, 0x1F, 0x14, + 0x00, 0x00, 0x00, 0xFC, 0x14, + 0x00, 0x00, 0xF0, 0x10, 0xF0, + 0x10, 0x10, 0xFF, 0x10, 0xFF, + 0x14, 0x14, 0x14, 0xFF, 0x14, + 0x10, 0x10, 0x10, 0x1F, 0x00, + 0x00, 0x00, 0x00, 0xF0, 0x10, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x38, 0x44, 0x44, 0x38, 0x44, + 0x7C, 0x2A, 0x2A, 0x3E, 0x14, + 0x7E, 0x02, 0x02, 0x06, 0x06, + 0x02, 0x7E, 0x02, 0x7E, 0x02, + 0x63, 0x55, 0x49, 0x41, 0x63, + 0x38, 0x44, 0x44, 0x3C, 0x04, + 0x40, 0x7E, 0x20, 0x1E, 0x20, + 0x06, 0x02, 0x7E, 0x02, 0x02, + 0x99, 0xA5, 0xE7, 0xA5, 0x99, + 0x1C, 0x2A, 0x49, 0x2A, 0x1C, + 0x4C, 0x72, 0x01, 0x72, 0x4C, + 0x30, 0x4A, 0x4D, 0x4D, 0x30, + 0x30, 0x48, 0x78, 0x48, 0x30, + 0xBC, 0x62, 0x5A, 0x46, 0x3D, + 0x3E, 0x49, 0x49, 0x49, 0x00, + 0x7E, 0x01, 0x01, 0x01, 0x7E, + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, + 0x44, 0x44, 0x5F, 0x44, 0x44, + 0x40, 0x51, 0x4A, 0x44, 0x40, + 0x40, 0x44, 0x4A, 0x51, 0x40, + 0x00, 0x00, 0xFF, 0x01, 0x03, + 0xE0, 0x80, 0xFF, 0x00, 0x00, + 0x08, 0x08, 0x6B, 0x6B, 0x08, + 0x36, 0x12, 0x36, 0x24, 0x36, + 0x06, 0x0F, 0x09, 0x0F, 0x06, + 0x00, 0x00, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x10, 0x10, 0x00, + 0x30, 0x40, 0xFF, 0x01, 0x01, + 0x00, 0x1F, 0x01, 0x01, 0x1E, + 0x00, 0x19, 0x1D, 0x17, 0x12, + 0x00, 0x3C, 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00] + + def getfont(self): + return self.font \ No newline at end of file