Skip to content

Instantly share code, notes, and snippets.

@hnky
Created January 20, 2020 19:19
Show Gist options
  • Save hnky/83b9e8f011e06ddaf276706e85560999 to your computer and use it in GitHub Desktop.
Save hnky/83b9e8f011e06ddaf276706e85560999 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.Devices.Gpio;
using Windows.Devices.Spi;
namespace RaspberryModules.App.Modules
{
public class SPIDisplay
{
/* Uncomment for Raspberry Pi 2 */
private const string SPI_CONTROLLER_NAME = "SPI0"; /* For Raspberry Pi 2, use SPI0 */
private const Int32 SPI_CHIP_SELECT_LINE = 0; /* Line 0 maps to physical pin number 24 on the Rpi2 */
private const Int32 DATA_COMMAND_PIN = 22; /* We use GPIO 22 since it's conveniently near the SPI pins */
private const Int32 RESET_PIN = 23; /* We use GPIO 23 since it's conveniently near the SPI pins */
/* This sample is intended to be used with the following OLED display: http://www.adafruit.com/product/938 */
private const UInt32 SCREEN_WIDTH_PX = 128; /* Number of horizontal pixels on the display */
private const UInt32 SCREEN_HEIGHT_PX = 64; /* Number of vertical pixels on the display */
private const UInt32 SCREEN_HEIGHT_PAGES = SCREEN_HEIGHT_PX / 8; /* The vertical pixels on this display are arranged into 'pages' of 8 pixels each */
private byte[,] DisplayBuffer =
new byte[SCREEN_WIDTH_PX, SCREEN_HEIGHT_PAGES]; /* A local buffer we use to store graphics data for the screen */
private byte[] SerializedDisplayBuffer =
new byte[SCREEN_WIDTH_PX * SCREEN_HEIGHT_PAGES]; /* A temporary buffer used to prepare graphics data for sending over SPI */
/* Definitions for SPI and GPIO */
private SpiDevice SpiDisplay;
private GpioController IoController;
private GpioPin DataCommandPin;
private GpioPin ResetPin;
/* Display commands. See the datasheet for details on commands: http://www.adafruit.com/datasheets/SSD1306.pdf */
private static readonly byte[] CMD_DISPLAY_OFF = { 0xAE }; /* Turns the display off */
private static readonly byte[] CMD_DISPLAY_ON = { 0xAF }; /* Turns the display on */
private static readonly byte[] CMD_CHARGEPUMP_ON = { 0x8D, 0x14 }; /* Turn on internal charge pump to supply power to display */
private static readonly byte[] CMD_MEMADDRMODE = { 0x20, 0x00 }; /* Horizontal memory mode */
private static readonly byte[] CMD_SEGREMAP = { 0xA1 }; /* Remaps the segments, which has the effect of mirroring the display horizontally */
private static readonly byte[] CMD_COMSCANDIR = { 0xC8 }; /* Set the COM scan direction to inverse, which flips the screen vertically */
private static readonly byte[] CMD_RESETCOLADDR = { 0x21, 0x00, 0x7F }; /* Reset the column address pointer */
private static readonly byte[] CMD_RESETPAGEADDR = { 0x22, 0x00, 0x07 };/* Reset the page address pointer */
private bool DisplayUnavailable = true;
public void WriteLinesToScreen(List<string> lines)
{
if (!DisplayUnavailable)
{
ClearDisplayBuf();
uint counter = 0;
foreach (string line in lines)
{
WriteLineDisplayBuf(line, 0, counter);
counter++;
}
DisplayUpdate();
}
}
public async void InitAll()
{
try
{
InitGpio(); /* Initialize the GPIO controller and GPIO pins */
await InitSpi(); /* Initialize the SPI controller */
await InitDisplay(); /* Initialize the display */
DisplayUnavailable = false;
WriteLineDisplayBuf("Ready...", 0, 0);
DisplayUpdate();
}
/* If initialization fails, display the exception and stop running */
catch (Exception ex)
{
Debug.WriteLine("Exception: " + ex.Message);
if (ex.InnerException != null)
{
Debug.WriteLine("\nInner Exception: " + ex.InnerException.Message);
}
return;
}
}
/* Initialize the SPI bus */
private async Task InitSpi()
{
try
{
var settings = new SpiConnectionSettings(SPI_CHIP_SELECT_LINE); /* Create SPI initialization settings */
settings.ClockFrequency = 10000000; /* Datasheet specifies maximum SPI clock frequency of 10MHz */
settings.Mode = SpiMode.Mode3; /* The display expects an idle-high clock polarity, we use Mode3
* to set the clock polarity and phase to: CPOL = 1, CPHA = 1
*/
var controller = await SpiController.GetDefaultAsync();
SpiDisplay = controller.GetDevice(settings); /* Create an SpiDevice with our bus controller and SPI settings */
}
/* If initialization fails, display the exception and stop running */
catch (Exception ex)
{
throw new Exception("SPI Initialization Failed", ex);
}
}
/* Send SPI commands to power up and initialize the display */
private async Task InitDisplay()
{
/* Initialize the display */
try
{
/* See the datasheet for more details on these commands: http://www.adafruit.com/datasheets/SSD1306.pdf */
await ResetDisplay(); /* Perform a hardware reset on the display */
DisplaySendCommand(CMD_CHARGEPUMP_ON); /* Turn on the internal charge pump to provide power to the screen */
DisplaySendCommand(CMD_MEMADDRMODE); /* Set the addressing mode to "horizontal" */
DisplaySendCommand(CMD_SEGREMAP); /* Flip the display horizontally, so it's easier to read on the breadboard */
DisplaySendCommand(CMD_COMSCANDIR); /* Flip the display vertically, so it's easier to read on the breadboard */
DisplaySendCommand(CMD_DISPLAY_ON); /* Turn the display on */
}
catch (Exception ex)
{
throw new Exception("Display Initialization Failed", ex);
}
}
/* Perform a hardware reset of the display */
private async Task ResetDisplay()
{
ResetPin.Write(GpioPinValue.Low); /* Put display into reset */
await Task.Delay(1); /* Wait at least 3uS (We wait 1mS since that is the minimum delay we can specify for Task.Delay() */
ResetPin.Write(GpioPinValue.High); /* Bring display out of reset */
await Task.Delay(100); /* Wait at least 100mS before sending commands */
}
/* Initialize the GPIO */
private void InitGpio()
{
IoController = GpioController.GetDefault(); /* Get the default GPIO controller on the system */
if (IoController == null)
{
throw new Exception("GPIO does not exist on the current system.");
}
/* Initialize a pin as output for the Data/Command line on the display */
DataCommandPin = IoController.OpenPin(DATA_COMMAND_PIN);
DataCommandPin.Write(GpioPinValue.High);
DataCommandPin.SetDriveMode(GpioPinDriveMode.Output);
/* Initialize a pin as output for the hardware Reset line on the display */
ResetPin = IoController.OpenPin(RESET_PIN);
ResetPin.Write(GpioPinValue.High);
ResetPin.SetDriveMode(GpioPinDriveMode.Output);
}
/* Send graphics data to the screen */
private void DisplaySendData(byte[] Data)
{
/* When the Data/Command pin is high, SPI data is treated as graphics data */
DataCommandPin.Write(GpioPinValue.High);
SpiDisplay.Write(Data);
}
/* Send commands to the screen */
private void DisplaySendCommand(byte[] Command)
{
/* When the Data/Command pin is low, SPI data is treated as commands for the display controller */
DataCommandPin.Write(GpioPinValue.Low);
SpiDisplay.Write(Command);
}
/* Writes the Display Buffer out to the physical screen for display */
private void DisplayUpdate()
{
int Index = 0;
/* We convert our 2-dimensional array into a serialized string of bytes that will be sent out to the display */
for (int PageY = 0; PageY < SCREEN_HEIGHT_PAGES; PageY++)
{
for (int PixelX = 0; PixelX < SCREEN_WIDTH_PX; PixelX++)
{
SerializedDisplayBuffer[Index] = DisplayBuffer[PixelX, PageY];
Index++;
}
}
/* Write the data out to the screen */
DisplaySendCommand(CMD_RESETCOLADDR); /* Reset the column address pointer back to 0 */
DisplaySendCommand(CMD_RESETPAGEADDR); /* Reset the page address pointer back to 0 */
DisplaySendData(SerializedDisplayBuffer); /* Send the data over SPI */
}
/*
* NAME: WriteLineDisplayBuf
* DESCRIPTION: Writes a string to the display screen buffer (DisplayUpdate() needs to be called subsequently to output the buffer to the screen)
* INPUTS:
*
* Line: The string we want to render. In this sample, special characters like tabs and newlines are not supported.
* Col: The horizontal column we want to start drawing at. This is equivalent to the 'X' axis pixel position.
* Row: The vertical row we want to write to. The screen is divided up into 4 rows of 16 pixels each, so valid values for Row are 0,1,2,3.
*
* RETURN VALUE:
* None. We simply return when we encounter characters that are out-of-bounds or aren't available in the font.
*/
private void WriteLineDisplayBuf(String Line, UInt32 Col, UInt32 Row)
{
if (!DisplayUnavailable)
{
UInt32 CharWidth = 0;
foreach (Char Character in Line)
{
CharWidth = WriteCharDisplayBuf(Character, Col, Row);
Col += CharWidth; /* Increment the column so we can track where to write the next character */
if (CharWidth == 0) /* Quit if we encounter a character that couldn't be printed */
{
return;
}
}
}
}
/*
* NAME: WriteCharDisplayBuf
* DESCRIPTION: Writes one character to the display screen buffer (DisplayUpdate() needs to be called subsequently to output the buffer to the screen)
* INPUTS:
*
* Character: The character we want to draw. In this sample, special characters like tabs and newlines are not supported.
* Col: The horizontal column we want to start drawing at. This is equivalent to the 'X' axis pixel position.
* Row: The vertical row we want to write to. The screen is divided up into 4 rows of 16 pixels each, so valid values for Row are 0,1,2,3.
*
* RETURN VALUE:
* We return the number of horizontal pixels used. This value is 0 if Row/Col are out-of-bounds, or if the character isn't available in the font.
*/
private UInt32 WriteCharDisplayBuf(Char Chr, UInt32 Col, UInt32 Row)
{
/* Check that we were able to find the font corresponding to our character */
FontCharacterDescriptor CharDescriptor = DisplayFontTable.GetCharacterDescriptor(Chr);
if (CharDescriptor == null)
{
return 0;
}
/* Make sure we're drawing within the boundaries of the screen buffer */
UInt32 MaxRowValue = (SCREEN_HEIGHT_PAGES / DisplayFontTable.FontHeightBytes) - 1;
UInt32 MaxColValue = SCREEN_WIDTH_PX;
if (Row > MaxRowValue)
{
return 0;
}
if ((Col + CharDescriptor.CharacterWidthPx + DisplayFontTable.FontCharSpacing) > MaxColValue)
{
return 0;
}
UInt32 CharDataIndex = 0;
UInt32 StartPage = Row * 2;
UInt32 EndPage = StartPage + CharDescriptor.CharacterHeightBytes;
UInt32 StartCol = Col;
UInt32 EndCol = StartCol + CharDescriptor.CharacterWidthPx;
UInt32 CurrentPage = 0;
UInt32 CurrentCol = 0;
/* Copy the character image into the display buffer */
for (CurrentPage = StartPage; CurrentPage < EndPage; CurrentPage++)
{
for (CurrentCol = StartCol; CurrentCol < EndCol; CurrentCol++)
{
DisplayBuffer[CurrentCol, CurrentPage] = CharDescriptor.CharacterData[CharDataIndex];
CharDataIndex++;
}
}
/* Pad blank spaces to the right of the character so there exists space between adjacent characters */
for (CurrentPage = StartPage; CurrentPage < EndPage; CurrentPage++)
{
for (; CurrentCol < EndCol + DisplayFontTable.FontCharSpacing; CurrentCol++)
{
DisplayBuffer[CurrentCol, CurrentPage] = 0x00;
}
}
/* Return the number of horizontal pixels used by the character */
return CurrentCol - StartCol;
}
/* Sets all pixels in the screen buffer to 0 */
private void ClearDisplayBuf()
{
Array.Clear(DisplayBuffer, 0, DisplayBuffer.Length);
}
private void Unloaded(object sender, object args)
{
/* Cleanup */
SpiDisplay.Dispose();
ResetPin.Dispose();
DataCommandPin.Dispose();
}
}
public class FontCharacterDescriptor
{
public readonly char Character;
public readonly UInt32 CharacterWidthPx;
public readonly UInt32 CharacterHeightBytes;
public readonly byte[] CharacterData;
public FontCharacterDescriptor(Char Chr, UInt32 CharHeightBytes, byte[] CharData)
{
Character = Chr;
CharacterWidthPx = (UInt32)CharData.Length / CharHeightBytes;
CharacterHeightBytes = CharHeightBytes;
CharacterData = CharData;
}
}
/* This class contains the character data needed to output render text on the display */
public static class DisplayFontTable
{
public static readonly UInt32 FontHeightBytes = 2; /* Height of the characters. A value of 2 would indicate a 16 (2*8) pixel tall character */
public static readonly UInt32 FontCharSpacing = 1; /* Number of blank horizontal pixels to insert between adjacent characters */
/* Takes and returns the character descriptor for the corresponding Char if it exists */
public static FontCharacterDescriptor GetCharacterDescriptor(Char Chr)
{
foreach (FontCharacterDescriptor CharDescriptor in FontTable)
{
if (CharDescriptor.Character == Chr)
{
return CharDescriptor;
}
}
return null;
}
/* Table with all the character data */
private static readonly FontCharacterDescriptor[] FontTable =
{
new FontCharacterDescriptor(' ' ,FontHeightBytes,new byte[]{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}),
new FontCharacterDescriptor('!' ,FontHeightBytes,new byte[]{0xFE,0x05}),
new FontCharacterDescriptor('"' ,FontHeightBytes,new byte[]{0x1E,0x00,0x1E,0x00,0x00,0x00}),
new FontCharacterDescriptor('#' ,FontHeightBytes,new byte[]{0x80,0x90,0xF0,0x9E,0xF0,0x9E,0x10,0x00,0x07,0x00,0x07,0x00,0x00,0x00}),
new FontCharacterDescriptor('$' ,FontHeightBytes,new byte[]{0x38,0x44,0xFE,0x44,0x98,0x02,0x04,0x0F,0x04,0x03}),
new FontCharacterDescriptor('%' ,FontHeightBytes,new byte[]{0x0C,0x12,0x12,0x8C,0x40,0x20,0x10,0x88,0x84,0x00,0x00,0x02,0x01,0x00,0x00,0x00,0x03,0x04,0x04,0x03}),
new FontCharacterDescriptor('&' ,FontHeightBytes,new byte[]{0x80,0x5C,0x22,0x62,0x9C,0x00,0x00,0x03,0x04,0x04,0x04,0x05,0x02,0x05}),
new FontCharacterDescriptor('\'',FontHeightBytes,new byte[]{0x1E,0x00}),
new FontCharacterDescriptor('(' ,FontHeightBytes,new byte[]{0xF0,0x0C,0x02,0x07,0x18,0x20}),
new FontCharacterDescriptor(')' ,FontHeightBytes,new byte[]{0x02,0x0C,0xF0,0x20,0x18,0x07}),
new FontCharacterDescriptor('*' ,FontHeightBytes,new byte[]{0x14,0x18,0x0E,0x18,0x14,0x00,0x00,0x00,0x00,0x00}),
new FontCharacterDescriptor('+' ,FontHeightBytes,new byte[]{0x40,0x40,0xF0,0x40,0x40,0x00,0x00,0x01,0x00,0x00}),
new FontCharacterDescriptor(',' ,FontHeightBytes,new byte[]{0x00,0x00,0x08,0x04}),
new FontCharacterDescriptor('-' ,FontHeightBytes,new byte[]{0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00}),
new FontCharacterDescriptor('.' ,FontHeightBytes,new byte[]{0x00,0x04}),
new FontCharacterDescriptor('/' ,FontHeightBytes,new byte[]{0x00,0x80,0x70,0x0E,0x1C,0x03,0x00,0x00}),
new FontCharacterDescriptor('0' ,FontHeightBytes,new byte[]{0xFC,0x02,0x02,0x02,0xFC,0x03,0x04,0x04,0x04,0x03}),
new FontCharacterDescriptor('1' ,FontHeightBytes,new byte[]{0x04,0x04,0xFE,0x00,0x00,0x07}),
new FontCharacterDescriptor('2' ,FontHeightBytes,new byte[]{0x0C,0x82,0x42,0x22,0x1C,0x07,0x04,0x04,0x04,0x04}),
new FontCharacterDescriptor('3' ,FontHeightBytes,new byte[]{0x04,0x02,0x22,0x22,0xDC,0x02,0x04,0x04,0x04,0x03}),
new FontCharacterDescriptor('4' ,FontHeightBytes,new byte[]{0xC0,0xA0,0x98,0x84,0xFE,0x00,0x00,0x00,0x00,0x07}),
new FontCharacterDescriptor('5' ,FontHeightBytes,new byte[]{0x7E,0x22,0x22,0x22,0xC2,0x02,0x04,0x04,0x04,0x03}),
new FontCharacterDescriptor('6' ,FontHeightBytes,new byte[]{0xFC,0x42,0x22,0x22,0xC4,0x03,0x04,0x04,0x04,0x03}),
new FontCharacterDescriptor('7' ,FontHeightBytes,new byte[]{0x02,0x02,0xC2,0x32,0x0E,0x00,0x07,0x00,0x00,0x00}),
new FontCharacterDescriptor('8' ,FontHeightBytes,new byte[]{0xDC,0x22,0x22,0x22,0xDC,0x03,0x04,0x04,0x04,0x03}),
new FontCharacterDescriptor('9' ,FontHeightBytes,new byte[]{0x3C,0x42,0x42,0x22,0xFC,0x02,0x04,0x04,0x04,0x03}),
new FontCharacterDescriptor(':' ,FontHeightBytes,new byte[]{0x10,0x04}),
new FontCharacterDescriptor(';' ,FontHeightBytes,new byte[]{0x00,0x10,0x08,0x04}),
new FontCharacterDescriptor('<' ,FontHeightBytes,new byte[]{0x40,0xE0,0xB0,0x18,0x08,0x00,0x00,0x01,0x03,0x02}),
new FontCharacterDescriptor('=' ,FontHeightBytes,new byte[]{0xA0,0xA0,0xA0,0xA0,0xA0,0x00,0x00,0x00,0x00,0x00}),
new FontCharacterDescriptor('>' ,FontHeightBytes,new byte[]{0x08,0x18,0xB0,0xE0,0x40,0x02,0x03,0x01,0x00,0x00}),
new FontCharacterDescriptor('?' ,FontHeightBytes,new byte[]{0x0C,0x02,0xC2,0x22,0x1C,0x00,0x00,0x05,0x00,0x00}),
new FontCharacterDescriptor('@' ,FontHeightBytes,new byte[]{0xF0,0x0C,0x02,0x02,0xE1,0x11,0x11,0x91,0x72,0x02,0x0C,0xF0,0x00,0x03,0x04,0x04,0x08,0x09,0x09,0x08,0x09,0x05,0x05,0x00}),
new FontCharacterDescriptor('A' ,FontHeightBytes,new byte[]{0x00,0x80,0xE0,0x98,0x86,0x98,0xE0,0x80,0x00,0x06,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x06}),
new FontCharacterDescriptor('B' ,FontHeightBytes,new byte[]{0xFE,0x22,0x22,0x22,0x22,0x22,0xDC,0x07,0x04,0x04,0x04,0x04,0x04,0x03}),
new FontCharacterDescriptor('C' ,FontHeightBytes,new byte[]{0xF8,0x04,0x02,0x02,0x02,0x02,0x04,0x08,0x01,0x02,0x04,0x04,0x04,0x04,0x02,0x01}),
new FontCharacterDescriptor('D' ,FontHeightBytes,new byte[]{0xFE,0x02,0x02,0x02,0x02,0x02,0x04,0xF8,0x07,0x04,0x04,0x04,0x04,0x04,0x02,0x01}),
new FontCharacterDescriptor('E' ,FontHeightBytes,new byte[]{0xFE,0x22,0x22,0x22,0x22,0x22,0x02,0x07,0x04,0x04,0x04,0x04,0x04,0x04}),
new FontCharacterDescriptor('F' ,FontHeightBytes,new byte[]{0xFE,0x22,0x22,0x22,0x22,0x22,0x02,0x07,0x00,0x00,0x00,0x00,0x00,0x00}),
new FontCharacterDescriptor('G' ,FontHeightBytes,new byte[]{0xF8,0x04,0x02,0x02,0x02,0x42,0x44,0xC8,0x01,0x02,0x04,0x04,0x04,0x04,0x02,0x07}),
new FontCharacterDescriptor('H' ,FontHeightBytes,new byte[]{0xFE,0x20,0x20,0x20,0x20,0x20,0x20,0xFE,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07}),
new FontCharacterDescriptor('I' ,FontHeightBytes,new byte[]{0xFE,0x07}),
new FontCharacterDescriptor('J' ,FontHeightBytes,new byte[]{0x00,0x00,0x00,0x00,0xFE,0x03,0x04,0x04,0x04,0x03}),
new FontCharacterDescriptor('K' ,FontHeightBytes,new byte[]{0xFE,0x20,0x50,0x88,0x04,0x02,0x00,0x07,0x00,0x00,0x00,0x01,0x02,0x04}),
new FontCharacterDescriptor('L' ,FontHeightBytes,new byte[]{0xFE,0x00,0x00,0x00,0x00,0x00,0x07,0x04,0x04,0x04,0x04,0x04}),
new FontCharacterDescriptor('M' ,FontHeightBytes,new byte[]{0xFE,0x18,0x60,0x80,0x00,0x80,0x60,0x18,0xFE,0x07,0x00,0x00,0x01,0x06,0x01,0x00,0x00,0x07}),
new FontCharacterDescriptor('N' ,FontHeightBytes,new byte[]{0xFE,0x04,0x18,0x20,0x40,0x80,0x00,0xFE,0x07,0x00,0x00,0x00,0x00,0x01,0x02,0x07}),
new FontCharacterDescriptor('O' ,FontHeightBytes,new byte[]{0xF8,0x04,0x02,0x02,0x02,0x02,0x04,0xF8,0x01,0x02,0x04,0x04,0x04,0x04,0x02,0x01}),
new FontCharacterDescriptor('P' ,FontHeightBytes,new byte[]{0xFE,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00}),
new FontCharacterDescriptor('Q' ,FontHeightBytes,new byte[]{0xF8,0x04,0x02,0x02,0x02,0x02,0x04,0xF8,0x01,0x02,0x04,0x04,0x04,0x05,0x02,0x05}),
new FontCharacterDescriptor('R' ,FontHeightBytes,new byte[]{0xFE,0x42,0x42,0x42,0x42,0x42,0x64,0x98,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x04}),
new FontCharacterDescriptor('S' ,FontHeightBytes,new byte[]{0x1C,0x22,0x22,0x22,0x42,0x42,0x8C,0x03,0x04,0x04,0x04,0x04,0x04,0x03}),
new FontCharacterDescriptor('T' ,FontHeightBytes,new byte[]{0x02,0x02,0x02,0x02,0xFE,0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00}),
new FontCharacterDescriptor('U' ,FontHeightBytes,new byte[]{0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x01,0x02,0x04,0x04,0x04,0x04,0x02,0x01}),
new FontCharacterDescriptor('V' ,FontHeightBytes,new byte[]{0x06,0x18,0x60,0x80,0x00,0x80,0x60,0x18,0x06,0x00,0x00,0x00,0x01,0x06,0x01,0x00,0x00,0x00}),
new FontCharacterDescriptor('W' ,FontHeightBytes,new byte[]{0x0E,0x30,0xC0,0x00,0xC0,0x30,0x0E,0x30,0xC0,0x00,0xC0,0x30,0x0E,0x00,0x00,0x01,0x06,0x01,0x00,0x00,0x00,0x01,0x06,0x01,0x00,0x00}),
new FontCharacterDescriptor('X' ,FontHeightBytes,new byte[]{0x06,0x08,0x90,0x60,0x60,0x90,0x08,0x06,0x06,0x01,0x00,0x00,0x00,0x00,0x01,0x06}),
new FontCharacterDescriptor('Y' ,FontHeightBytes,new byte[]{0x06,0x08,0x10,0x20,0xC0,0x20,0x10,0x08,0x06,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00}),
new FontCharacterDescriptor('Z' ,FontHeightBytes,new byte[]{0x02,0x82,0x42,0x22,0x1A,0x06,0x06,0x05,0x04,0x04,0x04,0x04}),
new FontCharacterDescriptor('[' ,FontHeightBytes,new byte[]{0xFE,0x02,0x02,0x3F,0x20,0x20}),
new FontCharacterDescriptor('\\',FontHeightBytes,new byte[]{0x0E,0x70,0x80,0x00,0x00,0x00,0x03,0x1C}),
new FontCharacterDescriptor('^' ,FontHeightBytes,new byte[]{0x02,0x02,0xFE,0x20,0x20,0x3F}),
new FontCharacterDescriptor('_' ,FontHeightBytes,new byte[]{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10}),
new FontCharacterDescriptor('`' ,FontHeightBytes,new byte[]{0x02,0x04,0x00,0x00}),
new FontCharacterDescriptor('a' ,FontHeightBytes,new byte[]{0xA0,0x50,0x50,0x50,0x50,0xE0,0x00,0x03,0x04,0x04,0x04,0x04,0x03,0x04}),
new FontCharacterDescriptor('b' ,FontHeightBytes,new byte[]{0xFE,0x20,0x10,0x10,0x10,0xE0,0x07,0x02,0x04,0x04,0x04,0x03}),
new FontCharacterDescriptor('c' ,FontHeightBytes,new byte[]{0xE0,0x10,0x10,0x10,0x10,0x20,0x03,0x04,0x04,0x04,0x04,0x02}),
new FontCharacterDescriptor('d' ,FontHeightBytes,new byte[]{0xE0,0x10,0x10,0x10,0x20,0xFE,0x03,0x04,0x04,0x04,0x02,0x07}),
new FontCharacterDescriptor('e' ,FontHeightBytes,new byte[]{0xE0,0x90,0x90,0x90,0x90,0xE0,0x03,0x04,0x04,0x04,0x04,0x02}),
new FontCharacterDescriptor('f' ,FontHeightBytes,new byte[]{0x10,0xFC,0x12,0x00,0x07,0x00}),
new FontCharacterDescriptor('g' ,FontHeightBytes,new byte[]{0xE0,0x10,0x10,0x10,0x20,0xF0,0x03,0x24,0x24,0x24,0x22,0x1F}),
new FontCharacterDescriptor('h' ,FontHeightBytes,new byte[]{0xFE,0x20,0x10,0x10,0xE0,0x07,0x00,0x00,0x00,0x07}),
new FontCharacterDescriptor('i' ,FontHeightBytes,new byte[]{0xF2,0x07}),
new FontCharacterDescriptor('j' ,FontHeightBytes,new byte[]{0x00,0xF2,0x20,0x1F}),
new FontCharacterDescriptor('k' ,FontHeightBytes,new byte[]{0xFE,0x80,0xC0,0x20,0x10,0x00,0x07,0x00,0x00,0x01,0x02,0x04}),
new FontCharacterDescriptor('l' ,FontHeightBytes,new byte[]{0xFE,0x07}),
new FontCharacterDescriptor('m' ,FontHeightBytes,new byte[]{0xF0,0x20,0x10,0x10,0xE0,0x20,0x10,0x10,0xE0,0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07}),
new FontCharacterDescriptor('n' ,FontHeightBytes,new byte[]{0xF0,0x20,0x10,0x10,0xE0,0x07,0x00,0x00,0x00,0x07}),
new FontCharacterDescriptor('o' ,FontHeightBytes,new byte[]{0xE0,0x10,0x10,0x10,0x10,0xE0,0x03,0x04,0x04,0x04,0x04,0x03}),
new FontCharacterDescriptor('p' ,FontHeightBytes,new byte[]{0xF0,0x20,0x10,0x10,0x10,0xE0,0x3F,0x02,0x04,0x04,0x04,0x03}),
new FontCharacterDescriptor('q' ,FontHeightBytes,new byte[]{0xE0,0x10,0x10,0x10,0x20,0xF0,0x03,0x04,0x04,0x04,0x02,0x3F}),
new FontCharacterDescriptor('r' ,FontHeightBytes,new byte[]{0xF0,0x20,0x10,0x07,0x00,0x00}),
new FontCharacterDescriptor('s' ,FontHeightBytes,new byte[]{0x60,0x90,0x90,0x90,0x20,0x02,0x04,0x04,0x04,0x03}),
new FontCharacterDescriptor('t' ,FontHeightBytes,new byte[]{0x10,0xFC,0x10,0x00,0x03,0x04}),
new FontCharacterDescriptor('u' ,FontHeightBytes,new byte[]{0xF0,0x00,0x00,0x00,0xF0,0x03,0x04,0x04,0x02,0x07}),
new FontCharacterDescriptor('v' ,FontHeightBytes,new byte[]{0x30,0xC0,0x00,0x00,0x00,0xC0,0x30,0x00,0x00,0x03,0x04,0x03,0x00,0x00}),
new FontCharacterDescriptor('w' ,FontHeightBytes,new byte[]{0x30,0xC0,0x00,0xC0,0x30,0xC0,0x00,0xC0,0x30,0x00,0x01,0x06,0x01,0x00,0x01,0x06,0x01,0x00}),
new FontCharacterDescriptor('x' ,FontHeightBytes,new byte[]{0x10,0x20,0xC0,0xC0,0x20,0x10,0x04,0x02,0x01,0x01,0x02,0x04}),
new FontCharacterDescriptor('y' ,FontHeightBytes,new byte[]{0x30,0xC0,0x00,0x00,0x00,0xC0,0x30,0x20,0x20,0x13,0x0C,0x03,0x00,0x00}),
new FontCharacterDescriptor('z' ,FontHeightBytes,new byte[]{0x10,0x90,0x50,0x30,0x06,0x05,0x04,0x04}),
new FontCharacterDescriptor('{' ,FontHeightBytes,new byte[]{0x80,0x80,0x7C,0x02,0x02,0x00,0x00,0x1F,0x20,0x20}),
new FontCharacterDescriptor('|' ,FontHeightBytes,new byte[]{0xFE,0x3F}),
new FontCharacterDescriptor('}' ,FontHeightBytes,new byte[]{0x02,0x02,0x7C,0x80,0x80,0x20,0x20,0x1F,0x00,0x00}),
new FontCharacterDescriptor('~' ,FontHeightBytes,new byte[]{0x0C,0x02,0x02,0x04,0x08,0x08,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00}),
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment