Signed-off-by: 吴文峰 <kevin@lmve.net>

This commit is contained in:
2026-03-03 22:16:00 +08:00
parent 7ae6e9e999
commit 88d56e1e9e
1660 changed files with 281430 additions and 0 deletions
@@ -0,0 +1,108 @@
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "./LatchingBacklight.h"
#include "assert.h"
#include "sleep.h"
using namespace NicheGraphics::Drivers;
// Private constructor
// Called by getInstance
LatchingBacklight::LatchingBacklight()
{
// Attach the deep sleep callback
deepSleepObserver.observe(&notifyDeepSleep);
}
// Get access to (or create) the singleton instance of this class
LatchingBacklight *LatchingBacklight::getInstance()
{
// Instantiate the class the first time this method is called
static LatchingBacklight *const singletonInstance = new LatchingBacklight;
return singletonInstance;
}
// Which pin controls the backlight?
// Is the light active HIGH (default) or active LOW?
void LatchingBacklight::setPin(uint8_t pin, bool activeWhen)
{
this->pin = pin;
this->logicActive = activeWhen;
pinMode(pin, OUTPUT);
off(); // Explicit off seem required by T-Echo?
}
// Called when device is shutting down
// Ensures the backlight is off
int LatchingBacklight::beforeDeepSleep(void *unused)
{
// Contingency only
// - pin wasn't set
if (pin != static_cast<uint8_t>(-1)) {
off();
pinMode(pin, INPUT); // High impedance - unnecessary?
} else
LOG_WARN("LatchingBacklight instantiated, but pin not set");
return 0; // Continue with deep sleep
}
// Turn the backlight on *temporarily*
// This should be used for momentary illumination, such as while a button is held
// The effect on the backlight is the same; peek and latch are separated to simplify short vs long press button handling
void LatchingBacklight::peek()
{
assert(pin != static_cast<uint8_t>(-1));
digitalWrite(pin, logicActive); // On
on = true;
latched = false;
}
// Turn the backlight on, and keep it on
// This should be used when the backlight should remain active, even after user input ends
// e.g. when enabled via the menu
// The effect on the backlight is the same; peek and latch are separated to simplify short vs long press button handling
void LatchingBacklight::latch()
{
assert(pin != static_cast<uint8_t>(-1));
// Blink if moving from peek to latch
// Indicates to user that the transition has taken place
if (on && !latched) {
digitalWrite(pin, !logicActive); // Off
delay(25);
digitalWrite(pin, logicActive); // On
delay(25);
digitalWrite(pin, !logicActive); // Off
delay(25);
}
digitalWrite(pin, logicActive); // On
on = true;
latched = true;
}
// Turn the backlight off
// Suitable for ending both peek and latch
void LatchingBacklight::off()
{
assert(pin != static_cast<uint8_t>(-1));
digitalWrite(pin, !logicActive); // Off
on = false;
latched = false;
}
bool LatchingBacklight::isOn()
{
return on;
}
bool LatchingBacklight::isLatched()
{
return latched;
}
#endif
@@ -0,0 +1,50 @@
/*
Singleton class
On-demand control of a display's backlight, connected to a GPIO
Initial use case is control of T-Echo's frontlight, via the capacitive touch button
- momentary on
- latched on
*/
#pragma once
#include "configuration.h"
#include "Observer.h"
namespace NicheGraphics::Drivers
{
class LatchingBacklight
{
public:
static LatchingBacklight *getInstance(); // Create or get the singleton instance
void setPin(uint8_t pin, bool activeWhen = HIGH);
int beforeDeepSleep(void *unused); // Callback for auto-shutoff
void peek(); // Backlight on temporarily, e.g. while button held
void latch(); // Backlight on permanently, e.g. toggled via menu
void off(); // Backlight off. Suitable for both peek and latch
bool isOn(); // Either peek or latch
bool isLatched();
private:
LatchingBacklight(); // Constructor made private: force use of getInstance
// Get notified when the system is shutting down
CallbackObserver<LatchingBacklight, void *> deepSleepObserver =
CallbackObserver<LatchingBacklight, void *>(this, &LatchingBacklight::beforeDeepSleep);
uint8_t pin = static_cast<uint8_t>(-1);
bool logicActive = HIGH; // Is light active HIGH or active LOW
bool on = false; // Is light on (either peek or latched)
bool latched = false; // Is light latched on
};
} // namespace NicheGraphics::Drivers
@@ -0,0 +1,132 @@
#include "./DEPG0213BNS800.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
using namespace NicheGraphics::Drivers;
// Describes the operation performed when a "fast refresh" is performed
// Source: Modified from GxEPD2 (GxEPD2_213_BN)
static const uint8_t LUT_FAST[] = {
// 1 2 3
0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // B2B (Existing black pixels)
0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // B2W (New white pixels)
0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // W2B (New black pixels)
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // W2W (Existing white pixels)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VCOM
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // 1. Any pixels changing W2B or B2W. Two medium taps.
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2. All pixels. One short tap.
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 3. Cooldown
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, //
};
// How strongly the pixels are pulled and pushed
void DEPG0213BNS800::configVoltages()
{
switch (updateType) {
case FAST:
// Reference: display datasheet, GxEPD1
sendCommand(0x03); // Gate voltage
sendData(0x17); // VGH: 20V
// Reference: display datasheet, GxEPD1
sendCommand(0x04); // Source voltage
sendData(0x41); // VSH1: 15V
sendData(0x00); // VSH2: NA
sendData(0x32); // VSL: -15V
// GxEPD1 sets this at -1.2V, but that seems to be drive the pixels very hard
sendCommand(0x2C); // VCOM voltage
sendData(0x08); // VCOM: -0.2V
break;
case FULL:
default:
// From OTP memory
break;
}
}
// Load settings about how the pixels are moved from old state to new state during a refresh
// - manually specified,
// - or with stored values from displays OTP memory
void DEPG0213BNS800::configWaveform()
{
switch (updateType) {
case FAST:
sendCommand(0x3C); // Border waveform:
sendData(0x80); // VSS
sendCommand(0x32); // Write LUT register from MCU:
sendData(LUT_FAST, sizeof(LUT_FAST)); // (describes operation for a FAST refresh)
break;
case FULL:
default:
// From OTP memory
break;
}
}
// Describes the sequence of events performed by the displays controller IC during a refresh
// Includes "power up", "load settings from memory", "update the pixels", etc
void DEPG0213BNS800::configUpdateSequence()
{
switch (updateType) {
case FAST:
sendCommand(0x22); // Set "update sequence"
sendData(0xCF); // Differential, use manually loaded waveform
break;
case FULL:
default:
sendCommand(0x22); // Set "update sequence"
sendData(0xF7); // Non-differential, load waveform from OTP
break;
}
}
// Once the refresh operation has been started,
// begin periodically polling the display to check for completion, using the normal Meshtastic threading code
// Only used when refresh is "async"
void DEPG0213BNS800::detachFromUpdate()
{
switch (updateType) {
case FAST:
return beginPolling(50, 500); // At least 500ms, then poll every 50ms
case FULL:
default:
return beginPolling(100, 3500); // At least 3500ms, then poll every 100ms
}
}
// For this display, we do not need to re-write the new image.
// We're overriding SSD16XX::finalizeUpdate to make this small optimization.
// The display does also work just fine with the generic SSD16XX method, though.
void DEPG0213BNS800::finalizeUpdate()
{
// Put a copy of the image into the "old memory".
// Used with differential refreshes (e.g. FAST update), to determine which px need to move, and which can remain in place
// We need to keep the "old memory" up to date, because don't know whether next refresh will be FULL or FAST etc.
if (updateType != FULL) {
// writeNewImage(); // Not required for this display
writeOldImage();
sendCommand(0x7F); // Terminate image write without update
wait();
}
// Enter deep-sleep to save a few µA
// Waking from this requires that display's reset pin is broken out
if (pin_rst != 0xFF)
deepSleep();
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,44 @@
/*
E-Ink display driver
- DEPG0213BNS800
- Manufacturer: DKE
- Size: 2.13 inch
- Resolution: 122px x 250px
- Flex connector marking (not a unique identifier): FPC-7528B
Note: this is from an older generation of DKE panels, which still used Solomon Systech controller ICs.
DKE's website suggests that the latest DEPG0213BN displays may use Fitipower controllers instead.
*/
#pragma once
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "configuration.h"
#include "./SSD16XX.h"
namespace NicheGraphics::Drivers
{
class DEPG0213BNS800 : public SSD16XX
{
// Display properties
private:
static constexpr uint32_t width = 122;
static constexpr uint32_t height = 250;
static constexpr UpdateTypes supported = (UpdateTypes)(FULL | FAST);
public:
DEPG0213BNS800() : SSD16XX(width, height, supported, 1) {} // Note: left edge of this display is offset by 1 byte
protected:
void configVoltages() override;
void configWaveform() override;
void configUpdateSequence() override;
void detachFromUpdate() override;
void finalizeUpdate() override; // Only overriden for a slight optimization
};
} // namespace NicheGraphics::Drivers
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,125 @@
#include "./DEPG0290BNS800.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
using namespace NicheGraphics::Drivers;
// Describes the operation performed when a "fast refresh" is performed
// Source: custom, with DEPG0150BNS810 as a reference
static const uint8_t LUT_FAST[] = {
// 1 2 3 4
0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // B2B (Existing black pixels)
0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // B2W (New white pixels)
0x00, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // W2B (New black pixels)
0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // W2W (Existing white pixels)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VCOM
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 1. Tap existing black pixels back into place
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2. Move new pixels
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 3. New pixels, and also existing black pixels
0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // 4. All pixels, then cooldown
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00,
};
// How strongly the pixels are pulled and pushed
void DEPG0290BNS800::configVoltages()
{
switch (updateType) {
case FAST:
// Listed as "typical" in datasheet
sendCommand(0x04);
sendData(0x41); // VSH1 15V
sendData(0x00); // VSH2 NA
sendData(0x32); // VSL -15V
break;
case FULL:
default:
// From OTP memory
break;
}
}
// Load settings about how the pixels are moved from old state to new state during a refresh
// - manually specified,
// - or with stored values from displays OTP memory
void DEPG0290BNS800::configWaveform()
{
switch (updateType) {
case FAST:
sendCommand(0x3C); // Border waveform:
sendData(0x60); // Actively hold screen border during update
sendCommand(0x32); // Write LUT register from MCU:
sendData(LUT_FAST, sizeof(LUT_FAST)); // (describes operation for a FAST refresh)
break;
case FULL:
default:
// From OTP memory
break;
}
}
// Describes the sequence of events performed by the displays controller IC during a refresh
// Includes "power up", "load settings from memory", "update the pixels", etc
void DEPG0290BNS800::configUpdateSequence()
{
switch (updateType) {
case FAST:
sendCommand(0x22); // Set "update sequence"
sendData(0xCF); // Differential, use manually loaded waveform
break;
case FULL:
default:
sendCommand(0x22); // Set "update sequence"
sendData(0xF7); // Non-differential, load waveform from OTP
break;
}
}
// Once the refresh operation has been started,
// begin periodically polling the display to check for completion, using the normal Meshtastic threading code
// Only used when refresh is "async"
void DEPG0290BNS800::detachFromUpdate()
{
switch (updateType) {
case FAST:
return beginPolling(50, 450); // At least 450ms for fast refresh
case FULL:
default:
return beginPolling(100, 3000); // At least 3 seconds for full refresh
}
}
// For this display, we do not need to re-write the new image.
// We're overriding SSD16XX::finalizeUpdate to make this small optimization.
// The display does also work just fine with the generic SSD16XX method, though.
void DEPG0290BNS800::finalizeUpdate()
{
// Put a copy of the image into the "old memory".
// Used with differential refreshes (e.g. FAST update), to determine which px need to move, and which can remain in place
// We need to keep the "old memory" up to date, because don't know whether next refresh will be FULL or FAST etc.
if (updateType != FULL) {
// writeNewImage(); // Not required for this display
writeOldImage();
sendCommand(0x7F); // Terminate image write without update
wait();
}
// Enter deep-sleep to save a few µA
// Waking from this requires that display's reset pin is broken out
if (pin_rst != 0xFF)
deepSleep();
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,42 @@
/*
E-Ink display driver
- DEPG0290BNS800
- Manufacturer: DKE
- Size: 2.9 inch
- Resolution: 128px x 296px
- Flex connector marking (not a unique identifier): FPC-7519 rev.b
*/
#pragma once
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "configuration.h"
#include "./SSD16XX.h"
namespace NicheGraphics::Drivers
{
class DEPG0290BNS800 : public SSD16XX
{
// Display properties
private:
static constexpr uint32_t width = 128;
static constexpr uint32_t height = 296;
static constexpr UpdateTypes supported = (UpdateTypes)(FULL | FAST);
public:
DEPG0290BNS800() : SSD16XX(width, height, supported, 1) {} // Note: left edge of this display is offset by 1 byte
protected:
void configVoltages() override;
void configWaveform() override;
void configUpdateSequence() override;
void detachFromUpdate() override;
void finalizeUpdate() override; // Only overriden for a slight optimization
};
} // namespace NicheGraphics::Drivers
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,84 @@
#include "./E0213A367.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
using namespace NicheGraphics::Drivers;
// Map the display controller IC's output to the connected panel
void E0213A367::configScanning()
{
// "Driver output control"
// Scan gates from 0 to 249 (vertical resolution 250px)
sendCommand(0x01);
sendData(0xF9);
sendData(0x00);
}
// Specify which information is used to control the sequence of voltages applied to move the pixels
void E0213A367::configWaveform()
{
// This command (0x37) is poorly documented
// As of July 2025, the datasheet for this display's controller IC is unavailable
// The values are supplied by Heltec, who presumably have privileged access to information from the display manufacturer
// Datasheet for the similar SSD1680 IC hints at the function of this command:
// "Spare VCOM OTP selection":
// Unclear why 0x40 is set. Sane values for related SSD1680 seem to be 0x80 or 0x00.
// Maybe value is redundant? No noticeable impact when set to 0x00.
// We'll leave it set to 0x40, following Heltec's lead, just in case.
// "Display Mode"
// Seems to specify whether a waveform stored in OTP should use display mode 1 or 2 (full refresh or differential refresh)
// Unusual that waveforms are programmed to OTP, but this meta information is not ..?
sendCommand(0x37); // "Write Register for Display Option" ?
sendData(0x40); // "Spare VCOM OTP selection" ?
sendData(0x80); // "Display Mode for WS[7:0]" ?
sendData(0x03); // "Display Mode for WS[15:8]" ?
sendData(0x0E); // "Display Mode [23:16]" ?
switch (updateType) {
case FAST:
sendCommand(0x3C); // Border waveform:
sendData(0x81); // As specified by Heltec. Actually VCOM (0x80)?. Bit 0 seems redundant here.
break;
case FULL:
default:
sendCommand(0x3C); // Border waveform:
sendData(0x01); // Follow LUT 1 (blink same as white pixels)
break;
}
}
// Tell controller IC which operations to run
void E0213A367::configUpdateSequence()
{
switch (updateType) {
case FAST:
sendCommand(0x22); // Set "update sequence"
sendData(0xFF); // Will load LUT from OTP memory, Display mode 2 "differential refresh"
break;
case FULL:
default:
sendCommand(0x22); // Set "update sequence"
sendData(0xF7); // Will load LUT from OTP memory, Display mode 1 "full refresh"
break;
}
}
// Once the refresh operation has been started,
// begin periodically polling the display to check for completion, using the normal Meshtastic threading code
// Only used when refresh is "async"
void E0213A367::detachFromUpdate()
{
switch (updateType) {
case FAST:
return beginPolling(50, 500); // At least 500ms for fast refresh
case FULL:
default:
return beginPolling(100, 1500); // At least 1.5 seconds for full refresh
}
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,41 @@
/*
E-Ink display driver
- SSD1682
- Manufacturer: SEEKINK
- Size: 2.13 inch
- Resolution: 122px x 255px
- Flex connector marking: HINK-E0213A162-A1 (hidden, printed on reverse)
*/
#pragma once
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "configuration.h"
#include "./SSD1682.h"
namespace NicheGraphics::Drivers
{
class E0213A367 : public SSD1682
{
// Display properties
private:
static constexpr uint32_t width = 122;
static constexpr uint32_t height = 250;
static constexpr UpdateTypes supported = (UpdateTypes)(FULL | FAST);
public:
E0213A367() : SSD1682(width, height, supported, 0) {}
protected:
void configScanning() override;
void configWaveform() override;
void configUpdateSequence() override;
void detachFromUpdate() override;
};
} // namespace NicheGraphics::Drivers
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,86 @@
#include "./EInk.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
using namespace NicheGraphics::Drivers;
// Separate from EInk::begin method, as derived class constructors can probably supply these parameters as constants
EInk::EInk(uint16_t width, uint16_t height, UpdateTypes supported)
: concurrency::OSThread("EInkDriver"), width(width), height(height), supportedUpdateTypes(supported)
{
OSThread::disable();
}
// Used by NicheGraphics implementations to check if a display supports a specific refresh operation.
// Whether or not the update type is supported is specified in the constructor
bool EInk::supports(UpdateTypes type)
{
// The EInkUpdateTypes enum assigns each type a unique bit. We are checking if that bit is set.
if (supportedUpdateTypes & type)
return true;
else
return false;
}
// Begins using the OSThread to detect when a display update is complete
// This allows the refresh operation to run "asynchronously".
// Rather than blocking execution waiting for the update to complete, we are periodically checking the hardware's BUSY pin
// The expectedDuration argument allows us to delay the start of this checking, if we know "roughly" how long an update takes.
// Potentially, a display without hardware BUSY could rely entirely on "expectedDuration",
// provided its isUpdateDone() override always returns true.
void EInk::beginPolling(uint32_t interval, uint32_t expectedDuration)
{
updateRunning = true;
pollingInterval = interval;
pollingBegunAt = millis();
// To minimize load, we can choose to delay polling for a few seconds, if we know roughly how long the update will take
// By default, expectedDuration is 0, and we'll start polling immediately
OSThread::setIntervalFromNow(expectedDuration);
OSThread::enabled = true;
}
// Meshtastic's pseudo-threading layer
// We're using this as a timer, to periodically check if an update is complete
// This is what allows us to update the display asynchronously
int32_t EInk::runOnce()
{
// Check for polling timeout
// Manually set at 10 seconds, in case some big task holds up the firmware's cooperative multitasking
if (millis() - pollingBegunAt > 10000)
failed = true;
// Handle failure
// - polling timeout
// - other error (derived classes)
if (failed) {
LOG_WARN("Display update failed. Check wiring & power supply.");
updateRunning = false;
failed = false;
return disable();
}
// If update not yet done
if (!isUpdateDone())
return pollingInterval; // Poll again in a few ms
// If update done
finalizeUpdate(); // Any post-update code: power down panel hardware, hibernate, etc
updateRunning = false; // Change what we report via EInk::busy()
return disable(); // Stop polling
}
// Wait for an in progress update to complete before continuing
// Run a normal (async) update first, *then* call await
void EInk::await()
{
// Stop our concurrency thread
OSThread::disable();
// Sit and block until the update is complete
while (updateRunning) {
runOnce();
yield();
}
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,57 @@
/*
Base class for E-Ink display drivers
*/
#pragma once
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "configuration.h"
#include "concurrency/OSThread.h"
#include <SPI.h>
namespace NicheGraphics::Drivers
{
class EInk : private concurrency::OSThread
{
public:
// Different possible operations used to update an E-Ink display
// Some displays will not support all operations
// Each value needs a unique bit. In some cases, we might set more than one bit (e.g. EInk::supportedUpdateType)
enum UpdateTypes : uint8_t {
UNSPECIFIED = 0,
FULL = 1 << 0,
FAST = 1 << 1, // "Partial Refresh"
};
EInk(uint16_t width, uint16_t height, UpdateTypes supported);
virtual void begin(SPIClass *spi, uint8_t pin_dc, uint8_t pin_cs, uint8_t pin_busy, uint8_t pin_rst = -1) = 0;
virtual void update(uint8_t *imageData, UpdateTypes type) = 0; // Change the display image
void await(); // Wait for an in-progress update to complete before proceeding
bool supports(UpdateTypes type); // Can display perform a certain update type
bool busy() { return updateRunning; } // Display able to update right now?
const uint16_t width; // Public so that NicheGraphics implementations can access. Safe because const.
const uint16_t height;
protected:
void beginPolling(uint32_t interval, uint32_t expectedDuration); // Begin checking repeatedly if update finished
virtual bool isUpdateDone() = 0; // Check once if update finished
virtual void finalizeUpdate() {} // Run any post-update code
bool failed = false; // If an error occurred during update
private:
int32_t runOnce() override; // Repeated checking if update finished
const UpdateTypes supportedUpdateTypes; // Capabilities of a derived display class
bool updateRunning = false; // see EInk::busy()
uint32_t pollingInterval = 0; // How often to check if update complete (ms)
uint32_t pollingBegunAt = 0; // To timeout during polling
};
} // namespace NicheGraphics::Drivers
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,58 @@
#include "./GDEY0154D67.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
using namespace NicheGraphics::Drivers;
// Map the display controller IC's output to the connected panel
void GDEY0154D67::configScanning()
{
// "Driver output control"
sendCommand(0x01);
sendData(0xC7); // Scan until gate 199 (200px vertical res.)
sendData(0x00);
sendData(0x00);
}
// Specify which information is used to control the sequence of voltages applied to move the pixels
// - For this display, configUpdateSequence() specifies that a suitable LUT will be loaded from
// the controller IC's OTP memory, when the update procedure begins.
void GDEY0154D67::configWaveform()
{
sendCommand(0x3C); // Border waveform:
sendData(0x05); // Screen border should follow LUT1 waveform (actively drive pixels white)
sendCommand(0x18); // Temperature sensor:
sendData(0x80); // Use internal temperature sensor to select an appropriate refresh waveform
}
void GDEY0154D67::configUpdateSequence()
{
switch (updateType) {
case FAST:
sendCommand(0x22); // Set "update sequence"
sendData(0xFF); // Will load LUT from OTP memory, Display mode 2 "differential refresh"
break;
case FULL:
default:
sendCommand(0x22); // Set "update sequence"
sendData(0xF7); // Will load LUT from OTP memory
break;
}
}
// Once the refresh operation has been started,
// begin periodically polling the display to check for completion, using the normal Meshtastic threading code
// Only used when refresh is "async"
void GDEY0154D67::detachFromUpdate()
{
switch (updateType) {
case FAST:
return beginPolling(50, 300); // At least 300ms for fast refresh
case FULL:
default:
return beginPolling(100, 1500); // At least 1.5 seconds for full refresh
}
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,42 @@
/*
E-Ink display driver
- GDEY0154D67
- Manufacturer: Goodisplay
- Size: 1.54 inch
- Resolution: 200px x 200px
- Flex connector marking (not a unique identifier): FPC-B001
*/
#pragma once
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "configuration.h"
#include "./SSD16XX.h"
namespace NicheGraphics::Drivers
{
class GDEY0154D67 : public SSD16XX
{
// Display properties
private:
static constexpr uint32_t width = 200;
static constexpr uint32_t height = 200;
static constexpr UpdateTypes supported = (UpdateTypes)(FULL | FAST);
public:
GDEY0154D67() : SSD16XX(width, height, supported) {}
protected:
void configScanning() override;
void configWaveform() override;
void configUpdateSequence() override;
void detachFromUpdate() override;
};
} // namespace NicheGraphics::Drivers
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,58 @@
#include "./GDEY0213B74.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
using namespace NicheGraphics::Drivers;
// Map the display controller IC's output to the connected panel
void GDEY0213B74::configScanning()
{
// "Driver output control"
sendCommand(0x01);
sendData(0xF9);
sendData(0x00);
sendData(0x00);
}
// Specify which information is used to control the sequence of voltages applied to move the pixels
// - For this display, configUpdateSequence() specifies that a suitable LUT will be loaded from
// the controller IC's OTP memory, when the update procedure begins.
void GDEY0213B74::configWaveform()
{
sendCommand(0x3C); // Border waveform:
sendData(0x05); // Screen border should follow LUT1 waveform (actively drive pixels white)
sendCommand(0x18); // Temperature sensor:
sendData(0x80); // Use internal temperature sensor to select an appropriate refresh waveform
}
void GDEY0213B74::configUpdateSequence()
{
switch (updateType) {
case FAST:
sendCommand(0x22); // Set "update sequence"
sendData(0xFF); // Will load LUT from OTP memory, Display mode 2 "differential refresh"
break;
case FULL:
default:
sendCommand(0x22); // Set "update sequence"
sendData(0xF7); // Will load LUT from OTP memory
break;
}
}
// Once the refresh operation has been started,
// begin periodically polling the display to check for completion, using the normal Meshtastic threading code
// Only used when refresh is "async"
void GDEY0213B74::detachFromUpdate()
{
switch (updateType) {
case FAST:
return beginPolling(50, 500); // At least 500ms for fast refresh
case FULL:
default:
return beginPolling(100, 2000); // At least 2 seconds for full refresh
}
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,44 @@
/*
E-Ink display driver
- GDEY0213B74
- Manufacturer: Goodisplay
- Size: 2.13 inch
- Resolution: 250px x 122px
- Flex connector marking (not a unique identifier):
- FPC-A002
- FPC-A005 20.06.15 TRX
*/
#pragma once
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "configuration.h"
#include "./SSD16XX.h"
namespace NicheGraphics::Drivers
{
class GDEY0213B74 : public SSD16XX
{
// Display properties
private:
static constexpr uint32_t width = 122;
static constexpr uint32_t height = 250;
static constexpr UpdateTypes supported = (UpdateTypes)(FULL | FAST);
public:
GDEY0213B74() : SSD16XX(width, height, supported) {}
protected:
virtual void configScanning() override;
virtual void configWaveform() override;
virtual void configUpdateSequence() override;
void detachFromUpdate() override;
};
} // namespace NicheGraphics::Drivers
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,61 @@
#include "./HINK_E0213A289.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
using namespace NicheGraphics::Drivers;
// Map the display controller IC's output to the connected panel
void HINK_E0213A289::configScanning()
{
// "Driver output control"
// Scan gates from 0 to 249 (vertical resolution 250px)
sendCommand(0x01);
sendData(0xF9); // Maximum gate # (249, bits 0-7)
sendData(0x00); // Maximum gate # (bit 8)
sendData(0x00); // (Do not invert scanning order)
}
// Specify which information is used to control the sequence of voltages applied to move the pixels
// - For this display, configUpdateSequence() specifies that a suitable LUT will be loaded from
// the controller IC's OTP memory, when the update procedure begins.
void HINK_E0213A289::configWaveform()
{
sendCommand(0x3C); // Border waveform:
sendData(0x05); // Screen border should follow LUT1 waveform (actively drive pixels white)
sendCommand(0x18); // Temperature sensor:
sendData(0x80); // Use internal temperature sensor to select an appropriate refresh waveform
}
// Describes the sequence of events performed by the displays controller IC during a refresh
// Includes "power up", "load settings from memory", "update the pixels", etc
void HINK_E0213A289::configUpdateSequence()
{
switch (updateType) {
case FAST:
sendCommand(0x22); // Set "update sequence"
sendData(0xFF); // Will load LUT from OTP memory, Display mode 2 "differential refresh"
break;
case FULL:
default:
sendCommand(0x22); // Set "update sequence"
sendData(0xF7); // Will load LUT from OTP memory
break;
}
}
// Once the refresh operation has been started,
// begin periodically polling the display to check for completion, using the normal Meshtastic threading code
// Only used when refresh is "async"
void HINK_E0213A289::detachFromUpdate()
{
switch (updateType) {
case FAST:
return beginPolling(50, 500); // At least 500ms for fast refresh
case FULL:
default:
return beginPolling(100, 1000); // At least 1 second for full refresh (quick; display only blinks pixels once)
}
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,44 @@
/*
E-Ink display driver
- HINK_E0213A289
- Manufacturer: Holitech
- Size: 2.13 inch
- Resolution: 122px x 250px
- Flex connector label (not a unique identifier): FPC-7528B
Note: as of Feb. 2025, these panels are used for "WeActStudio 2.13in B&W" display modules
*/
#pragma once
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "configuration.h"
#include "./SSD16XX.h"
namespace NicheGraphics::Drivers
{
class HINK_E0213A289 : public SSD16XX
{
// Display properties
private:
static constexpr uint32_t width = 122;
static constexpr uint32_t height = 250;
static constexpr UpdateTypes supported = (UpdateTypes)(FULL | FAST);
public:
HINK_E0213A289() : SSD16XX(width, height, supported, 1) {}
protected:
void configScanning() override;
void configWaveform() override;
void configUpdateSequence() override;
void detachFromUpdate() override;
};
} // namespace NicheGraphics::Drivers
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,58 @@
#include "./HINK_E042A87.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
using namespace NicheGraphics::Drivers;
// Load settings about how the pixels are moved from old state to new state during a refresh
// - manually specified,
// - or with stored values from displays OTP memory
void HINK_E042A87::configWaveform()
{
sendCommand(0x3C); // Border waveform:
sendData(0x01); // Follow LUT for VSH1
sendCommand(0x18); // Temperature sensor:
sendData(0x80); // Use internal temperature sensor to select an appropriate refresh waveform
}
// Describes the sequence of events performed by the displays controller IC during a refresh
// Includes "power up", "load settings from memory", "update the pixels", etc
void HINK_E042A87::configUpdateSequence()
{
switch (updateType) {
case FAST:
sendCommand(0x21); // Use both "old" and "new" image memory (differential)
sendData(0x00);
sendData(0x00);
sendCommand(0x22); // Set "update sequence"
sendData(0xFF); // Differential, load waveform from OTP
break;
case FULL:
default:
sendCommand(0x21); // Bypass "old" image memory (non-differential)
sendData(0x40);
sendData(0x00);
sendCommand(0x22); // Set "update sequence":
sendData(0xF7); // Non-differential, load waveform from OTP
break;
}
}
// Once the refresh operation has been started,
// begin periodically polling the display to check for completion, using the normal Meshtastic threading code
// Only used when refresh is "async"
void HINK_E042A87::detachFromUpdate()
{
switch (updateType) {
case FAST:
return beginPolling(50, 1000); // At least 1 second, then check every 50ms
case FULL:
default:
return beginPolling(100, 3500); // At least 3.5 seconds, then check every 100ms
}
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,43 @@
/*
E-Ink display driver
- HINK-E042A87
- Manufacturer: Holitech
- Size: 4.2 inch
- Resolution: 400px x 300px
- Flex connector marking (not a unique identifier): HINK-E042A07-FPC-A1
- Silver sticker with QR code, marked: HE042A87
Note: as of Feb. 2025, these panels are used for "WeActStudio 4.2in B&W" display modules
*/
#pragma once
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "configuration.h"
#include "./SSD16XX.h"
namespace NicheGraphics::Drivers
{
class HINK_E042A87 : public SSD16XX
{
// Display properties
private:
static constexpr uint32_t width = 400;
static constexpr uint32_t height = 300;
static constexpr UpdateTypes supported = (UpdateTypes)(FULL | FAST);
public:
HINK_E042A87() : SSD16XX(width, height, supported) {}
protected:
void configWaveform() override;
void configUpdateSequence() override;
void detachFromUpdate() override;
};
} // namespace NicheGraphics::Drivers
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,68 @@
#include "./LCMEN2R13ECC1.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
using namespace NicheGraphics::Drivers;
// Map the display controller IC's output to the connected panel
void LCMEN2R13ECC1::configScanning()
{
// "Driver output control"
sendCommand(0x01);
sendData(0xF9);
sendData(0x00);
sendData(0x00);
// To-do: delete this method?
// Values set here might be redundant: F9, 00, 00 seems to be default
}
// Specify which information is used to control the sequence of voltages applied to move the pixels
// - For this display, configUpdateSequence() specifies that a suitable LUT will be loaded from
// the controller IC's OTP memory, when the update procedure begins.
void LCMEN2R13ECC1::configWaveform()
{
switch (updateType) {
case FAST:
sendCommand(0x3C); // Border waveform:
sendData(0x85);
break;
case FULL:
default:
// From OTP memory
break;
}
}
void LCMEN2R13ECC1::configUpdateSequence()
{
switch (updateType) {
case FAST:
sendCommand(0x22); // Set "update sequence"
sendData(0xFF); // Will load LUT from OTP memory, Display mode 2 "differential refresh"
break;
case FULL:
default:
sendCommand(0x22); // Set "update sequence"
sendData(0xF7); // Will load LUT from OTP memory
break;
}
}
// Once the refresh operation has been started,
// begin periodically polling the display to check for completion, using the normal Meshtastic threading code
// Only used when refresh is "async"
void LCMEN2R13ECC1::detachFromUpdate()
{
switch (updateType) {
case FAST:
return beginPolling(50, 800); // At least 500ms for fast refresh
case FULL:
default:
return beginPolling(100, 2500); // At least 2 seconds for full refresh
}
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,40 @@
/*
E-Ink display driver
- SSD1680
- Manufacturer: WISEVAST
- Size: 2.13 inch
- Resolution: 122px x 255px
*/
#pragma once
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "configuration.h"
#include "./SSD16XX.h"
namespace NicheGraphics::Drivers
{
class LCMEN2R13ECC1 : public SSD16XX
{
// Display properties
private:
static constexpr uint32_t width = 122;
static constexpr uint32_t height = 250;
static constexpr UpdateTypes supported = (UpdateTypes)(FULL | FAST);
public:
LCMEN2R13ECC1() : SSD16XX(width, height, supported, 1) {} // Note: left edge of this display is offset by 1 byte
protected:
virtual void configScanning() override;
virtual void configWaveform() override;
virtual void configUpdateSequence() override;
void detachFromUpdate() override;
};
} // namespace NicheGraphics::Drivers
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,306 @@
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "./LCMEN2R13EFC1.h"
#include <assert.h>
#include "SPILock.h"
using namespace NicheGraphics::Drivers;
// Look up table: fast refresh, common electrode
static const uint8_t LUT_FAST_VCOMDC[] = {
0x01, 0x06, 0x03, 0x02, 0x01, 0x01, 0x01, //
0x01, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
};
// Look up table: fast refresh, pixels which remain white
static const uint8_t LUT_FAST_WW[] = {
0x01, 0x06, 0x03, 0x02, 0x81, 0x01, 0x01, //
0x01, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
};
// Look up table: fast refresh, pixel which change from black to white
static const uint8_t LUT_FAST_BW[] = {
0x01, 0x86, 0x83, 0x82, 0x81, 0x01, 0x01, //
0x01, 0x86, 0x82, 0x01, 0x01, 0x01, 0x01, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
};
// Look up table: fast refresh, pixels which change from white to black
static const uint8_t LUT_FAST_WB[] = {
0x01, 0x46, 0x43, 0x02, 0x01, 0x01, 0x01, //
0x01, 0x46, 0x42, 0x01, 0x01, 0x01, 0x01, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
};
// Look up table: fast refresh, pixels which remain black
static const uint8_t LUT_FAST_BB[] = {
0x01, 0x06, 0x03, 0x42, 0x41, 0x01, 0x01, //
0x01, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
};
LCMEN213EFC1::LCMEN213EFC1() : EInk(width, height, supported)
{
// Pre-calculate size of the image buffer, for convenience
// Determine the X dimension of the image buffer, in bytes.
// Along rows, pixels are stored 8 per byte.
// Not all display widths are divisible by 8. Need to make sure bytecount accommodates padding for these.
bufferRowSize = ((width - 1) / 8) + 1;
// Total size of image buffer, in bytes.
bufferSize = bufferRowSize * height;
}
void LCMEN213EFC1::begin(SPIClass *spi, uint8_t pin_dc, uint8_t pin_cs, uint8_t pin_busy, uint8_t pin_rst)
{
this->spi = spi;
this->pin_dc = pin_dc;
this->pin_cs = pin_cs;
this->pin_busy = pin_busy;
this->pin_rst = pin_rst;
pinMode(pin_dc, OUTPUT);
pinMode(pin_cs, OUTPUT);
pinMode(pin_busy, INPUT);
// Reset is active low, hold high
pinMode(pin_rst, INPUT_PULLUP);
reset();
}
// Display an image on the display
void LCMEN213EFC1::update(uint8_t *imageData, UpdateTypes type)
{
this->updateType = type;
this->buffer = imageData;
reset();
// Config
if (updateType == FULL)
configFull();
else
configFast();
// Transfer image data
if (updateType == FULL) {
writeNewImage();
writeOldImage();
} else {
writeNewImage();
}
sendCommand(0x04); // Power on the panel voltage
wait();
sendCommand(0x12); // Begin executing the update
// Let the update run async, on display hardware. Base class will poll completion, then finalize.
// For a blocking update, call await after update
detachFromUpdate();
}
void LCMEN213EFC1::wait()
{
// Busy when LOW
while (digitalRead(pin_busy) == LOW)
yield();
}
void LCMEN213EFC1::reset()
{
pinMode(pin_rst, OUTPUT);
digitalWrite(pin_rst, LOW);
delay(10);
pinMode(pin_rst, INPUT_PULLUP);
wait();
sendCommand(0x12);
wait();
}
void LCMEN213EFC1::sendCommand(const uint8_t command)
{
// Take firmware's SPI lock
spiLock->lock();
spi->beginTransaction(spiSettings);
digitalWrite(pin_dc, LOW); // DC pin low indicates command
digitalWrite(pin_cs, LOW);
spi->transfer(command);
digitalWrite(pin_cs, HIGH);
digitalWrite(pin_dc, HIGH);
spi->endTransaction();
spiLock->unlock();
}
void LCMEN213EFC1::sendData(uint8_t data)
{
sendData(&data, 1);
}
void LCMEN213EFC1::sendData(const uint8_t *data, uint32_t size)
{
// Take firmware's SPI lock
spiLock->lock();
spi->beginTransaction(spiSettings);
digitalWrite(pin_dc, HIGH); // DC pin HIGH indicates data, instead of command
digitalWrite(pin_cs, LOW);
// Platform-specific SPI command
// Mothballing. This display model is only used by Heltec Wireless Paper (ESP32)
#if defined(ARCH_ESP32)
spi->transferBytes(data, NULL, size); // NULL for a "write only" transfer
#elif defined(ARCH_NRF52)
spi->transfer(data, NULL, size); // NULL for a "write only" transfer
#else
#error Not implemented yet? Feel free to add other platforms here.
#endif
digitalWrite(pin_cs, HIGH);
digitalWrite(pin_dc, HIGH);
spi->endTransaction();
spiLock->unlock();
}
void LCMEN213EFC1::configFull()
{
sendCommand(0x00); // Panel setting register
sendData(0b11 << 6 // Display resolution
| 1 << 4 // B&W only
| 1 << 3 // Vertical scan direction
| 1 << 2 // Horizontal scan direction
| 1 << 1 // Shutdown: no
| 1 << 0 // Reset: no
);
sendCommand(0x50); // VCOM and data interval setting register
sendData(0b10 << 6 // Border driven white
| 0b11 << 4 // Invert image colors: no
| 0b0111 << 0 // Interval between VCOM on and image data (default)
);
}
void LCMEN213EFC1::configFast()
{
sendCommand(0x00); // Panel setting register
sendData(0b11 << 6 // Display resolution
| 1 << 5 // LUT from registers (set below)
| 1 << 4 // B&W only
| 1 << 3 // Vertical scan direction
| 1 << 2 // Horizontal scan direction
| 1 << 1 // Shutdown: no
| 1 << 0 // Reset: no
);
sendCommand(0x50); // VCOM and data interval setting register
sendData(0b11 << 6 // Border floating
| 0b01 << 4 // Invert image colors: no
| 0b0111 << 0 // Interval between VCOM on and image data (default)
);
// Load the various LUTs
sendCommand(0x20); // VCOM
sendData(LUT_FAST_VCOMDC, sizeof(LUT_FAST_VCOMDC));
sendCommand(0x21); // White -> White
sendData(LUT_FAST_WW, sizeof(LUT_FAST_WW));
sendCommand(0x22); // Black -> White
sendData(LUT_FAST_BW, sizeof(LUT_FAST_BW));
sendCommand(0x23); // White -> Black
sendData(LUT_FAST_WB, sizeof(LUT_FAST_WB));
sendCommand(0x24); // Black -> Black
sendData(LUT_FAST_BB, sizeof(LUT_FAST_BB));
}
void LCMEN213EFC1::writeNewImage()
{
sendCommand(0x13);
sendData(buffer, bufferSize);
}
void LCMEN213EFC1::writeOldImage()
{
sendCommand(0x10);
sendData(buffer, bufferSize);
}
void LCMEN213EFC1::detachFromUpdate()
{
// To save power / cycles, displays can choose to specify an "expected duration" for various refresh types
// If we know a full-refresh takes at least 4 seconds, we can delay polling until 3 seconds have passed
// If not implemented, we'll just poll right from the get-go
switch (updateType) {
case FULL:
EInk::beginPolling(10, 3650);
break;
case FAST:
EInk::beginPolling(10, 720);
break;
default:
assert(false);
}
}
bool LCMEN213EFC1::isUpdateDone()
{
// Busy when LOW
if (digitalRead(pin_busy) == LOW)
return false;
else
return true;
}
void LCMEN213EFC1::finalizeUpdate()
{
// Power off the panel voltages
sendCommand(0x02);
wait();
// Put a copy of the image into the "old memory".
// Used with differential refreshes (e.g. FAST update), to determine which px need to move, and which can remain in place
// We need to keep the "old memory" up to date, because don't know whether next refresh will be FULL or FAST etc.
if (updateType != FULL) {
writeOldImage();
wait();
}
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,71 @@
/*
E-Ink display driver
- LCMEN213EFC1
- Manufacturer: Wisevast
- Size: 2.13 inch
- Resolution: 122px x 250px
- Flex connector marking (not a unique identifier): HINK-E0213A162-FPC-A0 (Hidden, printed on back-side)
Note: this display uses an uncommon controller IC, Fitipower JD79656.
It is implemented as a "one-off", directly inheriting the EInk base class, unlike SSD16XX displays.
*/
#pragma once
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "configuration.h"
#include "./EInk.h"
namespace NicheGraphics::Drivers
{
class LCMEN213EFC1 : public EInk
{
// Display properties
private:
static constexpr uint32_t width = 122;
static constexpr uint32_t height = 250;
static constexpr UpdateTypes supported = (UpdateTypes)(FULL | FAST);
public:
LCMEN213EFC1();
void begin(SPIClass *spi, uint8_t pin_dc, uint8_t pin_cs, uint8_t pin_busy, uint8_t pin_rst);
void update(uint8_t *imageData, UpdateTypes type) override;
protected:
void wait();
void reset();
void sendCommand(const uint8_t command);
void sendData(const uint8_t data);
void sendData(const uint8_t *data, uint32_t size);
void configFull(); // Configure display for FULL refresh
void configFast(); // Configure display for FAST refresh
void writeNewImage();
void writeOldImage(); // Used for "differential update", aka FAST refresh
void detachFromUpdate();
bool isUpdateDone();
void finalizeUpdate();
protected:
uint8_t bufferOffsetX = 0; // In bytes. Panel x=0 does not always align with controller x=0. Quirky internal wiring?
uint8_t bufferRowSize = 0; // In bytes. Rows store 8 pixels per byte. Rounded up to fit (e.g. 122px would require 16 bytes)
uint32_t bufferSize = 0; // In bytes. Rows * Columns
uint8_t *buffer = nullptr;
UpdateTypes updateType = UpdateTypes::UNSPECIFIED;
uint8_t pin_dc = -1;
uint8_t pin_cs = -1;
uint8_t pin_busy = -1;
uint8_t pin_rst = -1;
SPIClass *spi = nullptr;
SPISettings spiSettings = SPISettings(6000000, MSBFIRST, SPI_MODE0);
};
} // namespace NicheGraphics::Drivers
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,132 @@
# NicheGraphics - E-Ink Driver
A driver for E-Ink SPI displays. Suitable for re-use by various NicheGraphics UIs.
Your UI should use the class `NicheGraphics::Drivers::EInk` .
When you set up a hardware variant, you will use one of the specific display model classes, which extend the EInk class.
An example setup might look like this:
```cpp
void setupNicheGraphics()
{
using namespace NicheGraphics;
// An imaginary UI
YourCustomUI *yourUI = new YourCustomUI();
// Setup SPI
SPIClass *hspi = new SPIClass(HSPI);
hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS);
// Setup Enk driver
Drivers::EInk *driver = new Drivers::DEPG0290BNS800;
driver->begin(hspi, PIN_EINK_DC, PIN_EINK_CS, PIN_EINK_BUSY);
// Pass the driver to your UI
YourUI::driver = driver;
}
```
- [Methods](#methods)
- [`update(uint8_t *imageData, UpdateTypes type)`](#updateuint8_t-imagedata-updatetypes-type)
- [`await()`](#await)
- [`supports(UpdateTypes type)`](#supportsupdatetypes-type)
- [`busy()`](#busy)
- [`width()`](#width)
- [`height()`](#height)
- [Supporting New Displays](#supporting-new-displays)
- [Controller IC](#controller-ic)
- [Finding Information](#finding-information)
## Methods
### `update(uint8_t *imageData, UpdateTypes type)`
Update the image on the display
- _`imageData`_ to draw to the display.
- _`type`_ which type of update to perform.
- `FULL`
- `FAST` (partial refresh)
- (Other custom types may be possible)
The imageData is a 1-bit image. X-Pixels are 8-per byte, with the MSB being the leftmost pixel. This was not an InkHUD design decision; it is the raw format accepted by the E-Ink display controllers ICs.
_To-do: add a helper method to `InkHUD::Drivers::EInk` to do this arithmetic for you._
```cpp
uint16_t w = driver::width();
uint16_t h = driver::height();
uint8_t image[ (w/8) * h ]; // X pixels are 8-per-byte
image[0] |= (1 << 7); // Set pixel x=0, y=0
image[0] |= (1 << 0); // Set pixel x=7, y=0
image[1] |= (1 << 7); // Set pixel x=8, y=0
uint8_t x = 12;
uint8_t y = 2;
uint8_t yBytes = y * (w/8);
uint8_t xBytes = x / 8;
uint8_t xBits = (7-x) % 8;
image[yByte + xByte] |= (1 << xBits); // Set pixel x=12, y=2
```
### `await()`
Wait for an in-progress update to complete before continuing
### `supports(UpdateTypes type)`
Check if display supports a specific update type. `true` if supported.
- _`type`_ type to check
### `busy()`
Check if display is already performing an `update()`. `true` if already updating.
### `width()`
Width of the display, in pixels. Note: most displays are portrait. Your UI will need to implement rotation in software.
### `height()`
Height of the display, in pixels. Note: most displays are portrait. Your UI will need to implement rotation in software.
## Supporting New Displays
_This topic is not covered in depth, but these notes may be helpful._
The `InkHUD::Drivers::EInk` class contains only the mechanism for implementing an E-Ink driver on-top of Meshtastic's `OSThread`. A driver for a specific display needs to extend this class.
### Controller IC
If your display uses a controller IC from Solomon Systech, you can probably extend the existing `Drivers::SSD16XX` class, making only minor modifications.
At this stage, displays using controller ICS from other manufacturers (UltraChip, Fitipower, etc) need to manually implemented. See `Drivers::LCMEN2R13EFC1` for an example.
Generic base classes for manufacturers other than Solomon Systech might be added here in future.
### Finding Information
#### Flex-Connector Labels
The orange flex-connector attached to E-Ink displays is often printed with an identifying label. This is not a _totally_ unique identifier, but does give a very strong clue as to the true model of the display, which can be used to search out further information.
#### Datasheets
The manufacturer of a DIY display module may publish a datasheet. These are often incomplete, but might reveal the true model of the display, or the controller IC.
If you can determine the true model name of the display, you can likely find a more complete datasheet on the display manufacturer's website. This will often provide a "typical operating sequence"; a general overview of the code used to drive the display
#### Example Code
The manufacturer of a DIY module may publish example code. You may have more luck finding example code published by the display manufacturer themselves, if you can determine the true model of the panel. These examples are a very valuable reference.
#### Other E-Ink drivers
Libraries like ZinggJM's GxEPD2 can be valuable sources of information, although your panel may not be _specifically_ supported, and only _compatible_ with a driver there, so some caution is advised.
The display selection file in GxEPD2's Hello World example is also a useful resource for matching "flex connector labels" with display models, but the flex connector label is _not_ a unique identifier, so this is only another clue.
@@ -0,0 +1,41 @@
#include "./SSD1682.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
using namespace NicheGraphics::Drivers;
SSD1682::SSD1682(uint16_t width, uint16_t height, EInk::UpdateTypes supported, uint8_t bufferOffsetX)
: SSD16XX(width, height, supported, bufferOffsetX)
{
}
// SSD1682 only accepts single-byte x and y values
// This causes an incompatibility with the default SSD16XX::configFullscreen
void SSD1682::configFullscreen()
{
// Define the boundaries of the "fullscreen" region, for the controller IC
static const uint8_t sx = bufferOffsetX; // Notice the offset
static const uint8_t sy = 0;
static const uint8_t ex = bufferRowSize + bufferOffsetX - 1; // End is "max index", not "count". Minus 1 handles this
static const uint8_t ey = height;
// Data entry mode - Left to Right, Top to Bottom
sendCommand(0x11);
sendData(0x03);
// Select controller IC memory region to display a fullscreen image
sendCommand(0x44); // Memory X start - end
sendData(sx);
sendData(ex);
sendCommand(0x45); // Memory Y start - end
sendData(sy);
sendData(ey);
// Place the cursor at the start of this memory region, ready to send image data x=0 y=0
sendCommand(0x4E); // Memory cursor X
sendData(sx);
sendCommand(0x4F); // Memory cursor y
sendData(sy);
}
#endif
@@ -0,0 +1,31 @@
/*
E-Ink base class for displays based on SSD1682
SSD1682 has a few quirks. We're implementing them here in a new base class,
to avoid re-implementing them every time we need to add a new SSD1682-based display.
*/
#pragma once
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "configuration.h"
#include "./SSD16XX.h"
namespace NicheGraphics::Drivers
{
class SSD1682 : public SSD16XX
{
public:
SSD1682(uint16_t width, uint16_t height, EInk::UpdateTypes supported, uint8_t bufferOffsetX = 0);
virtual void configFullscreen(); // Select memory region on controller IC
virtual void deepSleep() {} // Not usable (image memory not retained)
};
} // namespace NicheGraphics::Drivers
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,272 @@
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "./SSD16XX.h"
#include "SPILock.h"
using namespace NicheGraphics::Drivers;
SSD16XX::SSD16XX(uint16_t width, uint16_t height, UpdateTypes supported, uint8_t bufferOffsetX)
: EInk(width, height, supported), bufferOffsetX(bufferOffsetX)
{
// Pre-calculate size of the image buffer, for convenience
// Determine the X dimension of the image buffer, in bytes.
// Along rows, pixels are stored 8 per byte.
// Not all display widths are divisible by 8. Need to make sure bytecount accommodates padding for these.
bufferRowSize = ((width - 1) / 8) + 1;
// Total size of image buffer, in bytes.
bufferSize = bufferRowSize * height;
}
void SSD16XX::begin(SPIClass *spi, uint8_t pin_dc, uint8_t pin_cs, uint8_t pin_busy, uint8_t pin_rst)
{
this->spi = spi;
this->pin_dc = pin_dc;
this->pin_cs = pin_cs;
this->pin_busy = pin_busy;
this->pin_rst = pin_rst;
pinMode(pin_dc, OUTPUT);
pinMode(pin_cs, OUTPUT);
pinMode(pin_busy, INPUT);
// If using a reset pin, hold high
// Reset is active low for Solomon Systech ICs
if (pin_rst != 0xFF)
pinMode(pin_rst, INPUT_PULLUP);
reset();
}
// Poll the displays busy pin until an operation is complete
// Timeout and set fail flag if something went wrong and the display got stuck
void SSD16XX::wait(uint32_t timeout)
{
// Don't bother waiting if part of the update sequence failed
// In that situation, we're now just failing-through the process, until we can try again with next update.
if (failed)
return;
uint32_t startMs = millis();
// Busy when HIGH
while (digitalRead(pin_busy) == HIGH) {
// Check for timeout
if (millis() - startMs > timeout) {
failed = true;
break;
}
yield();
}
}
void SSD16XX::reset()
{
// Check if reset pin is defined
if (pin_rst != 0xFF) {
pinMode(pin_rst, OUTPUT);
digitalWrite(pin_rst, LOW);
delay(10);
digitalWrite(pin_rst, HIGH);
delay(10);
wait();
}
sendCommand(0x12);
wait();
}
void SSD16XX::sendCommand(const uint8_t command)
{
// Abort if part of the update sequence failed
// This will unlock again once we have failed-through the entire process
if (failed)
return;
// Take firmware's SPI lock
spiLock->lock();
spi->beginTransaction(spiSettings);
digitalWrite(pin_dc, LOW); // DC pin low indicates command
digitalWrite(pin_cs, LOW);
spi->transfer(command);
digitalWrite(pin_cs, HIGH);
digitalWrite(pin_dc, HIGH);
spi->endTransaction();
spiLock->unlock();
}
void SSD16XX::sendData(uint8_t data)
{
sendData(&data, 1);
}
void SSD16XX::sendData(const uint8_t *data, uint32_t size)
{
// Abort if part of the update sequence failed
// This will unlock again once we have failed-through the entire process
if (failed)
return;
// Take firmware's SPI lock
spiLock->lock();
spi->beginTransaction(spiSettings);
digitalWrite(pin_dc, HIGH); // DC pin HIGH indicates data, instead of command
digitalWrite(pin_cs, LOW);
// Platform-specific SPI command
#if defined(ARCH_ESP32)
spi->transferBytes(data, NULL, size); // NULL for a "write only" transfer
#elif defined(ARCH_NRF52)
spi->transfer(data, NULL, size); // NULL for a "write only" transfer
#else
#error Not implemented yet? Feel free to add other platforms here.
#endif
digitalWrite(pin_cs, HIGH);
digitalWrite(pin_dc, HIGH);
spi->endTransaction();
spiLock->unlock();
}
void SSD16XX::configFullscreen()
{
// Placing this code in a separate method because it's probably pretty consistent between displays
// Should make it tidier to override SSD16XX::configure
// Define the boundaries of the "fullscreen" region, for the controller IC
static const uint16_t sx = bufferOffsetX; // Notice the offset
static const uint16_t sy = 0;
static const uint16_t ex = bufferRowSize + bufferOffsetX - 1; // End is "max index", not "count". Minus 1 handles this
static const uint16_t ey = height;
// Split into bytes
static const uint8_t sy1 = sy & 0xFF;
static const uint8_t sy2 = (sy >> 8) & 0xFF;
static const uint8_t ey1 = ey & 0xFF;
static const uint8_t ey2 = (ey >> 8) & 0xFF;
// Data entry mode - Left to Right, Top to Bottom
sendCommand(0x11);
sendData(0x03);
// Select controller IC memory region to display a fullscreen image
sendCommand(0x44); // Memory X start - end
sendData(sx);
sendData(ex);
sendCommand(0x45); // Memory Y start - end
sendData(sy1);
sendData(sy2);
sendData(ey1);
sendData(ey2);
// Place the cursor at the start of this memory region, ready to send image data x=0 y=0
sendCommand(0x4E); // Memory cursor X
sendData(sx);
sendCommand(0x4F); // Memory cursor y
sendData(sy1);
sendData(sy2);
}
void SSD16XX::update(uint8_t *imageData, UpdateTypes type)
{
this->updateType = type;
this->buffer = imageData;
reset();
configFullscreen();
configScanning(); // Virtual, unused by base class
configVoltages(); // Virtual, unused by base class
configWaveform(); // Virtual, unused by base class
wait();
if (updateType == FULL) {
writeNewImage();
writeOldImage();
} else {
writeNewImage();
}
configUpdateSequence();
sendCommand(0x20); // Begin executing the update
// Let the update run async, on display hardware. Base class will poll completion, then finalize.
// For a blocking update, call await after update
detachFromUpdate();
}
// Send SPI commands for controller IC to begin executing the refresh operation
void SSD16XX::configUpdateSequence()
{
switch (updateType) {
default:
sendCommand(0x22); // Set "update sequence"
sendData(0xF7); // Non-differential, load waveform from OTP
break;
}
}
void SSD16XX::writeNewImage()
{
sendCommand(0x24);
sendData(buffer, bufferSize);
}
void SSD16XX::writeOldImage()
{
sendCommand(0x26);
sendData(buffer, bufferSize);
}
void SSD16XX::detachFromUpdate()
{
// To save power / cycles, displays can choose to specify an "expected duration" for various refresh types
// If we know a full-refresh takes at least 4 seconds, we can delay polling until 3 seconds have passed
// If not implemented, we'll just poll right from the get-go
switch (updateType) {
default:
EInk::beginPolling(100, 0);
}
}
bool SSD16XX::isUpdateDone()
{
// Busy when HIGH
if (digitalRead(pin_busy) == HIGH)
return false;
else
return true;
}
void SSD16XX::finalizeUpdate()
{
// Put a copy of the image into the "old memory".
// Used with differential refreshes (e.g. FAST update), to determine which px need to move, and which can remain in place
// We need to keep the "old memory" up to date, because don't know whether next refresh will be FULL or FAST etc.
if (updateType != FULL) {
writeNewImage(); // Only required by some controller variants. Todo: Override just for GDEY0154D678?
writeOldImage();
sendCommand(0x7F); // Terminate image write without update
wait();
}
// Enter deep-sleep to save a few µA
// Waking from this requires that display's reset pin is broken out
if (pin_rst != 0xFF)
deepSleep();
}
// Enter a lower-power state
// May only save a few µA..
void SSD16XX::deepSleep()
{
sendCommand(0x10); // Enter deep sleep
sendData(0x01); // Mode 1: preserve image RAM
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,66 @@
/*
E-Ink base class for displays based on SSD16XX
Most (but not all) SPI E-Ink displays use this family of controller IC.
Implementing new SSD16XX displays should be fairly painless.
See DEPG0154BNS800 and DEPG0290BNS800 for examples.
*/
#pragma once
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "configuration.h"
#include "./EInk.h"
namespace NicheGraphics::Drivers
{
class SSD16XX : public EInk
{
public:
SSD16XX(uint16_t width, uint16_t height, UpdateTypes supported, uint8_t bufferOffsetX = 0);
virtual void begin(SPIClass *spi, uint8_t pin_dc, uint8_t pin_cs, uint8_t pin_busy, uint8_t pin_rst = -1);
virtual void update(uint8_t *imageData, UpdateTypes type) override;
protected:
virtual void wait(uint32_t timeout = 1000);
virtual void reset();
virtual void sendCommand(const uint8_t command);
virtual void sendData(const uint8_t data);
virtual void sendData(const uint8_t *data, uint32_t size);
virtual void configFullscreen(); // Select memory region on controller IC
virtual void configScanning() {} // Optional. First & last gates, scan direction, etc
virtual void configVoltages() {} // Optional. Manual panel voltages, soft-start, etc
virtual void configWaveform() {} // Optional. LUT, panel border, temperature sensor, etc
virtual void configUpdateSequence(); // Tell controller IC which operations to run
virtual void writeNewImage();
virtual void writeOldImage(); // Image which can be used at *next* update for "differential refresh"
virtual void detachFromUpdate();
virtual bool isUpdateDone() override;
virtual void finalizeUpdate() override;
virtual void deepSleep();
protected:
uint8_t bufferOffsetX = 0; // In bytes. Panel x=0 does not always align with controller x=0. Quirky internal wiring?
uint8_t bufferRowSize = 0; // In bytes. Rows store 8 pixels per byte. Rounded up to fit (e.g. 122px would require 16 bytes)
uint32_t bufferSize = 0; // In bytes. Rows * Columns
uint8_t *buffer = nullptr;
UpdateTypes updateType = UpdateTypes::UNSPECIFIED;
uint8_t pin_dc = -1;
uint8_t pin_cs = -1;
uint8_t pin_busy = -1;
uint8_t pin_rst = -1;
SPIClass *spi = nullptr;
SPISettings spiSettings = SPISettings(4000000, MSBFIRST, SPI_MODE0);
};
} // namespace NicheGraphics::Drivers
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,68 @@
#include "./ZJY122250_0213BAAMFGN.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
using namespace NicheGraphics::Drivers;
// Map the display controller IC's output to the connected panel
void ZJY122250_0213BAAMFGN::configScanning()
{
// "Driver output control"
// Scan gates from 0 to 249 (vertical resolution 250px)
sendCommand(0x01);
sendData(0xF9);
sendData(0x00);
sendData(0x00);
}
// Specify which information is used to control the sequence of voltages applied to move the pixels
// - For this display, configUpdateSequence() specifies that a suitable LUT will be loaded from
// the controller IC's OTP memory, when the update procedure begins.
void ZJY122250_0213BAAMFGN::configWaveform()
{
switch (updateType) {
case FAST:
sendCommand(0x3C); // Border waveform:
sendData(0x80); // VCOM
break;
case FULL:
default:
sendCommand(0x3C); // Border waveform:
sendData(0x01); // Follow LUT 1 (blink same as white pixels)
break;
}
sendCommand(0x18); // Temperature sensor:
sendData(0x80); // Use internal temperature sensor to select an appropriate refresh waveform
}
void ZJY122250_0213BAAMFGN::configUpdateSequence()
{
switch (updateType) {
case FAST:
sendCommand(0x22); // Set "update sequence"
sendData(0xFF); // Will load LUT from OTP memory, Display mode 2 "differential refresh"
break;
case FULL:
default:
sendCommand(0x22); // Set "update sequence"
sendData(0xF7); // Will load LUT from OTP memory
break;
}
}
// Once the refresh operation has been started,
// begin periodically polling the display to check for completion, using the normal Meshtastic threading code
// Only used when refresh is "async"
void ZJY122250_0213BAAMFGN::detachFromUpdate()
{
switch (updateType) {
case FAST:
return beginPolling(50, 500); // At least 500ms for fast refresh
case FULL:
default:
return beginPolling(100, 2000); // At least 2 seconds for full refresh
}
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,42 @@
/*
E-Ink display driver
- ZJY122250_0213BAAMFGN
- Manufacturer: Zhongjingyuan
- Size: 2.13 inch
- Resolution: 250px x 122px
- Flex connector marking (not a unique identifier): FPC-A002
*/
#pragma once
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "configuration.h"
#include "./SSD16XX.h"
namespace NicheGraphics::Drivers
{
class ZJY122250_0213BAAMFGN : public SSD16XX
{
// Display properties
private:
static constexpr uint32_t width = 122;
static constexpr uint32_t height = 250;
static constexpr UpdateTypes supported = (UpdateTypes)(FULL | FAST);
public:
ZJY122250_0213BAAMFGN() : SSD16XX(width, height, supported) {}
protected:
virtual void configScanning() override;
virtual void configWaveform() override;
virtual void configUpdateSequence() override;
void detachFromUpdate() override;
};
} // namespace NicheGraphics::Drivers
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,59 @@
#include "./ZJY128296_029EAAMFGN.h"
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
using namespace NicheGraphics::Drivers;
// Map the display controller IC's output to the connected panel
void ZJY128296_029EAAMFGN::configScanning()
{
// "Driver output control"
// Scan gates from 0 to 295 (vertical resolution 296px)
sendCommand(0x01);
sendData(0x27); // Number of gates (295, bits 0-7)
sendData(0x01); // Number of gates (295, bit 8)
sendData(0x00); // (Do not invert scanning order)
}
// Specify which information is used to control the sequence of voltages applied to move the pixels
// - For this display, configUpdateSequence() specifies that a suitable LUT will be loaded from
// the controller IC's OTP memory, when the update procedure begins.
void ZJY128296_029EAAMFGN::configWaveform()
{
sendCommand(0x3C); // Border waveform:
sendData(0x05); // Screen border should follow LUT1 waveform (actively drive pixels white)
sendCommand(0x18); // Temperature sensor:
sendData(0x80); // Use internal temperature sensor to select an appropriate refresh waveform
}
void ZJY128296_029EAAMFGN::configUpdateSequence()
{
switch (updateType) {
case FAST:
sendCommand(0x22); // Set "update sequence"
sendData(0xFF); // Will load LUT from OTP memory, Display mode 2 "differential refresh"
break;
case FULL:
default:
sendCommand(0x22); // Set "update sequence"
sendData(0xF7); // Will load LUT from OTP memory
break;
}
}
// Once the refresh operation has been started,
// begin periodically polling the display to check for completion, using the normal Meshtastic threading code
// Only used when refresh is "async"
void ZJY128296_029EAAMFGN::detachFromUpdate()
{
switch (updateType) {
case FAST:
return beginPolling(50, 300); // At least 300ms for fast refresh
case FULL:
default:
return beginPolling(100, 2000); // At least 2 seconds for full refresh
}
}
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,44 @@
/*
E-Ink display driver
- ZJY128296-029EAAMFGN
- Manufacturer: Zhongjingyuan
- Size: 2.9 inch
- Resolution: 128px x 296px
- Flex connector label (not a unique identifier): FPC-A005 20.06.15 TRX
Note: as of Feb. 2025, these panels are used for "WeActStudio 2.9in B&W" display modules
*/
#pragma once
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "configuration.h"
#include "./SSD16XX.h"
namespace NicheGraphics::Drivers
{
class ZJY128296_029EAAMFGN : public SSD16XX
{
// Display properties
private:
static constexpr uint32_t width = 128;
static constexpr uint32_t height = 296;
static constexpr UpdateTypes supported = (UpdateTypes)(FULL | FAST);
public:
ZJY128296_029EAAMFGN() : SSD16XX(width, height, supported) {}
protected:
void configScanning() override;
void configWaveform() override;
void configUpdateSequence() override;
void detachFromUpdate() override;
};
} // namespace NicheGraphics::Drivers
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,32 @@
/*
E-Ink display driver
- ZJY200200-0154DAAMFGN
- Manufacturer: Zhongjingyuan
- Size: 1.54 inch
- Resolution: 200px x 200px
- Flex connector marking: FPC-B001
Note: as of Feb. 2025, these panels are used for "WeActStudio 1.54in B&W" display modules
This *is* a distinct panel, however the driver is currently identical to GDEY0154D67
We recognize it as separate now, to avoid breaking any custom builds if the drivers do need to diverge in future.
*/
#pragma once
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
#include "configuration.h"
#include "./GDEY0154D67.h"
namespace NicheGraphics::Drivers
{
typedef GDEY0154D67 ZJY200200_0154DAAMFGN;
} // namespace NicheGraphics::Drivers
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -0,0 +1,3 @@
# NicheGraphics - Drivers
Common drivers which can be used by various NicheGraphics UIs
@@ -0,0 +1,527 @@
// trunk-ignore-all(clang-format)
#pragma once
/* PROPERTIES
FONT_NAME FreeSans12pt_Win1250
*/
const uint8_t FreeSans12pt_Win1250Bitmaps[] PROGMEM = {
/* 0x01 */ 0x00, 0x30, 0x00, 0x09, 0x00, 0x01, 0x20, 0x00, 0x24, 0x00, 0x04, 0x80, 0x01, 0x90, 0x00, 0x62, 0x00, 0x30, 0xFE, 0x04, 0x10, 0x5F, 0x02, 0x0B, 0x00, 0x7F, 0xE0, 0x0C, 0x1C, 0x02, 0x83, 0x81, 0x9F, 0xF0, 0x02, 0x1E, 0x00, 0x41, 0xC0, 0x0E, 0x7F, 0x81, 0x78, 0x18, 0x62, 0x00, 0xFF, 0xC0,
/* 0x02 */ 0x00, 0xFF, 0x80, 0x61, 0x13, 0xF0, 0x62, 0x60, 0x07, 0xFC, 0x00, 0x83, 0x80, 0x10, 0xF0, 0x33, 0xF6, 0x01, 0x41, 0xC0, 0x18, 0x38, 0x03, 0xFF, 0xE0, 0x47, 0x02, 0x08, 0x20, 0x61, 0xC4, 0x06, 0x17, 0x00, 0x22, 0x00, 0x02, 0x40, 0x00, 0x48, 0x00, 0x09, 0x00, 0x01, 0x20, 0x00, 0x3C, 0x00,
/* 0x03 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x04, 0x08, 0x48, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x08, 0x10, 0x70, 0x00, 0x03, 0x80, 0x00, 0x14, 0x00, 0x00, 0xA1, 0x81, 0x8D, 0x87, 0xF0, 0x44, 0x00, 0x06, 0x30, 0x00, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x04 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x10, 0x02, 0x48, 0xE0, 0x61, 0xC1, 0xCC, 0x0E, 0x78, 0x1C, 0x70, 0x00, 0x03, 0x80, 0x00, 0x14, 0xFF, 0xFC, 0xA6, 0x00, 0xCD, 0x9F, 0xFE, 0x44, 0x71, 0xE6, 0x30, 0xFC, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x05 */ 0x00, 0x18, 0x00, 0x00, 0x40, 0x01, 0x90, 0x01, 0xF4, 0x08, 0x12, 0x23, 0xC1, 0x91, 0x2C, 0x1C, 0x8A, 0xC3, 0x64, 0x64, 0x13, 0x22, 0x41, 0x98, 0x26, 0x2C, 0xC4, 0x22, 0x60, 0x42, 0x13, 0x04, 0x30, 0x80, 0x61, 0xA4, 0x02, 0x18, 0x20, 0x03, 0x41, 0x00, 0x20, 0x08, 0x02, 0x00, 0x60, 0x40, 0x03, 0xF8,
/* 0x06 */ 0x00, 0x10, 0x00, 0x03, 0x00, 0x1C, 0x48, 0x00, 0xB4, 0x80, 0x09, 0xF9, 0xC0, 0xE0, 0xE4, 0x0C, 0x02, 0x8F, 0x80, 0x38, 0x88, 0x01, 0x0D, 0x00, 0x18, 0x30, 0x01, 0x60, 0x80, 0x13, 0x18, 0x03, 0xF2, 0xC0, 0x20, 0x26, 0x06, 0x07, 0xFF, 0xA0, 0x02, 0x39, 0x00, 0x14, 0x70, 0x01, 0xC3, 0x00, 0x18, 0x00,
/* 0x07 */
/* 0x08 */ 0x00, 0x1F, 0x80, 0x00, 0x60, 0x80, 0x01, 0x00, 0x80, 0x06, 0x00, 0x80, 0x3C, 0x01, 0x01, 0x8C, 0x02, 0x02, 0x08, 0x04, 0x04, 0x08, 0x0C, 0x38, 0x00, 0x04, 0x80, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x2E, 0xC0, 0x01, 0x83, 0x7E, 0x0C, 0x10, 0x37, 0xE2, 0x61, 0x00, 0x0C, 0xC6, 0x10, 0x98, 0x0C, 0x63, 0x00, 0x00, 0xC6, 0x00,
/* 0x09 */ 0x00, 0x1F, 0x80, 0x00, 0x60, 0x80, 0x01, 0x00, 0x80, 0x06, 0x00, 0x80, 0x3C, 0x01, 0x01, 0x8C, 0x02, 0x02, 0x08, 0x04, 0x04, 0x08, 0x0C, 0x38, 0x00, 0x04, 0x80, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x2E, 0xC0, 0x01, 0x83, 0x7E, 0x0C, 0x00, 0x37, 0xE0,
/* 0x0A */
/* 0x0B */ 0x1F, 0x07, 0xC1, 0x86, 0x41, 0x10, 0x0C, 0x04, 0x80, 0x40, 0x18, 0x00, 0x00, 0xC0, 0x00, 0x06, 0x00, 0x00, 0x30, 0x00, 0x01, 0x40, 0x00, 0x0A, 0x00, 0x00, 0x88, 0x00, 0x04, 0x40, 0x00, 0x41, 0x00, 0x02, 0x04, 0x00, 0x20, 0x20, 0x02, 0x00, 0x80, 0x20, 0x02, 0x02, 0x00, 0x08, 0x20, 0x00, 0x22, 0x00, 0x00, 0xE0, 0x00,
/* 0x0C */ 0x01, 0x00, 0x00, 0x38, 0x00, 0x04, 0xC0, 0x01, 0x08, 0x00, 0x18, 0x80, 0x1C, 0x10, 0x02, 0x07, 0x80, 0x81, 0x10, 0x1F, 0xC2, 0x02, 0x00, 0x60, 0x80, 0x1A, 0x20, 0x1C, 0x42, 0x1C, 0x08, 0xFE, 0x03, 0xA0, 0x01, 0x8C, 0x01, 0xC1, 0x43, 0xD0, 0x27, 0x81, 0xF8,
/* 0x0D */
/* 0x0E */ 0x00, 0xE0, 0x00, 0x11, 0x00, 0x01, 0x10, 0x00, 0x0B, 0x00, 0x03, 0xF8, 0x00, 0x60, 0x60, 0x09, 0x02, 0x00, 0xA0, 0x10, 0x16, 0x01, 0x01, 0x40, 0x10, 0x10, 0x01, 0x01, 0x00, 0x08, 0x10, 0x00, 0x82, 0x1F, 0x08, 0x3F, 0x90, 0x44, 0x00, 0x06, 0xBF, 0xFF, 0xAF, 0xF0, 0xFF, 0xFF, 0x0F, 0xE3, 0xFB, 0xFC,
/* 0x0F */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x40, 0x12, 0x34, 0x00, 0x69, 0x40, 0x01, 0x49, 0xE0, 0xF1, 0xCD, 0x06, 0x8E, 0x28, 0x14, 0x71, 0x40, 0xA3, 0x8B, 0xFD, 0x14, 0x50, 0x68, 0xA2, 0x81, 0x4D, 0x97, 0xFA, 0x44, 0xBF, 0xD6, 0x31, 0x02, 0xE0, 0xC8, 0x16, 0x08, 0x61, 0x08, 0x21, 0xF0, 0x80, 0xF8, 0x78, 0x00,
/* 0x10 */ 0x00, 0xF0, 0x00, 0x3A, 0x00, 0x07, 0xC0, 0x00, 0xA8, 0x00, 0x1F, 0x00, 0x02, 0xB0, 0x00, 0x52, 0x00, 0x0A, 0x40, 0x02, 0x48, 0x00, 0x49, 0x00, 0x09, 0x30, 0x01, 0x22, 0x01, 0xC4, 0x70, 0xF0, 0x85, 0xE1, 0x10, 0x88, 0x37, 0x20, 0x03, 0x9C, 0x00, 0x37, 0x00, 0x06, 0x40, 0x01, 0x86, 0x00,
/* 0x11 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x60, 0x02, 0x36, 0x00, 0x09, 0x04, 0x0C, 0x48, 0x60, 0xC1, 0xC3, 0x0F, 0x0E, 0x00, 0x08, 0x70, 0x00, 0x23, 0x80, 0x63, 0x84, 0x01, 0x9F, 0x20, 0x0C, 0xFD, 0x80, 0x27, 0xE4, 0x03, 0x3F, 0x30, 0x33, 0xE0, 0xC0, 0x00, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x12 */ 0x00, 0xC2, 0x00, 0x1C, 0x24, 0x02, 0x18, 0x60, 0x64, 0x02, 0x02, 0x40, 0x20, 0x00, 0xF2, 0x03, 0x89, 0xE0, 0x7C, 0x80, 0x0E, 0x25, 0x80, 0xE1, 0x00, 0x1A, 0x08, 0x71, 0xB0, 0xC4, 0x39, 0x84, 0xC2, 0xCC, 0x40, 0x76, 0x7C, 0x05, 0xBB, 0x80, 0x4C, 0xE0, 0x0A, 0x78, 0x00, 0x9C, 0x00, 0x0F, 0x00, 0x00,
/* 0x13 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x00, 0x00, 0x48, 0x60, 0xC1, 0xC6, 0xC9, 0x0E, 0x00, 0x00, 0x70, 0x00, 0x03, 0x80, 0x00, 0x14, 0xFF, 0xF8, 0xA6, 0x00, 0xCD, 0x9F, 0xFE, 0x44, 0x71, 0xE6, 0x30, 0xFC, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x14 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x20, 0x22, 0x33, 0x01, 0x89, 0x20, 0x02, 0x48, 0x60, 0xE1, 0xC8, 0x80, 0x8E, 0x46, 0x46, 0x72, 0x32, 0x33, 0x9F, 0x9F, 0x94, 0x78, 0x78, 0xA0, 0x00, 0x0D, 0x80, 0x00, 0x44, 0x0E, 0x06, 0x30, 0x00, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x15 */ 0x03, 0xFC, 0x20, 0x38, 0x1C, 0x81, 0x80, 0x1D, 0x08, 0x00, 0x32, 0x60, 0x00, 0x89, 0x00, 0x02, 0x18, 0x00, 0x08, 0x61, 0xC3, 0x22, 0x8D, 0x93, 0x72, 0x00, 0x00, 0x48, 0x00, 0x01, 0x20, 0x00, 0x04, 0x9F, 0xFF, 0x92, 0x60, 0x0E, 0x44, 0xFF, 0xF2, 0x11, 0xC3, 0x88, 0x21, 0xF8, 0x40, 0x40, 0x02, 0x00, 0xC0, 0x30, 0x00, 0xFF, 0x00,
/* 0x16 */ 0x03, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x01, 0xE0, 0x03, 0xF0, 0x03, 0xF0, 0x27, 0xF0, 0x6F, 0x70, 0x6E, 0x60, 0xFC, 0x60, 0xFC, 0x7E, 0xFC, 0x7E, 0xFC, 0x3F, 0xF4, 0x1F, 0xF4, 0x1F, 0xF0, 0x0E, 0x70, 0x0E, 0x30, 0x1C, 0x38, 0x38, 0x0F, 0xF0,
/* 0x17 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x00, 0x00, 0x48, 0x00, 0x21, 0xC0, 0x02, 0x8E, 0x20, 0xF4, 0x70, 0x84, 0x11, 0x82, 0x40, 0x84, 0x01, 0x03, 0x20, 0x0F, 0x85, 0x80, 0x03, 0x04, 0x00, 0x04, 0x30, 0x78, 0x10, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x18 */ 0x00, 0xFC, 0x00, 0x02, 0x06, 0x00, 0x08, 0x24, 0x00, 0x21, 0xA4, 0x00, 0x4C, 0x48, 0x00, 0xA0, 0x50, 0x01, 0x92, 0x60, 0x03, 0x24, 0xC0, 0x06, 0x01, 0x81, 0x28, 0x03, 0x49, 0x6C, 0xC4, 0xAD, 0xD8, 0x16, 0xA4, 0xCC, 0xC4, 0x44, 0x86, 0x13, 0x05, 0x00, 0x28, 0x0A, 0x00, 0x50, 0x14, 0x00, 0x90, 0x48, 0x01, 0x20, 0x90, 0x02, 0x41, 0x20, 0x00, 0x00,
/* 0x19 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x00, 0x00, 0x49, 0xC3, 0x81, 0xC0, 0x00, 0x0E, 0x78, 0xF0, 0x77, 0xEF, 0xC3, 0xA7, 0x4E, 0x15, 0x0A, 0x10, 0xA7, 0x8F, 0x0D, 0x80, 0x00, 0x44, 0x00, 0x06, 0x33, 0xF0, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x1A */ 0xFF, 0xFF, 0x00, 0x06, 0x00, 0x0C, 0x3E, 0x18, 0x82, 0x32, 0x02, 0x64, 0x04, 0xC8, 0x09, 0x80, 0x23, 0x00, 0x86, 0x02, 0x0C, 0x08, 0x18, 0x10, 0x30, 0x00, 0x60, 0x00, 0xC0, 0x81, 0x80, 0x03, 0x00, 0x07, 0xFF, 0xF8,
/* 0x1B */ 0x00, 0xFE, 0x00, 0x03, 0x81, 0x80, 0x04, 0x00, 0x60, 0x08, 0x00, 0x30, 0x10, 0x00, 0x10, 0x30, 0x07, 0x88, 0x23, 0xC8, 0x08, 0x22, 0x00, 0x04, 0x60, 0x00, 0x44, 0x60, 0x00, 0x84, 0x63, 0x03, 0x04, 0x61, 0xFC, 0x04, 0x6B, 0x00, 0x9E, 0xA5, 0x01, 0x6A, 0xD5, 0x01, 0x43, 0xA8, 0x81, 0x05, 0xD0, 0x82, 0x0A, 0xA0, 0x82, 0x05, 0xC0, 0x82, 0x02, 0x61, 0xFF, 0x0C, 0x1E, 0x00, 0xF0,
/* 0x1C */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x30, 0x02, 0x32, 0x00, 0x09, 0x00, 0x00, 0x48, 0x20, 0x61, 0xC3, 0x84, 0x0E, 0x1C, 0x78, 0x70, 0x40, 0x03, 0x80, 0x00, 0x14, 0x00, 0x00, 0xA0, 0x03, 0x0D, 0x83, 0xF0, 0x44, 0x00, 0x06, 0x30, 0x00, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x1D */ 0x01, 0xFE, 0x00, 0x3A, 0x1C, 0x03, 0x00, 0x30, 0x23, 0x1E, 0xC3, 0x38, 0x03, 0x10, 0xC3, 0x09, 0x00, 0x18, 0x68, 0x00, 0xC1, 0x40, 0x00, 0x0A, 0x07, 0x80, 0x50, 0x46, 0x02, 0x80, 0x00, 0x1A, 0x1E, 0x00, 0xCB, 0x10, 0x0D, 0x03, 0x00, 0x48, 0x60, 0x06, 0x40, 0x00, 0x22, 0x0C, 0x02, 0x10, 0x60, 0x60, 0x43, 0xFC, 0x01, 0xE0, 0x00, 0x00,
/* 0x1E */ 0x01, 0xF0, 0x00, 0xEA, 0xC0, 0x31, 0x5F, 0x04, 0x5F, 0x88, 0x80, 0xA0, 0x48, 0x0E, 0x02, 0x8F, 0x40, 0x3C, 0x10, 0x21, 0x66, 0x87, 0x15, 0x98, 0x71, 0x41, 0x02, 0x14, 0x00, 0x01, 0x40, 0x00, 0x14, 0x00, 0x01, 0x21, 0xFE, 0x12, 0x00, 0x02, 0x10, 0x00, 0x60, 0x80, 0x0C, 0x06, 0x01, 0x80, 0x3F, 0xE0,
/* 0x1F */ 0x0E, 0x00, 0x13, 0x00, 0x23, 0x00, 0xF3, 0x01, 0x31, 0x01, 0x11, 0x03, 0xD3, 0x06, 0xF2, 0x30, 0x34, 0xC7, 0x25, 0x33, 0x2B, 0xC2, 0x57, 0x04, 0x3A, 0x08, 0x72, 0x30, 0xA3, 0xC3, 0x40, 0x04, 0x40, 0x18, 0x40, 0x60, 0x7F, 0x80,
/* ' ' 0x20 */
/* '!' 0x21 */ 0xFF, 0xFF, 0xFF, 0xF0, 0xF0,
/* '"' 0x22 */ 0xCF, 0x3C, 0xF3, 0x8A, 0x20,
/* '#' 0x23 */ 0x06, 0x30, 0x31, 0x03, 0x18, 0x18, 0xC7, 0xFF, 0xBF, 0xFC, 0x31, 0x01, 0x18, 0x18, 0xC7, 0xFF, 0xBF, 0xFC, 0x31, 0x01, 0x18, 0x18, 0xC0, 0xC6, 0x06, 0x30,
/* '$' 0x24 */ 0x04, 0x03, 0xE1, 0xFF, 0x72, 0x7C, 0x47, 0x88, 0xF1, 0x07, 0xA0, 0x7E, 0x03, 0xF0, 0x17, 0x02, 0x7C, 0x47, 0x88, 0xF1, 0x1B, 0x26, 0x7F, 0xC3, 0xE0, 0x10, 0x02, 0x00,
/* '%' 0x25 */ 0x00, 0x06, 0x03, 0xC0, 0x40, 0x7E, 0x0C, 0x0E, 0x70, 0x80, 0xC3, 0x18, 0x0C, 0x31, 0x00, 0xE7, 0x30, 0x07, 0xE6, 0x00, 0x3C, 0x40, 0x00, 0x0C, 0x7C, 0x00, 0x8F, 0xE0, 0x19, 0xC7, 0x01, 0x18, 0x30, 0x31, 0x83, 0x02, 0x1C, 0x70, 0x40, 0xFE, 0x04, 0x07, 0xC0,
/* '&' 0x26 */ 0x0F, 0x00, 0x7E, 0x03, 0x9C, 0x0C, 0x30, 0x30, 0xC0, 0xE7, 0x01, 0xF8, 0x03, 0x80, 0x3E, 0x01, 0xCC, 0x6E, 0x39, 0xB0, 0x7C, 0xC0, 0xF3, 0x03, 0xCE, 0x1F, 0x9F, 0xE6, 0x3E, 0x1C,
/* ''' 0x27 */ 0xFF, 0xA0,
/* '(' 0x28 */ 0x08, 0x8C, 0x46, 0x31, 0x98, 0xC6, 0x31, 0x8C, 0x63, 0x08, 0x63, 0x08, 0x61, 0x0C, 0x20,
/* ')' 0x29 */ 0x82, 0x18, 0xC3, 0x18, 0xC3, 0x18, 0xC6, 0x31, 0x8C, 0x62, 0x31, 0x88, 0xC4, 0x62, 0x00,
/* '*' 0x2A */ 0x10, 0x23, 0x5B, 0xE3, 0x8D, 0x91, 0x00,
/* '+' 0x2B */ 0x0C, 0x03, 0x00, 0xC0, 0x30, 0xFF, 0xFF, 0xF0, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0,
/* ',' 0x2C */ 0xF5, 0x60,
/* '-' 0x2D */ 0xFF, 0xF0,
/* '.' 0x2E */ 0xF0,
/* '/' 0x2F */ 0x02, 0x0C, 0x10, 0x20, 0xC1, 0x02, 0x0C, 0x10, 0x20, 0xC1, 0x02, 0x0C, 0x10, 0x20, 0xC1, 0x00,
/* '0' 0x30 */ 0x1F, 0x07, 0xF1, 0xC7, 0x30, 0x6C, 0x0F, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3E, 0x0E, 0xC1, 0x9C, 0x71, 0xFC, 0x1F, 0x00,
/* '1' 0x31 */ 0x08, 0xCF, 0xFF, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18,
/* '2' 0x32 */ 0x1F, 0x0F, 0xF9, 0x87, 0x60, 0x7C, 0x06, 0x00, 0xC0, 0x18, 0x07, 0x01, 0xC0, 0xF0, 0x78, 0x1C, 0x06, 0x00, 0xC0, 0x30, 0x07, 0xFF, 0xFF, 0xE0,
/* '3' 0x33 */ 0x3F, 0x0F, 0xF3, 0x87, 0x60, 0x6C, 0x0C, 0x01, 0x80, 0x60, 0x78, 0x0F, 0x80, 0x18, 0x01, 0x80, 0x3C, 0x07, 0x80, 0xD8, 0x73, 0xFC, 0x3F, 0x00,
/* '4' 0x34 */ 0x01, 0x80, 0x70, 0x0E, 0x03, 0xC0, 0xD8, 0x1B, 0x06, 0x61, 0x8C, 0x21, 0x8C, 0x33, 0x06, 0x7F, 0xFF, 0xFE, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80,
/* '5' 0x35 */ 0x3F, 0xCF, 0xF9, 0x80, 0x30, 0x06, 0x00, 0xDE, 0x1F, 0xE7, 0x0E, 0x00, 0xE0, 0x0C, 0x01, 0x80, 0x30, 0x07, 0x81, 0xB8, 0x73, 0xFC, 0x1F, 0x00,
/* '6' 0x36 */ 0x0F, 0x07, 0xF9, 0xC3, 0x30, 0x74, 0x01, 0x80, 0x33, 0xC7, 0xFE, 0xF1, 0xDC, 0x1F, 0x01, 0xE0, 0x3C, 0x06, 0xC1, 0xDC, 0x71, 0xFC, 0x1F, 0x00,
/* '7' 0x37 */ 0xFF, 0xFF, 0xFC, 0x01, 0x00, 0x60, 0x18, 0x02, 0x00, 0xC0, 0x30, 0x06, 0x01, 0x80, 0x30, 0x04, 0x01, 0x80, 0x30, 0x06, 0x01, 0x80, 0x30, 0x00,
/* '8' 0x38 */ 0x1F, 0x07, 0xF1, 0xC7, 0x30, 0x66, 0x0C, 0xC1, 0x8C, 0x61, 0xF8, 0x3F, 0x8E, 0x3B, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xD8, 0x31, 0xFC, 0x1F, 0x00,
/* '9' 0x39 */ 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x6C, 0x07, 0x80, 0xF0, 0x1E, 0x07, 0x61, 0xEF, 0xFC, 0x79, 0x80, 0x30, 0x05, 0xC1, 0x98, 0x73, 0xFC, 0x1E, 0x00,
/* ':' 0x3A */ 0xF0, 0x00, 0x03, 0xC0,
/* ';' 0x3B */ 0xF0, 0x00, 0x0F, 0x56,
/* '<' 0x3C */ 0x00, 0x70, 0x1E, 0x0F, 0x83, 0xC0, 0xF0, 0x0E, 0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x10,
/* '=' 0x3D */ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
/* '>' 0x3E */ 0xE0, 0x07, 0x80, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x07, 0x01, 0xE0, 0xF0, 0x3C, 0x0F, 0x00, 0x80, 0x00,
/* '?' 0x3F */ 0x3F, 0x1F, 0xEE, 0x1F, 0x03, 0xC0, 0xC0, 0x30, 0x0C, 0x06, 0x03, 0x81, 0xC0, 0xE0, 0x30, 0x0C, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x03, 0x00,
/* '@' 0x40 */ 0x00, 0xFE, 0x00, 0x0F, 0xFE, 0x00, 0xF0, 0x3E, 0x07, 0x00, 0x3C, 0x38, 0x00, 0x38, 0xC1, 0xE0, 0x66, 0x0F, 0xD9, 0xD8, 0x61, 0xC3, 0xC3, 0x07, 0x0F, 0x1C, 0x1C, 0x3C, 0x60, 0x60, 0xF1, 0x81, 0x83, 0xC6, 0x06, 0x1B, 0x18, 0x38, 0xEE, 0x71, 0xE7, 0x18, 0xFD, 0xF8, 0x71, 0xE7, 0xC0, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x01, 0xFF, 0xC0, 0x01, 0xFC, 0x00,
/* 'A' 0x41 */ 0x07, 0x80, 0x1E, 0x00, 0x78, 0x03, 0xF0, 0x0C, 0xC0, 0x33, 0x01, 0xCE, 0x06, 0x18, 0x18, 0x60, 0xE1, 0xC3, 0x03, 0x0F, 0xFC, 0x7F, 0xF9, 0x80, 0x66, 0x01, 0xB8, 0x07, 0xC0, 0x0F, 0x00, 0x30,
/* 'B' 0x42 */ 0xFF, 0xC7, 0xFF, 0x30, 0x1D, 0x80, 0x6C, 0x03, 0x60, 0x1B, 0x00, 0xD8, 0x0C, 0xFF, 0xC7, 0xFF, 0x30, 0x0D, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x06, 0xFF, 0xF7, 0xFE, 0x00,
/* 'C' 0x43 */ 0x07, 0xE0, 0x3F, 0xF0, 0xE0, 0x73, 0x80, 0x76, 0x00, 0x6C, 0x00, 0x30, 0x00, 0x60, 0x00, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x00, 0x0E, 0x00, 0x6C, 0x00, 0xDC, 0x03, 0x1E, 0x0E, 0x1F, 0xF8, 0x0F, 0xC0,
/* 'D' 0x44 */ 0xFF, 0xC3, 0xFF, 0x8C, 0x07, 0x30, 0x0E, 0xC0, 0x1B, 0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x1F, 0x00, 0x6C, 0x03, 0xB0, 0x1C, 0xFF, 0xE3, 0xFE, 0x00,
/* 'E' 0x45 */ 0xFF, 0xFF, 0xFF, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xEF, 0xFE, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xFF, 0xFF,
/* 'F' 0x46 */ 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xFF, 0xDF, 0xFB, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x00,
/* 'G' 0x47 */ 0x07, 0xF0, 0x1F, 0xFC, 0x3C, 0x1E, 0x70, 0x07, 0x60, 0x03, 0xE0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x7F, 0xC0, 0x7F, 0xC0, 0x03, 0xC0, 0x03, 0x60, 0x03, 0x60, 0x07, 0x30, 0x0F, 0x3C, 0x1F, 0x1F, 0xFB, 0x07, 0xE1,
/* 'H' 0x48 */ 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xC0,
/* 'I' 0x49 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
/* 'J' 0x4A */ 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x3C, 0x1E, 0x0F, 0x07, 0xC7, 0x7F, 0x1F, 0x00,
/* 'K' 0x4B */ 0xC0, 0x3E, 0x03, 0xB0, 0x39, 0x83, 0x8C, 0x38, 0x63, 0x83, 0x38, 0x19, 0xC0, 0xDE, 0x07, 0xB8, 0x38, 0xE1, 0x83, 0x0C, 0x1C, 0x60, 0x73, 0x01, 0x98, 0x0E, 0xC0, 0x3E, 0x00, 0xC0,
/* 'L' 0x4C */ 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xFF, 0xFF, 0xF0,
/* 'M' 0x4D */ 0xE0, 0x07, 0xE0, 0x07, 0xF0, 0x0F, 0xF0, 0x0F, 0xD0, 0x0F, 0xD8, 0x1B, 0xD8, 0x1B, 0xD8, 0x1B, 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33, 0xC6, 0x63, 0xC6, 0x63, 0xC6, 0x63, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC1, 0x83,
/* 'N' 0x4E */ 0xE0, 0x1F, 0x00, 0xFC, 0x07, 0xE0, 0x3D, 0x81, 0xEE, 0x0F, 0x30, 0x79, 0xC3, 0xC6, 0x1E, 0x18, 0xF0, 0xE7, 0x83, 0x3C, 0x1D, 0xE0, 0x6F, 0x01, 0xF8, 0x0F, 0xC0, 0x3E, 0x01, 0xC0,
/* 'O' 0x4F */ 0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0x07, 0x86, 0x00, 0xC6, 0x00, 0x33, 0x00, 0x1B, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x36, 0x00, 0x33, 0x00, 0x18, 0xC0, 0x18, 0x78, 0x3C, 0x1F, 0xFC, 0x03, 0xF8, 0x00,
/* 'P' 0x50 */ 0xFF, 0x8F, 0xFE, 0xC0, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x06, 0xFF, 0xEF, 0xFC, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00,
/* 'Q' 0x51 */ 0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0x07, 0x86, 0x00, 0xC6, 0x00, 0x33, 0x00, 0x1B, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x36, 0x00, 0x33, 0x01, 0x98, 0xC0, 0xFC, 0x78, 0x3C, 0x1F, 0xFF, 0x03, 0xF9, 0x80, 0x00, 0x40,
/* 'R' 0x52 */ 0xFF, 0xE3, 0xFF, 0xCC, 0x03, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x6C, 0x01, 0xB0, 0x0C, 0xFF, 0xE3, 0xFF, 0xCC, 0x03, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x6C, 0x01, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x70,
/* 'S' 0x53 */ 0x0F, 0xE0, 0x7F, 0xC3, 0x83, 0x98, 0x07, 0x60, 0x0D, 0x80, 0x07, 0x00, 0x1E, 0x00, 0x3F, 0x80, 0x3F, 0xC0, 0x0F, 0x80, 0x07, 0xC0, 0x0F, 0x00, 0x3E, 0x00, 0xDE, 0x0E, 0x3F, 0xF0, 0x3F, 0x80,
/* 'T' 0x54 */ 0xFF, 0xFF, 0xFF, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60,
/* 'U' 0x55 */ 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x80, 0xEE, 0x0E, 0x3F, 0xE0, 0xFC, 0x00,
/* 'V' 0x56 */ 0xC0, 0x0F, 0x00, 0x7E, 0x01, 0x98, 0x06, 0x60, 0x39, 0xC0, 0xC3, 0x03, 0x0C, 0x1C, 0x38, 0x60, 0x61, 0x81, 0x8E, 0x07, 0x30, 0x0C, 0xC0, 0x37, 0x00, 0xF8, 0x01, 0xE0, 0x07, 0x80, 0x1C, 0x00,
/* 'W' 0x57 */ 0xE0, 0x30, 0x1D, 0x80, 0xE0, 0x76, 0x07, 0x81, 0xDC, 0x1E, 0x06, 0x70, 0x7C, 0x18, 0xC1, 0xB0, 0xE3, 0x0C, 0xC3, 0x8C, 0x33, 0x0C, 0x38, 0xC6, 0x30, 0x67, 0x18, 0xC1, 0x98, 0x67, 0x06, 0x61, 0xD8, 0x1D, 0x83, 0x60, 0x3C, 0x0D, 0x80, 0xF0, 0x3E, 0x03, 0xC0, 0x70, 0x0F, 0x01, 0xC0, 0x18, 0x07, 0x00,
/* 'X' 0x58 */ 0xE0, 0x1D, 0x80, 0xE7, 0x03, 0x0E, 0x1C, 0x18, 0x60, 0x73, 0x00, 0xFC, 0x01, 0xE0, 0x07, 0x00, 0x1E, 0x00, 0xF8, 0x03, 0x30, 0x1C, 0xE0, 0xE1, 0x83, 0x07, 0x1C, 0x0E, 0xE0, 0x1B, 0x00, 0x70,
/* 'Y' 0x59 */ 0xC0, 0x0F, 0x80, 0x76, 0x01, 0x9C, 0x0C, 0x38, 0x70, 0x61, 0x81, 0xCE, 0x03, 0x30, 0x0F, 0x80, 0x1E, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00,
/* 'Z' 0x5A */ 0xFF, 0xFF, 0xFF, 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0x60, 0x07, 0x00, 0x70, 0x07, 0x00, 0x30, 0x03, 0x80, 0x38, 0x03, 0x80, 0x18, 0x01, 0xC0, 0x1C, 0x00, 0xFF, 0xFF, 0xFF, 0xC0,
/* '[' 0x5B */ 0xFF, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCF, 0xF0,
/* '\' 0x5C */ 0x81, 0x81, 0x02, 0x06, 0x04, 0x08, 0x18, 0x10, 0x20, 0x60, 0x40, 0x81, 0x81, 0x02, 0x06, 0x04,
/* ']' 0x5D */ 0xFF, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0xF0,
/* '^' 0x5E */ 0x0C, 0x0E, 0x05, 0x86, 0xC3, 0x21, 0x19, 0x8C, 0x83, 0xC1, 0x80,
/* '_' 0x5F */ 0xFF, 0xFE,
/* '`' 0x60 */ 0xE3, 0x8C, 0x30,
/* 'a' 0x61 */ 0x3F, 0x07, 0xF8, 0xE1, 0xCC, 0x0C, 0x00, 0xC0, 0x1C, 0x3F, 0xCF, 0x8C, 0xC0, 0xCC, 0x0C, 0xE3, 0xC7, 0xEF, 0x3C, 0x70,
/* 'b' 0x62 */ 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0xF8, 0xDF, 0xCF, 0x0E, 0xE0, 0x7C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xE0, 0x6F, 0x0E, 0xDF, 0xCC, 0xF8,
/* 'c' 0x63 */ 0x1F, 0x0F, 0xE6, 0x1F, 0x83, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x38, 0x37, 0x1C, 0xFE, 0x1F, 0x00,
/* 'd' 0x64 */ 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x3C, 0xCF, 0xFB, 0x8F, 0xE0, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF8, 0x3B, 0x8F, 0x3F, 0x63, 0xCC,
/* 'e' 0x65 */ 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x3C, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0xC0, 0x1C, 0x0D, 0xC3, 0x1F, 0xC1, 0xF0,
/* 'f' 0x66 */ 0x3B, 0xD8, 0xC6, 0x7F, 0xEC, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x00,
/* 'g' 0x67 */ 0x1E, 0x67, 0xFD, 0xC7, 0xF0, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x7C, 0x1D, 0xC7, 0x9F, 0xB1, 0xE6, 0x00, 0xC0, 0x3E, 0x0E, 0x7F, 0xC7, 0xE0,
/* 'h' 0x68 */ 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x33, 0xCD, 0xFB, 0xC7, 0xE0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x30,
/* 'i' 0x69 */ 0xF0, 0x3F, 0xFF, 0xFF, 0xF0,
/* 'j' 0x6A */ 0x33, 0x00, 0x03, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0xE0,
/* 'k' 0x6B */ 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x6C, 0x33, 0x18, 0xCC, 0x37, 0x0F, 0xC3, 0xB8, 0xC6, 0x31, 0xCC, 0x3B, 0x06, 0xC1, 0xF0, 0x30,
/* 'l' 0x6C */ 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
/* 'm' 0x6D */ 0xCF, 0x1F, 0x6F, 0xDF, 0xFC, 0x78, 0xFC, 0x18, 0x3C, 0x0C, 0x1E, 0x06, 0x0F, 0x03, 0x07, 0x81, 0x83, 0xC0, 0xC1, 0xE0, 0x60, 0xF0, 0x30, 0x78, 0x18, 0x3C, 0x0C, 0x18,
/* 'n' 0x6E */ 0xCF, 0x37, 0xEF, 0x1F, 0x83, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xC0,
/* 'o' 0x6F */ 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x7C, 0x1D, 0xC7, 0x1F, 0xC1, 0xF0,
/* 'p' 0x70 */ 0xCF, 0x8D, 0xFC, 0xF0, 0xEE, 0x06, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3E, 0x06, 0xF0, 0xEF, 0xFC, 0xCF, 0x8C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x00,
/* 'q' 0x71 */ 0x1E, 0x67, 0xFD, 0xC7, 0xF0, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x7C, 0x1D, 0xC7, 0x9F, 0xF1, 0xE6, 0x00, 0xC0, 0x18, 0x03, 0x00, 0x60,
/* 'r' 0x72 */ 0xCF, 0x7F, 0x38, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC0,
/* 's' 0x73 */ 0x3E, 0x1F, 0xEE, 0x1B, 0x00, 0xC0, 0x3C, 0x07, 0xF0, 0x3F, 0x01, 0xF0, 0x3E, 0x1D, 0xFE, 0x3F, 0x00,
/* 't' 0x74 */ 0x63, 0x19, 0xFF, 0xB1, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0xE7,
/* 'u' 0x75 */ 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x7E, 0x3D, 0xFB, 0x3C, 0xC0,
/* 'v' 0x76 */ 0xE0, 0x6C, 0x0D, 0x81, 0xB8, 0x63, 0x0C, 0x61, 0x8E, 0x60, 0xCC, 0x19, 0x83, 0xE0, 0x3C, 0x07, 0x00, 0xE0,
/* 'w' 0x77 */ 0xC1, 0xC1, 0xB0, 0xE1, 0xD8, 0x70, 0xCC, 0x2C, 0x66, 0x36, 0x31, 0x9B, 0x18, 0xCD, 0x98, 0x64, 0x6C, 0x16, 0x36, 0x0F, 0x1A, 0x07, 0x8F, 0x03, 0x83, 0x80, 0xC1, 0xC0,
/* 'x' 0x78 */ 0xC1, 0xF8, 0x66, 0x30, 0xCC, 0x3E, 0x07, 0x00, 0xC0, 0x78, 0x36, 0x0C, 0xC6, 0x3B, 0x06, 0xC0, 0xC0,
/* 'y' 0x79 */ 0xE0, 0x6C, 0x0D, 0x83, 0x38, 0x63, 0x0C, 0x63, 0x0C, 0x60, 0xCC, 0x1B, 0x03, 0x60, 0x3C, 0x07, 0x00, 0xE0, 0x18, 0x03, 0x00, 0xE0, 0x78, 0x0E, 0x00,
/* 'z' 0x7A */ 0xFF, 0xFF, 0xF0, 0x18, 0x0C, 0x07, 0x03, 0x81, 0xC0, 0x60, 0x30, 0x18, 0x0E, 0x03, 0xFF, 0xFF, 0xC0,
/* '{' 0x7B */ 0x19, 0xCC, 0x63, 0x18, 0xC6, 0x31, 0x99, 0x86, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x1C, 0x60,
/* '|' 0x7C */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
/* '}' 0x7D */ 0xC7, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x0C, 0x33, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x73, 0x00,
/* '~' 0x7E */ 0x70, 0x3E, 0x09, 0xE4, 0x1F, 0x03, 0x80,
/* 0x7F */
/* 0x80 */ 0x01, 0xF0, 0x1F, 0xF0, 0xE0, 0xC7, 0x00, 0x18, 0x00, 0xC0, 0x07, 0xFF, 0x3F, 0xFC, 0x30, 0x01, 0xFF, 0x8F, 0xFC, 0x0C, 0x00, 0x18, 0x00, 0x70, 0x00, 0xE0, 0x81, 0xFE, 0x03, 0xF0,
/* 0x81 */
/* 0x82 */ 0xF5, 0x80,
/* 0x83 */
/* 0x84 */ 0xCF, 0x34, 0x51, 0x88,
/* 0x85 */ 0xC6, 0x3C, 0x63,
/* 0x86 */ 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x3F, 0xFF, 0xFC, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x00,
/* 0x87 */ 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x3F, 0xFF, 0xFC, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x0F, 0xFF, 0xFF, 0x0C, 0x03, 0x00, 0xC0, 0x30,
/* 0x88 */
/* 0x89 */ 0x38, 0x18, 0x00, 0xF8, 0x30, 0x03, 0x18, 0xC0, 0x04, 0x11, 0x80, 0x0C, 0x66, 0x00, 0x0F, 0x8C, 0x00, 0x0E, 0x30, 0x00, 0x00, 0x40, 0x00, 0x01, 0x80, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x31, 0xC0, 0xE0, 0x67, 0xC3, 0xC1, 0x98, 0xCC, 0xC3, 0x20, 0x90, 0x8C, 0x63, 0x33, 0x10, 0x7C, 0x3C, 0x60, 0x70, 0x38,
/* 0x8A */ 0x0C, 0x40, 0x1F, 0x00, 0x38, 0x03, 0xF8, 0x1F, 0xF0, 0xE0, 0xE6, 0x01, 0xD8, 0x03, 0x60, 0x01, 0xC0, 0x07, 0x80, 0x0F, 0xE0, 0x0F, 0xF0, 0x03, 0xE0, 0x01, 0xF0, 0x03, 0xC0, 0x0F, 0x80, 0x37, 0x83, 0x8F, 0xFC, 0x0F, 0xE0,
/* 0x8B */ 0x2F, 0x49, 0x99,
/* 0x8C */ 0x01, 0x80, 0x0C, 0x00, 0x60, 0x00, 0x00, 0x0F, 0xE0, 0x7F, 0xC3, 0x83, 0x98, 0x07, 0x60, 0x0D, 0x80, 0x07, 0x00, 0x1E, 0x00, 0x3F, 0x80, 0x3F, 0xC0, 0x0F, 0x80, 0x07, 0xC0, 0x0F, 0x00, 0x3E, 0x00, 0xDE, 0x0E, 0x3F, 0xF0, 0x3F, 0x80,
/* 0x8D */ 0x0C, 0xC0, 0xF8, 0x07, 0x0F, 0xFF, 0xFF, 0xF0, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00,
/* 0x8E */ 0x0C, 0xC0, 0x3C, 0x00, 0xE1, 0xFF, 0xFF, 0xFF, 0x80, 0x1C, 0x01, 0xC0, 0x1C, 0x00, 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0x60, 0x07, 0x00, 0x70, 0x07, 0x00, 0x30, 0x03, 0x80, 0x38, 0x01, 0xFF, 0xFF, 0xFF, 0x80,
/* 0x8F */ 0x01, 0x80, 0x18, 0x01, 0x80, 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x06, 0x00, 0x70, 0x07, 0x00, 0x70, 0x03, 0x00, 0x38, 0x03, 0x80, 0x38, 0x01, 0x80, 0x1C, 0x01, 0xC0, 0x0F, 0xFF, 0xFF, 0xFC,
/* 0x90 */
/* 0x91 */ 0x6A, 0xF0,
/* 0x92 */ 0xF5, 0x60,
/* 0x93 */ 0x4E, 0x28, 0xA2, 0xCF, 0x30,
/* 0x94 */ 0xCF, 0x34, 0x51, 0x4E, 0x20,
/* 0x95 */ 0x7B, 0xFF, 0xFF, 0xFD, 0xE0,
/* 0x96 */ 0xFF, 0xFF, 0xF0,
/* 0x97 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
/* 0x98 */
/* 0x99 */ 0xFF, 0x70, 0x1F, 0xFD, 0xC0, 0x71, 0x87, 0x83, 0xC6, 0x1E, 0x0F, 0x18, 0x68, 0x3C, 0x61, 0xB1, 0xB1, 0x86, 0xC6, 0xC6, 0x19, 0x1B, 0x18, 0x66, 0xCC, 0x61, 0x9B, 0x31, 0x86, 0x3C, 0xC6, 0x18, 0xE3, 0x18, 0x63, 0x8C,
/* 0x9A */ 0x63, 0x0D, 0x83, 0x60, 0x70, 0x00, 0x0F, 0x87, 0xFB, 0x86, 0xC0, 0x30, 0x0F, 0x01, 0xFC, 0x0F, 0xC0, 0x7C, 0x0F, 0x87, 0x7F, 0x8F, 0xC0,
/* 0x9B */ 0x99, 0x92, 0xF4,
/* 0x9C */ 0x07, 0x03, 0x80, 0xC0, 0x60, 0x00, 0x0F, 0x87, 0xFB, 0x86, 0xC0, 0x30, 0x0F, 0x01, 0xFC, 0x0F, 0xC0, 0x7C, 0x0F, 0x87, 0x7F, 0x8F, 0xC0,
/* 0x9D */ 0x03, 0x06, 0x66, 0x64, 0x60, 0xF8, 0xF8, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x38,
/* 0x9E */ 0x63, 0x0C, 0x83, 0x60, 0x70, 0x00, 0x3F, 0xFF, 0xFC, 0x06, 0x03, 0x01, 0xC0, 0xE0, 0x70, 0x18, 0x0C, 0x06, 0x03, 0x80, 0xFF, 0xFF, 0xF0,
/* 0x9F */ 0x07, 0x01, 0x80, 0xC0, 0x20, 0x00, 0x3F, 0xFF, 0xFC, 0x06, 0x03, 0x01, 0xC0, 0xE0, 0x70, 0x18, 0x0C, 0x06, 0x03, 0x80, 0xFF, 0xFF, 0xF0,
/* 0xA0 */
/* 0xA1 */ 0xC6, 0xD9, 0xB1, 0xC0,
/* 0xA2 */ 0x83, 0x8D, 0xF1, 0xC0,
/* 0xA3 */ 0x30, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x18, 0x80, 0xCC, 0x06, 0xC0, 0x3C, 0x01, 0xC0, 0x3C, 0x01, 0x60, 0x03, 0x00, 0x18, 0x00, 0xC0, 0x06, 0x00, 0x3F, 0xF9, 0xFF, 0xC0,
/* 0xA4 */ 0xDD, 0xFF, 0xD8, 0xD8, 0x3C, 0x1E, 0x0F, 0x8D, 0xFF, 0xDD, 0x80,
/* 0xA5 */ 0x03, 0x80, 0x03, 0xC0, 0x07, 0xC0, 0x07, 0xC0, 0x04, 0xE0, 0x0C, 0xE0, 0x0C, 0xE0, 0x08, 0x70, 0x18, 0x70, 0x18, 0x70, 0x10, 0x38, 0x3F, 0xF8, 0x3F, 0xF8, 0x30, 0x1C, 0x70, 0x0C, 0x60, 0x0C, 0x60, 0x0E, 0xE0, 0x06, 0x00, 0x0E, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x0F,
/* 0xA6 */ 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFC,
/* 0xA7 */ 0x0F, 0x03, 0xF0, 0xE7, 0x18, 0x63, 0x0C, 0x70, 0x07, 0x03, 0xF8, 0xC3, 0x98, 0x3B, 0x03, 0xF0, 0x37, 0x06, 0x78, 0xC7, 0xB0, 0x7C, 0x03, 0x80, 0x39, 0x83, 0x30, 0x67, 0x1C, 0x7F, 0x07, 0xC0,
/* 0xA8 */ 0xCF, 0x30,
/* 0xA9 */ 0x03, 0xF0, 0x03, 0xFF, 0x01, 0xE0, 0xE0, 0xE3, 0x1C, 0x73, 0xF3, 0x99, 0x86, 0x6C, 0xC1, 0x8F, 0x30, 0x03, 0xCC, 0x00, 0xF3, 0x00, 0x3C, 0xC1, 0x8D, 0x98, 0x66, 0x77, 0xF3, 0x8E, 0x79, 0xC1, 0xC0, 0xE0, 0x3F, 0xF0, 0x03, 0xF0, 0x00,
/* 0xAA */ 0x0F, 0xC0, 0xFF, 0xC3, 0x03, 0x98, 0x07, 0x60, 0x0D, 0x80, 0x07, 0x00, 0x1E, 0x00, 0x3F, 0x80, 0x3F, 0xC0, 0x0F, 0x80, 0x07, 0xC0, 0x0F, 0x00, 0x3E, 0x00, 0xDC, 0x0E, 0x3F, 0xF0, 0x3F, 0x00, 0x20, 0x01, 0xE0, 0x01, 0x80, 0x06, 0x00, 0xF0, 0x00,
/* 0xAB */ 0x21, 0x63, 0xE7, 0x84, 0x84, 0xE7, 0x63, 0x21,
/* 0xAC */ 0xFF, 0xFF, 0xFF, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03,
/* 0xAD */ 0xFF, 0xF0,
/* 0xAE */ 0x03, 0xF0, 0x03, 0xFF, 0x01, 0xE0, 0xE0, 0xFF, 0x1C, 0x7F, 0xF3, 0x9B, 0x04, 0x6C, 0xC1, 0x8F, 0x30, 0x43, 0xCF, 0xF0, 0xF3, 0xFC, 0x3C, 0xC1, 0x0D, 0xB0, 0x66, 0x7C, 0x1B, 0x8F, 0x07, 0xC1, 0xC0, 0xE0, 0x3F, 0xF0, 0x03, 0xF0, 0x00,
/* 0xAF */ 0x03, 0x00, 0x18, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x80, 0x1C, 0x01, 0xC0, 0x1C, 0x00, 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0x60, 0x07, 0x00, 0x70, 0x07, 0x00, 0x30, 0x03, 0x80, 0x38, 0x01, 0xFF, 0xFF, 0xFF, 0x80,
/* 0xB0 */ 0x38, 0xFB, 0x1C, 0x18, 0x38, 0xDF, 0x1C,
/* 0xB1 */ 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x7F, 0xE7, 0xFE, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF0,
/* 0xB2 */ 0x76, 0x31, 0x87, 0x80,
/* 0xB3 */ 0x66, 0x66, 0x66, 0x67, 0x7E, 0xE6, 0x66, 0x66, 0x66,
/* 0xB4 */ 0x3B, 0x99, 0x80,
/* 0xB5 */ 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x1C, 0xE3, 0xCF, 0xEF, 0xFC, 0x7C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x00,
/* 0xB6 */ 0x1F, 0xE7, 0xFD, 0xF3, 0x7E, 0x6F, 0xCD, 0xF9, 0xBF, 0x37, 0xE6, 0x7C, 0xCF, 0x98, 0xF3, 0x06, 0x60, 0xCC, 0x19, 0x83, 0x30, 0x66, 0x0C, 0xC1, 0x98, 0x33, 0x06, 0x60, 0xCC,
/* 0xB7 */ 0xF0,
/* 0xB8 */ 0x10, 0xF0, 0xE3, 0x78,
/* 0xB9 */ 0x1F, 0x01, 0xFC, 0x1C, 0x70, 0xC1, 0x80, 0x0C, 0x00, 0xE0, 0xFF, 0x1F, 0x18, 0xC0, 0xC6, 0x06, 0x38, 0x70, 0xFF, 0xE3, 0xC7, 0x00, 0x30, 0x03, 0x00, 0x18, 0x00, 0xC0, 0x03, 0xC0,
/* 0xBA */ 0x3F, 0x1F, 0xEE, 0x1B, 0x00, 0xC0, 0x3C, 0x07, 0xF0, 0x3E, 0x01, 0xF0, 0x3C, 0x0D, 0xDE, 0x7F, 0x02, 0x01, 0xE0, 0x18, 0x46, 0x0F, 0x00,
/* 0xBB */ 0x88, 0xC6, 0xE7, 0x21, 0x21, 0xE7, 0xC6, 0x88,
/* 0xBC */ 0xC3, 0x31, 0x8C, 0x63, 0x10, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xFF, 0xFF, 0xF0,
/* 0xBD */ 0x77, 0x66, 0xCC, 0xC8,
/* 0xBE */ 0xC7, 0x9B, 0x36, 0xCC, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x80,
/* 0xBF */ 0x0C, 0x03, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x18, 0x0C, 0x07, 0x03, 0x81, 0xC0, 0x60, 0x30, 0x18, 0x0E, 0x03, 0xFF, 0xFF, 0xC0,
/* 0xC0 */ 0x03, 0x80, 0x18, 0x00, 0x40, 0x00, 0x00, 0xFF, 0xE3, 0xFF, 0xCC, 0x03, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x6C, 0x01, 0xB0, 0x0C, 0xFF, 0xE3, 0xFF, 0xCC, 0x03, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x6C, 0x01, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x70,
/* 0xC1 */ 0x01, 0xC0, 0x0C, 0x00, 0x20, 0x00, 0x00, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x03, 0xF0, 0x0C, 0xC0, 0x33, 0x01, 0xCE, 0x06, 0x18, 0x18, 0x60, 0xE1, 0xC3, 0x03, 0x0F, 0xFC, 0x7F, 0xF9, 0x80, 0x66, 0x01, 0xB8, 0x07, 0xC0, 0x0F, 0x00, 0x30,
/* 0xC2 */ 0x07, 0x00, 0x3E, 0x01, 0x8C, 0x00, 0x00, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x03, 0xF0, 0x0C, 0xC0, 0x33, 0x01, 0xCE, 0x06, 0x18, 0x18, 0x60, 0xE1, 0xC3, 0x03, 0x0F, 0xFC, 0x7F, 0xF9, 0x80, 0x66, 0x01, 0xB8, 0x07, 0xC0, 0x0F, 0x00, 0x30,
/* 0xC3 */ 0x10, 0x40, 0x63, 0x00, 0xF8, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x03, 0xF0, 0x0C, 0xC0, 0x33, 0x01, 0xCE, 0x06, 0x18, 0x18, 0x60, 0xE1, 0xC3, 0x03, 0x0F, 0xFC, 0x7F, 0xF9, 0x80, 0x66, 0x01, 0xB8, 0x07, 0xC0, 0x0F, 0x00, 0x30,
/* 0xC4 */ 0x0C, 0xC0, 0x33, 0x00, 0x00, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00, 0xFC, 0x03, 0x30, 0x0C, 0xC0, 0x73, 0x81, 0x86, 0x06, 0x18, 0x38, 0x70, 0xC0, 0xC3, 0xFF, 0x1F, 0xFE, 0x60, 0x19, 0x80, 0x6E, 0x01, 0xF0, 0x03, 0xC0, 0x0C,
/* 0xC5 */ 0x18, 0x0C, 0x06, 0x00, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xFF, 0xFF, 0xF0,
/* 0xC6 */ 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x7E, 0x03, 0xFF, 0x0E, 0x07, 0x38, 0x07, 0x60, 0x06, 0xC0, 0x03, 0x00, 0x06, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x30, 0x00, 0x60, 0x00, 0xE0, 0x06, 0xC0, 0x0D, 0xC0, 0x31, 0xE0, 0xE1, 0xFF, 0x80, 0xFC, 0x00,
/* 0xC7 */ 0x07, 0xE0, 0x3F, 0xF0, 0xE0, 0x73, 0x80, 0x66, 0x00, 0x7C, 0x00, 0x30, 0x00, 0x60, 0x00, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x00, 0x0E, 0x00, 0x6C, 0x01, 0xDC, 0x03, 0x1C, 0x1E, 0x1F, 0xF8, 0x0F, 0xC0, 0x08, 0x00, 0x1E, 0x00, 0x0C, 0x01, 0x18, 0x01, 0xE0, 0x00,
/* 0xC8 */ 0x06, 0x30, 0x07, 0xC0, 0x07, 0x00, 0x3F, 0x01, 0xFF, 0x87, 0x03, 0x9C, 0x03, 0xB0, 0x03, 0x60, 0x01, 0x80, 0x03, 0x00, 0x06, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x30, 0x00, 0x70, 0x03, 0x60, 0x06, 0xE0, 0x18, 0xF0, 0x70, 0xFF, 0xC0, 0x7E, 0x00,
/* 0xC9 */ 0x07, 0x00, 0x60, 0x0C, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xEF, 0xFE, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xFF, 0xFF,
/* 0xCA */ 0xFF, 0xE7, 0xFF, 0x30, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x18, 0x00, 0xFF, 0xE7, 0xFF, 0x30, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x18, 0x00, 0xFF, 0xF7, 0xFF, 0x80, 0x18, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x01, 0xE0,
/* 0xCB */ 0x19, 0x81, 0x98, 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0F, 0xFE, 0xFF, 0xEC, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0F, 0xFF, 0xFF, 0xF0,
/* 0xCC */ 0x08, 0xC0, 0xF8, 0x07, 0x0F, 0xFF, 0xFF, 0xFC, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0F, 0xFE, 0xFF, 0xEC, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0F, 0xFF, 0xFF, 0xF0,
/* 0xCD */ 0x36, 0xC0, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
/* 0xCE */ 0x39, 0xFC, 0x40, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC0,
/* 0xCF */ 0x18, 0xC0, 0x3E, 0x00, 0x70, 0x3F, 0xF0, 0xFF, 0xE3, 0x01, 0xCC, 0x03, 0xB0, 0x06, 0xC0, 0x1F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x07, 0xC0, 0x1B, 0x00, 0xEC, 0x07, 0x3F, 0xF8, 0xFF, 0x80,
/* 0xD0 */ 0x7F, 0xE0, 0xFF, 0xE1, 0x80, 0xE3, 0x00, 0xE6, 0x00, 0xCC, 0x01, 0xD8, 0x01, 0xB0, 0x03, 0xFE, 0x07, 0xFC, 0x0D, 0x80, 0x1B, 0x00, 0x36, 0x00, 0x6C, 0x01, 0x98, 0x07, 0x30, 0x1C, 0x7F, 0xF0, 0xFF, 0xC0,
/* 0xD1 */ 0x01, 0x80, 0x18, 0x01, 0x80, 0x00, 0x0E, 0x01, 0xF0, 0x0F, 0xC0, 0x7E, 0x03, 0xD8, 0x1E, 0xE0, 0xF3, 0x07, 0x9C, 0x3C, 0x61, 0xE1, 0x8F, 0x0E, 0x78, 0x33, 0xC1, 0xDE, 0x06, 0xF0, 0x1F, 0x80, 0xFC, 0x03, 0xE0, 0x1C,
/* 0xD2 */ 0x0C, 0xC0, 0x3C, 0x00, 0xE1, 0xC0, 0x3E, 0x01, 0xF8, 0x0F, 0xC0, 0x7B, 0x03, 0xDC, 0x1E, 0x60, 0xF3, 0x87, 0x8C, 0x3C, 0x31, 0xE1, 0xCF, 0x06, 0x78, 0x3B, 0xC0, 0xDE, 0x03, 0xF0, 0x1F, 0x80, 0x7C, 0x03, 0x80,
/* 0xD3 */ 0x00, 0xE0, 0x00, 0x60, 0x00, 0x40, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xFF, 0xE0, 0xF0, 0x78, 0x60, 0x0C, 0x60, 0x03, 0x30, 0x01, 0xB0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x07, 0x80, 0x03, 0x60, 0x03, 0x30, 0x01, 0x8C, 0x01, 0x87, 0x83, 0xC1, 0xFF, 0xC0, 0x3F, 0x80,
/* 0xD4 */ 0x03, 0xC0, 0x01, 0xE0, 0x01, 0x98, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xFF, 0xE0, 0xF0, 0x78, 0x60, 0x0C, 0x60, 0x03, 0x30, 0x01, 0xB0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x07, 0x80, 0x03, 0x60, 0x03, 0x30, 0x01, 0x8C, 0x01, 0x87, 0x83, 0xC1, 0xFF, 0xC0, 0x3F, 0x80,
/* 0xD5 */ 0x03, 0xB8, 0x01, 0x98, 0x00, 0x98, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xFF, 0xE0, 0xF0, 0x78, 0x60, 0x0C, 0x60, 0x03, 0x30, 0x01, 0xB0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x07, 0x80, 0x03, 0x60, 0x03, 0x30, 0x01, 0x8C, 0x01, 0x87, 0x83, 0xC1, 0xFF, 0xC0, 0x3F, 0x80,
/* 0xD6 */ 0x06, 0x30, 0x03, 0x18, 0x00, 0x00, 0x00, 0xFE, 0x01, 0xFF, 0xC1, 0xE0, 0xF0, 0xC0, 0x18, 0xC0, 0x06, 0x60, 0x03, 0x60, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x06, 0xC0, 0x06, 0x60, 0x03, 0x18, 0x03, 0x0F, 0x07, 0x83, 0xFF, 0x80, 0x7F, 0x00,
/* 0xD7 */ 0x81, 0xC3, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0xC3, 0x81,
/* 0xD8 */ 0x0C, 0xC0, 0x1E, 0x00, 0x78, 0x3F, 0xF8, 0xFF, 0xF3, 0x00, 0xEC, 0x01, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x6C, 0x03, 0x3F, 0xF8, 0xFF, 0xF3, 0x00, 0xEC, 0x01, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x6C, 0x01, 0xB0, 0x06, 0xC0, 0x1C,
/* 0xD9 */ 0x03, 0x00, 0x7C, 0x03, 0x70, 0x19, 0x80, 0xF8, 0x03, 0xC3, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3E, 0x03, 0xB8, 0x38, 0xFF, 0x83, 0xF0,
/* 0xDA */ 0x03, 0x80, 0x18, 0x01, 0x80, 0x00, 0x0C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF8, 0x0E, 0xE0, 0xE3, 0xFE, 0x0F, 0xC0,
/* 0xDB */ 0x0E, 0xE0, 0x66, 0x03, 0x60, 0x00, 0x0C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF8, 0x0E, 0xE0, 0xE3, 0xFE, 0x0F, 0xC0,
/* 0xDC */ 0x0C, 0xC0, 0x66, 0x00, 0x01, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1F, 0x01, 0xDC, 0x1C, 0x7F, 0xC1, 0xF8, 0x00,
/* 0xDD */ 0x01, 0x80, 0x0C, 0x00, 0x60, 0x00, 0x00, 0xC0, 0x0F, 0x80, 0x76, 0x01, 0x9C, 0x0C, 0x38, 0x70, 0x61, 0x81, 0xCE, 0x03, 0x30, 0x0F, 0x80, 0x1E, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00,
/* 0xDE */ 0xFF, 0xFF, 0xFF, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x04, 0x00, 0x78, 0x01, 0x81, 0x18, 0x0F, 0x00,
/* 0xDF */ 0x1F, 0x0F, 0xF3, 0x87, 0x60, 0x6C, 0x0D, 0x81, 0xB0, 0x66, 0x38, 0xC7, 0xD8, 0x1B, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x3E, 0x0E, 0xCF, 0x99, 0xE0,
/* 0xE0 */ 0x0C, 0x61, 0x8C, 0x03, 0x3D, 0xFC, 0xE3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x00,
/* 0xE1 */ 0x07, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x00, 0x03, 0xF0, 0x7F, 0x8E, 0x1C, 0xC0, 0xC0, 0x0C, 0x01, 0xC3, 0xFC, 0xF8, 0xCC, 0x0C, 0xC0, 0xCE, 0x3C, 0x7E, 0xF3, 0xC7,
/* 0xE2 */ 0x0C, 0x01, 0xE0, 0x1B, 0x03, 0x30, 0x00, 0x03, 0xF0, 0x7F, 0x8E, 0x1C, 0xC0, 0xC0, 0x0C, 0x01, 0xC3, 0xFC, 0xF8, 0xCC, 0x0C, 0xC0, 0xCE, 0x3C, 0x7E, 0xF3, 0xC7,
/* 0xE3 */ 0x20, 0x82, 0x10, 0x3F, 0x01, 0xE0, 0x00, 0x03, 0xF0, 0x7F, 0x8E, 0x1C, 0xC0, 0xC0, 0x0C, 0x01, 0xC3, 0xFC, 0xF8, 0xCC, 0x0C, 0xC0, 0xCE, 0x3C, 0x7E, 0xF3, 0xC7,
/* 0xE4 */ 0x19, 0x81, 0x98, 0x00, 0x00, 0x00, 0x3F, 0x07, 0xF8, 0xE1, 0xCC, 0x0C, 0x00, 0xC0, 0x1C, 0x3F, 0xCF, 0x8C, 0xC0, 0xCC, 0x0C, 0xE3, 0xC7, 0xEF, 0x3C, 0x70,
/* 0xE5 */ 0x3B, 0x30, 0x06, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x30,
/* 0xE6 */ 0x07, 0x01, 0x80, 0xC0, 0x20, 0x00, 0x07, 0xC3, 0xF9, 0x87, 0xE0, 0xF0, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0E, 0x0D, 0xC7, 0x3F, 0x87, 0xC0,
/* 0xE7 */ 0x1F, 0x0F, 0xE7, 0x1D, 0x83, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x38, 0x37, 0x1C, 0xFE, 0x1F, 0x02, 0x00, 0xE0, 0x0C, 0x23, 0x07, 0x80,
/* 0xE8 */ 0x21, 0x0C, 0xC1, 0xE0, 0x78, 0x00, 0x07, 0xC3, 0xF9, 0x87, 0xE0, 0xF0, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0E, 0x0D, 0xC7, 0x3F, 0x87, 0xC0,
/* 0xE9 */ 0x03, 0x00, 0xC0, 0x30, 0x04, 0x00, 0x00, 0x3E, 0x0F, 0xE3, 0x8E, 0xE0, 0x78, 0x0F, 0xFF, 0xFF, 0xFC, 0x01, 0x80, 0x38, 0x1B, 0x86, 0x3F, 0x83, 0xE0,
/* 0xEA */ 0x1F, 0x07, 0xF1, 0x87, 0x60, 0x6C, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0xC0, 0x1C, 0x1D, 0x87, 0x1F, 0xC1, 0xF8, 0x06, 0x01, 0x80, 0x30, 0x06, 0x00, 0x78,
/* 0xEB */ 0x31, 0x86, 0x30, 0x00, 0x00, 0x01, 0xF0, 0x7F, 0x1C, 0x77, 0x03, 0xC0, 0x7F, 0xFF, 0xFF, 0xE0, 0x0C, 0x01, 0xC0, 0xDC, 0x31, 0xFC, 0x1F, 0x00,
/* 0xEC */ 0x31, 0x82, 0x60, 0x6C, 0x07, 0x00, 0x00, 0x3E, 0x0F, 0xE3, 0x8E, 0xE0, 0x78, 0x0F, 0xFF, 0xFF, 0xFC, 0x01, 0x80, 0x38, 0x1B, 0x86, 0x3F, 0x83, 0xE0,
/* 0xED */ 0x39, 0x99, 0x80, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x80,
/* 0xEE */ 0x71, 0xED, 0xA3, 0x00, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC0,
/* 0xEF */ 0x00, 0x67, 0x00, 0x66, 0x00, 0x64, 0x00, 0x6C, 0x00, 0x60, 0x1E, 0x60, 0x3F, 0xE0, 0x71, 0xE0, 0xE0, 0xE0, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xE0, 0xE0, 0x71, 0xE0, 0x3F, 0x60, 0x1E, 0x60,
/* 0xF0 */ 0x00, 0x60, 0x06, 0x03, 0xF0, 0x06, 0x00, 0x61, 0xE6, 0x3F, 0xE7, 0x1E, 0xE0, 0xEC, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xE0, 0xE7, 0x1E, 0x3F, 0xE1, 0xE6,
/* 0xF1 */ 0x03, 0x81, 0xC0, 0x60, 0x30, 0x00, 0x33, 0xCD, 0xFB, 0xC7, 0xE0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x30,
/* 0xF2 */ 0x31, 0x84, 0xC1, 0xA0, 0x38, 0x00, 0x33, 0xCD, 0xFB, 0xC7, 0xE0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x30,
/* 0xF3 */ 0x07, 0x00, 0xC0, 0x30, 0x04, 0x00, 0x00, 0x3E, 0x0F, 0xE3, 0x8E, 0xE0, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF8, 0x3B, 0x8E, 0x3F, 0x83, 0xE0,
/* 0xF4 */ 0x0C, 0x03, 0xC0, 0xD8, 0x19, 0x80, 0x00, 0x3E, 0x0F, 0xE3, 0x8E, 0xE0, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF8, 0x3B, 0x8E, 0x3F, 0x83, 0xE0,
/* 0xF5 */ 0x0C, 0xC3, 0xB8, 0x66, 0x0D, 0x80, 0x00, 0x3E, 0x0F, 0xE3, 0x8E, 0xE0, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF8, 0x3B, 0x8E, 0x3F, 0x83, 0xE0,
/* 0xF6 */ 0x31, 0x86, 0x30, 0x00, 0x00, 0x01, 0xF0, 0x7F, 0x1C, 0x77, 0x07, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0xC1, 0xDC, 0x71, 0xFC, 0x1F, 0x00,
/* 0xF7 */ 0x06, 0x00, 0x60, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x06, 0x00,
/* 0xF8 */ 0xC7, 0x37, 0x8E, 0x03, 0x3D, 0xFC, 0xE3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x00,
/* 0xF9 */ 0x0E, 0x07, 0xC1, 0xB8, 0x6C, 0x1F, 0x03, 0x8C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x07, 0xE3, 0xDF, 0xB3, 0xCC,
/* 0xFA */ 0x03, 0x01, 0x80, 0x60, 0x30, 0x00, 0x30, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x1F, 0x8F, 0x7E, 0xCF, 0x30,
/* 0xFB */ 0x1D, 0xC6, 0x61, 0xB0, 0xCC, 0x00, 0x30, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x1F, 0x8F, 0x7E, 0xCF, 0x30,
/* 0xFC */ 0x31, 0x8C, 0x60, 0x00, 0x00, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x7E, 0x3D, 0xFB, 0x3C, 0xC0,
/* 0xFD */ 0x03, 0x80, 0x60, 0x18, 0x06, 0x00, 0x01, 0xC0, 0xD8, 0x1B, 0x06, 0x70, 0xC6, 0x18, 0xC6, 0x18, 0xC1, 0x98, 0x36, 0x06, 0xC0, 0x78, 0x0E, 0x01, 0xC0, 0x30, 0x06, 0x01, 0xC0, 0xF0, 0x1C, 0x00,
/* 0xFE */ 0x61, 0x86, 0x3E, 0xF9, 0x86, 0x18, 0x61, 0x86, 0x18, 0x61, 0x87, 0x8E, 0x10, 0x83, 0xC3, 0x78,
/* 0xFF */ 0xF0,
};
const GFXglyph FreeSans12pt_Win1250Glyphs[] PROGMEM = {
/* 0x01 */ { 0, 19, 20, 21, 1, -17 },
/* 0x02 */ { 48, 19, 20, 21, 1, -17 },
/* 0x03 */ { 96, 21, 20, 23, 1, -17 },
/* 0x04 */ { 149, 21, 20, 23, 1, -17 },
/* 0x05 */ { 202, 20, 20, 22, 1, -17 },
/* 0x06 */ { 252, 20, 20, 22, 1, -17 },
/* 0x07 */ { 302, 0, 0, 8, 0, 0 },
/* 0x08 */ { 302, 23, 20, 25, 1, -17 },
/* 0x09 */ { 360, 23, 16, 25, 1, -16 },
/* 0x0A */ { 406, 0, 0, 8, 0, 0 },
/* 0x0B */ { 406, 21, 20, 23, 1, -17 },
/* 0x0C */ { 459, 19, 18, 21, 1, -15 },
/* 0x0D */ { 502, 0, 0, 8, 0, 0 },
/* 0x0E */ { 502, 20, 20, 22, 1, -17 },
/* 0x0F */ { 552, 21, 21, 23, 1, -18 },
/* 0x10 */ { 608, 19, 20, 21, 1, -17 },
/* 0x11 */ { 656, 21, 20, 23, 1, -17 },
/* 0x12 */ { 709, 20, 20, 22, 1, -17 },
/* 0x13 */ { 759, 21, 20, 23, 1, -17 },
/* 0x14 */ { 812, 21, 20, 23, 1, -17 },
/* 0x15 */ { 865, 22, 20, 24, 1, -17 },
/* 0x16 */ { 920, 16, 20, 18, 1, -17 },
/* 0x17 */ { 960, 21, 20, 23, 1, -17 },
/* 0x18 */ { 1013, 23, 20, 25, 1, -17 },
/* 0x19 */ { 1071, 21, 20, 23, 1, -17 },
/* 0x1A */ { 1124, 15, 19, 17, 1, -16 },
/* 0x1B */ { 1160, 24, 21, 26, 1, -18 },
/* 0x1C */ { 1223, 21, 20, 23, 1, -17 },
/* 0x1D */ { 1276, 21, 21, 23, 1, -18 },
/* 0x1E */ { 1332, 20, 20, 22, 1, -17 },
/* 0x1F */ { 1382, 15, 20, 17, 1, -17 },
/* ' ' 0x20 */ { 1420, 0, 0, 6, 0, 0 },
/* '!' 0x21 */ { 1420, 2, 18, 8, 3, -16 },
/* '"' 0x22 */ { 1425, 6, 6, 8, 1, -15 },
/* '#' 0x23 */ { 1430, 13, 16, 13, 0, -14 },
/* '$' 0x24 */ { 1456, 11, 20, 13, 1, -16 },
/* '%' 0x25 */ { 1484, 20, 17, 21, 1, -15 },
/* '&' 0x26 */ { 1527, 14, 17, 16, 1, -15 },
/* ''' 0x27 */ { 1557, 2, 6, 5, 1, -15 },
/* '(' 0x28 */ { 1559, 5, 23, 8, 2, -16 },
/* ')' 0x29 */ { 1574, 5, 23, 8, 1, -16 },
/* '*' 0x2A */ { 1589, 7, 7, 9, 1, -16 },
/* '+' 0x2B */ { 1596, 10, 11, 14, 2, -9 },
/* ',' 0x2C */ { 1610, 2, 6, 7, 2, 0 },
/* '-' 0x2D */ { 1612, 6, 2, 8, 1, -6 },
/* '.' 0x2E */ { 1614, 2, 2, 6, 2, 0 },
/* '/' 0x2F */ { 1615, 7, 18, 7, 0, -16 },
/* '0' 0x30 */ { 1631, 11, 17, 13, 1, -15 },
/* '1' 0x31 */ { 1655, 5, 17, 13, 3, -15 },
/* '2' 0x32 */ { 1666, 11, 17, 13, 1, -15 },
/* '3' 0x33 */ { 1690, 11, 17, 13, 1, -15 },
/* '4' 0x34 */ { 1714, 11, 17, 13, 1, -15 },
/* '5' 0x35 */ { 1738, 11, 17, 13, 1, -15 },
/* '6' 0x36 */ { 1762, 11, 17, 13, 1, -15 },
/* '7' 0x37 */ { 1786, 11, 17, 13, 1, -15 },
/* '8' 0x38 */ { 1810, 11, 17, 13, 1, -15 },
/* '9' 0x39 */ { 1834, 11, 17, 13, 1, -15 },
/* ':' 0x3A */ { 1858, 2, 13, 6, 2, -11 },
/* ';' 0x3B */ { 1862, 2, 16, 6, 2, -10 },
/* '<' 0x3C */ { 1866, 12, 11, 14, 1, -9 },
/* '=' 0x3D */ { 1883, 12, 6, 14, 1, -7 },
/* '>' 0x3E */ { 1892, 12, 11, 14, 1, -9 },
/* '?' 0x3F */ { 1909, 10, 18, 13, 2, -16 },
/* '@' 0x40 */ { 1932, 22, 21, 24, 1, -16 },
/* 'A' 0x41 */ { 1990, 14, 18, 16, 1, -16 },
/* 'B' 0x42 */ { 2022, 13, 18, 16, 2, -16 },
/* 'C' 0x43 */ { 2052, 15, 18, 17, 1, -16 },
/* 'D' 0x44 */ { 2086, 14, 18, 17, 2, -16 },
/* 'E' 0x45 */ { 2118, 12, 18, 15, 2, -16 },
/* 'F' 0x46 */ { 2145, 11, 18, 14, 2, -16 },
/* 'G' 0x47 */ { 2170, 16, 18, 18, 1, -16 },
/* 'H' 0x48 */ { 2206, 13, 18, 17, 2, -16 },
/* 'I' 0x49 */ { 2236, 2, 18, 7, 2, -16 },
/* 'J' 0x4A */ { 2241, 9, 18, 13, 1, -16 },
/* 'K' 0x4B */ { 2262, 13, 18, 16, 2, -16 },
/* 'L' 0x4C */ { 2292, 10, 18, 14, 2, -16 },
/* 'M' 0x4D */ { 2315, 16, 18, 20, 2, -16 },
/* 'N' 0x4E */ { 2351, 13, 18, 18, 2, -16 },
/* 'O' 0x4F */ { 2381, 17, 18, 19, 1, -16 },
/* 'P' 0x50 */ { 2420, 12, 18, 16, 2, -16 },
/* 'Q' 0x51 */ { 2447, 17, 19, 19, 1, -16 },
/* 'R' 0x52 */ { 2488, 14, 18, 17, 2, -16 },
/* 'S' 0x53 */ { 2520, 14, 18, 16, 1, -16 },
/* 'T' 0x54 */ { 2552, 12, 18, 15, 1, -16 },
/* 'U' 0x55 */ { 2579, 13, 18, 17, 2, -16 },
/* 'V' 0x56 */ { 2609, 14, 18, 15, 1, -16 },
/* 'W' 0x57 */ { 2641, 22, 18, 22, 0, -16 },
/* 'X' 0x58 */ { 2691, 14, 18, 16, 1, -16 },
/* 'Y' 0x59 */ { 2723, 14, 18, 16, 1, -16 },
/* 'Z' 0x5A */ { 2755, 13, 18, 15, 1, -16 },
/* '[' 0x5B */ { 2785, 4, 23, 7, 2, -16 },
/* '\' 0x5C */ { 2797, 7, 18, 7, 0, -16 },
/* ']' 0x5D */ { 2813, 4, 23, 7, 1, -16 },
/* '^' 0x5E */ { 2825, 9, 9, 11, 1, -15 },
/* '_' 0x5F */ { 2836, 15, 1, 13, -1, 5 },
/* '`' 0x60 */ { 2838, 5, 4, 6, 1, -16 },
/* 'a' 0x61 */ { 2841, 12, 13, 13, 1, -11 },
/* 'b' 0x62 */ { 2861, 12, 18, 13, 1, -16 },
/* 'c' 0x63 */ { 2888, 10, 13, 12, 1, -11 },
/* 'd' 0x64 */ { 2905, 11, 18, 13, 1, -16 },
/* 'e' 0x65 */ { 2930, 11, 13, 13, 1, -11 },
/* 'f' 0x66 */ { 2948, 5, 18, 7, 1, -16 },
/* 'g' 0x67 */ { 2960, 11, 18, 13, 1, -11 },
/* 'h' 0x68 */ { 2985, 10, 18, 13, 1, -16 },
/* 'i' 0x69 */ { 3008, 2, 18, 5, 2, -16 },
/* 'j' 0x6A */ { 3013, 4, 23, 6, 0, -16 },
/* 'k' 0x6B */ { 3025, 10, 18, 12, 1, -16 },
/* 'l' 0x6C */ { 3048, 2, 18, 5, 1, -16 },
/* 'm' 0x6D */ { 3053, 17, 13, 19, 1, -11 },
/* 'n' 0x6E */ { 3081, 10, 13, 13, 1, -11 },
/* 'o' 0x6F */ { 3098, 11, 13, 13, 1, -11 },
/* 'p' 0x70 */ { 3116, 12, 17, 13, 1, -11 },
/* 'q' 0x71 */ { 3142, 11, 17, 13, 1, -11 },
/* 'r' 0x72 */ { 3166, 6, 13, 8, 1, -11 },
/* 's' 0x73 */ { 3176, 10, 13, 12, 1, -11 },
/* 't' 0x74 */ { 3193, 5, 16, 7, 1, -14 },
/* 'u' 0x75 */ { 3203, 10, 13, 13, 1, -11 },
/* 'v' 0x76 */ { 3220, 11, 13, 12, 0, -11 },
/* 'w' 0x77 */ { 3238, 17, 13, 17, 0, -11 },
/* 'x' 0x78 */ { 3266, 10, 13, 11, 1, -11 },
/* 'y' 0x79 */ { 3283, 11, 18, 11, 0, -11 },
/* 'z' 0x7A */ { 3308, 10, 13, 12, 1, -11 },
/* '{' 0x7B */ { 3325, 5, 23, 8, 1, -16 },
/* '|' 0x7C */ { 3340, 2, 23, 6, 2, -16 },
/* '}' 0x7D */ { 3346, 5, 23, 8, 2, -16 },
/* '~' 0x7E */ { 3361, 10, 5, 12, 1, -9 },
/* 0x7F */ { 3368, 0, 0, 0, 0, 0 },
/* 0x80 */ { 3368, 14, 17, 16, 1, -17 },
/* 0x81 */ { 3398, 0, 0, 8, 0, 0 },
/* 0x82 */ { 3398, 2, 5, 6, 2, -2 },
/* 0x83 */ { 3400, 0, 0, 8, 0, 0 },
/* 0x84 */ { 3400, 6, 5, 10, 2, -2 },
/* 0x85 */ { 3404, 12, 2, 16, 2, -2 },
/* 0x86 */ { 3407, 10, 21, 13, 2, -17 },
/* 0x87 */ { 3434, 10, 20, 13, 2, -17 },
/* 0x88 */ { 3459, 0, 0, 8, 0, 0 },
/* 0x89 */ { 3459, 23, 18, 24, 0, -18 },
/* 0x8A */ { 3511, 14, 21, 16, 1, -21 },
/* 0x8B */ { 3548, 3, 8, 6, 1, -11 },
/* 0x8C */ { 3551, 14, 22, 16, 1, -22 },
/* 0x8D */ { 3590, 12, 21, 15, 1, -21 },
/* 0x8E */ { 3622, 13, 21, 15, 1, -21 },
/* 0x8F */ { 3657, 13, 22, 15, 1, -22 },
/* 0x90 */ { 3693, 0, 0, 8, 0, 0 },
/* 0x91 */ { 3693, 2, 6, 6, 2, -18 },
/* 0x92 */ { 3695, 2, 6, 6, 2, -18 },
/* 0x93 */ { 3697, 6, 6, 10, 2, -18 },
/* 0x94 */ { 3702, 6, 6, 10, 2, -18 },
/* 0x95 */ { 3707, 6, 6, 10, 2, -11 },
/* 0x96 */ { 3712, 10, 2, 12, 1, -8 },
/* 0x97 */ { 3715, 22, 2, 24, 1, -8 },
/* 0x98 */ { 3721, 0, 0, 8, 0, 0 },
/* 0x99 */ { 3721, 22, 13, 24, 2, -18 },
/* 0x9A */ { 3757, 10, 18, 12, 1, -18 },
/* 0x9B */ { 3780, 3, 8, 6, 2, -10 },
/* 0x9C */ { 3783, 10, 18, 12, 1, -18 },
/* 0x9D */ { 3806, 8, 18, 11, 1, -18 },
/* 0x9E */ { 3824, 10, 18, 12, 1, -18 },
/* 0x9F */ { 3847, 10, 18, 12, 1, -18 },
/* 0xA0 */ { 3870, 0, 0, 7, 0, 0 },
/* 0xA1 */ { 3870, 7, 4, 8, 0, -18 },
/* 0xA2 */ { 3874, 7, 4, 8, 0, -18 },
/* 0xA3 */ { 3878, 13, 18, 15, 1, -18 },
/* 0xA4 */ { 3908, 9, 9, 13, 2, -13 },
/* 0xA5 */ { 3919, 16, 23, 16, 1, -18 },
/* 0xA6 */ { 3965, 2, 23, 6, 2, -18 },
/* 0xA7 */ { 3971, 11, 23, 13, 1, -18 },
/* 0xA8 */ { 4003, 6, 2, 8, 1, -17 },
/* 0xA9 */ { 4005, 18, 17, 19, 1, -17 },
/* 0xAA */ { 4044, 14, 23, 16, 1, -18 },
/* 0xAB */ { 4085, 8, 8, 12, 2, -11 },
/* 0xAC */ { 4093, 12, 6, 14, 1, -9 },
/* 0xAD */ { 4102, 6, 2, 8, 1, -8 },
/* 0xAE */ { 4104, 18, 17, 19, 1, -17 },
/* 0xAF */ { 4143, 13, 21, 15, 1, -21 },
/* 0xB0 */ { 4178, 7, 8, 15, 4, -17 },
/* 0xB1 */ { 4185, 12, 15, 14, 1, -15 },
/* 0xB2 */ { 4208, 5, 5, 8, 1, 0 },
/* 0xB3 */ { 4212, 4, 18, 6, 1, -18 },
/* 0xB4 */ { 4221, 5, 4, 8, 2, -18 },
/* 0xB5 */ { 4224, 12, 17, 13, 2, -13 },
/* 0xB6 */ { 4250, 11, 21, 13, 2, -18 },
/* 0xB7 */ { 4279, 2, 2, 6, 2, -8 },
/* 0xB8 */ { 4280, 6, 5, 8, 1, 0 },
/* 0xB9 */ { 4284, 13, 18, 13, 1, -13 },
/* 0xBA */ { 4314, 10, 18, 12, 1, -13 },
/* 0xBB */ { 4337, 8, 8, 12, 2, -10 },
/* 0xBC */ { 4345, 10, 18, 14, 2, -18 },
/* 0xBD */ { 4368, 8, 4, 8, 0, -18 },
/* 0xBE */ { 4372, 7, 18, 9, 1, -18 },
/* 0xBF */ { 4388, 10, 17, 12, 1, -17 },
/* 0xC0 */ { 4410, 14, 22, 17, 2, -22 },
/* 0xC1 */ { 4449, 14, 22, 16, 1, -22 },
/* 0xC2 */ { 4488, 14, 22, 16, 1, -22 },
/* 0xC3 */ { 4527, 14, 22, 16, 1, -22 },
/* 0xC4 */ { 4566, 14, 21, 16, 1, -21 },
/* 0xC5 */ { 4603, 10, 22, 14, 2, -22 },
/* 0xC6 */ { 4631, 15, 22, 17, 1, -22 },
/* 0xC7 */ { 4673, 15, 23, 17, 1, -18 },
/* 0xC8 */ { 4717, 15, 21, 17, 1, -21 },
/* 0xC9 */ { 4757, 12, 22, 15, 2, -22 },
/* 0xCA */ { 4790, 13, 23, 15, 2, -18 },
/* 0xCB */ { 4828, 12, 21, 15, 2, -21 },
/* 0xCC */ { 4860, 12, 21, 15, 2, -21 },
/* 0xCD */ { 4892, 4, 22, 7, 1, -22 },
/* 0xCE */ { 4903, 6, 22, 7, 0, -22 },
/* 0xCF */ { 4920, 14, 21, 17, 2, -21 },
/* 0xD0 */ { 4957, 15, 18, 17, 1, -18 },
/* 0xD1 */ { 4991, 13, 22, 18, 2, -22 },
/* 0xD2 */ { 5027, 13, 21, 18, 2, -21 },
/* 0xD3 */ { 5062, 17, 22, 19, 1, -22 },
/* 0xD4 */ { 5109, 17, 22, 19, 1, -22 },
/* 0xD5 */ { 5156, 17, 22, 19, 1, -22 },
/* 0xD6 */ { 5203, 17, 21, 19, 1, -21 },
/* 0xD7 */ { 5248, 8, 9, 14, 3, -10 },
/* 0xD8 */ { 5257, 14, 21, 17, 2, -21 },
/* 0xD9 */ { 5294, 13, 24, 17, 2, -24 },
/* 0xDA */ { 5333, 13, 22, 17, 2, -22 },
/* 0xDB */ { 5369, 13, 22, 17, 2, -22 },
/* 0xDC */ { 5405, 13, 21, 17, 2, -21 },
/* 0xDD */ { 5440, 14, 22, 16, 1, -22 },
/* 0xDE */ { 5479, 12, 23, 15, 1, -18 },
/* 0xDF */ { 5514, 11, 18, 14, 2, -18 },
/* 0xE0 */ { 5539, 6, 18, 8, 1, -18 },
/* 0xE1 */ { 5553, 12, 18, 13, 1, -18 },
/* 0xE2 */ { 5580, 12, 18, 13, 1, -18 },
/* 0xE3 */ { 5607, 12, 18, 13, 1, -18 },
/* 0xE4 */ { 5634, 12, 17, 13, 1, -17 },
/* 0xE5 */ { 5660, 5, 22, 6, 0, -22 },
/* 0xE6 */ { 5674, 10, 18, 12, 1, -18 },
/* 0xE7 */ { 5697, 10, 18, 12, 1, -13 },
/* 0xE8 */ { 5720, 10, 18, 12, 1, -18 },
/* 0xE9 */ { 5743, 11, 18, 13, 1, -18 },
/* 0xEA */ { 5768, 11, 18, 13, 1, -13 },
/* 0xEB */ { 5793, 11, 17, 13, 1, -17 },
/* 0xEC */ { 5817, 11, 18, 13, 1, -18 },
/* 0xED */ { 5842, 5, 18, 5, 0, -18 },
/* 0xEE */ { 5854, 6, 18, 6, 0, -18 },
/* 0xEF */ { 5868, 16, 18, 18, 1, -18 },
/* 0xF0 */ { 5904, 12, 18, 14, 1, -18 },
/* 0xF1 */ { 5931, 10, 18, 13, 1, -18 },
/* 0xF2 */ { 5954, 10, 18, 13, 1, -18 },
/* 0xF3 */ { 5977, 11, 18, 13, 1, -18 },
/* 0xF4 */ { 6002, 11, 18, 13, 1, -18 },
/* 0xF5 */ { 6027, 11, 18, 13, 1, -18 },
/* 0xF6 */ { 6052, 11, 17, 13, 1, -17 },
/* 0xF7 */ { 6076, 12, 11, 14, 1, -11 },
/* 0xF8 */ { 6093, 6, 18, 8, 1, -18 },
/* 0xF9 */ { 6107, 10, 19, 13, 1, -19 },
/* 0xFA */ { 6131, 10, 18, 13, 1, -18 },
/* 0xFB */ { 6154, 10, 18, 13, 1, -18 },
/* 0xFC */ { 6177, 10, 17, 13, 1, -17 },
/* 0xFD */ { 6199, 11, 23, 11, 0, -18 },
/* 0xFE */ { 6231, 6, 21, 7, 1, -16 },
/* 0xFF */ { 6247, 2, 2, 8, 3, -17 },
};
const GFXfont FreeSans12pt_Win1250 PROGMEM = {
(uint8_t*)FreeSans12pt_Win1250Bitmaps,
(GFXglyph*)FreeSans12pt_Win1250Glyphs,
0x01, 0xFF, 19
};
@@ -0,0 +1,527 @@
// trunk-ignore-all(clang-format)
#pragma once
/* PROPERTIES
FONT_NAME FreeSans12pt_Win1251
*/
const uint8_t FreeSans12pt_Win1251Bitmaps[] PROGMEM = {
/* 0x01 */ 0x00, 0x30, 0x00, 0x09, 0x00, 0x01, 0x20, 0x00, 0x24, 0x00, 0x04, 0x80, 0x01, 0x90, 0x00, 0x62, 0x00, 0x30, 0xFE, 0x04, 0x10, 0x5F, 0x02, 0x0B, 0x00, 0x7F, 0xE0, 0x0C, 0x1C, 0x02, 0x83, 0x81, 0x9F, 0xF0, 0x02, 0x1E, 0x00, 0x41, 0xC0, 0x0E, 0x7F, 0x81, 0x78, 0x18, 0x62, 0x00, 0xFF, 0xC0,
/* 0x02 */ 0x00, 0xFF, 0x80, 0x61, 0x13, 0xF0, 0x62, 0x60, 0x07, 0xFC, 0x00, 0x83, 0x80, 0x10, 0xF0, 0x33, 0xF6, 0x01, 0x41, 0xC0, 0x18, 0x38, 0x03, 0xFF, 0xE0, 0x47, 0x02, 0x08, 0x20, 0x61, 0xC4, 0x06, 0x17, 0x00, 0x22, 0x00, 0x02, 0x40, 0x00, 0x48, 0x00, 0x09, 0x00, 0x01, 0x20, 0x00, 0x3C, 0x00,
/* 0x03 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x04, 0x08, 0x48, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x08, 0x10, 0x70, 0x00, 0x03, 0x80, 0x00, 0x14, 0x00, 0x00, 0xA1, 0x81, 0x8D, 0x87, 0xF0, 0x44, 0x00, 0x06, 0x30, 0x00, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x04 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x10, 0x02, 0x48, 0xE0, 0x61, 0xC1, 0xCC, 0x0E, 0x78, 0x1C, 0x70, 0x00, 0x03, 0x80, 0x00, 0x14, 0xFF, 0xFC, 0xA6, 0x00, 0xCD, 0x9F, 0xFE, 0x44, 0x71, 0xE6, 0x30, 0xFC, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x05 */ 0x00, 0x18, 0x00, 0x00, 0x40, 0x01, 0x90, 0x01, 0xF4, 0x08, 0x12, 0x23, 0xC1, 0x91, 0x2C, 0x1C, 0x8A, 0xC3, 0x64, 0x64, 0x13, 0x22, 0x41, 0x98, 0x26, 0x2C, 0xC4, 0x22, 0x60, 0x42, 0x13, 0x04, 0x30, 0x80, 0x61, 0xA4, 0x02, 0x18, 0x20, 0x03, 0x41, 0x00, 0x20, 0x08, 0x02, 0x00, 0x60, 0x40, 0x03, 0xF8,
/* 0x06 */ 0x00, 0x10, 0x00, 0x03, 0x00, 0x1C, 0x48, 0x00, 0xB4, 0x80, 0x09, 0xF9, 0xC0, 0xE0, 0xE4, 0x0C, 0x02, 0x8F, 0x80, 0x38, 0x88, 0x01, 0x0D, 0x00, 0x18, 0x30, 0x01, 0x60, 0x80, 0x13, 0x18, 0x03, 0xF2, 0xC0, 0x20, 0x26, 0x06, 0x07, 0xFF, 0xA0, 0x02, 0x39, 0x00, 0x14, 0x70, 0x01, 0xC3, 0x00, 0x18, 0x00,
/* 0x07 */
/* 0x08 */ 0x00, 0x1F, 0x80, 0x00, 0x60, 0x80, 0x01, 0x00, 0x80, 0x06, 0x00, 0x80, 0x3C, 0x01, 0x01, 0x8C, 0x02, 0x02, 0x08, 0x04, 0x04, 0x08, 0x0C, 0x38, 0x00, 0x04, 0x80, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x2E, 0xC0, 0x01, 0x83, 0x7E, 0x0C, 0x10, 0x37, 0xE2, 0x61, 0x00, 0x0C, 0xC6, 0x10, 0x98, 0x0C, 0x63, 0x00, 0x00, 0xC6, 0x00,
/* 0x09 */ 0x00, 0x1F, 0x80, 0x00, 0x60, 0x80, 0x01, 0x00, 0x80, 0x06, 0x00, 0x80, 0x3C, 0x01, 0x01, 0x8C, 0x02, 0x02, 0x08, 0x04, 0x04, 0x08, 0x0C, 0x38, 0x00, 0x04, 0x80, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x2E, 0xC0, 0x01, 0x83, 0x7E, 0x0C, 0x00, 0x37, 0xE0,
/* 0x0A */
/* 0x0B */ 0x1F, 0x07, 0xC1, 0x86, 0x41, 0x10, 0x0C, 0x04, 0x80, 0x40, 0x18, 0x00, 0x00, 0xC0, 0x00, 0x06, 0x00, 0x00, 0x30, 0x00, 0x01, 0x40, 0x00, 0x0A, 0x00, 0x00, 0x88, 0x00, 0x04, 0x40, 0x00, 0x41, 0x00, 0x02, 0x04, 0x00, 0x20, 0x20, 0x02, 0x00, 0x80, 0x20, 0x02, 0x02, 0x00, 0x08, 0x20, 0x00, 0x22, 0x00, 0x00, 0xE0, 0x00,
/* 0x0C */ 0x01, 0x00, 0x00, 0x38, 0x00, 0x04, 0xC0, 0x01, 0x08, 0x00, 0x18, 0x80, 0x1C, 0x10, 0x02, 0x07, 0x80, 0x81, 0x10, 0x1F, 0xC2, 0x02, 0x00, 0x60, 0x80, 0x1A, 0x20, 0x1C, 0x42, 0x1C, 0x08, 0xFE, 0x03, 0xA0, 0x01, 0x8C, 0x01, 0xC1, 0x43, 0xD0, 0x27, 0x81, 0xF8,
/* 0x0D */
/* 0x0E */ 0x00, 0xE0, 0x00, 0x11, 0x00, 0x01, 0x10, 0x00, 0x0B, 0x00, 0x03, 0xF8, 0x00, 0x60, 0x60, 0x09, 0x02, 0x00, 0xA0, 0x10, 0x16, 0x01, 0x01, 0x40, 0x10, 0x10, 0x01, 0x01, 0x00, 0x08, 0x10, 0x00, 0x82, 0x1F, 0x08, 0x3F, 0x90, 0x44, 0x00, 0x06, 0xBF, 0xFF, 0xAF, 0xF0, 0xFF, 0xFF, 0x0F, 0xE3, 0xFB, 0xFC,
/* 0x0F */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x40, 0x12, 0x34, 0x00, 0x69, 0x40, 0x01, 0x49, 0xE0, 0xF1, 0xCD, 0x06, 0x8E, 0x28, 0x14, 0x71, 0x40, 0xA3, 0x8B, 0xFD, 0x14, 0x50, 0x68, 0xA2, 0x81, 0x4D, 0x97, 0xFA, 0x44, 0xBF, 0xD6, 0x31, 0x02, 0xE0, 0xC8, 0x16, 0x08, 0x61, 0x08, 0x21, 0xF0, 0x80, 0xF8, 0x78, 0x00,
/* 0x10 */ 0x00, 0xF0, 0x00, 0x3A, 0x00, 0x07, 0xC0, 0x00, 0xA8, 0x00, 0x1F, 0x00, 0x02, 0xB0, 0x00, 0x52, 0x00, 0x0A, 0x40, 0x02, 0x48, 0x00, 0x49, 0x00, 0x09, 0x30, 0x01, 0x22, 0x01, 0xC4, 0x70, 0xF0, 0x85, 0xE1, 0x10, 0x88, 0x37, 0x20, 0x03, 0x9C, 0x00, 0x37, 0x00, 0x06, 0x40, 0x01, 0x86, 0x00,
/* 0x11 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x60, 0x02, 0x36, 0x00, 0x09, 0x04, 0x0C, 0x48, 0x60, 0xC1, 0xC3, 0x0F, 0x0E, 0x00, 0x08, 0x70, 0x00, 0x23, 0x80, 0x63, 0x84, 0x01, 0x9F, 0x20, 0x0C, 0xFD, 0x80, 0x27, 0xE4, 0x03, 0x3F, 0x30, 0x33, 0xE0, 0xC0, 0x00, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x12 */ 0x00, 0xC2, 0x00, 0x1C, 0x24, 0x02, 0x18, 0x60, 0x64, 0x02, 0x02, 0x40, 0x20, 0x00, 0xF2, 0x03, 0x89, 0xE0, 0x7C, 0x80, 0x0E, 0x25, 0x80, 0xE1, 0x00, 0x1A, 0x08, 0x71, 0xB0, 0xC4, 0x39, 0x84, 0xC2, 0xCC, 0x40, 0x76, 0x7C, 0x05, 0xBB, 0x80, 0x4C, 0xE0, 0x0A, 0x78, 0x00, 0x9C, 0x00, 0x0F, 0x00, 0x00,
/* 0x13 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x00, 0x00, 0x48, 0x60, 0xC1, 0xC6, 0xC9, 0x0E, 0x00, 0x00, 0x70, 0x00, 0x03, 0x80, 0x00, 0x14, 0xFF, 0xF8, 0xA6, 0x00, 0xCD, 0x9F, 0xFE, 0x44, 0x71, 0xE6, 0x30, 0xFC, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x14 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x20, 0x22, 0x33, 0x01, 0x89, 0x20, 0x02, 0x48, 0x60, 0xE1, 0xC8, 0x80, 0x8E, 0x46, 0x46, 0x72, 0x32, 0x33, 0x9F, 0x9F, 0x94, 0x78, 0x78, 0xA0, 0x00, 0x0D, 0x80, 0x00, 0x44, 0x0E, 0x06, 0x30, 0x00, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x15 */ 0x03, 0xFC, 0x20, 0x38, 0x1C, 0x81, 0x80, 0x1D, 0x08, 0x00, 0x32, 0x60, 0x00, 0x89, 0x00, 0x02, 0x18, 0x00, 0x08, 0x61, 0xC3, 0x22, 0x8D, 0x93, 0x72, 0x00, 0x00, 0x48, 0x00, 0x01, 0x20, 0x00, 0x04, 0x9F, 0xFF, 0x92, 0x60, 0x0E, 0x44, 0xFF, 0xF2, 0x11, 0xC3, 0x88, 0x21, 0xF8, 0x40, 0x40, 0x02, 0x00, 0xC0, 0x30, 0x00, 0xFF, 0x00,
/* 0x16 */ 0x03, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x01, 0xE0, 0x03, 0xF0, 0x03, 0xF0, 0x27, 0xF0, 0x6F, 0x70, 0x6E, 0x60, 0xFC, 0x60, 0xFC, 0x7E, 0xFC, 0x7E, 0xFC, 0x3F, 0xF4, 0x1F, 0xF4, 0x1F, 0xF0, 0x0E, 0x70, 0x0E, 0x30, 0x1C, 0x38, 0x38, 0x0F, 0xF0,
/* 0x17 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x00, 0x00, 0x48, 0x00, 0x21, 0xC0, 0x02, 0x8E, 0x20, 0xF4, 0x70, 0x84, 0x11, 0x82, 0x40, 0x84, 0x01, 0x03, 0x20, 0x0F, 0x85, 0x80, 0x03, 0x04, 0x00, 0x04, 0x30, 0x78, 0x10, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x18 */ 0x00, 0xFC, 0x00, 0x02, 0x06, 0x00, 0x08, 0x24, 0x00, 0x21, 0xA4, 0x00, 0x4C, 0x48, 0x00, 0xA0, 0x50, 0x01, 0x92, 0x60, 0x03, 0x24, 0xC0, 0x06, 0x01, 0x81, 0x28, 0x03, 0x49, 0x6C, 0xC4, 0xAD, 0xD8, 0x16, 0xA4, 0xCC, 0xC4, 0x44, 0x86, 0x13, 0x05, 0x00, 0x28, 0x0A, 0x00, 0x50, 0x14, 0x00, 0x90, 0x48, 0x01, 0x20, 0x90, 0x02, 0x41, 0x20, 0x00, 0x00,
/* 0x19 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x00, 0x00, 0x49, 0xC3, 0x81, 0xC0, 0x00, 0x0E, 0x78, 0xF0, 0x77, 0xEF, 0xC3, 0xA7, 0x4E, 0x15, 0x0A, 0x10, 0xA7, 0x8F, 0x0D, 0x80, 0x00, 0x44, 0x00, 0x06, 0x33, 0xF0, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x1A */ 0xFF, 0xFF, 0x00, 0x06, 0x00, 0x0C, 0x3E, 0x18, 0x82, 0x32, 0x02, 0x64, 0x04, 0xC8, 0x09, 0x80, 0x23, 0x00, 0x86, 0x02, 0x0C, 0x08, 0x18, 0x10, 0x30, 0x00, 0x60, 0x00, 0xC0, 0x81, 0x80, 0x03, 0x00, 0x07, 0xFF, 0xF8,
/* 0x1B */ 0x00, 0xFE, 0x00, 0x03, 0x81, 0x80, 0x04, 0x00, 0x60, 0x08, 0x00, 0x30, 0x10, 0x00, 0x10, 0x30, 0x07, 0x88, 0x23, 0xC8, 0x08, 0x22, 0x00, 0x04, 0x60, 0x00, 0x44, 0x60, 0x00, 0x84, 0x63, 0x03, 0x04, 0x61, 0xFC, 0x04, 0x6B, 0x00, 0x9E, 0xA5, 0x01, 0x6A, 0xD5, 0x01, 0x43, 0xA8, 0x81, 0x05, 0xD0, 0x82, 0x0A, 0xA0, 0x82, 0x05, 0xC0, 0x82, 0x02, 0x61, 0xFF, 0x0C, 0x1E, 0x00, 0xF0,
/* 0x1C */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x30, 0x02, 0x32, 0x00, 0x09, 0x00, 0x00, 0x48, 0x20, 0x61, 0xC3, 0x84, 0x0E, 0x1C, 0x78, 0x70, 0x40, 0x03, 0x80, 0x00, 0x14, 0x00, 0x00, 0xA0, 0x03, 0x0D, 0x83, 0xF0, 0x44, 0x00, 0x06, 0x30, 0x00, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x1D */ 0x01, 0xFE, 0x00, 0x3A, 0x1C, 0x03, 0x00, 0x30, 0x23, 0x1E, 0xC3, 0x38, 0x03, 0x10, 0xC3, 0x09, 0x00, 0x18, 0x68, 0x00, 0xC1, 0x40, 0x00, 0x0A, 0x07, 0x80, 0x50, 0x46, 0x02, 0x80, 0x00, 0x1A, 0x1E, 0x00, 0xCB, 0x10, 0x0D, 0x03, 0x00, 0x48, 0x60, 0x06, 0x40, 0x00, 0x22, 0x0C, 0x02, 0x10, 0x60, 0x60, 0x43, 0xFC, 0x01, 0xE0, 0x00, 0x00,
/* 0x1E */ 0x01, 0xF0, 0x00, 0xEA, 0xC0, 0x31, 0x5F, 0x04, 0x5F, 0x88, 0x80, 0xA0, 0x48, 0x0E, 0x02, 0x8F, 0x40, 0x3C, 0x10, 0x21, 0x66, 0x87, 0x15, 0x98, 0x71, 0x41, 0x02, 0x14, 0x00, 0x01, 0x40, 0x00, 0x14, 0x00, 0x01, 0x21, 0xFE, 0x12, 0x00, 0x02, 0x10, 0x00, 0x60, 0x80, 0x0C, 0x06, 0x01, 0x80, 0x3F, 0xE0,
/* 0x1F */ 0x0E, 0x00, 0x13, 0x00, 0x23, 0x00, 0xF3, 0x01, 0x31, 0x01, 0x11, 0x03, 0xD3, 0x06, 0xF2, 0x30, 0x34, 0xC7, 0x25, 0x33, 0x2B, 0xC2, 0x57, 0x04, 0x3A, 0x08, 0x72, 0x30, 0xA3, 0xC3, 0x40, 0x04, 0x40, 0x18, 0x40, 0x60, 0x7F, 0x80,
/* ' ' 0x20 */
/* '!' 0x21 */ 0xFF, 0xFF, 0xFF, 0xF0, 0xF0,
/* '"' 0x22 */ 0xCF, 0x3C, 0xF3, 0x8A, 0x20,
/* '#' 0x23 */ 0x06, 0x30, 0x31, 0x03, 0x18, 0x18, 0xC7, 0xFF, 0xBF, 0xFC, 0x31, 0x01, 0x18, 0x18, 0xC7, 0xFF, 0xBF, 0xFC, 0x31, 0x01, 0x18, 0x18, 0xC0, 0xC6, 0x06, 0x30,
/* '$' 0x24 */ 0x04, 0x03, 0xE1, 0xFF, 0x72, 0x7C, 0x47, 0x88, 0xF1, 0x07, 0xA0, 0x7E, 0x03, 0xF0, 0x17, 0x02, 0x7C, 0x47, 0x88, 0xF1, 0x1B, 0x26, 0x7F, 0xC3, 0xE0, 0x10, 0x02, 0x00,
/* '%' 0x25 */ 0x00, 0x06, 0x03, 0xC0, 0x40, 0x7E, 0x0C, 0x0E, 0x70, 0x80, 0xC3, 0x18, 0x0C, 0x31, 0x00, 0xE7, 0x30, 0x07, 0xE6, 0x00, 0x3C, 0x40, 0x00, 0x0C, 0x7C, 0x00, 0x8F, 0xE0, 0x19, 0xC7, 0x01, 0x18, 0x30, 0x31, 0x83, 0x02, 0x1C, 0x70, 0x40, 0xFE, 0x04, 0x07, 0xC0,
/* '&' 0x26 */ 0x0F, 0x00, 0x7E, 0x03, 0x9C, 0x0C, 0x30, 0x30, 0xC0, 0xE7, 0x01, 0xF8, 0x03, 0x80, 0x3E, 0x01, 0xCC, 0x6E, 0x39, 0xB0, 0x7C, 0xC0, 0xF3, 0x03, 0xCE, 0x1F, 0x9F, 0xE6, 0x3E, 0x1C,
/* ''' 0x27 */ 0xFF, 0xA0,
/* '(' 0x28 */ 0x08, 0x8C, 0x46, 0x31, 0x98, 0xC6, 0x31, 0x8C, 0x63, 0x08, 0x63, 0x08, 0x61, 0x0C, 0x20,
/* ')' 0x29 */ 0x82, 0x18, 0xC3, 0x18, 0xC3, 0x18, 0xC6, 0x31, 0x8C, 0x62, 0x31, 0x88, 0xC4, 0x62, 0x00,
/* '*' 0x2A */ 0x10, 0x23, 0x5B, 0xE3, 0x8D, 0x91, 0x00,
/* '+' 0x2B */ 0x0C, 0x03, 0x00, 0xC0, 0x30, 0xFF, 0xFF, 0xF0, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0,
/* ',' 0x2C */ 0xF5, 0x60,
/* '-' 0x2D */ 0xFF, 0xF0,
/* '.' 0x2E */ 0xF0,
/* '/' 0x2F */ 0x02, 0x0C, 0x10, 0x20, 0xC1, 0x02, 0x0C, 0x10, 0x20, 0xC1, 0x02, 0x0C, 0x10, 0x20, 0xC1, 0x00,
/* '0' 0x30 */ 0x1F, 0x07, 0xF1, 0xC7, 0x30, 0x6C, 0x0F, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3E, 0x0E, 0xC1, 0x9C, 0x71, 0xFC, 0x1F, 0x00,
/* '1' 0x31 */ 0x08, 0xCF, 0xFF, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18,
/* '2' 0x32 */ 0x1F, 0x0F, 0xF9, 0x87, 0x60, 0x7C, 0x06, 0x00, 0xC0, 0x18, 0x07, 0x01, 0xC0, 0xF0, 0x78, 0x1C, 0x06, 0x00, 0xC0, 0x30, 0x07, 0xFF, 0xFF, 0xE0,
/* '3' 0x33 */ 0x3F, 0x0F, 0xF3, 0x87, 0x60, 0x6C, 0x0C, 0x01, 0x80, 0x60, 0x78, 0x0F, 0x80, 0x18, 0x01, 0x80, 0x3C, 0x07, 0x80, 0xD8, 0x73, 0xFC, 0x3F, 0x00,
/* '4' 0x34 */ 0x01, 0x80, 0x70, 0x0E, 0x03, 0xC0, 0xD8, 0x1B, 0x06, 0x61, 0x8C, 0x21, 0x8C, 0x33, 0x06, 0x7F, 0xFF, 0xFE, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80,
/* '5' 0x35 */ 0x3F, 0xCF, 0xF9, 0x80, 0x30, 0x06, 0x00, 0xDE, 0x1F, 0xE7, 0x0E, 0x00, 0xE0, 0x0C, 0x01, 0x80, 0x30, 0x07, 0x81, 0xB8, 0x73, 0xFC, 0x1F, 0x00,
/* '6' 0x36 */ 0x0F, 0x07, 0xF9, 0xC3, 0x30, 0x74, 0x01, 0x80, 0x33, 0xC7, 0xFE, 0xF1, 0xDC, 0x1F, 0x01, 0xE0, 0x3C, 0x06, 0xC1, 0xDC, 0x71, 0xFC, 0x1F, 0x00,
/* '7' 0x37 */ 0xFF, 0xFF, 0xFC, 0x01, 0x00, 0x60, 0x18, 0x02, 0x00, 0xC0, 0x30, 0x06, 0x01, 0x80, 0x30, 0x04, 0x01, 0x80, 0x30, 0x06, 0x01, 0x80, 0x30, 0x00,
/* '8' 0x38 */ 0x1F, 0x07, 0xF1, 0xC7, 0x30, 0x66, 0x0C, 0xC1, 0x8C, 0x61, 0xF8, 0x3F, 0x8E, 0x3B, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xD8, 0x31, 0xFC, 0x1F, 0x00,
/* '9' 0x39 */ 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x6C, 0x07, 0x80, 0xF0, 0x1E, 0x07, 0x61, 0xEF, 0xFC, 0x79, 0x80, 0x30, 0x05, 0xC1, 0x98, 0x73, 0xFC, 0x1E, 0x00,
/* ':' 0x3A */ 0xF0, 0x00, 0x03, 0xC0,
/* ';' 0x3B */ 0xF0, 0x00, 0x0F, 0x56,
/* '<' 0x3C */ 0x00, 0x70, 0x1E, 0x0F, 0x83, 0xC0, 0xF0, 0x0E, 0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x10,
/* '=' 0x3D */ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
/* '>' 0x3E */ 0xE0, 0x07, 0x80, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x07, 0x01, 0xE0, 0xF0, 0x3C, 0x0F, 0x00, 0x80, 0x00,
/* '?' 0x3F */ 0x3F, 0x1F, 0xEE, 0x1F, 0x03, 0xC0, 0xC0, 0x30, 0x0C, 0x06, 0x03, 0x81, 0xC0, 0xE0, 0x30, 0x0C, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x03, 0x00,
/* '@' 0x40 */ 0x00, 0xFE, 0x00, 0x0F, 0xFE, 0x00, 0xF0, 0x3E, 0x07, 0x00, 0x3C, 0x38, 0x00, 0x38, 0xC1, 0xE0, 0x66, 0x0F, 0xD9, 0xD8, 0x61, 0xC3, 0xC3, 0x07, 0x0F, 0x1C, 0x1C, 0x3C, 0x60, 0x60, 0xF1, 0x81, 0x83, 0xC6, 0x06, 0x1B, 0x18, 0x38, 0xEE, 0x71, 0xE7, 0x18, 0xFD, 0xF8, 0x71, 0xE7, 0xC0, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x01, 0xFF, 0xC0, 0x01, 0xFC, 0x00,
/* 'A' 0x41 */ 0x07, 0x80, 0x1E, 0x00, 0x78, 0x03, 0xF0, 0x0C, 0xC0, 0x33, 0x01, 0xCE, 0x06, 0x18, 0x18, 0x60, 0xE1, 0xC3, 0x03, 0x0F, 0xFC, 0x7F, 0xF9, 0x80, 0x66, 0x01, 0xB8, 0x07, 0xC0, 0x0F, 0x00, 0x30,
/* 'B' 0x42 */ 0xFF, 0xC7, 0xFF, 0x30, 0x1D, 0x80, 0x6C, 0x03, 0x60, 0x1B, 0x00, 0xD8, 0x0C, 0xFF, 0xC7, 0xFF, 0x30, 0x0D, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x06, 0xFF, 0xF7, 0xFE, 0x00,
/* 'C' 0x43 */ 0x07, 0xE0, 0x3F, 0xF0, 0xE0, 0x73, 0x80, 0x76, 0x00, 0x6C, 0x00, 0x30, 0x00, 0x60, 0x00, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x00, 0x0E, 0x00, 0x6C, 0x00, 0xDC, 0x03, 0x1E, 0x0E, 0x1F, 0xF8, 0x0F, 0xC0,
/* 'D' 0x44 */ 0xFF, 0xC3, 0xFF, 0x8C, 0x07, 0x30, 0x0E, 0xC0, 0x1B, 0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x1F, 0x00, 0x6C, 0x03, 0xB0, 0x1C, 0xFF, 0xE3, 0xFE, 0x00,
/* 'E' 0x45 */ 0xFF, 0xFF, 0xFF, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xEF, 0xFE, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xFF, 0xFF,
/* 'F' 0x46 */ 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xFF, 0xDF, 0xFB, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x00,
/* 'G' 0x47 */ 0x07, 0xF0, 0x1F, 0xFC, 0x3C, 0x1E, 0x70, 0x07, 0x60, 0x03, 0xE0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x7F, 0xC0, 0x7F, 0xC0, 0x03, 0xC0, 0x03, 0x60, 0x03, 0x60, 0x07, 0x30, 0x0F, 0x3C, 0x1F, 0x1F, 0xFB, 0x07, 0xE1,
/* 'H' 0x48 */ 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xC0,
/* 'I' 0x49 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
/* 'J' 0x4A */ 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x3C, 0x1E, 0x0F, 0x07, 0xC7, 0x7F, 0x1F, 0x00,
/* 'K' 0x4B */ 0xC0, 0x3E, 0x03, 0xB0, 0x39, 0x83, 0x8C, 0x38, 0x63, 0x83, 0x38, 0x19, 0xC0, 0xDE, 0x07, 0xB8, 0x38, 0xE1, 0x83, 0x0C, 0x1C, 0x60, 0x73, 0x01, 0x98, 0x0E, 0xC0, 0x3E, 0x00, 0xC0,
/* 'L' 0x4C */ 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xFF, 0xFF, 0xF0,
/* 'M' 0x4D */ 0xE0, 0x07, 0xE0, 0x07, 0xF0, 0x0F, 0xF0, 0x0F, 0xD0, 0x0F, 0xD8, 0x1B, 0xD8, 0x1B, 0xD8, 0x1B, 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33, 0xC6, 0x63, 0xC6, 0x63, 0xC6, 0x63, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC1, 0x83,
/* 'N' 0x4E */ 0xE0, 0x1F, 0x00, 0xFC, 0x07, 0xE0, 0x3D, 0x81, 0xEE, 0x0F, 0x30, 0x79, 0xC3, 0xC6, 0x1E, 0x18, 0xF0, 0xE7, 0x83, 0x3C, 0x1D, 0xE0, 0x6F, 0x01, 0xF8, 0x0F, 0xC0, 0x3E, 0x01, 0xC0,
/* 'O' 0x4F */ 0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0x07, 0x86, 0x00, 0xC6, 0x00, 0x33, 0x00, 0x1B, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x36, 0x00, 0x33, 0x00, 0x18, 0xC0, 0x18, 0x78, 0x3C, 0x1F, 0xFC, 0x03, 0xF8, 0x00,
/* 'P' 0x50 */ 0xFF, 0x8F, 0xFE, 0xC0, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x06, 0xFF, 0xEF, 0xFC, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00,
/* 'Q' 0x51 */ 0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0x07, 0x86, 0x00, 0xC6, 0x00, 0x33, 0x00, 0x1B, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x36, 0x00, 0x33, 0x01, 0x98, 0xC0, 0xFC, 0x78, 0x3C, 0x1F, 0xFF, 0x03, 0xF9, 0x80, 0x00, 0x40,
/* 'R' 0x52 */ 0xFF, 0xE3, 0xFF, 0xCC, 0x03, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x6C, 0x01, 0xB0, 0x0C, 0xFF, 0xE3, 0xFF, 0xCC, 0x03, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x6C, 0x01, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x70,
/* 'S' 0x53 */ 0x0F, 0xE0, 0x7F, 0xC3, 0x83, 0x98, 0x07, 0x60, 0x0D, 0x80, 0x07, 0x00, 0x1E, 0x00, 0x3F, 0x80, 0x3F, 0xC0, 0x0F, 0x80, 0x07, 0xC0, 0x0F, 0x00, 0x3E, 0x00, 0xDE, 0x0E, 0x3F, 0xF0, 0x3F, 0x80,
/* 'T' 0x54 */ 0xFF, 0xFF, 0xFF, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60,
/* 'U' 0x55 */ 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x80, 0xEE, 0x0E, 0x3F, 0xE0, 0xFC, 0x00,
/* 'V' 0x56 */ 0xC0, 0x0F, 0x00, 0x7E, 0x01, 0x98, 0x06, 0x60, 0x39, 0xC0, 0xC3, 0x03, 0x0C, 0x1C, 0x38, 0x60, 0x61, 0x81, 0x8E, 0x07, 0x30, 0x0C, 0xC0, 0x37, 0x00, 0xF8, 0x01, 0xE0, 0x07, 0x80, 0x1C, 0x00,
/* 'W' 0x57 */ 0xE0, 0x30, 0x1D, 0x80, 0xE0, 0x76, 0x07, 0x81, 0xDC, 0x1E, 0x06, 0x70, 0x7C, 0x18, 0xC1, 0xB0, 0xE3, 0x0C, 0xC3, 0x8C, 0x33, 0x0C, 0x38, 0xC6, 0x30, 0x67, 0x18, 0xC1, 0x98, 0x67, 0x06, 0x61, 0xD8, 0x1D, 0x83, 0x60, 0x3C, 0x0D, 0x80, 0xF0, 0x3E, 0x03, 0xC0, 0x70, 0x0F, 0x01, 0xC0, 0x18, 0x07, 0x00,
/* 'X' 0x58 */ 0xE0, 0x1D, 0x80, 0xE7, 0x03, 0x0E, 0x1C, 0x18, 0x60, 0x73, 0x00, 0xFC, 0x01, 0xE0, 0x07, 0x00, 0x1E, 0x00, 0xF8, 0x03, 0x30, 0x1C, 0xE0, 0xE1, 0x83, 0x07, 0x1C, 0x0E, 0xE0, 0x1B, 0x00, 0x70,
/* 'Y' 0x59 */ 0xC0, 0x0F, 0x80, 0x76, 0x01, 0x9C, 0x0C, 0x38, 0x70, 0x61, 0x81, 0xCE, 0x03, 0x30, 0x0F, 0x80, 0x1E, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00,
/* 'Z' 0x5A */ 0xFF, 0xFF, 0xFF, 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0x60, 0x07, 0x00, 0x70, 0x07, 0x00, 0x30, 0x03, 0x80, 0x38, 0x03, 0x80, 0x18, 0x01, 0xC0, 0x1C, 0x00, 0xFF, 0xFF, 0xFF, 0xC0,
/* '[' 0x5B */ 0xFF, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCF, 0xF0,
/* '\' 0x5C */ 0x81, 0x81, 0x02, 0x06, 0x04, 0x08, 0x18, 0x10, 0x20, 0x60, 0x40, 0x81, 0x81, 0x02, 0x06, 0x04,
/* ']' 0x5D */ 0xFF, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0xF0,
/* '^' 0x5E */ 0x0C, 0x0E, 0x05, 0x86, 0xC3, 0x21, 0x19, 0x8C, 0x83, 0xC1, 0x80,
/* '_' 0x5F */ 0xFF, 0xFE,
/* '`' 0x60 */ 0xE3, 0x8C, 0x30,
/* 'a' 0x61 */ 0x3F, 0x07, 0xF8, 0xE1, 0xCC, 0x0C, 0x00, 0xC0, 0x1C, 0x3F, 0xCF, 0x8C, 0xC0, 0xCC, 0x0C, 0xE3, 0xC7, 0xEF, 0x3C, 0x70,
/* 'b' 0x62 */ 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0xF8, 0xDF, 0xCF, 0x0E, 0xE0, 0x7C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xE0, 0x6F, 0x0E, 0xDF, 0xCC, 0xF8,
/* 'c' 0x63 */ 0x1F, 0x0F, 0xE6, 0x1F, 0x83, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x38, 0x37, 0x1C, 0xFE, 0x1F, 0x00,
/* 'd' 0x64 */ 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x3C, 0xCF, 0xFB, 0x8F, 0xE0, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF8, 0x3B, 0x8F, 0x3F, 0x63, 0xCC,
/* 'e' 0x65 */ 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x3C, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0xC0, 0x1C, 0x0D, 0xC3, 0x1F, 0xC1, 0xF0,
/* 'f' 0x66 */ 0x3B, 0xD8, 0xC6, 0x7F, 0xEC, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x00,
/* 'g' 0x67 */ 0x1E, 0x67, 0xFD, 0xC7, 0xF0, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x7C, 0x1D, 0xC7, 0x9F, 0xB1, 0xE6, 0x00, 0xC0, 0x3E, 0x0E, 0x7F, 0xC7, 0xE0,
/* 'h' 0x68 */ 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x33, 0xCD, 0xFB, 0xC7, 0xE0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x30,
/* 'i' 0x69 */ 0xF0, 0x3F, 0xFF, 0xFF, 0xF0,
/* 'j' 0x6A */ 0x33, 0x00, 0x03, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0xE0,
/* 'k' 0x6B */ 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x6C, 0x33, 0x18, 0xCC, 0x37, 0x0F, 0xC3, 0xB8, 0xC6, 0x31, 0xCC, 0x3B, 0x06, 0xC1, 0xF0, 0x30,
/* 'l' 0x6C */ 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
/* 'm' 0x6D */ 0xCF, 0x1F, 0x6F, 0xDF, 0xFC, 0x78, 0xFC, 0x18, 0x3C, 0x0C, 0x1E, 0x06, 0x0F, 0x03, 0x07, 0x81, 0x83, 0xC0, 0xC1, 0xE0, 0x60, 0xF0, 0x30, 0x78, 0x18, 0x3C, 0x0C, 0x18,
/* 'n' 0x6E */ 0xCF, 0x37, 0xEF, 0x1F, 0x83, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xC0,
/* 'o' 0x6F */ 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x7C, 0x1D, 0xC7, 0x1F, 0xC1, 0xF0,
/* 'p' 0x70 */ 0xCF, 0x8D, 0xFC, 0xF0, 0xEE, 0x06, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3E, 0x06, 0xF0, 0xEF, 0xFC, 0xCF, 0x8C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x00,
/* 'q' 0x71 */ 0x1E, 0x67, 0xFD, 0xC7, 0xF0, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x7C, 0x1D, 0xC7, 0x9F, 0xF1, 0xE6, 0x00, 0xC0, 0x18, 0x03, 0x00, 0x60,
/* 'r' 0x72 */ 0xCF, 0x7F, 0x38, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC0,
/* 's' 0x73 */ 0x3E, 0x1F, 0xEE, 0x1B, 0x00, 0xC0, 0x3C, 0x07, 0xF0, 0x3F, 0x01, 0xF0, 0x3E, 0x1D, 0xFE, 0x3F, 0x00,
/* 't' 0x74 */ 0x63, 0x19, 0xFF, 0xB1, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0xE7,
/* 'u' 0x75 */ 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x7E, 0x3D, 0xFB, 0x3C, 0xC0,
/* 'v' 0x76 */ 0xE0, 0x6C, 0x0D, 0x81, 0xB8, 0x63, 0x0C, 0x61, 0x8E, 0x60, 0xCC, 0x19, 0x83, 0xE0, 0x3C, 0x07, 0x00, 0xE0,
/* 'w' 0x77 */ 0xC1, 0xC1, 0xB0, 0xE1, 0xD8, 0x70, 0xCC, 0x2C, 0x66, 0x36, 0x31, 0x9B, 0x18, 0xCD, 0x98, 0x64, 0x6C, 0x16, 0x36, 0x0F, 0x1A, 0x07, 0x8F, 0x03, 0x83, 0x80, 0xC1, 0xC0,
/* 'x' 0x78 */ 0xC1, 0xF8, 0x66, 0x30, 0xCC, 0x3E, 0x07, 0x00, 0xC0, 0x78, 0x36, 0x0C, 0xC6, 0x3B, 0x06, 0xC0, 0xC0,
/* 'y' 0x79 */ 0xE0, 0x6C, 0x0D, 0x83, 0x38, 0x63, 0x0C, 0x63, 0x0C, 0x60, 0xCC, 0x1B, 0x03, 0x60, 0x3C, 0x07, 0x00, 0xE0, 0x18, 0x03, 0x00, 0xE0, 0x78, 0x0E, 0x00,
/* 'z' 0x7A */ 0xFF, 0xFF, 0xF0, 0x18, 0x0C, 0x07, 0x03, 0x81, 0xC0, 0x60, 0x30, 0x18, 0x0E, 0x03, 0xFF, 0xFF, 0xC0,
/* '{' 0x7B */ 0x19, 0xCC, 0x63, 0x18, 0xC6, 0x31, 0x99, 0x86, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x1C, 0x60,
/* '|' 0x7C */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
/* '}' 0x7D */ 0xC7, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x0C, 0x33, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x73, 0x00,
/* '~' 0x7E */ 0x70, 0x3E, 0x09, 0xE4, 0x1F, 0x03, 0x80,
/* 0x7F */
/* 0x80 */ 0xFF, 0xE0, 0xFF, 0xE0, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x07, 0xFC, 0x07, 0xFE, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x1E, 0x00, 0x1C,
/* 0x81 */ 0x07, 0x01, 0xC0, 0x20, 0x00, 0x0F, 0xFF, 0xFF, 0xF0, 0x06, 0x00, 0xC0, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x00,
/* 0x82 */ 0xF5, 0x80,
/* 0x83 */ 0x0C, 0x38, 0x61, 0x80, 0x1F, 0xFF, 0xE0, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x80,
/* 0x84 */ 0xCF, 0x34, 0x51, 0x88,
/* 0x85 */ 0xC6, 0x3C, 0x63,
/* 0x86 */ 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x3F, 0xFF, 0xFC, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x00,
/* 0x87 */ 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x3F, 0xFF, 0xFC, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x0F, 0xFF, 0xFF, 0x0C, 0x03, 0x00, 0xC0, 0x30,
/* 0x88 */ 0x01, 0xF0, 0x1F, 0xF0, 0xE0, 0xC7, 0x00, 0x18, 0x00, 0xC0, 0x07, 0xFF, 0x3F, 0xFC, 0x30, 0x01, 0xFF, 0x8F, 0xFC, 0x0C, 0x00, 0x18, 0x00, 0x70, 0x00, 0xE0, 0x81, 0xFE, 0x03, 0xF0,
/* 0x89 */ 0x38, 0x18, 0x00, 0xF8, 0x30, 0x03, 0x18, 0xC0, 0x04, 0x11, 0x80, 0x0C, 0x66, 0x00, 0x0F, 0x8C, 0x00, 0x0E, 0x30, 0x00, 0x00, 0x40, 0x00, 0x01, 0x80, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x31, 0xC0, 0xE0, 0x67, 0xC3, 0xC1, 0x98, 0xCC, 0xC3, 0x20, 0x90, 0x8C, 0x63, 0x33, 0x10, 0x7C, 0x3C, 0x60, 0x70, 0x38,
/* 0x8A */ 0x1F, 0xF8, 0x00, 0x3F, 0xF0, 0x00, 0x60, 0x60, 0x00, 0xC0, 0xC0, 0x01, 0x81, 0x80, 0x03, 0x03, 0x00, 0x06, 0x06, 0x00, 0x0C, 0x0C, 0x00, 0x18, 0x1F, 0xF0, 0x30, 0x3F, 0xF0, 0x60, 0x60, 0x30, 0xC0, 0xC0, 0x31, 0x81, 0x80, 0x66, 0x03, 0x00, 0xCC, 0x06, 0x01, 0xB8, 0x0C, 0x06, 0xE0, 0x1F, 0xFD, 0x80, 0x3F, 0xE0,
/* 0x8B */ 0x2F, 0x49, 0x99,
/* 0x8C */ 0xC0, 0x60, 0x06, 0x03, 0x00, 0x30, 0x18, 0x01, 0x80, 0xC0, 0x0C, 0x06, 0x00, 0x60, 0x30, 0x03, 0x01, 0x80, 0x18, 0x0C, 0x00, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0x30, 0x18, 0x1D, 0x80, 0xC0, 0x3C, 0x06, 0x01, 0xE0, 0x30, 0x0F, 0x01, 0x80, 0x78, 0x0C, 0x06, 0xC0, 0x7F, 0xF6, 0x03, 0xFE, 0x00,
/* 0x8D */ 0x03, 0x00, 0x60, 0x0C, 0x00, 0x00, 0xC0, 0x7C, 0x0E, 0xC1, 0xCC, 0x38, 0xC7, 0x0C, 0xE0, 0xDC, 0x0F, 0x80, 0xF0, 0x0F, 0x80, 0xDC, 0x0C, 0xE0, 0xC7, 0x0C, 0x30, 0xC3, 0x8C, 0x1C, 0xC0, 0xEC, 0x07,
/* 0x8E */ 0xFF, 0xE0, 0xFF, 0xE0, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x07, 0xFC, 0x07, 0xFE, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03, 0x06, 0x03,
/* 0x8F */ 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xFF, 0xFF, 0xFF, 0xC0, 0xC0, 0x06, 0x00, 0x30, 0x00,
/* 0x90 */ 0x30, 0x0F, 0xF0, 0xFF, 0x03, 0x00, 0x30, 0x03, 0x3C, 0x37, 0xE3, 0xC7, 0x38, 0x33, 0x03, 0x30, 0x33, 0x03, 0x30, 0x33, 0x03, 0x30, 0x33, 0x03, 0x30, 0x33, 0x03, 0x00, 0x60, 0x06, 0x01, 0x80, 0x30,
/* 0x91 */ 0x6A, 0xF0,
/* 0x92 */ 0xF5, 0x60,
/* 0x93 */ 0x4E, 0x28, 0xA2, 0xCF, 0x30,
/* 0x94 */ 0xCF, 0x34, 0x51, 0x4E, 0x20,
/* 0x95 */ 0x7B, 0xFF, 0xFF, 0xFD, 0xE0,
/* 0x96 */ 0xFF, 0xFF, 0xF0,
/* 0x97 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
/* 0x98 */
/* 0x99 */ 0xFF, 0x70, 0x1F, 0xFD, 0xC0, 0x71, 0x87, 0x83, 0xC6, 0x1E, 0x0F, 0x18, 0x68, 0x3C, 0x61, 0xB1, 0xB1, 0x86, 0xC6, 0xC6, 0x19, 0x1B, 0x18, 0x66, 0xCC, 0x61, 0x9B, 0x31, 0x86, 0x3C, 0xC6, 0x18, 0xE3, 0x18, 0x63, 0x8C,
/* 0x9A */ 0x7F, 0x80, 0x3F, 0xC0, 0x18, 0x60, 0x0C, 0x30, 0x06, 0x18, 0x03, 0x0F, 0xF1, 0x87, 0xFC, 0xC3, 0x07, 0x61, 0x81, 0xB0, 0xC0, 0xD0, 0x60, 0xF8, 0x3F, 0xEC, 0x1F, 0xE0,
/* 0x9B */ 0x99, 0x92, 0xF4,
/* 0x9C */ 0xC0, 0xC0, 0x30, 0x30, 0x0C, 0x0C, 0x03, 0x03, 0x00, 0xC0, 0xC0, 0x3F, 0xFF, 0xCF, 0xFF, 0xFB, 0x03, 0x07, 0xC0, 0xC0, 0xF0, 0x30, 0x3C, 0x0C, 0x1F, 0x03, 0xFE, 0xC0, 0xFF, 0x00,
/* 0x9D */ 0x07, 0x07, 0x03, 0x03, 0x00, 0x06, 0x0F, 0x0D, 0x8C, 0xCC, 0x6C, 0x3C, 0x1E, 0x0F, 0x86, 0xE3, 0x39, 0x8E, 0xC3, 0xE0, 0xC0,
/* 0x9E */ 0x30, 0x1F, 0xE3, 0xFC, 0x18, 0x03, 0x00, 0x67, 0x0D, 0xF9, 0xC7, 0x38, 0x66, 0x0C, 0xC1, 0x98, 0x33, 0x06, 0x60, 0xCC, 0x19, 0x83, 0x30, 0x66, 0x0C,
/* 0x9F */ 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0xFF, 0xFF, 0xC1, 0x80, 0x60,
/* 0xA0 */
/* 0xA1 */ 0x10, 0x40, 0xC4, 0x07, 0xE0, 0x1E, 0x0C, 0x01, 0xF0, 0x1D, 0x80, 0xCE, 0x0E, 0x30, 0x61, 0xC7, 0x06, 0x30, 0x3B, 0x81, 0xD8, 0x07, 0xC0, 0x3C, 0x00, 0xE0, 0x06, 0x00, 0x70, 0x03, 0x80, 0x38, 0x01, 0xC0, 0x1C, 0x00,
/* 0xA2 */ 0x21, 0x86, 0x20, 0xFC, 0x07, 0x0E, 0x06, 0xC0, 0xD8, 0x33, 0x86, 0x30, 0xC6, 0x30, 0xC6, 0x0C, 0xC1, 0xB0, 0x36, 0x03, 0xC0, 0x70, 0x0E, 0x01, 0x80, 0x30, 0x0E, 0x07, 0x80, 0xE0, 0x00,
/* 0xA3 */ 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x3C, 0x1E, 0x0F, 0x07, 0xC7, 0x7F, 0x1F, 0x00,
/* 0xA4 */ 0xDD, 0xFF, 0xD8, 0xD8, 0x3C, 0x1E, 0x0F, 0x8D, 0xFF, 0xDD, 0x80,
/* 0xA5 */ 0x00, 0x60, 0x0F, 0xFF, 0xFF, 0xFC, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x03, 0x00, 0x60, 0x00,
/* 0xA6 */ 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFC,
/* 0xA7 */ 0x0F, 0x03, 0xF0, 0xE7, 0x18, 0x63, 0x0C, 0x70, 0x07, 0x03, 0xF8, 0xC3, 0x98, 0x3B, 0x03, 0xF0, 0x37, 0x06, 0x78, 0xC7, 0xB0, 0x7C, 0x03, 0x80, 0x39, 0x83, 0x30, 0x67, 0x1C, 0x7F, 0x07, 0xC0,
/* 0xA8 */ 0x19, 0x81, 0x98, 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0F, 0xFE, 0xFF, 0xEC, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0F, 0xFF, 0xFF, 0xF0,
/* 0xA9 */ 0x03, 0xF0, 0x03, 0xFF, 0x01, 0xE0, 0xE0, 0xE3, 0x1C, 0x73, 0xF3, 0x99, 0x86, 0x6C, 0xC1, 0x8F, 0x30, 0x03, 0xCC, 0x00, 0xF3, 0x00, 0x3C, 0xC1, 0x8D, 0x98, 0x66, 0x77, 0xF3, 0x8E, 0x79, 0xC1, 0xC0, 0xE0, 0x3F, 0xF0, 0x03, 0xF0, 0x00,
/* 0xAA */ 0x07, 0xE0, 0x3F, 0xF0, 0xF0, 0x71, 0x80, 0x76, 0x00, 0x6C, 0x00, 0x30, 0x00, 0x60, 0x00, 0xFF, 0xE1, 0xFF, 0xC3, 0x00, 0x06, 0x00, 0x0E, 0x00, 0x6C, 0x00, 0xDC, 0x03, 0x1C, 0x0E, 0x1F, 0xF8, 0x0F, 0xC0,
/* 0xAB */ 0x21, 0x63, 0xE7, 0x84, 0x84, 0xE7, 0x63, 0x21,
/* 0xAC */ 0xFF, 0xFF, 0xFF, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03,
/* 0xAD */ 0xFF, 0xF0,
/* 0xAE */ 0x03, 0xF0, 0x03, 0xFF, 0x01, 0xE0, 0xE0, 0xFF, 0x1C, 0x7F, 0xF3, 0x9B, 0x04, 0x6C, 0xC1, 0x8F, 0x30, 0x43, 0xCF, 0xF0, 0xF3, 0xFC, 0x3C, 0xC1, 0x0D, 0xB0, 0x66, 0x7C, 0x1B, 0x8F, 0x07, 0xC1, 0xC0, 0xE0, 0x3F, 0xF0, 0x03, 0xF0, 0x00,
/* 0xAF */ 0xC7, 0x8C, 0x01, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x00,
/* 0xB0 */ 0x38, 0xFB, 0x1C, 0x18, 0x38, 0xDF, 0x1C,
/* 0xB1 */ 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x7F, 0xE7, 0xFE, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF0,
/* 0xB2 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
/* 0xB3 */ 0xF0, 0x3F, 0xFF, 0xFF, 0xF0,
/* 0xB4 */ 0x03, 0x03, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
/* 0xB5 */ 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x1C, 0xE3, 0xCF, 0xEF, 0xFC, 0x7C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x00,
/* 0xB6 */ 0x1F, 0xE7, 0xFD, 0xF3, 0x7E, 0x6F, 0xCD, 0xF9, 0xBF, 0x37, 0xE6, 0x7C, 0xCF, 0x98, 0xF3, 0x06, 0x60, 0xCC, 0x19, 0x83, 0x30, 0x66, 0x0C, 0xC1, 0x98, 0x33, 0x06, 0x60, 0xCC,
/* 0xB7 */ 0xF0,
/* 0xB8 */ 0x19, 0x83, 0x30, 0x00, 0x00, 0x01, 0xF0, 0x7F, 0x1C, 0x77, 0x03, 0xC0, 0x7F, 0xFF, 0xFF, 0xE0, 0x0C, 0x01, 0xC0, 0xDC, 0x31, 0xFC, 0x1F, 0x00,
/* 0xB9 */ 0xC0, 0xC0, 0x18, 0x18, 0x03, 0x83, 0x00, 0x70, 0x60, 0x0B, 0x0C, 0x01, 0x61, 0x8F, 0xA6, 0x33, 0x1C, 0xC6, 0x41, 0x88, 0xC8, 0x31, 0x99, 0x06, 0x13, 0x20, 0xC3, 0x66, 0x38, 0x6C, 0xEF, 0x07, 0x8F, 0xA0, 0xF0, 0x04, 0x0E, 0x00, 0x81, 0xC7, 0xF0, 0x18, 0xFC,
/* 0xBA */ 0x1F, 0x87, 0xF9, 0xC3, 0x30, 0x3E, 0x01, 0xFE, 0x3F, 0xC6, 0x00, 0xE0, 0x0C, 0x0D, 0xC3, 0x9F, 0xE1, 0xF8,
/* 0xBB */ 0x88, 0xC6, 0xE7, 0x21, 0x21, 0xE7, 0xC6, 0x88,
/* 0xBC */ 0x33, 0x00, 0x03, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0xE0,
/* 0xBD */ 0x0F, 0xE0, 0x7F, 0xC3, 0x83, 0x98, 0x07, 0x60, 0x0D, 0x80, 0x07, 0x00, 0x1E, 0x00, 0x3F, 0x80, 0x3F, 0xC0, 0x0F, 0x80, 0x07, 0xC0, 0x0F, 0x00, 0x3E, 0x00, 0xDE, 0x0E, 0x3F, 0xF0, 0x3F, 0x80,
/* 0xBE */ 0x3E, 0x1F, 0xEE, 0x1B, 0x00, 0xC0, 0x3C, 0x07, 0xF0, 0x3F, 0x00, 0xF0, 0x3E, 0x1D, 0xFE, 0x3E, 0x00,
/* 0xBF */ 0xCF, 0x30, 0x00, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30,
/* 0xC0 */ 0x07, 0x80, 0x1E, 0x00, 0x78, 0x03, 0xF0, 0x0C, 0xC0, 0x33, 0x01, 0xCE, 0x06, 0x18, 0x18, 0x60, 0xE1, 0xC3, 0x03, 0x0F, 0xFC, 0x7F, 0xF9, 0x80, 0x66, 0x01, 0xB8, 0x07, 0xC0, 0x0F, 0x00, 0x30,
/* 0xC1 */ 0xFF, 0xE7, 0xFF, 0x30, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x1F, 0xF8, 0xFF, 0xF6, 0x01, 0xB0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x06, 0xFF, 0xF7, 0xFE, 0x00,
/* 0xC2 */ 0xFF, 0xC7, 0xFF, 0x30, 0x1D, 0x80, 0x6C, 0x03, 0x60, 0x1B, 0x00, 0xD8, 0x0C, 0xFF, 0xC7, 0xFF, 0x30, 0x0D, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x06, 0xFF, 0xF7, 0xFE, 0x00,
/* 0xC3 */ 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x00,
/* 0xC4 */ 0x07, 0xFE, 0x01, 0xFF, 0x80, 0x60, 0x60, 0x18, 0x18, 0x06, 0x06, 0x01, 0x81, 0x80, 0x60, 0x60, 0x18, 0x18, 0x06, 0x06, 0x01, 0x81, 0x80, 0x60, 0x60, 0x18, 0x18, 0x0E, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x70, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x00, 0x03, 0xC0, 0x00, 0xC0,
/* 0xC5 */ 0xFF, 0xFF, 0xFF, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xEF, 0xFE, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xFF, 0xFF,
/* 0xC6 */ 0x70, 0x60, 0xE3, 0x06, 0x0C, 0x38, 0x61, 0xC1, 0xC6, 0x38, 0x0E, 0x67, 0x00, 0x66, 0x60, 0x03, 0x6C, 0x00, 0x3F, 0xC0, 0x01, 0xF8, 0x00, 0x1F, 0x80, 0x03, 0xFC, 0x00, 0x76, 0xE0, 0x0E, 0x67, 0x01, 0xC6, 0x38, 0x38, 0x61, 0xC3, 0x06, 0x0C, 0x60, 0x60, 0xEE, 0x06, 0x07,
/* 0xC7 */ 0x0F, 0x81, 0xFF, 0x0C, 0x18, 0xC0, 0x66, 0x03, 0x00, 0x18, 0x01, 0xC0, 0x1C, 0x07, 0xC0, 0x3F, 0x00, 0x1C, 0x00, 0x7C, 0x01, 0xE0, 0x0F, 0x80, 0x6E, 0x0E, 0x3F, 0xE0, 0x7E, 0x00,
/* 0xC8 */ 0xC0, 0x3E, 0x01, 0xF0, 0x1F, 0x80, 0xFC, 0x0D, 0xE0, 0xEF, 0x06, 0x78, 0x73, 0xC3, 0x1E, 0x30, 0xF1, 0x87, 0x98, 0x3D, 0xC1, 0xEC, 0x0F, 0xC0, 0x7E, 0x03, 0xE0, 0x1F, 0x00, 0xC0,
/* 0xC9 */ 0x10, 0x40, 0xC4, 0x07, 0xE0, 0x1E, 0x0C, 0x03, 0xE0, 0x1F, 0x01, 0xF8, 0x0F, 0xC0, 0xDE, 0x0E, 0xF0, 0x67, 0x87, 0x3C, 0x31, 0xE3, 0x0F, 0x18, 0x79, 0x83, 0xDC, 0x1E, 0xC0, 0xFC, 0x07, 0xE0, 0x3E, 0x01, 0xF0, 0x0C,
/* 0xCA */ 0xC0, 0x7C, 0x0E, 0xC1, 0xCC, 0x38, 0xC7, 0x0C, 0xE0, 0xDC, 0x0F, 0x80, 0xF0, 0x0F, 0x80, 0xDC, 0x0C, 0xE0, 0xC7, 0x0C, 0x30, 0xC3, 0x8C, 0x1C, 0xC0, 0xEC, 0x07,
/* 0xCB */ 0x1F, 0xFC, 0x7F, 0xF1, 0x80, 0xC6, 0x03, 0x18, 0x0C, 0x60, 0x31, 0x80, 0xC6, 0x03, 0x18, 0x0C, 0x60, 0x31, 0x80, 0xC6, 0x03, 0x18, 0x0C, 0xC0, 0x33, 0x00, 0xDC, 0x03, 0xE0, 0x0F, 0x00, 0x30,
/* 0xCC */ 0xE0, 0x07, 0xE0, 0x07, 0xF0, 0x0F, 0xF0, 0x0F, 0xD0, 0x0F, 0xD8, 0x1B, 0xD8, 0x1B, 0xD8, 0x1B, 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33, 0xC6, 0x63, 0xC6, 0x63, 0xC6, 0x63, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC1, 0x83,
/* 0xCD */ 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xC0,
/* 0xCE */ 0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0x07, 0x86, 0x00, 0xC6, 0x00, 0x33, 0x00, 0x1B, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x36, 0x00, 0x33, 0x00, 0x18, 0xC0, 0x18, 0x78, 0x3C, 0x1F, 0xFC, 0x03, 0xF8, 0x00,
/* 0xCF */ 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xC0,
/* 0xD0 */ 0xFF, 0x8F, 0xFE, 0xC0, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x06, 0xFF, 0xEF, 0xFC, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00,
/* 0xD1 */ 0x07, 0xE0, 0x3F, 0xF0, 0xE0, 0x73, 0x80, 0x76, 0x00, 0x6C, 0x00, 0x30, 0x00, 0x60, 0x00, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x00, 0x0E, 0x00, 0x6C, 0x00, 0xDC, 0x03, 0x1E, 0x0E, 0x1F, 0xF8, 0x0F, 0xC0,
/* 0xD2 */ 0xFF, 0xFF, 0xFF, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60,
/* 0xD3 */ 0xC0, 0x1F, 0x01, 0xD8, 0x0C, 0xE0, 0xE3, 0x06, 0x1C, 0x70, 0x63, 0x03, 0xB8, 0x1D, 0x80, 0x7C, 0x03, 0xC0, 0x0E, 0x00, 0x60, 0x07, 0x00, 0x38, 0x03, 0x80, 0x1C, 0x01, 0xC0, 0x00,
/* 0xD4 */ 0x00, 0xC0, 0x00, 0x30, 0x00, 0xFF, 0xC0, 0xFF, 0xFC, 0x78, 0xC7, 0x98, 0x30, 0x6E, 0x0C, 0x1F, 0x03, 0x03, 0xC0, 0xC0, 0xF0, 0x30, 0x3C, 0x0C, 0x0F, 0x83, 0x07, 0x60, 0xC1, 0x9E, 0x31, 0xE3, 0xFF, 0xF0, 0x3F, 0xF0, 0x00, 0xC0, 0x00, 0x30, 0x00,
/* 0xD5 */ 0xE0, 0x1D, 0x80, 0xE7, 0x03, 0x0E, 0x1C, 0x18, 0x60, 0x73, 0x00, 0xFC, 0x01, 0xE0, 0x07, 0x00, 0x1E, 0x00, 0xF8, 0x03, 0x30, 0x1C, 0xE0, 0xE1, 0x83, 0x07, 0x1C, 0x0E, 0xE0, 0x1B, 0x00, 0x70,
/* 0xD6 */ 0xC0, 0x19, 0x80, 0x33, 0x00, 0x66, 0x00, 0xCC, 0x01, 0x98, 0x03, 0x30, 0x06, 0x60, 0x0C, 0xC0, 0x19, 0x80, 0x33, 0x00, 0x66, 0x00, 0xCC, 0x01, 0x98, 0x03, 0x30, 0x06, 0x60, 0x0C, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x18, 0x00, 0x30, 0x00, 0x60,
/* 0xD7 */ 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x37, 0xFF, 0x3F, 0xF0, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03,
/* 0xD8 */ 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xFF, 0xFF, 0xFF, 0xFF,
/* 0xD9 */ 0xC1, 0x83, 0x30, 0x60, 0xCC, 0x18, 0x33, 0x06, 0x0C, 0xC1, 0x83, 0x30, 0x60, 0xCC, 0x18, 0x33, 0x06, 0x0C, 0xC1, 0x83, 0x30, 0x60, 0xCC, 0x18, 0x33, 0x06, 0x0C, 0xC1, 0x83, 0x30, 0x60, 0xCC, 0x18, 0x33, 0x06, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x0C, 0x00, 0x03, 0x00, 0x00, 0xC0,
/* 0xDA */ 0xFE, 0x00, 0x3F, 0x80, 0x00, 0x60, 0x00, 0x18, 0x00, 0x06, 0x00, 0x01, 0x80, 0x00, 0x60, 0x00, 0x1F, 0xF8, 0x07, 0xFF, 0x01, 0x80, 0xE0, 0x60, 0x1C, 0x18, 0x03, 0x06, 0x00, 0xC1, 0x80, 0x30, 0x60, 0x1C, 0x18, 0x0E, 0x07, 0xFF, 0x01, 0xFF, 0x80,
/* 0xDB */ 0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x07, 0xFF, 0x83, 0xFF, 0xE1, 0xE0, 0x38, 0xF0, 0x0E, 0x78, 0x03, 0x3C, 0x01, 0x9E, 0x00, 0xCF, 0x00, 0xE7, 0x80, 0xE3, 0xFF, 0xE1, 0xFF, 0xE0, 0xC0,
/* 0xDC */ 0xC0, 0x06, 0x00, 0x30, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x1F, 0xF8, 0xFF, 0xE6, 0x03, 0xB0, 0x0F, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0xF8, 0x0E, 0xFF, 0xE7, 0xFE, 0x00,
/* 0xDD */ 0x0F, 0xC0, 0x7F, 0xE1, 0xC1, 0xE7, 0x01, 0xCC, 0x01, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x07, 0x1F, 0xFE, 0x3F, 0xFC, 0x00, 0x38, 0x00, 0x7C, 0x00, 0xD8, 0x03, 0x98, 0x0E, 0x38, 0x3C, 0x3F, 0xF0, 0x1F, 0x80,
/* 0xDE */ 0xC0, 0x3F, 0x06, 0x07, 0xFE, 0x30, 0x70, 0x39, 0x87, 0x00, 0xEC, 0x30, 0x03, 0x61, 0x80, 0x1B, 0x18, 0x00, 0x78, 0xC0, 0x03, 0xFE, 0x00, 0x1F, 0xF0, 0x00, 0xF1, 0x80, 0x07, 0x8C, 0x00, 0x3C, 0x70, 0x03, 0xE1, 0x80, 0x1B, 0x0E, 0x01, 0xD8, 0x38, 0x1C, 0xC0, 0xFF, 0xC6, 0x01, 0xF8, 0x00,
/* 0xDF */ 0x0F, 0xFC, 0xFF, 0xF3, 0x00, 0xD8, 0x03, 0x60, 0x0D, 0x80, 0x36, 0x00, 0xCC, 0x03, 0x3F, 0xFC, 0x3F, 0xF0, 0x38, 0xC1, 0xC3, 0x0E, 0x0C, 0x70, 0x31, 0x80, 0xCE, 0x03, 0x70, 0x0F, 0x80, 0x30,
/* 0xE0 */ 0x3F, 0x07, 0xF8, 0xE1, 0xCC, 0x0C, 0x00, 0xC0, 0x1C, 0x3F, 0xCF, 0x8C, 0xC0, 0xCC, 0x0C, 0xE3, 0xC7, 0xEF, 0x3C, 0x70,
/* 0xE1 */ 0x00, 0xC0, 0x38, 0x3F, 0x1F, 0x87, 0x00, 0xC0, 0x17, 0xC7, 0xFC, 0xF1, 0xDC, 0x1F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1F, 0x07, 0x71, 0xC7, 0xF0, 0x7C, 0x00,
/* 0xE2 */ 0xFE, 0x3F, 0xEC, 0x3B, 0x06, 0xC1, 0xB0, 0xEF, 0xF3, 0x0E, 0xC0, 0xF0, 0x3C, 0x1F, 0xFE, 0xFF, 0x00,
/* 0xE3 */ 0xFF, 0xFF, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x06, 0x0C, 0x00,
/* 0xE4 */ 0x0F, 0xF0, 0x3F, 0xC0, 0xC3, 0x03, 0x0C, 0x0C, 0x30, 0x30, 0xC0, 0xC3, 0x03, 0x0C, 0x1C, 0x30, 0x60, 0xC1, 0x83, 0x3F, 0xFF, 0xFF, 0xFF, 0x00, 0x3C, 0x00, 0xC0,
/* 0xE5 */ 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x3C, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0xC0, 0x1C, 0x0D, 0xC3, 0x1F, 0xC1, 0xF0,
/* 0xE6 */ 0xE1, 0x87, 0x71, 0x8E, 0x39, 0x9C, 0x1D, 0xB8, 0x0F, 0xF0, 0x07, 0xE0, 0x07, 0xE0, 0x0F, 0xF0, 0x1D, 0xB8, 0x39, 0x9C, 0x71, 0x8E, 0xE1, 0x87, 0xC1, 0x83,
/* 0xE7 */ 0x3E, 0x7F, 0xB0, 0xE0, 0x30, 0x18, 0x78, 0x3C, 0x07, 0x01, 0xE0, 0xF8, 0xEF, 0xE3, 0xE0,
/* 0xE8 */ 0xC0, 0xF8, 0x3F, 0x07, 0xE1, 0xFC, 0x37, 0x8C, 0xF3, 0x9E, 0x63, 0xD8, 0x7F, 0x0F, 0xC1, 0xF8, 0x3E, 0x06,
/* 0xE9 */ 0x21, 0x86, 0x20, 0xFC, 0x0F, 0x0C, 0x0F, 0x83, 0xF0, 0x7E, 0x1F, 0xC3, 0x78, 0xCF, 0x39, 0xE6, 0x3D, 0x87, 0xF0, 0xFC, 0x1F, 0x83, 0xE0, 0x60,
/* 0xEA */ 0xC1, 0xE1, 0xB1, 0x99, 0x8D, 0x87, 0x83, 0xC1, 0xF0, 0xDC, 0x67, 0x31, 0xD8, 0x7C, 0x18,
/* 0xEB */ 0x3F, 0xCF, 0xF3, 0x0C, 0xC3, 0x30, 0xCC, 0x33, 0x0C, 0xC3, 0x30, 0xDC, 0x36, 0x0F, 0x83, 0xC0, 0xC0,
/* 0xEC */ 0xE0, 0x7E, 0x07, 0xF0, 0xFF, 0x0F, 0xF0, 0xFD, 0x9B, 0xD9, 0xBD, 0xFB, 0xCF, 0x3C, 0xF3, 0xC6, 0x3C, 0x63, 0xC0, 0x30,
/* 0xED */ 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xC0,
/* 0xEE */ 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x7C, 0x1D, 0xC7, 0x1F, 0xC1, 0xF0,
/* 0xEF */ 0xFF, 0xFF, 0xFC, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xC0,
/* 0xF0 */ 0xCF, 0x8D, 0xFC, 0xF0, 0xEE, 0x06, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3E, 0x06, 0xF0, 0xEF, 0xFC, 0xCF, 0x8C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x00,
/* 0xF1 */ 0x1F, 0x0F, 0xE6, 0x1F, 0x83, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x38, 0x37, 0x1C, 0xFE, 0x1F, 0x00,
/* 0xF2 */ 0xFF, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
/* 0xF3 */ 0xE0, 0x6C, 0x0D, 0x83, 0x38, 0x63, 0x0C, 0x63, 0x0C, 0x60, 0xCC, 0x1B, 0x03, 0x60, 0x3C, 0x07, 0x00, 0xE0, 0x18, 0x03, 0x00, 0xE0, 0x78, 0x0E, 0x00,
/* 0xF4 */ 0x00, 0xC0, 0x00, 0x18, 0x00, 0x03, 0x00, 0x0F, 0x67, 0x87, 0xFD, 0xF8, 0xC3, 0xE3, 0xB8, 0x78, 0x3E, 0x06, 0x03, 0xC0, 0xC0, 0x78, 0x18, 0x0F, 0x03, 0x01, 0xE0, 0x60, 0x3E, 0x1E, 0x0E, 0xC3, 0xE3, 0x9F, 0xFF, 0xE1, 0xF6, 0x78, 0x00, 0xC0, 0x00, 0x18, 0x00, 0x03, 0x00, 0x00, 0x60, 0x00,
/* 0xF5 */ 0xC1, 0xF8, 0x66, 0x30, 0xCC, 0x3E, 0x07, 0x00, 0xC0, 0x78, 0x36, 0x0C, 0xC6, 0x3B, 0x06, 0xC0, 0xC0,
/* 0xF6 */ 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x0C, 0xC0, 0xCF, 0xFF, 0xFF, 0xF0, 0x03, 0x00, 0x30,
/* 0xF7 */ 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0xFE, 0xFF, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18,
/* 0xF8 */ 0xC3, 0x0F, 0x0C, 0x3C, 0x30, 0xF0, 0xC3, 0xC3, 0x0F, 0x0C, 0x3C, 0x30, 0xF0, 0xC3, 0xC3, 0x0F, 0x0C, 0x3C, 0x30, 0xFF, 0xFF, 0xFF, 0xFC,
/* 0xF9 */ 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x03, 0x00, 0x03,
/* 0xFA */ 0xFC, 0x03, 0xF0, 0x00, 0xC0, 0x03, 0x00, 0x0F, 0xF0, 0x3F, 0xE0, 0xC1, 0xC3, 0x03, 0x0C, 0x0C, 0x30, 0x30, 0xC1, 0xC3, 0xFE, 0x0F, 0xF0,
/* 0xFB */ 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xFF, 0x0F, 0xFE, 0x3C, 0x1C, 0xF0, 0x33, 0xC0, 0xCF, 0x03, 0x3C, 0x1C, 0xFF, 0xE3, 0xFF, 0x0C,
/* 0xFC */ 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xFF, 0x3F, 0xEC, 0x1F, 0x03, 0xC0, 0xF0, 0x3C, 0x1F, 0xFE, 0xFF, 0x00,
/* 0xFD */ 0x3F, 0x0F, 0xF1, 0x87, 0x60, 0x60, 0x0E, 0x3F, 0xC7, 0xF8, 0x03, 0x00, 0xD8, 0x1B, 0x87, 0x3F, 0xC3, 0xF0,
/* 0xFE */ 0xC0, 0xF8, 0xC1, 0xFC, 0xC3, 0x8E, 0xC7, 0x07, 0xC6, 0x03, 0xFE, 0x03, 0xFE, 0x03, 0xC6, 0x03, 0xC6, 0x03, 0xC7, 0x06, 0xC3, 0x8E, 0xC1, 0xFC, 0xC0, 0xF8,
/* 0xFF */ 0x1F, 0xCF, 0xF7, 0x0D, 0x83, 0x60, 0xD8, 0x33, 0xFC, 0x7F, 0x0C, 0xC6, 0x33, 0x0D, 0x83, 0xC0, 0xC0,
};
const GFXglyph FreeSans12pt_Win1251Glyphs[] PROGMEM = {
/* 0x01 */ { 0, 19, 20, 21, 1, -17 },
/* 0x02 */ { 48, 19, 20, 21, 1, -17 },
/* 0x03 */ { 96, 21, 20, 23, 1, -17 },
/* 0x04 */ { 149, 21, 20, 23, 1, -17 },
/* 0x05 */ { 202, 20, 20, 22, 1, -17 },
/* 0x06 */ { 252, 20, 20, 22, 1, -17 },
/* 0x07 */ { 302, 0, 0, 8, 0, 0 },
/* 0x08 */ { 302, 23, 20, 25, 1, -17 },
/* 0x09 */ { 360, 23, 16, 25, 1, -16 },
/* 0x0A */ { 406, 0, 0, 8, 0, 0 },
/* 0x0B */ { 406, 21, 20, 23, 1, -17 },
/* 0x0C */ { 459, 19, 18, 21, 1, -15 },
/* 0x0D */ { 502, 0, 0, 8, 0, 0 },
/* 0x0E */ { 502, 20, 20, 22, 1, -17 },
/* 0x0F */ { 552, 21, 21, 23, 1, -18 },
/* 0x10 */ { 608, 19, 20, 21, 1, -17 },
/* 0x11 */ { 656, 21, 20, 23, 1, -17 },
/* 0x12 */ { 709, 20, 20, 22, 1, -17 },
/* 0x13 */ { 759, 21, 20, 23, 1, -17 },
/* 0x14 */ { 812, 21, 20, 23, 1, -17 },
/* 0x15 */ { 865, 22, 20, 24, 1, -17 },
/* 0x16 */ { 920, 16, 20, 18, 1, -17 },
/* 0x17 */ { 960, 21, 20, 23, 1, -17 },
/* 0x18 */ { 1013, 23, 20, 25, 1, -17 },
/* 0x19 */ { 1071, 21, 20, 23, 1, -17 },
/* 0x1A */ { 1124, 15, 19, 17, 1, -16 },
/* 0x1B */ { 1160, 24, 21, 26, 1, -18 },
/* 0x1C */ { 1223, 21, 20, 23, 1, -17 },
/* 0x1D */ { 1276, 21, 21, 23, 1, -18 },
/* 0x1E */ { 1332, 20, 20, 22, 1, -17 },
/* 0x1F */ { 1382, 15, 20, 17, 1, -17 },
/* ' ' 0x20 */ { 1420, 0, 0, 6, 0, 0 },
/* '!' 0x21 */ { 1420, 2, 18, 8, 3, -16 },
/* '"' 0x22 */ { 1425, 6, 6, 8, 1, -15 },
/* '#' 0x23 */ { 1430, 13, 16, 13, 0, -14 },
/* '$' 0x24 */ { 1456, 11, 20, 13, 1, -16 },
/* '%' 0x25 */ { 1484, 20, 17, 21, 1, -15 },
/* '&' 0x26 */ { 1527, 14, 17, 16, 1, -15 },
/* ''' 0x27 */ { 1557, 2, 6, 5, 1, -15 },
/* '(' 0x28 */ { 1559, 5, 23, 8, 2, -16 },
/* ')' 0x29 */ { 1574, 5, 23, 8, 1, -16 },
/* '*' 0x2A */ { 1589, 7, 7, 9, 1, -16 },
/* '+' 0x2B */ { 1596, 10, 11, 14, 2, -9 },
/* ',' 0x2C */ { 1610, 2, 6, 7, 2, 0 },
/* '-' 0x2D */ { 1612, 6, 2, 8, 1, -6 },
/* '.' 0x2E */ { 1614, 2, 2, 6, 2, 0 },
/* '/' 0x2F */ { 1615, 7, 18, 7, 0, -16 },
/* '0' 0x30 */ { 1631, 11, 17, 13, 1, -15 },
/* '1' 0x31 */ { 1655, 5, 17, 13, 3, -15 },
/* '2' 0x32 */ { 1666, 11, 17, 13, 1, -15 },
/* '3' 0x33 */ { 1690, 11, 17, 13, 1, -15 },
/* '4' 0x34 */ { 1714, 11, 17, 13, 1, -15 },
/* '5' 0x35 */ { 1738, 11, 17, 13, 1, -15 },
/* '6' 0x36 */ { 1762, 11, 17, 13, 1, -15 },
/* '7' 0x37 */ { 1786, 11, 17, 13, 1, -15 },
/* '8' 0x38 */ { 1810, 11, 17, 13, 1, -15 },
/* '9' 0x39 */ { 1834, 11, 17, 13, 1, -15 },
/* ':' 0x3A */ { 1858, 2, 13, 6, 2, -11 },
/* ';' 0x3B */ { 1862, 2, 16, 6, 2, -10 },
/* '<' 0x3C */ { 1866, 12, 11, 14, 1, -9 },
/* '=' 0x3D */ { 1883, 12, 6, 14, 1, -7 },
/* '>' 0x3E */ { 1892, 12, 11, 14, 1, -9 },
/* '?' 0x3F */ { 1909, 10, 18, 13, 2, -16 },
/* '@' 0x40 */ { 1932, 22, 21, 24, 1, -16 },
/* 'A' 0x41 */ { 1990, 14, 18, 16, 1, -16 },
/* 'B' 0x42 */ { 2022, 13, 18, 16, 2, -16 },
/* 'C' 0x43 */ { 2052, 15, 18, 17, 1, -16 },
/* 'D' 0x44 */ { 2086, 14, 18, 17, 2, -16 },
/* 'E' 0x45 */ { 2118, 12, 18, 15, 2, -16 },
/* 'F' 0x46 */ { 2145, 11, 18, 14, 2, -16 },
/* 'G' 0x47 */ { 2170, 16, 18, 18, 1, -16 },
/* 'H' 0x48 */ { 2206, 13, 18, 17, 2, -16 },
/* 'I' 0x49 */ { 2236, 2, 18, 7, 2, -16 },
/* 'J' 0x4A */ { 2241, 9, 18, 13, 1, -16 },
/* 'K' 0x4B */ { 2262, 13, 18, 16, 2, -16 },
/* 'L' 0x4C */ { 2292, 10, 18, 14, 2, -16 },
/* 'M' 0x4D */ { 2315, 16, 18, 20, 2, -16 },
/* 'N' 0x4E */ { 2351, 13, 18, 18, 2, -16 },
/* 'O' 0x4F */ { 2381, 17, 18, 19, 1, -16 },
/* 'P' 0x50 */ { 2420, 12, 18, 16, 2, -16 },
/* 'Q' 0x51 */ { 2447, 17, 19, 19, 1, -16 },
/* 'R' 0x52 */ { 2488, 14, 18, 17, 2, -16 },
/* 'S' 0x53 */ { 2520, 14, 18, 16, 1, -16 },
/* 'T' 0x54 */ { 2552, 12, 18, 15, 1, -16 },
/* 'U' 0x55 */ { 2579, 13, 18, 17, 2, -16 },
/* 'V' 0x56 */ { 2609, 14, 18, 15, 1, -16 },
/* 'W' 0x57 */ { 2641, 22, 18, 22, 0, -16 },
/* 'X' 0x58 */ { 2691, 14, 18, 16, 1, -16 },
/* 'Y' 0x59 */ { 2723, 14, 18, 16, 1, -16 },
/* 'Z' 0x5A */ { 2755, 13, 18, 15, 1, -16 },
/* '[' 0x5B */ { 2785, 4, 23, 7, 2, -16 },
/* '\' 0x5C */ { 2797, 7, 18, 7, 0, -16 },
/* ']' 0x5D */ { 2813, 4, 23, 7, 1, -16 },
/* '^' 0x5E */ { 2825, 9, 9, 11, 1, -15 },
/* '_' 0x5F */ { 2836, 15, 1, 13, -1, 5 },
/* '`' 0x60 */ { 2838, 5, 4, 6, 1, -16 },
/* 'a' 0x61 */ { 2841, 12, 13, 13, 1, -11 },
/* 'b' 0x62 */ { 2861, 12, 18, 13, 1, -16 },
/* 'c' 0x63 */ { 2888, 10, 13, 12, 1, -11 },
/* 'd' 0x64 */ { 2905, 11, 18, 13, 1, -16 },
/* 'e' 0x65 */ { 2930, 11, 13, 13, 1, -11 },
/* 'f' 0x66 */ { 2948, 5, 18, 7, 1, -16 },
/* 'g' 0x67 */ { 2960, 11, 18, 13, 1, -11 },
/* 'h' 0x68 */ { 2985, 10, 18, 13, 1, -16 },
/* 'i' 0x69 */ { 3008, 2, 18, 5, 2, -16 },
/* 'j' 0x6A */ { 3013, 4, 23, 6, 0, -16 },
/* 'k' 0x6B */ { 3025, 10, 18, 12, 1, -16 },
/* 'l' 0x6C */ { 3048, 2, 18, 5, 1, -16 },
/* 'm' 0x6D */ { 3053, 17, 13, 19, 1, -11 },
/* 'n' 0x6E */ { 3081, 10, 13, 13, 1, -11 },
/* 'o' 0x6F */ { 3098, 11, 13, 13, 1, -11 },
/* 'p' 0x70 */ { 3116, 12, 17, 13, 1, -11 },
/* 'q' 0x71 */ { 3142, 11, 17, 13, 1, -11 },
/* 'r' 0x72 */ { 3166, 6, 13, 8, 1, -11 },
/* 's' 0x73 */ { 3176, 10, 13, 12, 1, -11 },
/* 't' 0x74 */ { 3193, 5, 16, 7, 1, -14 },
/* 'u' 0x75 */ { 3203, 10, 13, 13, 1, -11 },
/* 'v' 0x76 */ { 3220, 11, 13, 12, 0, -11 },
/* 'w' 0x77 */ { 3238, 17, 13, 17, 0, -11 },
/* 'x' 0x78 */ { 3266, 10, 13, 11, 1, -11 },
/* 'y' 0x79 */ { 3283, 11, 18, 11, 0, -11 },
/* 'z' 0x7A */ { 3308, 10, 13, 12, 1, -11 },
/* '{' 0x7B */ { 3325, 5, 23, 8, 1, -16 },
/* '|' 0x7C */ { 3340, 2, 23, 6, 2, -16 },
/* '}' 0x7D */ { 3346, 5, 23, 8, 2, -16 },
/* '~' 0x7E */ { 3361, 10, 5, 12, 1, -9 },
/* 0x7F */ { 3368, 0, 0, 0, 0, 0 },
/* 0x80 */ { 3368, 16, 22, 18, 1, -18 },
/* 0x81 */ { 3412, 11, 22, 14, 2, -22 },
/* 0x82 */ { 3443, 2, 5, 6, 2, -2 },
/* 0x83 */ { 3445, 7, 18, 9, 1, -18 },
/* 0x84 */ { 3461, 6, 5, 10, 2, -2 },
/* 0x85 */ { 3465, 12, 2, 16, 2, -2 },
/* 0x86 */ { 3468, 10, 21, 13, 2, -17 },
/* 0x87 */ { 3495, 10, 20, 13, 2, -17 },
/* 0x88 */ { 3520, 14, 17, 16, 1, -17 },
/* 0x89 */ { 3550, 23, 18, 24, 0, -18 },
/* 0x8A */ { 3602, 23, 18, 24, 0, -18 },
/* 0x8B */ { 3654, 3, 8, 6, 1, -11 },
/* 0x8C */ { 3657, 21, 18, 24, 2, -18 },
/* 0x8D */ { 3705, 12, 22, 15, 2, -22 },
/* 0x8E */ { 3738, 16, 18, 18, 1, -18 },
/* 0x8F */ { 3774, 13, 21, 17, 2, -18 },
/* 0x90 */ { 3809, 12, 22, 14, 0, -18 },
/* 0x91 */ { 3842, 2, 6, 6, 2, -18 },
/* 0x92 */ { 3844, 2, 6, 6, 2, -18 },
/* 0x93 */ { 3846, 6, 6, 10, 2, -18 },
/* 0x94 */ { 3851, 6, 6, 10, 2, -18 },
/* 0x95 */ { 3856, 6, 6, 10, 2, -11 },
/* 0x96 */ { 3861, 10, 2, 12, 1, -8 },
/* 0x97 */ { 3864, 22, 2, 24, 1, -8 },
/* 0x98 */ { 3870, 0, 0, 8, 0, 0 },
/* 0x99 */ { 3870, 22, 13, 24, 2, -18 },
/* 0x9A */ { 3906, 17, 13, 19, 1, -13 },
/* 0x9B */ { 3934, 3, 8, 6, 2, -10 },
/* 0x9C */ { 3937, 18, 13, 20, 1, -13 },
/* 0x9D */ { 3967, 9, 18, 12, 1, -18 },
/* 0x9E */ { 3988, 11, 18, 14, 1, -18 },
/* 0x9F */ { 4013, 10, 15, 13, 1, -13 },
/* 0xA0 */ { 4032, 0, 0, 7, 0, 0 },
/* 0xA1 */ { 4032, 13, 22, 15, 1, -22 },
/* 0xA2 */ { 4068, 11, 22, 11, 0, -17 },
/* 0xA3 */ { 4099, 9, 18, 13, 1, -18 },
/* 0xA4 */ { 4120, 9, 9, 13, 2, -13 },
/* 0xA5 */ { 4131, 11, 20, 14, 2, -20 },
/* 0xA6 */ { 4159, 2, 23, 6, 2, -18 },
/* 0xA7 */ { 4165, 11, 23, 13, 1, -18 },
/* 0xA8 */ { 4197, 12, 21, 15, 2, -21 },
/* 0xA9 */ { 4229, 18, 17, 19, 1, -17 },
/* 0xAA */ { 4268, 15, 18, 17, 1, -18 },
/* 0xAB */ { 4302, 8, 8, 12, 2, -11 },
/* 0xAC */ { 4310, 12, 6, 14, 1, -9 },
/* 0xAD */ { 4319, 6, 2, 8, 1, -8 },
/* 0xAE */ { 4321, 18, 17, 19, 1, -17 },
/* 0xAF */ { 4360, 7, 21, 7, 0, -21 },
/* 0xB0 */ { 4379, 7, 8, 15, 4, -17 },
/* 0xB1 */ { 4386, 12, 15, 14, 1, -15 },
/* 0xB2 */ { 4409, 2, 18, 7, 2, -18 },
/* 0xB3 */ { 4414, 2, 18, 5, 2, -18 },
/* 0xB4 */ { 4419, 8, 15, 9, 1, -15 },
/* 0xB5 */ { 4434, 12, 17, 13, 2, -13 },
/* 0xB6 */ { 4460, 11, 21, 13, 2, -18 },
/* 0xB7 */ { 4489, 2, 2, 6, 2, -8 },
/* 0xB8 */ { 4490, 11, 17, 13, 1, -17 },
/* 0xB9 */ { 4514, 19, 18, 22, 2, -18 },
/* 0xBA */ { 4557, 11, 13, 12, 0, -13 },
/* 0xBB */ { 4575, 8, 8, 12, 2, -10 },
/* 0xBC */ { 4583, 4, 23, 6, 0, -18 },
/* 0xBD */ { 4595, 14, 18, 16, 1, -18 },
/* 0xBE */ { 4627, 10, 13, 12, 1, -13 },
/* 0xBF */ { 4644, 6, 17, 6, 0, -17 },
/* 0xC0 */ { 4657, 14, 18, 16, 1, -18 },
/* 0xC1 */ { 4689, 13, 18, 16, 2, -18 },
/* 0xC2 */ { 4719, 13, 18, 16, 2, -18 },
/* 0xC3 */ { 4749, 11, 18, 14, 2, -18 },
/* 0xC4 */ { 4774, 18, 21, 19, 1, -18 },
/* 0xC5 */ { 4822, 12, 18, 15, 2, -18 },
/* 0xC6 */ { 4849, 20, 18, 22, 1, -18 },
/* 0xC7 */ { 4894, 13, 18, 16, 1, -18 },
/* 0xC8 */ { 4924, 13, 18, 18, 2, -18 },
/* 0xC9 */ { 4954, 13, 22, 18, 2, -22 },
/* 0xCA */ { 4990, 12, 18, 15, 2, -18 },
/* 0xCB */ { 5017, 14, 18, 16, 0, -18 },
/* 0xCC */ { 5049, 16, 18, 20, 2, -18 },
/* 0xCD */ { 5085, 13, 18, 17, 2, -18 },
/* 0xCE */ { 5115, 17, 18, 19, 1, -18 },
/* 0xCF */ { 5154, 13, 18, 17, 2, -18 },
/* 0xD0 */ { 5184, 12, 18, 16, 2, -18 },
/* 0xD1 */ { 5211, 15, 18, 17, 1, -18 },
/* 0xD2 */ { 5245, 12, 18, 15, 1, -18 },
/* 0xD3 */ { 5272, 13, 18, 15, 1, -18 },
/* 0xD4 */ { 5302, 18, 18, 20, 1, -18 },
/* 0xD5 */ { 5343, 14, 18, 16, 1, -18 },
/* 0xD6 */ { 5375, 15, 21, 18, 2, -18 },
/* 0xD7 */ { 5415, 12, 18, 15, 1, -18 },
/* 0xD8 */ { 5442, 16, 18, 20, 2, -18 },
/* 0xD9 */ { 5478, 18, 21, 20, 2, -18 },
/* 0xDA */ { 5526, 18, 18, 20, 1, -18 },
/* 0xDB */ { 5567, 17, 18, 21, 2, -18 },
/* 0xDC */ { 5606, 13, 18, 16, 2, -18 },
/* 0xDD */ { 5636, 15, 18, 17, 1, -18 },
/* 0xDE */ { 5670, 21, 18, 24, 2, -18 },
/* 0xDF */ { 5718, 14, 18, 16, 0, -18 },
/* 0xE0 */ { 5750, 12, 13, 13, 1, -13 },
/* 0xE1 */ { 5770, 11, 19, 13, 1, -19 },
/* 0xE2 */ { 5797, 10, 13, 12, 1, -13 },
/* 0xE3 */ { 5814, 7, 13, 9, 1, -13 },
/* 0xE4 */ { 5826, 14, 15, 14, 0, -13 },
/* 0xE5 */ { 5853, 11, 13, 13, 1, -13 },
/* 0xE6 */ { 5871, 16, 13, 18, 1, -13 },
/* 0xE7 */ { 5897, 9, 13, 12, 1, -13 },
/* 0xE8 */ { 5912, 11, 13, 13, 1, -13 },
/* 0xE9 */ { 5930, 11, 17, 13, 1, -17 },
/* 0xEA */ { 5954, 9, 13, 12, 1, -13 },
/* 0xEB */ { 5969, 10, 13, 12, 0, -13 },
/* 0xEC */ { 5986, 12, 13, 14, 1, -13 },
/* 0xED */ { 6006, 10, 13, 13, 1, -13 },
/* 0xEE */ { 6023, 11, 13, 13, 1, -13 },
/* 0xEF */ { 6041, 10, 13, 13, 1, -13 },
/* 0xF0 */ { 6058, 12, 17, 13, 1, -13 },
/* 0xF1 */ { 6084, 10, 13, 12, 1, -13 },
/* 0xF2 */ { 6101, 8, 13, 10, 1, -13 },
/* 0xF3 */ { 6114, 11, 18, 11, 0, -13 },
/* 0xF4 */ { 6139, 19, 20, 20, 1, -16 },
/* 0xF5 */ { 6187, 10, 13, 11, 1, -13 },
/* 0xF6 */ { 6204, 12, 15, 13, 1, -13 },
/* 0xF7 */ { 6227, 9, 13, 12, 1, -13 },
/* 0xF8 */ { 6242, 14, 13, 16, 1, -13 },
/* 0xF9 */ { 6265, 16, 15, 17, 1, -13 },
/* 0xFA */ { 6295, 14, 13, 15, 1, -13 },
/* 0xFB */ { 6318, 14, 13, 16, 1, -13 },
/* 0xFC */ { 6341, 10, 13, 12, 1, -13 },
/* 0xFD */ { 6358, 11, 13, 12, 1, -13 },
/* 0xFE */ { 6376, 16, 13, 18, 1, -13 },
/* 0xFF */ { 6402, 10, 13, 13, 1, -13 },
};
const GFXfont FreeSans12pt_Win1251 PROGMEM = {
(uint8_t*)FreeSans12pt_Win1251Bitmaps,
(GFXglyph*)FreeSans12pt_Win1251Glyphs,
0x01, 0xFF, 19
};
@@ -0,0 +1,527 @@
// trunk-ignore-all(clang-format)
#pragma once
/* PROPERTIES
FONT_NAME FreeSans12pt_Win1252
*/
const uint8_t FreeSans12pt_Win1252Bitmaps[] PROGMEM = {
/* 0x01 */ 0x00, 0x30, 0x00, 0x09, 0x00, 0x01, 0x20, 0x00, 0x24, 0x00, 0x04, 0x80, 0x01, 0x90, 0x00, 0x62, 0x00, 0x30, 0xFE, 0x04, 0x10, 0x5F, 0x02, 0x0B, 0x00, 0x7F, 0xE0, 0x0C, 0x1C, 0x02, 0x83, 0x81, 0x9F, 0xF0, 0x02, 0x1E, 0x00, 0x41, 0xC0, 0x0E, 0x7F, 0x81, 0x78, 0x18, 0x62, 0x00, 0xFF, 0xC0,
/* 0x02 */ 0x00, 0xFF, 0x80, 0x61, 0x13, 0xF0, 0x62, 0x60, 0x07, 0xFC, 0x00, 0x83, 0x80, 0x10, 0xF0, 0x33, 0xF6, 0x01, 0x41, 0xC0, 0x18, 0x38, 0x03, 0xFF, 0xE0, 0x47, 0x02, 0x08, 0x20, 0x61, 0xC4, 0x06, 0x17, 0x00, 0x22, 0x00, 0x02, 0x40, 0x00, 0x48, 0x00, 0x09, 0x00, 0x01, 0x20, 0x00, 0x3C, 0x00,
/* 0x03 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x04, 0x08, 0x48, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x08, 0x10, 0x70, 0x00, 0x03, 0x80, 0x00, 0x14, 0x00, 0x00, 0xA1, 0x81, 0x8D, 0x87, 0xF0, 0x44, 0x00, 0x06, 0x30, 0x00, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x04 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x10, 0x02, 0x48, 0xE0, 0x61, 0xC1, 0xCC, 0x0E, 0x78, 0x1C, 0x70, 0x00, 0x03, 0x80, 0x00, 0x14, 0xFF, 0xFC, 0xA6, 0x00, 0xCD, 0x9F, 0xFE, 0x44, 0x71, 0xE6, 0x30, 0xFC, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x05 */ 0x00, 0x18, 0x00, 0x00, 0x40, 0x01, 0x90, 0x01, 0xF4, 0x08, 0x12, 0x23, 0xC1, 0x91, 0x2C, 0x1C, 0x8A, 0xC3, 0x64, 0x64, 0x13, 0x22, 0x41, 0x98, 0x26, 0x2C, 0xC4, 0x22, 0x60, 0x42, 0x13, 0x04, 0x30, 0x80, 0x61, 0xA4, 0x02, 0x18, 0x20, 0x03, 0x41, 0x00, 0x20, 0x08, 0x02, 0x00, 0x60, 0x40, 0x03, 0xF8,
/* 0x06 */ 0x00, 0x10, 0x00, 0x03, 0x00, 0x1C, 0x48, 0x00, 0xB4, 0x80, 0x09, 0xF9, 0xC0, 0xE0, 0xE4, 0x0C, 0x02, 0x8F, 0x80, 0x38, 0x88, 0x01, 0x0D, 0x00, 0x18, 0x30, 0x01, 0x60, 0x80, 0x13, 0x18, 0x03, 0xF2, 0xC0, 0x20, 0x26, 0x06, 0x07, 0xFF, 0xA0, 0x02, 0x39, 0x00, 0x14, 0x70, 0x01, 0xC3, 0x00, 0x18, 0x00,
/* 0x07 */
/* 0x08 */ 0x00, 0x1F, 0x80, 0x00, 0x60, 0x80, 0x01, 0x00, 0x80, 0x06, 0x00, 0x80, 0x3C, 0x01, 0x01, 0x8C, 0x02, 0x02, 0x08, 0x04, 0x04, 0x08, 0x0C, 0x38, 0x00, 0x04, 0x80, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x2E, 0xC0, 0x01, 0x83, 0x7E, 0x0C, 0x10, 0x37, 0xE2, 0x61, 0x00, 0x0C, 0xC6, 0x10, 0x98, 0x0C, 0x63, 0x00, 0x00, 0xC6, 0x00,
/* 0x09 */ 0x00, 0x1F, 0x80, 0x00, 0x60, 0x80, 0x01, 0x00, 0x80, 0x06, 0x00, 0x80, 0x3C, 0x01, 0x01, 0x8C, 0x02, 0x02, 0x08, 0x04, 0x04, 0x08, 0x0C, 0x38, 0x00, 0x04, 0x80, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x2E, 0xC0, 0x01, 0x83, 0x7E, 0x0C, 0x00, 0x37, 0xE0,
/* 0x0A */
/* 0x0B */ 0x1F, 0x07, 0xC1, 0x86, 0x41, 0x10, 0x0C, 0x04, 0x80, 0x40, 0x18, 0x00, 0x00, 0xC0, 0x00, 0x06, 0x00, 0x00, 0x30, 0x00, 0x01, 0x40, 0x00, 0x0A, 0x00, 0x00, 0x88, 0x00, 0x04, 0x40, 0x00, 0x41, 0x00, 0x02, 0x04, 0x00, 0x20, 0x20, 0x02, 0x00, 0x80, 0x20, 0x02, 0x02, 0x00, 0x08, 0x20, 0x00, 0x22, 0x00, 0x00, 0xE0, 0x00,
/* 0x0C */ 0x01, 0x00, 0x00, 0x38, 0x00, 0x04, 0xC0, 0x01, 0x08, 0x00, 0x18, 0x80, 0x1C, 0x10, 0x02, 0x07, 0x80, 0x81, 0x10, 0x1F, 0xC2, 0x02, 0x00, 0x60, 0x80, 0x1A, 0x20, 0x1C, 0x42, 0x1C, 0x08, 0xFE, 0x03, 0xA0, 0x01, 0x8C, 0x01, 0xC1, 0x43, 0xD0, 0x27, 0x81, 0xF8,
/* 0x0D */
/* 0x0E */ 0x00, 0xE0, 0x00, 0x11, 0x00, 0x01, 0x10, 0x00, 0x0B, 0x00, 0x03, 0xF8, 0x00, 0x60, 0x60, 0x09, 0x02, 0x00, 0xA0, 0x10, 0x16, 0x01, 0x01, 0x40, 0x10, 0x10, 0x01, 0x01, 0x00, 0x08, 0x10, 0x00, 0x82, 0x1F, 0x08, 0x3F, 0x90, 0x44, 0x00, 0x06, 0xBF, 0xFF, 0xAF, 0xF0, 0xFF, 0xFF, 0x0F, 0xE3, 0xFB, 0xFC,
/* 0x0F */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x40, 0x12, 0x34, 0x00, 0x69, 0x40, 0x01, 0x49, 0xE0, 0xF1, 0xCD, 0x06, 0x8E, 0x28, 0x14, 0x71, 0x40, 0xA3, 0x8B, 0xFD, 0x14, 0x50, 0x68, 0xA2, 0x81, 0x4D, 0x97, 0xFA, 0x44, 0xBF, 0xD6, 0x31, 0x02, 0xE0, 0xC8, 0x16, 0x08, 0x61, 0x08, 0x21, 0xF0, 0x80, 0xF8, 0x78, 0x00,
/* 0x10 */ 0x00, 0xF0, 0x00, 0x3A, 0x00, 0x07, 0xC0, 0x00, 0xA8, 0x00, 0x1F, 0x00, 0x02, 0xB0, 0x00, 0x52, 0x00, 0x0A, 0x40, 0x02, 0x48, 0x00, 0x49, 0x00, 0x09, 0x30, 0x01, 0x22, 0x01, 0xC4, 0x70, 0xF0, 0x85, 0xE1, 0x10, 0x88, 0x37, 0x20, 0x03, 0x9C, 0x00, 0x37, 0x00, 0x06, 0x40, 0x01, 0x86, 0x00,
/* 0x11 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x60, 0x02, 0x36, 0x00, 0x09, 0x04, 0x0C, 0x48, 0x60, 0xC1, 0xC3, 0x0F, 0x0E, 0x00, 0x08, 0x70, 0x00, 0x23, 0x80, 0x63, 0x84, 0x01, 0x9F, 0x20, 0x0C, 0xFD, 0x80, 0x27, 0xE4, 0x03, 0x3F, 0x30, 0x33, 0xE0, 0xC0, 0x00, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x12 */ 0x00, 0xC2, 0x00, 0x1C, 0x24, 0x02, 0x18, 0x60, 0x64, 0x02, 0x02, 0x40, 0x20, 0x00, 0xF2, 0x03, 0x89, 0xE0, 0x7C, 0x80, 0x0E, 0x25, 0x80, 0xE1, 0x00, 0x1A, 0x08, 0x71, 0xB0, 0xC4, 0x39, 0x84, 0xC2, 0xCC, 0x40, 0x76, 0x7C, 0x05, 0xBB, 0x80, 0x4C, 0xE0, 0x0A, 0x78, 0x00, 0x9C, 0x00, 0x0F, 0x00, 0x00,
/* 0x13 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x00, 0x00, 0x48, 0x60, 0xC1, 0xC6, 0xC9, 0x0E, 0x00, 0x00, 0x70, 0x00, 0x03, 0x80, 0x00, 0x14, 0xFF, 0xF8, 0xA6, 0x00, 0xCD, 0x9F, 0xFE, 0x44, 0x71, 0xE6, 0x30, 0xFC, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x14 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x20, 0x22, 0x33, 0x01, 0x89, 0x20, 0x02, 0x48, 0x60, 0xE1, 0xC8, 0x80, 0x8E, 0x46, 0x46, 0x72, 0x32, 0x33, 0x9F, 0x9F, 0x94, 0x78, 0x78, 0xA0, 0x00, 0x0D, 0x80, 0x00, 0x44, 0x0E, 0x06, 0x30, 0x00, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x15 */ 0x03, 0xFC, 0x20, 0x38, 0x1C, 0x81, 0x80, 0x1D, 0x08, 0x00, 0x32, 0x60, 0x00, 0x89, 0x00, 0x02, 0x18, 0x00, 0x08, 0x61, 0xC3, 0x22, 0x8D, 0x93, 0x72, 0x00, 0x00, 0x48, 0x00, 0x01, 0x20, 0x00, 0x04, 0x9F, 0xFF, 0x92, 0x60, 0x0E, 0x44, 0xFF, 0xF2, 0x11, 0xC3, 0x88, 0x21, 0xF8, 0x40, 0x40, 0x02, 0x00, 0xC0, 0x30, 0x00, 0xFF, 0x00,
/* 0x16 */ 0x03, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x01, 0xE0, 0x03, 0xF0, 0x03, 0xF0, 0x27, 0xF0, 0x6F, 0x70, 0x6E, 0x60, 0xFC, 0x60, 0xFC, 0x7E, 0xFC, 0x7E, 0xFC, 0x3F, 0xF4, 0x1F, 0xF4, 0x1F, 0xF0, 0x0E, 0x70, 0x0E, 0x30, 0x1C, 0x38, 0x38, 0x0F, 0xF0,
/* 0x17 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x00, 0x00, 0x48, 0x00, 0x21, 0xC0, 0x02, 0x8E, 0x20, 0xF4, 0x70, 0x84, 0x11, 0x82, 0x40, 0x84, 0x01, 0x03, 0x20, 0x0F, 0x85, 0x80, 0x03, 0x04, 0x00, 0x04, 0x30, 0x78, 0x10, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x18 */ 0x00, 0xFC, 0x00, 0x02, 0x06, 0x00, 0x08, 0x24, 0x00, 0x21, 0xA4, 0x00, 0x4C, 0x48, 0x00, 0xA0, 0x50, 0x01, 0x92, 0x60, 0x03, 0x24, 0xC0, 0x06, 0x01, 0x81, 0x28, 0x03, 0x49, 0x6C, 0xC4, 0xAD, 0xD8, 0x16, 0xA4, 0xCC, 0xC4, 0x44, 0x86, 0x13, 0x05, 0x00, 0x28, 0x0A, 0x00, 0x50, 0x14, 0x00, 0x90, 0x48, 0x01, 0x20, 0x90, 0x02, 0x41, 0x20, 0x00, 0x00,
/* 0x19 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x00, 0x00, 0x49, 0xC3, 0x81, 0xC0, 0x00, 0x0E, 0x78, 0xF0, 0x77, 0xEF, 0xC3, 0xA7, 0x4E, 0x15, 0x0A, 0x10, 0xA7, 0x8F, 0x0D, 0x80, 0x00, 0x44, 0x00, 0x06, 0x33, 0xF0, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x1A */ 0xFF, 0xFF, 0x00, 0x06, 0x00, 0x0C, 0x3E, 0x18, 0x82, 0x32, 0x02, 0x64, 0x04, 0xC8, 0x09, 0x80, 0x23, 0x00, 0x86, 0x02, 0x0C, 0x08, 0x18, 0x10, 0x30, 0x00, 0x60, 0x00, 0xC0, 0x81, 0x80, 0x03, 0x00, 0x07, 0xFF, 0xF8,
/* 0x1B */ 0x00, 0xFE, 0x00, 0x03, 0x81, 0x80, 0x04, 0x00, 0x60, 0x08, 0x00, 0x30, 0x10, 0x00, 0x10, 0x30, 0x07, 0x88, 0x23, 0xC8, 0x08, 0x22, 0x00, 0x04, 0x60, 0x00, 0x44, 0x60, 0x00, 0x84, 0x63, 0x03, 0x04, 0x61, 0xFC, 0x04, 0x6B, 0x00, 0x9E, 0xA5, 0x01, 0x6A, 0xD5, 0x01, 0x43, 0xA8, 0x81, 0x05, 0xD0, 0x82, 0x0A, 0xA0, 0x82, 0x05, 0xC0, 0x82, 0x02, 0x61, 0xFF, 0x0C, 0x1E, 0x00, 0xF0,
/* 0x1C */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x30, 0x02, 0x32, 0x00, 0x09, 0x00, 0x00, 0x48, 0x20, 0x61, 0xC3, 0x84, 0x0E, 0x1C, 0x78, 0x70, 0x40, 0x03, 0x80, 0x00, 0x14, 0x00, 0x00, 0xA0, 0x03, 0x0D, 0x83, 0xF0, 0x44, 0x00, 0x06, 0x30, 0x00, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x1D */ 0x01, 0xFE, 0x00, 0x3A, 0x1C, 0x03, 0x00, 0x30, 0x23, 0x1E, 0xC3, 0x38, 0x03, 0x10, 0xC3, 0x09, 0x00, 0x18, 0x68, 0x00, 0xC1, 0x40, 0x00, 0x0A, 0x07, 0x80, 0x50, 0x46, 0x02, 0x80, 0x00, 0x1A, 0x1E, 0x00, 0xCB, 0x10, 0x0D, 0x03, 0x00, 0x48, 0x60, 0x06, 0x40, 0x00, 0x22, 0x0C, 0x02, 0x10, 0x60, 0x60, 0x43, 0xFC, 0x01, 0xE0, 0x00, 0x00,
/* 0x1E */ 0x01, 0xF0, 0x00, 0xEA, 0xC0, 0x31, 0x5F, 0x04, 0x5F, 0x88, 0x80, 0xA0, 0x48, 0x0E, 0x02, 0x8F, 0x40, 0x3C, 0x10, 0x21, 0x66, 0x87, 0x15, 0x98, 0x71, 0x41, 0x02, 0x14, 0x00, 0x01, 0x40, 0x00, 0x14, 0x00, 0x01, 0x21, 0xFE, 0x12, 0x00, 0x02, 0x10, 0x00, 0x60, 0x80, 0x0C, 0x06, 0x01, 0x80, 0x3F, 0xE0,
/* 0x1F */ 0x0E, 0x00, 0x13, 0x00, 0x23, 0x00, 0xF3, 0x01, 0x31, 0x01, 0x11, 0x03, 0xD3, 0x06, 0xF2, 0x30, 0x34, 0xC7, 0x25, 0x33, 0x2B, 0xC2, 0x57, 0x04, 0x3A, 0x08, 0x72, 0x30, 0xA3, 0xC3, 0x40, 0x04, 0x40, 0x18, 0x40, 0x60, 0x7F, 0x80,
/* ' ' 0x20 */
/* '!' 0x21 */ 0xFF, 0xFF, 0xFF, 0xF0, 0xF0,
/* '"' 0x22 */ 0xCF, 0x3C, 0xF3, 0x8A, 0x20,
/* '#' 0x23 */ 0x06, 0x30, 0x31, 0x03, 0x18, 0x18, 0xC7, 0xFF, 0xBF, 0xFC, 0x31, 0x01, 0x18, 0x18, 0xC7, 0xFF, 0xBF, 0xFC, 0x31, 0x01, 0x18, 0x18, 0xC0, 0xC6, 0x06, 0x30,
/* '$' 0x24 */ 0x04, 0x03, 0xE1, 0xFF, 0x72, 0x7C, 0x47, 0x88, 0xF1, 0x07, 0xA0, 0x7E, 0x03, 0xF0, 0x17, 0x02, 0x7C, 0x47, 0x88, 0xF1, 0x1B, 0x26, 0x7F, 0xC3, 0xE0, 0x10, 0x02, 0x00,
/* '%' 0x25 */ 0x00, 0x06, 0x03, 0xC0, 0x40, 0x7E, 0x0C, 0x0E, 0x70, 0x80, 0xC3, 0x18, 0x0C, 0x31, 0x00, 0xE7, 0x30, 0x07, 0xE6, 0x00, 0x3C, 0x40, 0x00, 0x0C, 0x7C, 0x00, 0x8F, 0xE0, 0x19, 0xC7, 0x01, 0x18, 0x30, 0x31, 0x83, 0x02, 0x1C, 0x70, 0x40, 0xFE, 0x04, 0x07, 0xC0,
/* '&' 0x26 */ 0x0F, 0x00, 0x7E, 0x03, 0x9C, 0x0C, 0x30, 0x30, 0xC0, 0xE7, 0x01, 0xF8, 0x03, 0x80, 0x3E, 0x01, 0xCC, 0x6E, 0x39, 0xB0, 0x7C, 0xC0, 0xF3, 0x03, 0xCE, 0x1F, 0x9F, 0xE6, 0x3E, 0x1C,
/* ''' 0x27 */ 0xFF, 0xA0,
/* '(' 0x28 */ 0x08, 0x8C, 0x46, 0x31, 0x98, 0xC6, 0x31, 0x8C, 0x63, 0x08, 0x63, 0x08, 0x61, 0x0C, 0x20,
/* ')' 0x29 */ 0x82, 0x18, 0xC3, 0x18, 0xC3, 0x18, 0xC6, 0x31, 0x8C, 0x62, 0x31, 0x88, 0xC4, 0x62, 0x00,
/* '*' 0x2A */ 0x10, 0x23, 0x5B, 0xE3, 0x8D, 0x91, 0x00,
/* '+' 0x2B */ 0x0C, 0x03, 0x00, 0xC0, 0x30, 0xFF, 0xFF, 0xF0, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0,
/* ',' 0x2C */ 0xF5, 0x60,
/* '-' 0x2D */ 0xFF, 0xF0,
/* '.' 0x2E */ 0xF0,
/* '/' 0x2F */ 0x02, 0x0C, 0x10, 0x20, 0xC1, 0x02, 0x0C, 0x10, 0x20, 0xC1, 0x02, 0x0C, 0x10, 0x20, 0xC1, 0x00,
/* '0' 0x30 */ 0x1F, 0x07, 0xF1, 0xC7, 0x30, 0x6C, 0x0F, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3E, 0x0E, 0xC1, 0x9C, 0x71, 0xFC, 0x1F, 0x00,
/* '1' 0x31 */ 0x08, 0xCF, 0xFF, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18,
/* '2' 0x32 */ 0x1F, 0x0F, 0xF9, 0x87, 0x60, 0x7C, 0x06, 0x00, 0xC0, 0x18, 0x07, 0x01, 0xC0, 0xF0, 0x78, 0x1C, 0x06, 0x00, 0xC0, 0x30, 0x07, 0xFF, 0xFF, 0xE0,
/* '3' 0x33 */ 0x3F, 0x0F, 0xF3, 0x87, 0x60, 0x6C, 0x0C, 0x01, 0x80, 0x60, 0x78, 0x0F, 0x80, 0x18, 0x01, 0x80, 0x3C, 0x07, 0x80, 0xD8, 0x73, 0xFC, 0x3F, 0x00,
/* '4' 0x34 */ 0x01, 0x80, 0x70, 0x0E, 0x03, 0xC0, 0xD8, 0x1B, 0x06, 0x61, 0x8C, 0x21, 0x8C, 0x33, 0x06, 0x7F, 0xFF, 0xFE, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80,
/* '5' 0x35 */ 0x3F, 0xCF, 0xF9, 0x80, 0x30, 0x06, 0x00, 0xDE, 0x1F, 0xE7, 0x0E, 0x00, 0xE0, 0x0C, 0x01, 0x80, 0x30, 0x07, 0x81, 0xB8, 0x73, 0xFC, 0x1F, 0x00,
/* '6' 0x36 */ 0x0F, 0x07, 0xF9, 0xC3, 0x30, 0x74, 0x01, 0x80, 0x33, 0xC7, 0xFE, 0xF1, 0xDC, 0x1F, 0x01, 0xE0, 0x3C, 0x06, 0xC1, 0xDC, 0x71, 0xFC, 0x1F, 0x00,
/* '7' 0x37 */ 0xFF, 0xFF, 0xFC, 0x01, 0x00, 0x60, 0x18, 0x02, 0x00, 0xC0, 0x30, 0x06, 0x01, 0x80, 0x30, 0x04, 0x01, 0x80, 0x30, 0x06, 0x01, 0x80, 0x30, 0x00,
/* '8' 0x38 */ 0x1F, 0x07, 0xF1, 0xC7, 0x30, 0x66, 0x0C, 0xC1, 0x8C, 0x61, 0xF8, 0x3F, 0x8E, 0x3B, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xD8, 0x31, 0xFC, 0x1F, 0x00,
/* '9' 0x39 */ 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x6C, 0x07, 0x80, 0xF0, 0x1E, 0x07, 0x61, 0xEF, 0xFC, 0x79, 0x80, 0x30, 0x05, 0xC1, 0x98, 0x73, 0xFC, 0x1E, 0x00,
/* ':' 0x3A */ 0xF0, 0x00, 0x03, 0xC0,
/* ';' 0x3B */ 0xF0, 0x00, 0x0F, 0x56,
/* '<' 0x3C */ 0x00, 0x70, 0x1E, 0x0F, 0x83, 0xC0, 0xF0, 0x0E, 0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x10,
/* '=' 0x3D */ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
/* '>' 0x3E */ 0xE0, 0x07, 0x80, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x07, 0x01, 0xE0, 0xF0, 0x3C, 0x0F, 0x00, 0x80, 0x00,
/* '?' 0x3F */ 0x3F, 0x1F, 0xEE, 0x1F, 0x03, 0xC0, 0xC0, 0x30, 0x0C, 0x06, 0x03, 0x81, 0xC0, 0xE0, 0x30, 0x0C, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x03, 0x00,
/* '@' 0x40 */ 0x00, 0xFE, 0x00, 0x0F, 0xFE, 0x00, 0xF0, 0x3E, 0x07, 0x00, 0x3C, 0x38, 0x00, 0x38, 0xC1, 0xE0, 0x66, 0x0F, 0xD9, 0xD8, 0x61, 0xC3, 0xC3, 0x07, 0x0F, 0x1C, 0x1C, 0x3C, 0x60, 0x60, 0xF1, 0x81, 0x83, 0xC6, 0x06, 0x1B, 0x18, 0x38, 0xEE, 0x71, 0xE7, 0x18, 0xFD, 0xF8, 0x71, 0xE7, 0xC0, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x01, 0xFF, 0xC0, 0x01, 0xFC, 0x00,
/* 'A' 0x41 */ 0x07, 0x80, 0x1E, 0x00, 0x78, 0x03, 0xF0, 0x0C, 0xC0, 0x33, 0x01, 0xCE, 0x06, 0x18, 0x18, 0x60, 0xE1, 0xC3, 0x03, 0x0F, 0xFC, 0x7F, 0xF9, 0x80, 0x66, 0x01, 0xB8, 0x07, 0xC0, 0x0F, 0x00, 0x30,
/* 'B' 0x42 */ 0xFF, 0xC7, 0xFF, 0x30, 0x1D, 0x80, 0x6C, 0x03, 0x60, 0x1B, 0x00, 0xD8, 0x0C, 0xFF, 0xC7, 0xFF, 0x30, 0x0D, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x06, 0xFF, 0xF7, 0xFE, 0x00,
/* 'C' 0x43 */ 0x07, 0xE0, 0x3F, 0xF0, 0xE0, 0x73, 0x80, 0x76, 0x00, 0x6C, 0x00, 0x30, 0x00, 0x60, 0x00, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x00, 0x0E, 0x00, 0x6C, 0x00, 0xDC, 0x03, 0x1E, 0x0E, 0x1F, 0xF8, 0x0F, 0xC0,
/* 'D' 0x44 */ 0xFF, 0xC3, 0xFF, 0x8C, 0x07, 0x30, 0x0E, 0xC0, 0x1B, 0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x1F, 0x00, 0x6C, 0x03, 0xB0, 0x1C, 0xFF, 0xE3, 0xFE, 0x00,
/* 'E' 0x45 */ 0xFF, 0xFF, 0xFF, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xEF, 0xFE, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xFF, 0xFF,
/* 'F' 0x46 */ 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xFF, 0xDF, 0xFB, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x00,
/* 'G' 0x47 */ 0x07, 0xF0, 0x1F, 0xFC, 0x3C, 0x1E, 0x70, 0x07, 0x60, 0x03, 0xE0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x7F, 0xC0, 0x7F, 0xC0, 0x03, 0xC0, 0x03, 0x60, 0x03, 0x60, 0x07, 0x30, 0x0F, 0x3C, 0x1F, 0x1F, 0xFB, 0x07, 0xE1,
/* 'H' 0x48 */ 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xC0,
/* 'I' 0x49 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
/* 'J' 0x4A */ 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x3C, 0x1E, 0x0F, 0x07, 0xC7, 0x7F, 0x1F, 0x00,
/* 'K' 0x4B */ 0xC0, 0x3E, 0x03, 0xB0, 0x39, 0x83, 0x8C, 0x38, 0x63, 0x83, 0x38, 0x19, 0xC0, 0xDE, 0x07, 0xB8, 0x38, 0xE1, 0x83, 0x0C, 0x1C, 0x60, 0x73, 0x01, 0x98, 0x0E, 0xC0, 0x3E, 0x00, 0xC0,
/* 'L' 0x4C */ 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xFF, 0xFF, 0xF0,
/* 'M' 0x4D */ 0xE0, 0x07, 0xE0, 0x07, 0xF0, 0x0F, 0xF0, 0x0F, 0xD0, 0x0F, 0xD8, 0x1B, 0xD8, 0x1B, 0xD8, 0x1B, 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33, 0xC6, 0x63, 0xC6, 0x63, 0xC6, 0x63, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC1, 0x83,
/* 'N' 0x4E */ 0xE0, 0x1F, 0x00, 0xFC, 0x07, 0xE0, 0x3D, 0x81, 0xEE, 0x0F, 0x30, 0x79, 0xC3, 0xC6, 0x1E, 0x18, 0xF0, 0xE7, 0x83, 0x3C, 0x1D, 0xE0, 0x6F, 0x01, 0xF8, 0x0F, 0xC0, 0x3E, 0x01, 0xC0,
/* 'O' 0x4F */ 0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0x07, 0x86, 0x00, 0xC6, 0x00, 0x33, 0x00, 0x1B, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x36, 0x00, 0x33, 0x00, 0x18, 0xC0, 0x18, 0x78, 0x3C, 0x1F, 0xFC, 0x03, 0xF8, 0x00,
/* 'P' 0x50 */ 0xFF, 0x8F, 0xFE, 0xC0, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x06, 0xFF, 0xEF, 0xFC, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00,
/* 'Q' 0x51 */ 0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0x07, 0x86, 0x00, 0xC6, 0x00, 0x33, 0x00, 0x1B, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x36, 0x00, 0x33, 0x01, 0x98, 0xC0, 0xFC, 0x78, 0x3C, 0x1F, 0xFF, 0x03, 0xF9, 0x80, 0x00, 0x40,
/* 'R' 0x52 */ 0xFF, 0xE3, 0xFF, 0xCC, 0x03, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x6C, 0x01, 0xB0, 0x0C, 0xFF, 0xE3, 0xFF, 0xCC, 0x03, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x6C, 0x01, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x70,
/* 'S' 0x53 */ 0x0F, 0xE0, 0x7F, 0xC3, 0x83, 0x98, 0x07, 0x60, 0x0D, 0x80, 0x07, 0x00, 0x1E, 0x00, 0x3F, 0x80, 0x3F, 0xC0, 0x0F, 0x80, 0x07, 0xC0, 0x0F, 0x00, 0x3E, 0x00, 0xDE, 0x0E, 0x3F, 0xF0, 0x3F, 0x80,
/* 'T' 0x54 */ 0xFF, 0xFF, 0xFF, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60,
/* 'U' 0x55 */ 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x80, 0xEE, 0x0E, 0x3F, 0xE0, 0xFC, 0x00,
/* 'V' 0x56 */ 0xC0, 0x0F, 0x00, 0x7E, 0x01, 0x98, 0x06, 0x60, 0x39, 0xC0, 0xC3, 0x03, 0x0C, 0x1C, 0x38, 0x60, 0x61, 0x81, 0x8E, 0x07, 0x30, 0x0C, 0xC0, 0x37, 0x00, 0xF8, 0x01, 0xE0, 0x07, 0x80, 0x1C, 0x00,
/* 'W' 0x57 */ 0xE0, 0x30, 0x1D, 0x80, 0xE0, 0x76, 0x07, 0x81, 0xDC, 0x1E, 0x06, 0x70, 0x7C, 0x18, 0xC1, 0xB0, 0xE3, 0x0C, 0xC3, 0x8C, 0x33, 0x0C, 0x38, 0xC6, 0x30, 0x67, 0x18, 0xC1, 0x98, 0x67, 0x06, 0x61, 0xD8, 0x1D, 0x83, 0x60, 0x3C, 0x0D, 0x80, 0xF0, 0x3E, 0x03, 0xC0, 0x70, 0x0F, 0x01, 0xC0, 0x18, 0x07, 0x00,
/* 'X' 0x58 */ 0xE0, 0x1D, 0x80, 0xE7, 0x03, 0x0E, 0x1C, 0x18, 0x60, 0x73, 0x00, 0xFC, 0x01, 0xE0, 0x07, 0x00, 0x1E, 0x00, 0xF8, 0x03, 0x30, 0x1C, 0xE0, 0xE1, 0x83, 0x07, 0x1C, 0x0E, 0xE0, 0x1B, 0x00, 0x70,
/* 'Y' 0x59 */ 0xC0, 0x0F, 0x80, 0x76, 0x01, 0x9C, 0x0C, 0x38, 0x70, 0x61, 0x81, 0xCE, 0x03, 0x30, 0x0F, 0x80, 0x1E, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00,
/* 'Z' 0x5A */ 0xFF, 0xFF, 0xFF, 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0x60, 0x07, 0x00, 0x70, 0x07, 0x00, 0x30, 0x03, 0x80, 0x38, 0x03, 0x80, 0x18, 0x01, 0xC0, 0x1C, 0x00, 0xFF, 0xFF, 0xFF, 0xC0,
/* '[' 0x5B */ 0xFF, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCF, 0xF0,
/* '\' 0x5C */ 0x81, 0x81, 0x02, 0x06, 0x04, 0x08, 0x18, 0x10, 0x20, 0x60, 0x40, 0x81, 0x81, 0x02, 0x06, 0x04,
/* ']' 0x5D */ 0xFF, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0xF0,
/* '^' 0x5E */ 0x0C, 0x0E, 0x05, 0x86, 0xC3, 0x21, 0x19, 0x8C, 0x83, 0xC1, 0x80,
/* '_' 0x5F */ 0xFF, 0xFE,
/* '`' 0x60 */ 0xE3, 0x8C, 0x30,
/* 'a' 0x61 */ 0x3F, 0x07, 0xF8, 0xE1, 0xCC, 0x0C, 0x00, 0xC0, 0x1C, 0x3F, 0xCF, 0x8C, 0xC0, 0xCC, 0x0C, 0xE3, 0xC7, 0xEF, 0x3C, 0x70,
/* 'b' 0x62 */ 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0xF8, 0xDF, 0xCF, 0x0E, 0xE0, 0x7C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xE0, 0x6F, 0x0E, 0xDF, 0xCC, 0xF8,
/* 'c' 0x63 */ 0x1F, 0x0F, 0xE6, 0x1F, 0x83, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x38, 0x37, 0x1C, 0xFE, 0x1F, 0x00,
/* 'd' 0x64 */ 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x3C, 0xCF, 0xFB, 0x8F, 0xE0, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF8, 0x3B, 0x8F, 0x3F, 0x63, 0xCC,
/* 'e' 0x65 */ 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x3C, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0xC0, 0x1C, 0x0D, 0xC3, 0x1F, 0xC1, 0xF0,
/* 'f' 0x66 */ 0x3B, 0xD8, 0xC6, 0x7F, 0xEC, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x00,
/* 'g' 0x67 */ 0x1E, 0x67, 0xFD, 0xC7, 0xF0, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x7C, 0x1D, 0xC7, 0x9F, 0xB1, 0xE6, 0x00, 0xC0, 0x3E, 0x0E, 0x7F, 0xC7, 0xE0,
/* 'h' 0x68 */ 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x33, 0xCD, 0xFB, 0xC7, 0xE0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x30,
/* 'i' 0x69 */ 0xF0, 0x3F, 0xFF, 0xFF, 0xF0,
/* 'j' 0x6A */ 0x33, 0x00, 0x03, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0xE0,
/* 'k' 0x6B */ 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x6C, 0x33, 0x18, 0xCC, 0x37, 0x0F, 0xC3, 0xB8, 0xC6, 0x31, 0xCC, 0x3B, 0x06, 0xC1, 0xF0, 0x30,
/* 'l' 0x6C */ 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
/* 'm' 0x6D */ 0xCF, 0x1F, 0x6F, 0xDF, 0xFC, 0x78, 0xFC, 0x18, 0x3C, 0x0C, 0x1E, 0x06, 0x0F, 0x03, 0x07, 0x81, 0x83, 0xC0, 0xC1, 0xE0, 0x60, 0xF0, 0x30, 0x78, 0x18, 0x3C, 0x0C, 0x18,
/* 'n' 0x6E */ 0xCF, 0x37, 0xEF, 0x1F, 0x83, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xC0,
/* 'o' 0x6F */ 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x7C, 0x1D, 0xC7, 0x1F, 0xC1, 0xF0,
/* 'p' 0x70 */ 0xCF, 0x8D, 0xFC, 0xF0, 0xEE, 0x06, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3E, 0x06, 0xF0, 0xEF, 0xFC, 0xCF, 0x8C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x00,
/* 'q' 0x71 */ 0x1E, 0x67, 0xFD, 0xC7, 0xF0, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x7C, 0x1D, 0xC7, 0x9F, 0xF1, 0xE6, 0x00, 0xC0, 0x18, 0x03, 0x00, 0x60,
/* 'r' 0x72 */ 0xCF, 0x7F, 0x38, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC0,
/* 's' 0x73 */ 0x3E, 0x1F, 0xEE, 0x1B, 0x00, 0xC0, 0x3C, 0x07, 0xF0, 0x3F, 0x01, 0xF0, 0x3E, 0x1D, 0xFE, 0x3F, 0x00,
/* 't' 0x74 */ 0x63, 0x19, 0xFF, 0xB1, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0xE7,
/* 'u' 0x75 */ 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x7E, 0x3D, 0xFB, 0x3C, 0xC0,
/* 'v' 0x76 */ 0xE0, 0x6C, 0x0D, 0x81, 0xB8, 0x63, 0x0C, 0x61, 0x8E, 0x60, 0xCC, 0x19, 0x83, 0xE0, 0x3C, 0x07, 0x00, 0xE0,
/* 'w' 0x77 */ 0xC1, 0xC1, 0xB0, 0xE1, 0xD8, 0x70, 0xCC, 0x2C, 0x66, 0x36, 0x31, 0x9B, 0x18, 0xCD, 0x98, 0x64, 0x6C, 0x16, 0x36, 0x0F, 0x1A, 0x07, 0x8F, 0x03, 0x83, 0x80, 0xC1, 0xC0,
/* 'x' 0x78 */ 0xC1, 0xF8, 0x66, 0x30, 0xCC, 0x3E, 0x07, 0x00, 0xC0, 0x78, 0x36, 0x0C, 0xC6, 0x3B, 0x06, 0xC0, 0xC0,
/* 'y' 0x79 */ 0xE0, 0x6C, 0x0D, 0x83, 0x38, 0x63, 0x0C, 0x63, 0x0C, 0x60, 0xCC, 0x1B, 0x03, 0x60, 0x3C, 0x07, 0x00, 0xE0, 0x18, 0x03, 0x00, 0xE0, 0x78, 0x0E, 0x00,
/* 'z' 0x7A */ 0xFF, 0xFF, 0xF0, 0x18, 0x0C, 0x07, 0x03, 0x81, 0xC0, 0x60, 0x30, 0x18, 0x0E, 0x03, 0xFF, 0xFF, 0xC0,
/* '{' 0x7B */ 0x19, 0xCC, 0x63, 0x18, 0xC6, 0x31, 0x99, 0x86, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x1C, 0x60,
/* '|' 0x7C */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
/* '}' 0x7D */ 0xC7, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x0C, 0x33, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x73, 0x00,
/* '~' 0x7E */ 0x70, 0x3E, 0x09, 0xE4, 0x1F, 0x03, 0x80,
/* 0x7F */
/* 0x80 */ 0x01, 0xF0, 0x1F, 0xF0, 0xE0, 0xC7, 0x00, 0x18, 0x00, 0xC0, 0x07, 0xFF, 0x3F, 0xFC, 0x30, 0x01, 0xFF, 0x8F, 0xFC, 0x0C, 0x00, 0x18, 0x00, 0x70, 0x00, 0xE0, 0x81, 0xFE, 0x03, 0xF0,
/* 0x81 */
/* 0x82 */ 0xF5, 0x80,
/* 0x83 */ 0x1C, 0xF3, 0x0C, 0x31, 0xF7, 0xCC, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x33, 0xCE, 0x00,
/* 0x84 */ 0xCF, 0x34, 0x51, 0x88,
/* 0x85 */ 0xC6, 0x3C, 0x63,
/* 0x86 */ 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x3F, 0xFF, 0xFC, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x00,
/* 0x87 */ 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x3F, 0xFF, 0xFC, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x0F, 0xFF, 0xFF, 0x0C, 0x03, 0x00, 0xC0, 0x30,
/* 0x88 */ 0x38, 0xD9, 0xB6, 0x30,
/* 0x89 */ 0x38, 0x18, 0x00, 0xF8, 0x30, 0x03, 0x18, 0xC0, 0x04, 0x11, 0x80, 0x0C, 0x66, 0x00, 0x0F, 0x8C, 0x00, 0x0E, 0x30, 0x00, 0x00, 0x40, 0x00, 0x01, 0x80, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x31, 0xC0, 0xE0, 0x67, 0xC3, 0xC1, 0x98, 0xCC, 0xC3, 0x20, 0x90, 0x8C, 0x63, 0x33, 0x10, 0x7C, 0x3C, 0x60, 0x70, 0x38,
/* 0x8A */ 0x0C, 0x40, 0x1F, 0x00, 0x38, 0x03, 0xF8, 0x1F, 0xF0, 0xE0, 0xE6, 0x01, 0xD8, 0x03, 0x60, 0x01, 0xC0, 0x07, 0x80, 0x0F, 0xE0, 0x0F, 0xF0, 0x03, 0xE0, 0x01, 0xF0, 0x03, 0xC0, 0x0F, 0x80, 0x37, 0x83, 0x8F, 0xFC, 0x0F, 0xE0,
/* 0x8B */ 0x2F, 0x49, 0x99,
/* 0x8C */ 0x07, 0xCF, 0xFC, 0x7F, 0xFF, 0xF3, 0x83, 0xC0, 0x18, 0x07, 0x00, 0x60, 0x0C, 0x03, 0x00, 0x30, 0x0C, 0x00, 0xC0, 0x30, 0x03, 0x00, 0xC0, 0x0F, 0xFF, 0x00, 0x3F, 0xFC, 0x00, 0xC0, 0x30, 0x03, 0x00, 0xC0, 0x0C, 0x01, 0x80, 0x30, 0x07, 0x01, 0xC0, 0x0E, 0x0F, 0x00, 0x1F, 0xEF, 0xFC, 0x1F, 0x3F, 0xF0,
/* 0x8D */
/* 0x8E */ 0x0C, 0xC0, 0x3C, 0x00, 0xE1, 0xFF, 0xFF, 0xFF, 0x80, 0x1C, 0x01, 0xC0, 0x1C, 0x00, 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0x60, 0x07, 0x00, 0x70, 0x07, 0x00, 0x30, 0x03, 0x80, 0x38, 0x01, 0xFF, 0xFF, 0xFF, 0x80,
/* 0x8F */
/* 0x90 */
/* 0x91 */ 0x6A, 0xF0,
/* 0x92 */ 0xF5, 0x60,
/* 0x93 */ 0x4E, 0x28, 0xA2, 0xCF, 0x30,
/* 0x94 */ 0xCF, 0x34, 0x51, 0x4E, 0x20,
/* 0x95 */ 0x7B, 0xFF, 0xFF, 0xFD, 0xE0,
/* 0x96 */ 0xFF, 0xFF, 0xF0,
/* 0x97 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
/* 0x98 */ 0x63, 0xFE, 0x70,
/* 0x99 */ 0xFF, 0x70, 0x1F, 0xFD, 0xC0, 0x71, 0x87, 0x83, 0xC6, 0x1E, 0x0F, 0x18, 0x68, 0x3C, 0x61, 0xB1, 0xB1, 0x86, 0xC6, 0xC6, 0x19, 0x1B, 0x18, 0x66, 0xCC, 0x61, 0x9B, 0x31, 0x86, 0x3C, 0xC6, 0x18, 0xE3, 0x18, 0x63, 0x8C,
/* 0x9A */ 0x63, 0x0D, 0x83, 0x60, 0x70, 0x00, 0x0F, 0x87, 0xFB, 0x86, 0xC0, 0x30, 0x0F, 0x01, 0xFC, 0x0F, 0xC0, 0x7C, 0x0F, 0x87, 0x7F, 0x8F, 0xC0,
/* 0x9B */ 0x99, 0x92, 0xF4,
/* 0x9C */ 0x1F, 0x0F, 0x83, 0xF9, 0xFC, 0x71, 0xF8, 0x6E, 0x0F, 0x03, 0xC0, 0x60, 0x3C, 0x07, 0xFF, 0xC0, 0x7F, 0xFC, 0x06, 0x00, 0xC0, 0x60, 0x0E, 0x0F, 0x03, 0x71, 0xF8, 0x63, 0xF9, 0xFC, 0x1F, 0x0F, 0x80,
/* 0x9D */
/* 0x9E */ 0x63, 0x0C, 0x83, 0x60, 0x70, 0x00, 0x3F, 0xFF, 0xFC, 0x06, 0x03, 0x01, 0xC0, 0xE0, 0x70, 0x18, 0x0C, 0x06, 0x03, 0x80, 0xFF, 0xFF, 0xF0,
/* 0x9F */ 0x0C, 0xC0, 0x33, 0x00, 0x00, 0x30, 0x03, 0xE0, 0x1D, 0x80, 0x67, 0x03, 0x0E, 0x1C, 0x18, 0x60, 0x73, 0x80, 0xCC, 0x03, 0xE0, 0x07, 0x80, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00,
/* 0xA0 */
/* 0xA1 */ 0xF0, 0xBF, 0xFF, 0xFF, 0xF0,
/* 0xA2 */ 0x04, 0x00, 0x80, 0x7C, 0x1F, 0xE7, 0x4C, 0xC8, 0xF1, 0x1E, 0x20, 0xC4, 0x18, 0x83, 0x10, 0x72, 0x37, 0x4E, 0x7F, 0x87, 0xC0, 0x20, 0x04, 0x00,
/* 0xA3 */ 0x0F, 0xC1, 0xFE, 0x38, 0x76, 0x03, 0x60, 0x36, 0x00, 0x70, 0x03, 0x80, 0xFF, 0x0F, 0xF0, 0x1C, 0x00, 0xC0, 0x0C, 0x01, 0x80, 0x10, 0x02, 0xF1, 0x7F, 0xF6, 0x1F,
/* 0xA4 */ 0xDD, 0xFF, 0xD8, 0xD8, 0x3C, 0x1E, 0x0F, 0x8D, 0xFF, 0xDD, 0x80,
/* 0xA5 */ 0xC0, 0x3E, 0x06, 0x60, 0x63, 0x0C, 0x30, 0xC1, 0x98, 0x19, 0x80, 0xF0, 0x0F, 0x07, 0xFE, 0x06, 0x00, 0x60, 0x7F, 0xE0, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00,
/* 0xA6 */ 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFC,
/* 0xA7 */ 0x0F, 0x03, 0xF0, 0xE7, 0x18, 0x63, 0x0C, 0x70, 0x07, 0x03, 0xF8, 0xC3, 0x98, 0x3B, 0x03, 0xF0, 0x37, 0x06, 0x78, 0xC7, 0xB0, 0x7C, 0x03, 0x80, 0x39, 0x83, 0x30, 0x67, 0x1C, 0x7F, 0x07, 0xC0,
/* 0xA8 */ 0xCF, 0x30,
/* 0xA9 */ 0x03, 0xF0, 0x03, 0xFF, 0x01, 0xE0, 0xE0, 0xE3, 0x1C, 0x73, 0xF3, 0x99, 0x86, 0x6C, 0xC1, 0x8F, 0x30, 0x03, 0xCC, 0x00, 0xF3, 0x00, 0x3C, 0xC1, 0x8D, 0x98, 0x66, 0x77, 0xF3, 0x8E, 0x79, 0xC1, 0xC0, 0xE0, 0x3F, 0xF0, 0x03, 0xF0, 0x00,
/* 0xAA */ 0x79, 0x08, 0x11, 0xEE, 0x50, 0xA3, 0x3B, 0x00, 0x03, 0xF8,
/* 0xAB */ 0x21, 0x63, 0xE7, 0x84, 0x84, 0xE7, 0x63, 0x21,
/* 0xAC */ 0xFF, 0xFF, 0xFF, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03,
/* 0xAD */ 0xFF, 0xF0,
/* 0xAE */ 0x03, 0xF0, 0x03, 0xFF, 0x01, 0xE0, 0xE0, 0xFF, 0x1C, 0x7F, 0xF3, 0x9B, 0x04, 0x6C, 0xC1, 0x8F, 0x30, 0x43, 0xCF, 0xF0, 0xF3, 0xFC, 0x3C, 0xC1, 0x0D, 0xB0, 0x66, 0x7C, 0x1B, 0x8F, 0x07, 0xC1, 0xC0, 0xE0, 0x3F, 0xF0, 0x03, 0xF0, 0x00,
/* 0xAF */ 0xFF, 0xF0,
/* 0xB0 */ 0x38, 0xFB, 0x1C, 0x18, 0x38, 0xDF, 0x1C,
/* 0xB1 */ 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x7F, 0xE7, 0xFE, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF0,
/* 0xB2 */ 0x7D, 0x8F, 0x18, 0x30, 0xC6, 0x18, 0x60, 0xFF, 0xFC,
/* 0xB3 */ 0x7D, 0x8F, 0x18, 0x31, 0x80, 0xC1, 0xE3, 0xC6, 0xF8,
/* 0xB4 */ 0x3B, 0x99, 0x80,
/* 0xB5 */ 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x1C, 0xE3, 0xCF, 0xEF, 0xFC, 0x7C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x00,
/* 0xB6 */ 0x1F, 0xE7, 0xFD, 0xF3, 0x7E, 0x6F, 0xCD, 0xF9, 0xBF, 0x37, 0xE6, 0x7C, 0xCF, 0x98, 0xF3, 0x06, 0x60, 0xCC, 0x19, 0x83, 0x30, 0x66, 0x0C, 0xC1, 0x98, 0x33, 0x06, 0x60, 0xCC,
/* 0xB7 */ 0xF0,
/* 0xB8 */ 0x10, 0xF0, 0xE3, 0x78,
/* 0xB9 */ 0x2F, 0xB6, 0xDB, 0x6C,
/* 0xBA */ 0x79, 0x38, 0x61, 0x86, 0x1C, 0xDE, 0x00, 0x0F, 0xC0,
/* 0xBB */ 0x88, 0xC6, 0xE7, 0x21, 0x21, 0xE7, 0xC6, 0x88,
/* 0xBC */ 0x20, 0x08, 0x30, 0x0C, 0x38, 0x04, 0x0C, 0x06, 0x06, 0x02, 0x03, 0x02, 0x01, 0x81, 0x00, 0xC1, 0x06, 0x61, 0x87, 0x30, 0x83, 0x80, 0xC2, 0xC0, 0x42, 0x60, 0x43, 0x30, 0x21, 0xFC, 0x20, 0x0C, 0x30, 0x06, 0x10, 0x03, 0x00,
/* 0xBD */ 0x20, 0x00, 0x08, 0x02, 0x06, 0x01, 0x83, 0x80, 0x40, 0x60, 0x20, 0x18, 0x18, 0x06, 0x04, 0x01, 0x83, 0x00, 0x61, 0x9F, 0x98, 0x4E, 0x76, 0x33, 0x0C, 0x08, 0x03, 0x04, 0x03, 0x83, 0x01, 0x80, 0x81, 0x80, 0x60, 0xC0, 0x30, 0x3F, 0xC8, 0x0F, 0xF0,
/* 0xBE */ 0x7C, 0x00, 0x18, 0xC0, 0x43, 0x18, 0x18, 0x03, 0x02, 0x00, 0x60, 0xC0, 0x30, 0x10, 0x01, 0x84, 0x00, 0x31, 0x80, 0xC6, 0x20, 0xD8, 0xC8, 0x39, 0xF1, 0x07, 0x00, 0x41, 0x60, 0x18, 0x4C, 0x02, 0x11, 0x80, 0x83, 0xF8, 0x10, 0x06, 0x04, 0x00, 0xC1, 0x00, 0x18,
/* 0xBF */ 0x0C, 0x06, 0x00, 0x00, 0x00, 0xC0, 0x60, 0x60, 0x30, 0x30, 0x38, 0x38, 0x18, 0x0C, 0x06, 0x0F, 0x07, 0xC7, 0x7F, 0x1F, 0x00,
/* 0xC0 */ 0x0C, 0x00, 0x18, 0x00, 0x30, 0x00, 0x00, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x03, 0xF0, 0x0C, 0xC0, 0x33, 0x01, 0xCE, 0x06, 0x18, 0x18, 0x60, 0xE1, 0xC3, 0x03, 0x0F, 0xFC, 0x7F, 0xF9, 0x80, 0x66, 0x01, 0xB8, 0x07, 0xC0, 0x0F, 0x00, 0x30,
/* 0xC1 */ 0x01, 0xC0, 0x0C, 0x00, 0x20, 0x00, 0x00, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x03, 0xF0, 0x0C, 0xC0, 0x33, 0x01, 0xCE, 0x06, 0x18, 0x18, 0x60, 0xE1, 0xC3, 0x03, 0x0F, 0xFC, 0x7F, 0xF9, 0x80, 0x66, 0x01, 0xB8, 0x07, 0xC0, 0x0F, 0x00, 0x30,
/* 0xC2 */ 0x07, 0x00, 0x3E, 0x01, 0x8C, 0x00, 0x00, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x03, 0xF0, 0x0C, 0xC0, 0x33, 0x01, 0xCE, 0x06, 0x18, 0x18, 0x60, 0xE1, 0xC3, 0x03, 0x0F, 0xFC, 0x7F, 0xF9, 0x80, 0x66, 0x01, 0xB8, 0x07, 0xC0, 0x0F, 0x00, 0x30,
/* 0xC3 */ 0x0E, 0x40, 0x7F, 0x01, 0x98, 0x00, 0x00, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x03, 0xF0, 0x0C, 0xC0, 0x33, 0x01, 0xCE, 0x06, 0x18, 0x18, 0x60, 0xE1, 0xC3, 0x03, 0x0F, 0xFC, 0x7F, 0xF9, 0x80, 0x66, 0x01, 0xB8, 0x07, 0xC0, 0x0F, 0x00, 0x30,
/* 0xC4 */ 0x0C, 0xC0, 0x33, 0x00, 0x00, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00, 0xFC, 0x03, 0x30, 0x0C, 0xC0, 0x73, 0x81, 0x86, 0x06, 0x18, 0x38, 0x70, 0xC0, 0xC3, 0xFF, 0x1F, 0xFE, 0x60, 0x19, 0x80, 0x6E, 0x01, 0xF0, 0x03, 0xC0, 0x0C,
/* 0xC5 */ 0x03, 0x00, 0x1E, 0x00, 0xEC, 0x03, 0x30, 0x0F, 0xC0, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x3F, 0x00, 0xCC, 0x03, 0x30, 0x1C, 0xE0, 0x61, 0x81, 0x86, 0x0E, 0x1C, 0x30, 0x30, 0xFF, 0xC7, 0xFF, 0x98, 0x06, 0x60, 0x1B, 0x80, 0x7C, 0x00, 0xF0, 0x03,
/* 0xC6 */ 0x01, 0xFF, 0xFC, 0x07, 0xFF, 0xF0, 0x31, 0x80, 0x00, 0xC6, 0x00, 0x07, 0x18, 0x00, 0x18, 0x60, 0x00, 0x61, 0x80, 0x03, 0x86, 0x00, 0x0C, 0x1F, 0xF8, 0x70, 0x7F, 0xE1, 0x81, 0x80, 0x07, 0xFE, 0x00, 0x3F, 0xF8, 0x00, 0xC0, 0x60, 0x07, 0x01, 0x80, 0x1C, 0x06, 0x00, 0x60, 0x1F, 0xFF, 0x80, 0x7F, 0xF0,
/* 0xC7 */ 0x07, 0xE0, 0x3F, 0xF0, 0xE0, 0x73, 0x80, 0x66, 0x00, 0x7C, 0x00, 0x30, 0x00, 0x60, 0x00, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x00, 0x0E, 0x00, 0x6C, 0x01, 0xDC, 0x03, 0x1C, 0x1E, 0x1F, 0xF8, 0x0F, 0xC0, 0x08, 0x00, 0x1E, 0x00, 0x0C, 0x01, 0x18, 0x01, 0xE0, 0x00,
/* 0xC8 */ 0x1C, 0x00, 0xC0, 0x02, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xEF, 0xFE, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xFF, 0xFF,
/* 0xC9 */ 0x07, 0x00, 0x60, 0x0C, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xEF, 0xFE, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xFF, 0xFF,
/* 0xCA */ 0x0E, 0x01, 0xF0, 0x31, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xEF, 0xFE, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xFF, 0xFF,
/* 0xCB */ 0x19, 0x81, 0x98, 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0F, 0xFE, 0xFF, 0xEC, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0F, 0xFF, 0xFF, 0xF0,
/* 0xCC */ 0xE7, 0x10, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
/* 0xCD */ 0x36, 0xC0, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
/* 0xCE */ 0x39, 0xFC, 0x40, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC0,
/* 0xCF */ 0xC7, 0x8C, 0x01, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x00,
/* 0xD0 */ 0x7F, 0xE0, 0xFF, 0xE1, 0x80, 0xE3, 0x00, 0xE6, 0x00, 0xCC, 0x01, 0xD8, 0x01, 0xB0, 0x03, 0xFE, 0x07, 0xFC, 0x0D, 0x80, 0x1B, 0x00, 0x36, 0x00, 0x6C, 0x01, 0x98, 0x07, 0x30, 0x1C, 0x7F, 0xF0, 0xFF, 0xC0,
/* 0xD1 */ 0x08, 0xC0, 0xFE, 0x05, 0xE0, 0x00, 0x0E, 0x01, 0xF0, 0x0F, 0xC0, 0x7E, 0x03, 0xD8, 0x1E, 0xE0, 0xF3, 0x07, 0x9C, 0x3C, 0x61, 0xE1, 0x8F, 0x0E, 0x78, 0x33, 0xC1, 0xDE, 0x06, 0xF0, 0x1F, 0x80, 0xFC, 0x03, 0xE0, 0x1C,
/* 0xD2 */ 0x07, 0x00, 0x01, 0x80, 0x00, 0x60, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xFF, 0xE0, 0xF0, 0x78, 0x60, 0x0C, 0x60, 0x03, 0x30, 0x01, 0xB0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x07, 0x80, 0x03, 0x60, 0x03, 0x30, 0x01, 0x8C, 0x01, 0x87, 0x83, 0xC1, 0xFF, 0xC0, 0x3F, 0x80,
/* 0xD3 */ 0x00, 0xE0, 0x00, 0x60, 0x00, 0x40, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xFF, 0xE0, 0xF0, 0x78, 0x60, 0x0C, 0x60, 0x03, 0x30, 0x01, 0xB0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x07, 0x80, 0x03, 0x60, 0x03, 0x30, 0x01, 0x8C, 0x01, 0x87, 0x83, 0xC1, 0xFF, 0xC0, 0x3F, 0x80,
/* 0xD4 */ 0x03, 0xC0, 0x01, 0xE0, 0x01, 0x98, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xFF, 0xE0, 0xF0, 0x78, 0x60, 0x0C, 0x60, 0x03, 0x30, 0x01, 0xB0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x07, 0x80, 0x03, 0x60, 0x03, 0x30, 0x01, 0x8C, 0x01, 0x87, 0x83, 0xC1, 0xFF, 0xC0, 0x3F, 0x80,
/* 0xD5 */ 0x07, 0x20, 0x03, 0xF0, 0x01, 0x38, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xFF, 0xE0, 0xF0, 0x78, 0x60, 0x0C, 0x60, 0x03, 0x30, 0x01, 0xB0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x07, 0x80, 0x03, 0x60, 0x03, 0x30, 0x01, 0x8C, 0x01, 0x87, 0x83, 0xC1, 0xFF, 0xC0, 0x3F, 0x80,
/* 0xD6 */ 0x06, 0x30, 0x03, 0x18, 0x00, 0x00, 0x00, 0xFE, 0x01, 0xFF, 0xC1, 0xE0, 0xF0, 0xC0, 0x18, 0xC0, 0x06, 0x60, 0x03, 0x60, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x06, 0xC0, 0x06, 0x60, 0x03, 0x18, 0x03, 0x0F, 0x07, 0x83, 0xFF, 0x80, 0x7F, 0x00,
/* 0xD7 */ 0x81, 0xC3, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0xC3, 0x81,
/* 0xD8 */ 0x07, 0xF0, 0x8F, 0xFE, 0x8F, 0x07, 0xC6, 0x00, 0xE6, 0x00, 0xF3, 0x00, 0xDF, 0x00, 0xC7, 0x80, 0xC3, 0xC0, 0xC1, 0xE0, 0xC0, 0xF0, 0xC0, 0x78, 0xC0, 0x3E, 0xC0, 0x33, 0xC0, 0x19, 0xC0, 0x1C, 0xF8, 0x3C, 0xDF, 0xF8, 0x43, 0xF8, 0x00,
/* 0xD9 */ 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x0C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF8, 0x0E, 0xE0, 0xE3, 0xFE, 0x0F, 0xC0,
/* 0xDA */ 0x03, 0x80, 0x18, 0x01, 0x80, 0x00, 0x0C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF8, 0x0E, 0xE0, 0xE3, 0xFE, 0x0F, 0xC0,
/* 0xDB */ 0x07, 0x00, 0x7C, 0x06, 0x20, 0x00, 0x0C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF8, 0x0E, 0xE0, 0xE3, 0xFE, 0x0F, 0xC0,
/* 0xDC */ 0x0C, 0xC0, 0x66, 0x00, 0x01, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1F, 0x01, 0xDC, 0x1C, 0x7F, 0xC1, 0xF8, 0x00,
/* 0xDD */ 0x01, 0x80, 0x0C, 0x00, 0x60, 0x00, 0x00, 0xC0, 0x0F, 0x80, 0x76, 0x01, 0x9C, 0x0C, 0x38, 0x70, 0x61, 0x81, 0xCE, 0x03, 0x30, 0x0F, 0x80, 0x1E, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00,
/* 0xDE */ 0xC0, 0x0C, 0x00, 0xC0, 0x0F, 0xF8, 0xFF, 0xEC, 0x06, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x6F, 0xFE, 0xFF, 0x8C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00,
/* 0xDF */ 0x1F, 0x0F, 0xF3, 0x87, 0x60, 0x6C, 0x0D, 0x81, 0xB0, 0x66, 0x38, 0xC7, 0xD8, 0x1B, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x3E, 0x0E, 0xCF, 0x99, 0xE0,
/* 0xE0 */ 0x1C, 0x00, 0xC0, 0x06, 0x00, 0x20, 0x00, 0x03, 0xF0, 0x7F, 0x8E, 0x1C, 0xC0, 0xC0, 0x0C, 0x01, 0xC3, 0xFC, 0xF8, 0xCC, 0x0C, 0xC0, 0xCE, 0x3C, 0x7E, 0xF3, 0xC7,
/* 0xE1 */ 0x07, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x00, 0x03, 0xF0, 0x7F, 0x8E, 0x1C, 0xC0, 0xC0, 0x0C, 0x01, 0xC3, 0xFC, 0xF8, 0xCC, 0x0C, 0xC0, 0xCE, 0x3C, 0x7E, 0xF3, 0xC7,
/* 0xE2 */ 0x0C, 0x01, 0xE0, 0x1B, 0x03, 0x30, 0x00, 0x03, 0xF0, 0x7F, 0x8E, 0x1C, 0xC0, 0xC0, 0x0C, 0x01, 0xC3, 0xFC, 0xF8, 0xCC, 0x0C, 0xC0, 0xCE, 0x3C, 0x7E, 0xF3, 0xC7,
/* 0xE3 */ 0x19, 0x83, 0xF0, 0x27, 0x00, 0x00, 0x00, 0x03, 0xF0, 0x7F, 0x8E, 0x1C, 0xC0, 0xC0, 0x0C, 0x01, 0xC3, 0xFC, 0xF8, 0xCC, 0x0C, 0xC0, 0xCE, 0x3C, 0x7E, 0xF3, 0xC7,
/* 0xE4 */ 0x19, 0x81, 0x98, 0x00, 0x00, 0x00, 0x3F, 0x07, 0xF8, 0xE1, 0xCC, 0x0C, 0x00, 0xC0, 0x1C, 0x3F, 0xCF, 0x8C, 0xC0, 0xCC, 0x0C, 0xE3, 0xC7, 0xEF, 0x3C, 0x70,
/* 0xE5 */ 0x0E, 0x01, 0xF0, 0x1B, 0x81, 0xB8, 0x1F, 0x00, 0xE0, 0x3F, 0x07, 0xF8, 0xE1, 0xCC, 0x0C, 0x00, 0xC0, 0x1C, 0x3F, 0xCF, 0x8C, 0xC0, 0xCC, 0x0C, 0xE3, 0xC7, 0xEF, 0x3C, 0x70,
/* 0xE6 */ 0x3F, 0x1F, 0x0F, 0xF7, 0xF3, 0x87, 0xC3, 0x60, 0x70, 0x30, 0x0C, 0x06, 0x3F, 0xFF, 0xDF, 0xFF, 0xFF, 0x06, 0x00, 0xC0, 0xC0, 0x18, 0x3C, 0x0F, 0x8F, 0xC7, 0x3F, 0x9F, 0xE3, 0xC1, 0xF0,
/* 0xE7 */ 0x1F, 0x0F, 0xE7, 0x1D, 0x83, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x38, 0x37, 0x1C, 0xFE, 0x1F, 0x02, 0x00, 0xE0, 0x0C, 0x23, 0x07, 0x80,
/* 0xE8 */ 0x1C, 0x01, 0x80, 0x18, 0x01, 0x00, 0x00, 0x3E, 0x0F, 0xE3, 0x8E, 0xE0, 0x78, 0x0F, 0xFF, 0xFF, 0xFC, 0x01, 0x80, 0x38, 0x1B, 0x86, 0x3F, 0x83, 0xE0,
/* 0xE9 */ 0x03, 0x00, 0xC0, 0x30, 0x04, 0x00, 0x00, 0x3E, 0x0F, 0xE3, 0x8E, 0xE0, 0x78, 0x0F, 0xFF, 0xFF, 0xFC, 0x01, 0x80, 0x38, 0x1B, 0x86, 0x3F, 0x83, 0xE0,
/* 0xEA */ 0x0C, 0x03, 0xC0, 0x6C, 0x18, 0x80, 0x00, 0x3E, 0x0F, 0xE3, 0x8E, 0xE0, 0x78, 0x0F, 0xFF, 0xFF, 0xFC, 0x01, 0x80, 0x38, 0x1B, 0x86, 0x3F, 0x83, 0xE0,
/* 0xEB */ 0x31, 0x86, 0x30, 0x00, 0x00, 0x01, 0xF0, 0x7F, 0x1C, 0x77, 0x03, 0xC0, 0x7F, 0xFF, 0xFF, 0xE0, 0x0C, 0x01, 0xC0, 0xDC, 0x31, 0xFC, 0x1F, 0x00,
/* 0xEC */ 0xC6, 0x31, 0x06, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
/* 0xED */ 0x39, 0x99, 0x80, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x80,
/* 0xEE */ 0x71, 0xED, 0xA3, 0x00, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC0,
/* 0xEF */ 0xCF, 0x30, 0x00, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30,
/* 0xF0 */ 0x20, 0x07, 0xE0, 0x70, 0x3B, 0x00, 0x30, 0x3F, 0x0F, 0xF3, 0x8E, 0xE0, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF8, 0x3B, 0x8E, 0x3F, 0x83, 0xE0,
/* 0xF1 */ 0x19, 0x8F, 0xE2, 0x70, 0x00, 0x00, 0x33, 0xCD, 0xFB, 0xC7, 0xE0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x30,
/* 0xF2 */ 0x1C, 0x01, 0x80, 0x18, 0x01, 0x00, 0x00, 0x3E, 0x0F, 0xE3, 0x8E, 0xE0, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF8, 0x3B, 0x8E, 0x3F, 0x83, 0xE0,
/* 0xF3 */ 0x07, 0x00, 0xC0, 0x30, 0x04, 0x00, 0x00, 0x3E, 0x0F, 0xE3, 0x8E, 0xE0, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF8, 0x3B, 0x8E, 0x3F, 0x83, 0xE0,
/* 0xF4 */ 0x0C, 0x03, 0xC0, 0xD8, 0x19, 0x80, 0x00, 0x3E, 0x0F, 0xE3, 0x8E, 0xE0, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF8, 0x3B, 0x8E, 0x3F, 0x83, 0xE0,
/* 0xF5 */ 0x19, 0x87, 0xE0, 0x9C, 0x00, 0x00, 0x00, 0x3E, 0x0F, 0xE3, 0x8E, 0xE0, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF8, 0x3B, 0x8E, 0x3F, 0x83, 0xE0,
/* 0xF6 */ 0x31, 0x86, 0x30, 0x00, 0x00, 0x01, 0xF0, 0x7F, 0x1C, 0x77, 0x07, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0xC1, 0xDC, 0x71, 0xFC, 0x1F, 0x00,
/* 0xF7 */ 0x06, 0x00, 0x60, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x06, 0x00,
/* 0xF8 */ 0x1F, 0x27, 0xF5, 0xC7, 0x70, 0x7C, 0x17, 0x84, 0xF1, 0x1E, 0x43, 0xD0, 0x7C, 0x1D, 0xC7, 0x3F, 0xC9, 0xF0,
/* 0xF9 */ 0x18, 0x03, 0x00, 0x60, 0x08, 0x00, 0x30, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x1F, 0x8F, 0x7E, 0xCF, 0x30,
/* 0xFA */ 0x03, 0x01, 0x80, 0x60, 0x30, 0x00, 0x30, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x1F, 0x8F, 0x7E, 0xCF, 0x30,
/* 0xFB */ 0x0C, 0x07, 0x81, 0x20, 0xCC, 0x00, 0x30, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x1F, 0x8F, 0x7E, 0xCF, 0x30,
/* 0xFC */ 0x31, 0x8C, 0x60, 0x00, 0x00, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x7E, 0x3D, 0xFB, 0x3C, 0xC0,
/* 0xFD */ 0x03, 0x80, 0x60, 0x18, 0x06, 0x00, 0x01, 0xC0, 0xD8, 0x1B, 0x06, 0x70, 0xC6, 0x18, 0xC6, 0x18, 0xC1, 0x98, 0x36, 0x06, 0xC0, 0x78, 0x0E, 0x01, 0xC0, 0x30, 0x06, 0x01, 0xC0, 0xF0, 0x1C, 0x00,
/* 0xFE */ 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xCF, 0x8F, 0xFC, 0xF0, 0xEE, 0x06, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3E, 0x06, 0xF0, 0xEF, 0xFC, 0xCF, 0x8C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x00,
/* 0xFF */ 0x19, 0x83, 0x30, 0x00, 0x00, 0x0E, 0x06, 0xC0, 0xD8, 0x33, 0x86, 0x30, 0xC6, 0x30, 0xC6, 0x0C, 0xC1, 0xB0, 0x36, 0x03, 0xC0, 0x70, 0x0E, 0x01, 0x80, 0x30, 0x0E, 0x07, 0x80, 0xE0, 0x00,
};
const GFXglyph FreeSans12pt_Win1252Glyphs[] PROGMEM = {
/* 0x01 */ { 0, 19, 20, 21, 1, -17 },
/* 0x02 */ { 48, 19, 20, 21, 1, -17 },
/* 0x03 */ { 96, 21, 20, 23, 1, -17 },
/* 0x04 */ { 149, 21, 20, 23, 1, -17 },
/* 0x05 */ { 202, 20, 20, 22, 1, -17 },
/* 0x06 */ { 252, 20, 20, 22, 1, -17 },
/* 0x07 */ { 302, 0, 0, 8, 0, 0 },
/* 0x08 */ { 302, 23, 20, 25, 1, -17 },
/* 0x09 */ { 360, 23, 16, 25, 1, -16 },
/* 0x0A */ { 406, 0, 0, 8, 0, 0 },
/* 0x0B */ { 406, 21, 20, 23, 1, -17 },
/* 0x0C */ { 459, 19, 18, 21, 1, -15 },
/* 0x0D */ { 502, 0, 0, 8, 0, 0 },
/* 0x0E */ { 502, 20, 20, 22, 1, -17 },
/* 0x0F */ { 552, 21, 21, 23, 1, -18 },
/* 0x10 */ { 608, 19, 20, 21, 1, -17 },
/* 0x11 */ { 656, 21, 20, 23, 1, -17 },
/* 0x12 */ { 709, 20, 20, 22, 1, -17 },
/* 0x13 */ { 759, 21, 20, 23, 1, -17 },
/* 0x14 */ { 812, 21, 20, 23, 1, -17 },
/* 0x15 */ { 865, 22, 20, 24, 1, -17 },
/* 0x16 */ { 920, 16, 20, 18, 1, -17 },
/* 0x17 */ { 960, 21, 20, 23, 1, -17 },
/* 0x18 */ { 1013, 23, 20, 25, 1, -17 },
/* 0x19 */ { 1071, 21, 20, 23, 1, -17 },
/* 0x1A */ { 1124, 15, 19, 17, 1, -16 },
/* 0x1B */ { 1160, 24, 21, 26, 1, -18 },
/* 0x1C */ { 1223, 21, 20, 23, 1, -17 },
/* 0x1D */ { 1276, 21, 21, 23, 1, -18 },
/* 0x1E */ { 1332, 20, 20, 22, 1, -17 },
/* 0x1F */ { 1382, 15, 20, 17, 1, -17 },
/* ' ' 0x20 */ { 1420, 0, 0, 6, 0, 0 },
/* '!' 0x21 */ { 1420, 2, 18, 8, 3, -16 },
/* '"' 0x22 */ { 1425, 6, 6, 8, 1, -15 },
/* '#' 0x23 */ { 1430, 13, 16, 13, 0, -14 },
/* '$' 0x24 */ { 1456, 11, 20, 13, 1, -16 },
/* '%' 0x25 */ { 1484, 20, 17, 21, 1, -15 },
/* '&' 0x26 */ { 1527, 14, 17, 16, 1, -15 },
/* ''' 0x27 */ { 1557, 2, 6, 5, 1, -15 },
/* '(' 0x28 */ { 1559, 5, 23, 8, 2, -16 },
/* ')' 0x29 */ { 1574, 5, 23, 8, 1, -16 },
/* '*' 0x2A */ { 1589, 7, 7, 9, 1, -16 },
/* '+' 0x2B */ { 1596, 10, 11, 14, 2, -9 },
/* ',' 0x2C */ { 1610, 2, 6, 7, 2, 0 },
/* '-' 0x2D */ { 1612, 6, 2, 8, 1, -6 },
/* '.' 0x2E */ { 1614, 2, 2, 6, 2, 0 },
/* '/' 0x2F */ { 1615, 7, 18, 7, 0, -16 },
/* '0' 0x30 */ { 1631, 11, 17, 13, 1, -15 },
/* '1' 0x31 */ { 1655, 5, 17, 13, 3, -15 },
/* '2' 0x32 */ { 1666, 11, 17, 13, 1, -15 },
/* '3' 0x33 */ { 1690, 11, 17, 13, 1, -15 },
/* '4' 0x34 */ { 1714, 11, 17, 13, 1, -15 },
/* '5' 0x35 */ { 1738, 11, 17, 13, 1, -15 },
/* '6' 0x36 */ { 1762, 11, 17, 13, 1, -15 },
/* '7' 0x37 */ { 1786, 11, 17, 13, 1, -15 },
/* '8' 0x38 */ { 1810, 11, 17, 13, 1, -15 },
/* '9' 0x39 */ { 1834, 11, 17, 13, 1, -15 },
/* ':' 0x3A */ { 1858, 2, 13, 6, 2, -11 },
/* ';' 0x3B */ { 1862, 2, 16, 6, 2, -10 },
/* '<' 0x3C */ { 1866, 12, 11, 14, 1, -9 },
/* '=' 0x3D */ { 1883, 12, 6, 14, 1, -7 },
/* '>' 0x3E */ { 1892, 12, 11, 14, 1, -9 },
/* '?' 0x3F */ { 1909, 10, 18, 13, 2, -16 },
/* '@' 0x40 */ { 1932, 22, 21, 24, 1, -16 },
/* 'A' 0x41 */ { 1990, 14, 18, 16, 1, -16 },
/* 'B' 0x42 */ { 2022, 13, 18, 16, 2, -16 },
/* 'C' 0x43 */ { 2052, 15, 18, 17, 1, -16 },
/* 'D' 0x44 */ { 2086, 14, 18, 17, 2, -16 },
/* 'E' 0x45 */ { 2118, 12, 18, 15, 2, -16 },
/* 'F' 0x46 */ { 2145, 11, 18, 14, 2, -16 },
/* 'G' 0x47 */ { 2170, 16, 18, 18, 1, -16 },
/* 'H' 0x48 */ { 2206, 13, 18, 17, 2, -16 },
/* 'I' 0x49 */ { 2236, 2, 18, 7, 2, -16 },
/* 'J' 0x4A */ { 2241, 9, 18, 13, 1, -16 },
/* 'K' 0x4B */ { 2262, 13, 18, 16, 2, -16 },
/* 'L' 0x4C */ { 2292, 10, 18, 14, 2, -16 },
/* 'M' 0x4D */ { 2315, 16, 18, 20, 2, -16 },
/* 'N' 0x4E */ { 2351, 13, 18, 18, 2, -16 },
/* 'O' 0x4F */ { 2381, 17, 18, 19, 1, -16 },
/* 'P' 0x50 */ { 2420, 12, 18, 16, 2, -16 },
/* 'Q' 0x51 */ { 2447, 17, 19, 19, 1, -16 },
/* 'R' 0x52 */ { 2488, 14, 18, 17, 2, -16 },
/* 'S' 0x53 */ { 2520, 14, 18, 16, 1, -16 },
/* 'T' 0x54 */ { 2552, 12, 18, 15, 1, -16 },
/* 'U' 0x55 */ { 2579, 13, 18, 17, 2, -16 },
/* 'V' 0x56 */ { 2609, 14, 18, 15, 1, -16 },
/* 'W' 0x57 */ { 2641, 22, 18, 22, 0, -16 },
/* 'X' 0x58 */ { 2691, 14, 18, 16, 1, -16 },
/* 'Y' 0x59 */ { 2723, 14, 18, 16, 1, -16 },
/* 'Z' 0x5A */ { 2755, 13, 18, 15, 1, -16 },
/* '[' 0x5B */ { 2785, 4, 23, 7, 2, -16 },
/* '\' 0x5C */ { 2797, 7, 18, 7, 0, -16 },
/* ']' 0x5D */ { 2813, 4, 23, 7, 1, -16 },
/* '^' 0x5E */ { 2825, 9, 9, 11, 1, -15 },
/* '_' 0x5F */ { 2836, 15, 1, 13, -1, 5 },
/* '`' 0x60 */ { 2838, 5, 4, 6, 1, -16 },
/* 'a' 0x61 */ { 2841, 12, 13, 13, 1, -11 },
/* 'b' 0x62 */ { 2861, 12, 18, 13, 1, -16 },
/* 'c' 0x63 */ { 2888, 10, 13, 12, 1, -11 },
/* 'd' 0x64 */ { 2905, 11, 18, 13, 1, -16 },
/* 'e' 0x65 */ { 2930, 11, 13, 13, 1, -11 },
/* 'f' 0x66 */ { 2948, 5, 18, 7, 1, -16 },
/* 'g' 0x67 */ { 2960, 11, 18, 13, 1, -11 },
/* 'h' 0x68 */ { 2985, 10, 18, 13, 1, -16 },
/* 'i' 0x69 */ { 3008, 2, 18, 5, 2, -16 },
/* 'j' 0x6A */ { 3013, 4, 23, 6, 0, -16 },
/* 'k' 0x6B */ { 3025, 10, 18, 12, 1, -16 },
/* 'l' 0x6C */ { 3048, 2, 18, 5, 1, -16 },
/* 'm' 0x6D */ { 3053, 17, 13, 19, 1, -11 },
/* 'n' 0x6E */ { 3081, 10, 13, 13, 1, -11 },
/* 'o' 0x6F */ { 3098, 11, 13, 13, 1, -11 },
/* 'p' 0x70 */ { 3116, 12, 17, 13, 1, -11 },
/* 'q' 0x71 */ { 3142, 11, 17, 13, 1, -11 },
/* 'r' 0x72 */ { 3166, 6, 13, 8, 1, -11 },
/* 's' 0x73 */ { 3176, 10, 13, 12, 1, -11 },
/* 't' 0x74 */ { 3193, 5, 16, 7, 1, -14 },
/* 'u' 0x75 */ { 3203, 10, 13, 13, 1, -11 },
/* 'v' 0x76 */ { 3220, 11, 13, 12, 0, -11 },
/* 'w' 0x77 */ { 3238, 17, 13, 17, 0, -11 },
/* 'x' 0x78 */ { 3266, 10, 13, 11, 1, -11 },
/* 'y' 0x79 */ { 3283, 11, 18, 11, 0, -11 },
/* 'z' 0x7A */ { 3308, 10, 13, 12, 1, -11 },
/* '{' 0x7B */ { 3325, 5, 23, 8, 1, -16 },
/* '|' 0x7C */ { 3340, 2, 23, 6, 2, -16 },
/* '}' 0x7D */ { 3346, 5, 23, 8, 2, -16 },
/* '~' 0x7E */ { 3361, 10, 5, 12, 1, -9 },
/* 0x7F */ { 3368, 0, 0, 0, 0, 0 },
/* 0x80 */ { 3368, 14, 17, 16, 1, -15 },
/* 0x81 */ { 3398, 0, 0, 8, 0, 0 },
/* 0x82 */ { 3398, 2, 5, 6, 2, 0 },
/* 0x83 */ { 3400, 6, 23, 7, 0, -16 },
/* 0x84 */ { 3418, 6, 5, 10, 2, 0 },
/* 0x85 */ { 3422, 12, 2, 16, 2, 0 },
/* 0x86 */ { 3425, 10, 21, 13, 2, -15 },
/* 0x87 */ { 3452, 10, 20, 13, 2, -15 },
/* 0x88 */ { 3477, 7, 4, 8, 0, -16 },
/* 0x89 */ { 3481, 23, 18, 24, 0, -16 },
/* 0x8A */ { 3533, 14, 21, 16, 1, -19 },
/* 0x8B */ { 3570, 3, 8, 6, 1, -9 },
/* 0x8C */ { 3573, 22, 18, 24, 1, -16 },
/* 0x8D */ { 3623, 0, 0, 8, 0, 0 },
/* 0x8E */ { 3623, 13, 21, 15, 1, -19 },
/* 0x8F */ { 3658, 0, 0, 8, 0, 0 },
/* 0x90 */ { 3658, 0, 0, 8, 0, 0 },
/* 0x91 */ { 3658, 2, 6, 6, 2, -16 },
/* 0x92 */ { 3660, 2, 6, 6, 2, -16 },
/* 0x93 */ { 3662, 6, 6, 10, 2, -16 },
/* 0x94 */ { 3667, 6, 6, 10, 2, -16 },
/* 0x95 */ { 3672, 6, 6, 10, 2, -9 },
/* 0x96 */ { 3677, 10, 2, 12, 1, -6 },
/* 0x97 */ { 3680, 22, 2, 24, 1, -6 },
/* 0x98 */ { 3686, 7, 3, 8, 0, -16 },
/* 0x99 */ { 3689, 22, 13, 24, 2, -16 },
/* 0x9A */ { 3725, 10, 18, 12, 1, -16 },
/* 0x9B */ { 3748, 3, 8, 6, 2, -8 },
/* 0x9C */ { 3751, 20, 13, 22, 1, -11 },
/* 0x9D */ { 3784, 0, 0, 8, 0, 0 },
/* 0x9E */ { 3784, 10, 18, 12, 1, -16 },
/* 0x9F */ { 3807, 14, 21, 16, 1, -19 },
/* 0xA0 */ { 3844, 0, 0, 7, 0, 0 },
/* 0xA1 */ { 3844, 2, 18, 8, 3, -11 },
/* 0xA2 */ { 3849, 11, 17, 13, 1, -13 },
/* 0xA3 */ { 3873, 12, 18, 13, 0, -16 },
/* 0xA4 */ { 3900, 9, 9, 13, 2, -11 },
/* 0xA5 */ { 3911, 12, 17, 13, 1, -15 },
/* 0xA6 */ { 3937, 2, 23, 6, 2, -16 },
/* 0xA7 */ { 3943, 11, 23, 13, 1, -16 },
/* 0xA8 */ { 3975, 6, 2, 8, 1, -15 },
/* 0xA9 */ { 3977, 18, 17, 19, 1, -15 },
/* 0xAA */ { 4016, 7, 11, 9, 1, -16 },
/* 0xAB */ { 4026, 8, 8, 12, 2, -9 },
/* 0xAC */ { 4034, 12, 6, 14, 1, -7 },
/* 0xAD */ { 4043, 6, 2, 8, 1, -6 },
/* 0xAE */ { 4045, 18, 17, 19, 1, -15 },
/* 0xAF */ { 4084, 6, 2, 8, 1, -15 },
/* 0xB0 */ { 4086, 7, 8, 15, 4, -15 },
/* 0xB1 */ { 4093, 12, 15, 14, 1, -13 },
/* 0xB2 */ { 4116, 7, 10, 8, 1, -17 },
/* 0xB3 */ { 4125, 7, 10, 8, 1, -17 },
/* 0xB4 */ { 4134, 5, 4, 8, 2, -16 },
/* 0xB5 */ { 4137, 12, 17, 13, 2, -11 },
/* 0xB6 */ { 4163, 11, 21, 13, 2, -16 },
/* 0xB7 */ { 4192, 2, 2, 6, 2, -6 },
/* 0xB8 */ { 4193, 6, 5, 8, 1, 2 },
/* 0xB9 */ { 4197, 3, 10, 8, 3, -18 },
/* 0xBA */ { 4201, 6, 11, 9, 1, -16 },
/* 0xBB */ { 4210, 8, 8, 12, 2, -8 },
/* 0xBC */ { 4218, 17, 17, 21, 3, -15 },
/* 0xBD */ { 4255, 18, 18, 21, 3, -16 },
/* 0xBE */ { 4296, 19, 18, 21, 1, -16 },
/* 0xBF */ { 4339, 9, 18, 13, 3, -11 },
/* 0xC0 */ { 4360, 14, 22, 16, 1, -20 },
/* 0xC1 */ { 4399, 14, 22, 16, 1, -20 },
/* 0xC2 */ { 4438, 14, 22, 16, 1, -20 },
/* 0xC3 */ { 4477, 14, 22, 16, 1, -20 },
/* 0xC4 */ { 4516, 14, 21, 16, 1, -19 },
/* 0xC5 */ { 4553, 14, 24, 16, 1, -22 },
/* 0xC6 */ { 4595, 22, 18, 24, 0, -16 },
/* 0xC7 */ { 4645, 15, 23, 17, 1, -16 },
/* 0xC8 */ { 4689, 12, 22, 15, 2, -20 },
/* 0xC9 */ { 4722, 12, 22, 15, 2, -20 },
/* 0xCA */ { 4755, 12, 22, 15, 2, -20 },
/* 0xCB */ { 4788, 12, 21, 15, 2, -19 },
/* 0xCC */ { 4820, 4, 22, 7, 0, -20 },
/* 0xCD */ { 4831, 4, 22, 7, 1, -20 },
/* 0xCE */ { 4842, 6, 22, 7, 0, -20 },
/* 0xCF */ { 4859, 7, 21, 7, 0, -19 },
/* 0xD0 */ { 4878, 15, 18, 17, 1, -16 },
/* 0xD1 */ { 4912, 13, 22, 18, 2, -20 },
/* 0xD2 */ { 4948, 17, 22, 19, 1, -20 },
/* 0xD3 */ { 4995, 17, 22, 19, 1, -20 },
/* 0xD4 */ { 5042, 17, 22, 19, 1, -20 },
/* 0xD5 */ { 5089, 17, 22, 19, 1, -20 },
/* 0xD6 */ { 5136, 17, 21, 19, 1, -19 },
/* 0xD7 */ { 5181, 8, 9, 14, 3, -8 },
/* 0xD8 */ { 5190, 17, 18, 19, 1, -16 },
/* 0xD9 */ { 5229, 13, 22, 17, 2, -20 },
/* 0xDA */ { 5265, 13, 22, 17, 2, -20 },
/* 0xDB */ { 5301, 13, 22, 17, 2, -20 },
/* 0xDC */ { 5337, 13, 21, 17, 2, -19 },
/* 0xDD */ { 5372, 14, 22, 16, 1, -20 },
/* 0xDE */ { 5411, 12, 18, 15, 2, -16 },
/* 0xDF */ { 5438, 11, 18, 14, 2, -16 },
/* 0xE0 */ { 5463, 12, 18, 13, 1, -16 },
/* 0xE1 */ { 5490, 12, 18, 13, 1, -16 },
/* 0xE2 */ { 5517, 12, 18, 13, 1, -16 },
/* 0xE3 */ { 5544, 12, 18, 13, 1, -16 },
/* 0xE4 */ { 5571, 12, 17, 13, 1, -15 },
/* 0xE5 */ { 5597, 12, 19, 13, 1, -17 },
/* 0xE6 */ { 5626, 19, 13, 21, 1, -11 },
/* 0xE7 */ { 5657, 10, 18, 12, 1, -11 },
/* 0xE8 */ { 5680, 11, 18, 13, 1, -16 },
/* 0xE9 */ { 5705, 11, 18, 13, 1, -16 },
/* 0xEA */ { 5730, 11, 18, 13, 1, -16 },
/* 0xEB */ { 5755, 11, 17, 13, 1, -15 },
/* 0xEC */ { 5779, 4, 18, 5, 1, -16 },
/* 0xED */ { 5788, 5, 18, 5, 0, -16 },
/* 0xEE */ { 5800, 6, 18, 6, 0, -16 },
/* 0xEF */ { 5814, 6, 17, 6, 0, -15 },
/* 0xF0 */ { 5827, 11, 18, 13, 1, -16 },
/* 0xF1 */ { 5852, 10, 18, 13, 1, -16 },
/* 0xF2 */ { 5875, 11, 18, 13, 1, -16 },
/* 0xF3 */ { 5900, 11, 18, 13, 1, -16 },
/* 0xF4 */ { 5925, 11, 18, 13, 1, -16 },
/* 0xF5 */ { 5950, 11, 18, 13, 1, -16 },
/* 0xF6 */ { 5975, 11, 17, 13, 1, -15 },
/* 0xF7 */ { 5999, 12, 11, 14, 1, -9 },
/* 0xF8 */ { 6016, 11, 13, 13, 1, -11 },
/* 0xF9 */ { 6034, 10, 18, 13, 1, -16 },
/* 0xFA */ { 6057, 10, 18, 13, 1, -16 },
/* 0xFB */ { 6080, 10, 18, 13, 1, -16 },
/* 0xFC */ { 6103, 10, 17, 13, 1, -15 },
/* 0xFD */ { 6125, 11, 23, 11, 0, -16 },
/* 0xFE */ { 6157, 12, 21, 13, 1, -15 },
/* 0xFF */ { 6189, 11, 22, 11, 0, -15 },
};
const GFXfont FreeSans12pt_Win1252 PROGMEM = {
(uint8_t*)FreeSans12pt_Win1252Bitmaps,
(GFXglyph*)FreeSans12pt_Win1252Glyphs,
0x01, 0xFF, 19
};
@@ -0,0 +1,527 @@
// trunk-ignore-all(clang-format)
#pragma once
/* PROPERTIES
FONT_NAME FreeSans12pt_Win1253
*/
const uint8_t FreeSans12pt_Win1253Bitmaps[] PROGMEM = {
/* 0x01 */ 0x00, 0x30, 0x00, 0x09, 0x00, 0x01, 0x20, 0x00, 0x24, 0x00, 0x04, 0x80, 0x01, 0x90, 0x00, 0x62, 0x00, 0x30, 0xFE, 0x04, 0x10, 0x5F, 0x02, 0x0B, 0x00, 0x7F, 0xE0, 0x0C, 0x1C, 0x02, 0x83, 0x81, 0x9F, 0xF0, 0x02, 0x1E, 0x00, 0x41, 0xC0, 0x0E, 0x7F, 0x81, 0x78, 0x18, 0x62, 0x00, 0xFF, 0xC0,
/* 0x02 */ 0x00, 0xFF, 0x80, 0x61, 0x13, 0xF0, 0x62, 0x60, 0x07, 0xFC, 0x00, 0x83, 0x80, 0x10, 0xF0, 0x33, 0xF6, 0x01, 0x41, 0xC0, 0x18, 0x38, 0x03, 0xFF, 0xE0, 0x47, 0x02, 0x08, 0x20, 0x61, 0xC4, 0x06, 0x17, 0x00, 0x22, 0x00, 0x02, 0x40, 0x00, 0x48, 0x00, 0x09, 0x00, 0x01, 0x20, 0x00, 0x3C, 0x00,
/* 0x03 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x04, 0x08, 0x48, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x08, 0x10, 0x70, 0x00, 0x03, 0x80, 0x00, 0x14, 0x00, 0x00, 0xA1, 0x81, 0x8D, 0x87, 0xF0, 0x44, 0x00, 0x06, 0x30, 0x00, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x04 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x10, 0x02, 0x48, 0xE0, 0x61, 0xC1, 0xCC, 0x0E, 0x78, 0x1C, 0x70, 0x00, 0x03, 0x80, 0x00, 0x14, 0xFF, 0xFC, 0xA6, 0x00, 0xCD, 0x9F, 0xFE, 0x44, 0x71, 0xE6, 0x30, 0xFC, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x05 */ 0x00, 0x18, 0x00, 0x00, 0x40, 0x01, 0x90, 0x01, 0xF4, 0x08, 0x12, 0x23, 0xC1, 0x91, 0x2C, 0x1C, 0x8A, 0xC3, 0x64, 0x64, 0x13, 0x22, 0x41, 0x98, 0x26, 0x2C, 0xC4, 0x22, 0x60, 0x42, 0x13, 0x04, 0x30, 0x80, 0x61, 0xA4, 0x02, 0x18, 0x20, 0x03, 0x41, 0x00, 0x20, 0x08, 0x02, 0x00, 0x60, 0x40, 0x03, 0xF8,
/* 0x06 */ 0x00, 0x10, 0x00, 0x03, 0x00, 0x1C, 0x48, 0x00, 0xB4, 0x80, 0x09, 0xF9, 0xC0, 0xE0, 0xE4, 0x0C, 0x02, 0x8F, 0x80, 0x38, 0x88, 0x01, 0x0D, 0x00, 0x18, 0x30, 0x01, 0x60, 0x80, 0x13, 0x18, 0x03, 0xF2, 0xC0, 0x20, 0x26, 0x06, 0x07, 0xFF, 0xA0, 0x02, 0x39, 0x00, 0x14, 0x70, 0x01, 0xC3, 0x00, 0x18, 0x00,
/* 0x07 */
/* 0x08 */ 0x00, 0x1F, 0x80, 0x00, 0x60, 0x80, 0x01, 0x00, 0x80, 0x06, 0x00, 0x80, 0x3C, 0x01, 0x01, 0x8C, 0x02, 0x02, 0x08, 0x04, 0x04, 0x08, 0x0C, 0x38, 0x00, 0x04, 0x80, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x2E, 0xC0, 0x01, 0x83, 0x7E, 0x0C, 0x10, 0x37, 0xE2, 0x61, 0x00, 0x0C, 0xC6, 0x10, 0x98, 0x0C, 0x63, 0x00, 0x00, 0xC6, 0x00,
/* 0x09 */ 0x00, 0x1F, 0x80, 0x00, 0x60, 0x80, 0x01, 0x00, 0x80, 0x06, 0x00, 0x80, 0x3C, 0x01, 0x01, 0x8C, 0x02, 0x02, 0x08, 0x04, 0x04, 0x08, 0x0C, 0x38, 0x00, 0x04, 0x80, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x2E, 0xC0, 0x01, 0x83, 0x7E, 0x0C, 0x00, 0x37, 0xE0,
/* 0x0A */
/* 0x0B */ 0x1F, 0x07, 0xC1, 0x86, 0x41, 0x10, 0x0C, 0x04, 0x80, 0x40, 0x18, 0x00, 0x00, 0xC0, 0x00, 0x06, 0x00, 0x00, 0x30, 0x00, 0x01, 0x40, 0x00, 0x0A, 0x00, 0x00, 0x88, 0x00, 0x04, 0x40, 0x00, 0x41, 0x00, 0x02, 0x04, 0x00, 0x20, 0x20, 0x02, 0x00, 0x80, 0x20, 0x02, 0x02, 0x00, 0x08, 0x20, 0x00, 0x22, 0x00, 0x00, 0xE0, 0x00,
/* 0x0C */ 0x01, 0x00, 0x00, 0x38, 0x00, 0x04, 0xC0, 0x01, 0x08, 0x00, 0x18, 0x80, 0x1C, 0x10, 0x02, 0x07, 0x80, 0x81, 0x10, 0x1F, 0xC2, 0x02, 0x00, 0x60, 0x80, 0x1A, 0x20, 0x1C, 0x42, 0x1C, 0x08, 0xFE, 0x03, 0xA0, 0x01, 0x8C, 0x01, 0xC1, 0x43, 0xD0, 0x27, 0x81, 0xF8,
/* 0x0D */
/* 0x0E */ 0x00, 0xE0, 0x00, 0x11, 0x00, 0x01, 0x10, 0x00, 0x0B, 0x00, 0x03, 0xF8, 0x00, 0x60, 0x60, 0x09, 0x02, 0x00, 0xA0, 0x10, 0x16, 0x01, 0x01, 0x40, 0x10, 0x10, 0x01, 0x01, 0x00, 0x08, 0x10, 0x00, 0x82, 0x1F, 0x08, 0x3F, 0x90, 0x44, 0x00, 0x06, 0xBF, 0xFF, 0xAF, 0xF0, 0xFF, 0xFF, 0x0F, 0xE3, 0xFB, 0xFC,
/* 0x0F */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x40, 0x12, 0x34, 0x00, 0x69, 0x40, 0x01, 0x49, 0xE0, 0xF1, 0xCD, 0x06, 0x8E, 0x28, 0x14, 0x71, 0x40, 0xA3, 0x8B, 0xFD, 0x14, 0x50, 0x68, 0xA2, 0x81, 0x4D, 0x97, 0xFA, 0x44, 0xBF, 0xD6, 0x31, 0x02, 0xE0, 0xC8, 0x16, 0x08, 0x61, 0x08, 0x21, 0xF0, 0x80, 0xF8, 0x78, 0x00,
/* 0x10 */ 0x00, 0xF0, 0x00, 0x3A, 0x00, 0x07, 0xC0, 0x00, 0xA8, 0x00, 0x1F, 0x00, 0x02, 0xB0, 0x00, 0x52, 0x00, 0x0A, 0x40, 0x02, 0x48, 0x00, 0x49, 0x00, 0x09, 0x30, 0x01, 0x22, 0x01, 0xC4, 0x70, 0xF0, 0x85, 0xE1, 0x10, 0x88, 0x37, 0x20, 0x03, 0x9C, 0x00, 0x37, 0x00, 0x06, 0x40, 0x01, 0x86, 0x00,
/* 0x11 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x60, 0x02, 0x36, 0x00, 0x09, 0x04, 0x0C, 0x48, 0x60, 0xC1, 0xC3, 0x0F, 0x0E, 0x00, 0x08, 0x70, 0x00, 0x23, 0x80, 0x63, 0x84, 0x01, 0x9F, 0x20, 0x0C, 0xFD, 0x80, 0x27, 0xE4, 0x03, 0x3F, 0x30, 0x33, 0xE0, 0xC0, 0x00, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x12 */ 0x00, 0xC2, 0x00, 0x1C, 0x24, 0x02, 0x18, 0x60, 0x64, 0x02, 0x02, 0x40, 0x20, 0x00, 0xF2, 0x03, 0x89, 0xE0, 0x7C, 0x80, 0x0E, 0x25, 0x80, 0xE1, 0x00, 0x1A, 0x08, 0x71, 0xB0, 0xC4, 0x39, 0x84, 0xC2, 0xCC, 0x40, 0x76, 0x7C, 0x05, 0xBB, 0x80, 0x4C, 0xE0, 0x0A, 0x78, 0x00, 0x9C, 0x00, 0x0F, 0x00, 0x00,
/* 0x13 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x00, 0x00, 0x48, 0x60, 0xC1, 0xC6, 0xC9, 0x0E, 0x00, 0x00, 0x70, 0x00, 0x03, 0x80, 0x00, 0x14, 0xFF, 0xF8, 0xA6, 0x00, 0xCD, 0x9F, 0xFE, 0x44, 0x71, 0xE6, 0x30, 0xFC, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x14 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x20, 0x22, 0x33, 0x01, 0x89, 0x20, 0x02, 0x48, 0x60, 0xE1, 0xC8, 0x80, 0x8E, 0x46, 0x46, 0x72, 0x32, 0x33, 0x9F, 0x9F, 0x94, 0x78, 0x78, 0xA0, 0x00, 0x0D, 0x80, 0x00, 0x44, 0x0E, 0x06, 0x30, 0x00, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x15 */ 0x03, 0xFC, 0x20, 0x38, 0x1C, 0x81, 0x80, 0x1D, 0x08, 0x00, 0x32, 0x60, 0x00, 0x89, 0x00, 0x02, 0x18, 0x00, 0x08, 0x61, 0xC3, 0x22, 0x8D, 0x93, 0x72, 0x00, 0x00, 0x48, 0x00, 0x01, 0x20, 0x00, 0x04, 0x9F, 0xFF, 0x92, 0x60, 0x0E, 0x44, 0xFF, 0xF2, 0x11, 0xC3, 0x88, 0x21, 0xF8, 0x40, 0x40, 0x02, 0x00, 0xC0, 0x30, 0x00, 0xFF, 0x00,
/* 0x16 */ 0x03, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x01, 0xE0, 0x03, 0xF0, 0x03, 0xF0, 0x27, 0xF0, 0x6F, 0x70, 0x6E, 0x60, 0xFC, 0x60, 0xFC, 0x7E, 0xFC, 0x7E, 0xFC, 0x3F, 0xF4, 0x1F, 0xF4, 0x1F, 0xF0, 0x0E, 0x70, 0x0E, 0x30, 0x1C, 0x38, 0x38, 0x0F, 0xF0,
/* 0x17 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x00, 0x00, 0x48, 0x00, 0x21, 0xC0, 0x02, 0x8E, 0x20, 0xF4, 0x70, 0x84, 0x11, 0x82, 0x40, 0x84, 0x01, 0x03, 0x20, 0x0F, 0x85, 0x80, 0x03, 0x04, 0x00, 0x04, 0x30, 0x78, 0x10, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x18 */ 0x00, 0xFC, 0x00, 0x02, 0x06, 0x00, 0x08, 0x24, 0x00, 0x21, 0xA4, 0x00, 0x4C, 0x48, 0x00, 0xA0, 0x50, 0x01, 0x92, 0x60, 0x03, 0x24, 0xC0, 0x06, 0x01, 0x81, 0x28, 0x03, 0x49, 0x6C, 0xC4, 0xAD, 0xD8, 0x16, 0xA4, 0xCC, 0xC4, 0x44, 0x86, 0x13, 0x05, 0x00, 0x28, 0x0A, 0x00, 0x50, 0x14, 0x00, 0x90, 0x48, 0x01, 0x20, 0x90, 0x02, 0x41, 0x20, 0x00, 0x00,
/* 0x19 */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x00, 0x02, 0x30, 0x00, 0x09, 0x00, 0x00, 0x49, 0xC3, 0x81, 0xC0, 0x00, 0x0E, 0x78, 0xF0, 0x77, 0xEF, 0xC3, 0xA7, 0x4E, 0x15, 0x0A, 0x10, 0xA7, 0x8F, 0x0D, 0x80, 0x00, 0x44, 0x00, 0x06, 0x33, 0xF0, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x1A */ 0xFF, 0xFF, 0x00, 0x06, 0x00, 0x0C, 0x3E, 0x18, 0x82, 0x32, 0x02, 0x64, 0x04, 0xC8, 0x09, 0x80, 0x23, 0x00, 0x86, 0x02, 0x0C, 0x08, 0x18, 0x10, 0x30, 0x00, 0x60, 0x00, 0xC0, 0x81, 0x80, 0x03, 0x00, 0x07, 0xFF, 0xF8,
/* 0x1B */ 0x00, 0xFE, 0x00, 0x03, 0x81, 0x80, 0x04, 0x00, 0x60, 0x08, 0x00, 0x30, 0x10, 0x00, 0x10, 0x30, 0x07, 0x88, 0x23, 0xC8, 0x08, 0x22, 0x00, 0x04, 0x60, 0x00, 0x44, 0x60, 0x00, 0x84, 0x63, 0x03, 0x04, 0x61, 0xFC, 0x04, 0x6B, 0x00, 0x9E, 0xA5, 0x01, 0x6A, 0xD5, 0x01, 0x43, 0xA8, 0x81, 0x05, 0xD0, 0x82, 0x0A, 0xA0, 0x82, 0x05, 0xC0, 0x82, 0x02, 0x61, 0xFF, 0x0C, 0x1E, 0x00, 0xF0,
/* 0x1C */ 0x01, 0xFC, 0x00, 0x38, 0x18, 0x02, 0x00, 0x30, 0x20, 0x00, 0xC2, 0x30, 0x02, 0x32, 0x00, 0x09, 0x00, 0x00, 0x48, 0x20, 0x61, 0xC3, 0x84, 0x0E, 0x1C, 0x78, 0x70, 0x40, 0x03, 0x80, 0x00, 0x14, 0x00, 0x00, 0xA0, 0x03, 0x0D, 0x83, 0xF0, 0x44, 0x00, 0x06, 0x30, 0x00, 0x60, 0xC0, 0x06, 0x03, 0x80, 0x60, 0x07, 0xFC, 0x00,
/* 0x1D */ 0x01, 0xFE, 0x00, 0x3A, 0x1C, 0x03, 0x00, 0x30, 0x23, 0x1E, 0xC3, 0x38, 0x03, 0x10, 0xC3, 0x09, 0x00, 0x18, 0x68, 0x00, 0xC1, 0x40, 0x00, 0x0A, 0x07, 0x80, 0x50, 0x46, 0x02, 0x80, 0x00, 0x1A, 0x1E, 0x00, 0xCB, 0x10, 0x0D, 0x03, 0x00, 0x48, 0x60, 0x06, 0x40, 0x00, 0x22, 0x0C, 0x02, 0x10, 0x60, 0x60, 0x43, 0xFC, 0x01, 0xE0, 0x00, 0x00,
/* 0x1E */ 0x01, 0xF0, 0x00, 0xEA, 0xC0, 0x31, 0x5F, 0x04, 0x5F, 0x88, 0x80, 0xA0, 0x48, 0x0E, 0x02, 0x8F, 0x40, 0x3C, 0x10, 0x21, 0x66, 0x87, 0x15, 0x98, 0x71, 0x41, 0x02, 0x14, 0x00, 0x01, 0x40, 0x00, 0x14, 0x00, 0x01, 0x21, 0xFE, 0x12, 0x00, 0x02, 0x10, 0x00, 0x60, 0x80, 0x0C, 0x06, 0x01, 0x80, 0x3F, 0xE0,
/* 0x1F */ 0x0E, 0x00, 0x13, 0x00, 0x23, 0x00, 0xF3, 0x01, 0x31, 0x01, 0x11, 0x03, 0xD3, 0x06, 0xF2, 0x30, 0x34, 0xC7, 0x25, 0x33, 0x2B, 0xC2, 0x57, 0x04, 0x3A, 0x08, 0x72, 0x30, 0xA3, 0xC3, 0x40, 0x04, 0x40, 0x18, 0x40, 0x60, 0x7F, 0x80,
/* ' ' 0x20 */
/* '!' 0x21 */ 0xFF, 0xFF, 0xFF, 0xF0, 0xF0,
/* '"' 0x22 */ 0xCF, 0x3C, 0xF3, 0x8A, 0x20,
/* '#' 0x23 */ 0x06, 0x30, 0x31, 0x03, 0x18, 0x18, 0xC7, 0xFF, 0xBF, 0xFC, 0x31, 0x01, 0x18, 0x18, 0xC7, 0xFF, 0xBF, 0xFC, 0x31, 0x01, 0x18, 0x18, 0xC0, 0xC6, 0x06, 0x30,
/* '$' 0x24 */ 0x04, 0x03, 0xE1, 0xFF, 0x72, 0x7C, 0x47, 0x88, 0xF1, 0x07, 0xA0, 0x7E, 0x03, 0xF0, 0x17, 0x02, 0x7C, 0x47, 0x88, 0xF1, 0x1B, 0x26, 0x7F, 0xC3, 0xE0, 0x10, 0x02, 0x00,
/* '%' 0x25 */ 0x00, 0x06, 0x03, 0xC0, 0x40, 0x7E, 0x0C, 0x0E, 0x70, 0x80, 0xC3, 0x18, 0x0C, 0x31, 0x00, 0xE7, 0x30, 0x07, 0xE6, 0x00, 0x3C, 0x40, 0x00, 0x0C, 0x7C, 0x00, 0x8F, 0xE0, 0x19, 0xC7, 0x01, 0x18, 0x30, 0x31, 0x83, 0x02, 0x1C, 0x70, 0x40, 0xFE, 0x04, 0x07, 0xC0,
/* '&' 0x26 */ 0x0F, 0x00, 0x7E, 0x03, 0x9C, 0x0C, 0x30, 0x30, 0xC0, 0xE7, 0x01, 0xF8, 0x03, 0x80, 0x3E, 0x01, 0xCC, 0x6E, 0x39, 0xB0, 0x7C, 0xC0, 0xF3, 0x03, 0xCE, 0x1F, 0x9F, 0xE6, 0x3E, 0x1C,
/* ''' 0x27 */ 0xFF, 0xA0,
/* '(' 0x28 */ 0x08, 0x8C, 0x46, 0x31, 0x98, 0xC6, 0x31, 0x8C, 0x63, 0x08, 0x63, 0x08, 0x61, 0x0C, 0x20,
/* ')' 0x29 */ 0x82, 0x18, 0xC3, 0x18, 0xC3, 0x18, 0xC6, 0x31, 0x8C, 0x62, 0x31, 0x88, 0xC4, 0x62, 0x00,
/* '*' 0x2A */ 0x10, 0x23, 0x5B, 0xE3, 0x8D, 0x91, 0x00,
/* '+' 0x2B */ 0x0C, 0x03, 0x00, 0xC0, 0x30, 0xFF, 0xFF, 0xF0, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0,
/* ',' 0x2C */ 0xF5, 0x60,
/* '-' 0x2D */ 0xFF, 0xF0,
/* '.' 0x2E */ 0xF0,
/* '/' 0x2F */ 0x02, 0x0C, 0x10, 0x20, 0xC1, 0x02, 0x0C, 0x10, 0x20, 0xC1, 0x02, 0x0C, 0x10, 0x20, 0xC1, 0x00,
/* '0' 0x30 */ 0x1F, 0x07, 0xF1, 0xC7, 0x30, 0x6C, 0x0F, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3E, 0x0E, 0xC1, 0x9C, 0x71, 0xFC, 0x1F, 0x00,
/* '1' 0x31 */ 0x08, 0xCF, 0xFF, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18,
/* '2' 0x32 */ 0x1F, 0x0F, 0xF9, 0x87, 0x60, 0x7C, 0x06, 0x00, 0xC0, 0x18, 0x07, 0x01, 0xC0, 0xF0, 0x78, 0x1C, 0x06, 0x00, 0xC0, 0x30, 0x07, 0xFF, 0xFF, 0xE0,
/* '3' 0x33 */ 0x3F, 0x0F, 0xF3, 0x87, 0x60, 0x6C, 0x0C, 0x01, 0x80, 0x60, 0x78, 0x0F, 0x80, 0x18, 0x01, 0x80, 0x3C, 0x07, 0x80, 0xD8, 0x73, 0xFC, 0x3F, 0x00,
/* '4' 0x34 */ 0x01, 0x80, 0x70, 0x0E, 0x03, 0xC0, 0xD8, 0x1B, 0x06, 0x61, 0x8C, 0x21, 0x8C, 0x33, 0x06, 0x7F, 0xFF, 0xFE, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80,
/* '5' 0x35 */ 0x3F, 0xCF, 0xF9, 0x80, 0x30, 0x06, 0x00, 0xDE, 0x1F, 0xE7, 0x0E, 0x00, 0xE0, 0x0C, 0x01, 0x80, 0x30, 0x07, 0x81, 0xB8, 0x73, 0xFC, 0x1F, 0x00,
/* '6' 0x36 */ 0x0F, 0x07, 0xF9, 0xC3, 0x30, 0x74, 0x01, 0x80, 0x33, 0xC7, 0xFE, 0xF1, 0xDC, 0x1F, 0x01, 0xE0, 0x3C, 0x06, 0xC1, 0xDC, 0x71, 0xFC, 0x1F, 0x00,
/* '7' 0x37 */ 0xFF, 0xFF, 0xFC, 0x01, 0x00, 0x60, 0x18, 0x02, 0x00, 0xC0, 0x30, 0x06, 0x01, 0x80, 0x30, 0x04, 0x01, 0x80, 0x30, 0x06, 0x01, 0x80, 0x30, 0x00,
/* '8' 0x38 */ 0x1F, 0x07, 0xF1, 0xC7, 0x30, 0x66, 0x0C, 0xC1, 0x8C, 0x61, 0xF8, 0x3F, 0x8E, 0x3B, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xD8, 0x31, 0xFC, 0x1F, 0x00,
/* '9' 0x39 */ 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x6C, 0x07, 0x80, 0xF0, 0x1E, 0x07, 0x61, 0xEF, 0xFC, 0x79, 0x80, 0x30, 0x05, 0xC1, 0x98, 0x73, 0xFC, 0x1E, 0x00,
/* ':' 0x3A */ 0xF0, 0x00, 0x03, 0xC0,
/* ';' 0x3B */ 0xF0, 0x00, 0x0F, 0x56,
/* '<' 0x3C */ 0x00, 0x70, 0x1E, 0x0F, 0x83, 0xC0, 0xF0, 0x0E, 0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x10,
/* '=' 0x3D */ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
/* '>' 0x3E */ 0xE0, 0x07, 0x80, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x07, 0x01, 0xE0, 0xF0, 0x3C, 0x0F, 0x00, 0x80, 0x00,
/* '?' 0x3F */ 0x3F, 0x1F, 0xEE, 0x1F, 0x03, 0xC0, 0xC0, 0x30, 0x0C, 0x06, 0x03, 0x81, 0xC0, 0xE0, 0x30, 0x0C, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x03, 0x00,
/* '@' 0x40 */ 0x00, 0xFE, 0x00, 0x0F, 0xFE, 0x00, 0xF0, 0x3E, 0x07, 0x00, 0x3C, 0x38, 0x00, 0x38, 0xC1, 0xE0, 0x66, 0x0F, 0xD9, 0xD8, 0x61, 0xC3, 0xC3, 0x07, 0x0F, 0x1C, 0x1C, 0x3C, 0x60, 0x60, 0xF1, 0x81, 0x83, 0xC6, 0x06, 0x1B, 0x18, 0x38, 0xEE, 0x71, 0xE7, 0x18, 0xFD, 0xF8, 0x71, 0xE7, 0xC0, 0xE0, 0x00, 0x01, 0xE0, 0x00, 0x01, 0xFF, 0xC0, 0x01, 0xFC, 0x00,
/* 'A' 0x41 */ 0x07, 0x80, 0x1E, 0x00, 0x78, 0x03, 0xF0, 0x0C, 0xC0, 0x33, 0x01, 0xCE, 0x06, 0x18, 0x18, 0x60, 0xE1, 0xC3, 0x03, 0x0F, 0xFC, 0x7F, 0xF9, 0x80, 0x66, 0x01, 0xB8, 0x07, 0xC0, 0x0F, 0x00, 0x30,
/* 'B' 0x42 */ 0xFF, 0xC7, 0xFF, 0x30, 0x1D, 0x80, 0x6C, 0x03, 0x60, 0x1B, 0x00, 0xD8, 0x0C, 0xFF, 0xC7, 0xFF, 0x30, 0x0D, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x06, 0xFF, 0xF7, 0xFE, 0x00,
/* 'C' 0x43 */ 0x07, 0xE0, 0x3F, 0xF0, 0xE0, 0x73, 0x80, 0x76, 0x00, 0x6C, 0x00, 0x30, 0x00, 0x60, 0x00, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x00, 0x0E, 0x00, 0x6C, 0x00, 0xDC, 0x03, 0x1E, 0x0E, 0x1F, 0xF8, 0x0F, 0xC0,
/* 'D' 0x44 */ 0xFF, 0xC3, 0xFF, 0x8C, 0x07, 0x30, 0x0E, 0xC0, 0x1B, 0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x1F, 0x00, 0x6C, 0x03, 0xB0, 0x1C, 0xFF, 0xE3, 0xFE, 0x00,
/* 'E' 0x45 */ 0xFF, 0xFF, 0xFF, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xEF, 0xFE, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xFF, 0xFF,
/* 'F' 0x46 */ 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xFF, 0xDF, 0xFB, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x00,
/* 'G' 0x47 */ 0x07, 0xF0, 0x1F, 0xFC, 0x3C, 0x1E, 0x70, 0x07, 0x60, 0x03, 0xE0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x7F, 0xC0, 0x7F, 0xC0, 0x03, 0xC0, 0x03, 0x60, 0x03, 0x60, 0x07, 0x30, 0x0F, 0x3C, 0x1F, 0x1F, 0xFB, 0x07, 0xE1,
/* 'H' 0x48 */ 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xC0,
/* 'I' 0x49 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
/* 'J' 0x4A */ 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x3C, 0x1E, 0x0F, 0x07, 0xC7, 0x7F, 0x1F, 0x00,
/* 'K' 0x4B */ 0xC0, 0x3E, 0x03, 0xB0, 0x39, 0x83, 0x8C, 0x38, 0x63, 0x83, 0x38, 0x19, 0xC0, 0xDE, 0x07, 0xB8, 0x38, 0xE1, 0x83, 0x0C, 0x1C, 0x60, 0x73, 0x01, 0x98, 0x0E, 0xC0, 0x3E, 0x00, 0xC0,
/* 'L' 0x4C */ 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xFF, 0xFF, 0xF0,
/* 'M' 0x4D */ 0xE0, 0x07, 0xE0, 0x07, 0xF0, 0x0F, 0xF0, 0x0F, 0xD0, 0x0F, 0xD8, 0x1B, 0xD8, 0x1B, 0xD8, 0x1B, 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33, 0xC6, 0x63, 0xC6, 0x63, 0xC6, 0x63, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC1, 0x83,
/* 'N' 0x4E */ 0xE0, 0x1F, 0x00, 0xFC, 0x07, 0xE0, 0x3D, 0x81, 0xEE, 0x0F, 0x30, 0x79, 0xC3, 0xC6, 0x1E, 0x18, 0xF0, 0xE7, 0x83, 0x3C, 0x1D, 0xE0, 0x6F, 0x01, 0xF8, 0x0F, 0xC0, 0x3E, 0x01, 0xC0,
/* 'O' 0x4F */ 0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0x07, 0x86, 0x00, 0xC6, 0x00, 0x33, 0x00, 0x1B, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x36, 0x00, 0x33, 0x00, 0x18, 0xC0, 0x18, 0x78, 0x3C, 0x1F, 0xFC, 0x03, 0xF8, 0x00,
/* 'P' 0x50 */ 0xFF, 0x8F, 0xFE, 0xC0, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x06, 0xFF, 0xEF, 0xFC, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00,
/* 'Q' 0x51 */ 0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0x07, 0x86, 0x00, 0xC6, 0x00, 0x33, 0x00, 0x1B, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x36, 0x00, 0x33, 0x01, 0x98, 0xC0, 0xFC, 0x78, 0x3C, 0x1F, 0xFF, 0x03, 0xF9, 0x80, 0x00, 0x40,
/* 'R' 0x52 */ 0xFF, 0xE3, 0xFF, 0xCC, 0x03, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x6C, 0x01, 0xB0, 0x0C, 0xFF, 0xE3, 0xFF, 0xCC, 0x03, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x6C, 0x01, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x70,
/* 'S' 0x53 */ 0x0F, 0xE0, 0x7F, 0xC3, 0x83, 0x98, 0x07, 0x60, 0x0D, 0x80, 0x07, 0x00, 0x1E, 0x00, 0x3F, 0x80, 0x3F, 0xC0, 0x0F, 0x80, 0x07, 0xC0, 0x0F, 0x00, 0x3E, 0x00, 0xDE, 0x0E, 0x3F, 0xF0, 0x3F, 0x80,
/* 'T' 0x54 */ 0xFF, 0xFF, 0xFF, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60,
/* 'U' 0x55 */ 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x80, 0xEE, 0x0E, 0x3F, 0xE0, 0xFC, 0x00,
/* 'V' 0x56 */ 0xC0, 0x0F, 0x00, 0x7E, 0x01, 0x98, 0x06, 0x60, 0x39, 0xC0, 0xC3, 0x03, 0x0C, 0x1C, 0x38, 0x60, 0x61, 0x81, 0x8E, 0x07, 0x30, 0x0C, 0xC0, 0x37, 0x00, 0xF8, 0x01, 0xE0, 0x07, 0x80, 0x1C, 0x00,
/* 'W' 0x57 */ 0xE0, 0x30, 0x1D, 0x80, 0xE0, 0x76, 0x07, 0x81, 0xDC, 0x1E, 0x06, 0x70, 0x7C, 0x18, 0xC1, 0xB0, 0xE3, 0x0C, 0xC3, 0x8C, 0x33, 0x0C, 0x38, 0xC6, 0x30, 0x67, 0x18, 0xC1, 0x98, 0x67, 0x06, 0x61, 0xD8, 0x1D, 0x83, 0x60, 0x3C, 0x0D, 0x80, 0xF0, 0x3E, 0x03, 0xC0, 0x70, 0x0F, 0x01, 0xC0, 0x18, 0x07, 0x00,
/* 'X' 0x58 */ 0xE0, 0x1D, 0x80, 0xE7, 0x03, 0x0E, 0x1C, 0x18, 0x60, 0x73, 0x00, 0xFC, 0x01, 0xE0, 0x07, 0x00, 0x1E, 0x00, 0xF8, 0x03, 0x30, 0x1C, 0xE0, 0xE1, 0x83, 0x07, 0x1C, 0x0E, 0xE0, 0x1B, 0x00, 0x70,
/* 'Y' 0x59 */ 0xC0, 0x0F, 0x80, 0x76, 0x01, 0x9C, 0x0C, 0x38, 0x70, 0x61, 0x81, 0xCE, 0x03, 0x30, 0x0F, 0x80, 0x1E, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00,
/* 'Z' 0x5A */ 0xFF, 0xFF, 0xFF, 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0x60, 0x07, 0x00, 0x70, 0x07, 0x00, 0x30, 0x03, 0x80, 0x38, 0x03, 0x80, 0x18, 0x01, 0xC0, 0x1C, 0x00, 0xFF, 0xFF, 0xFF, 0xC0,
/* '[' 0x5B */ 0xFF, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCF, 0xF0,
/* '\' 0x5C */ 0x81, 0x81, 0x02, 0x06, 0x04, 0x08, 0x18, 0x10, 0x20, 0x60, 0x40, 0x81, 0x81, 0x02, 0x06, 0x04,
/* ']' 0x5D */ 0xFF, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0xF0,
/* '^' 0x5E */ 0x0C, 0x0E, 0x05, 0x86, 0xC3, 0x21, 0x19, 0x8C, 0x83, 0xC1, 0x80,
/* '_' 0x5F */ 0xFF, 0xFE,
/* '`' 0x60 */ 0xE3, 0x8C, 0x30,
/* 'a' 0x61 */ 0x3F, 0x07, 0xF8, 0xE1, 0xCC, 0x0C, 0x00, 0xC0, 0x1C, 0x3F, 0xCF, 0x8C, 0xC0, 0xCC, 0x0C, 0xE3, 0xC7, 0xEF, 0x3C, 0x70,
/* 'b' 0x62 */ 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0xF8, 0xDF, 0xCF, 0x0E, 0xE0, 0x7C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xE0, 0x6F, 0x0E, 0xDF, 0xCC, 0xF8,
/* 'c' 0x63 */ 0x1F, 0x0F, 0xE6, 0x1F, 0x83, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x38, 0x37, 0x1C, 0xFE, 0x1F, 0x00,
/* 'd' 0x64 */ 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x3C, 0xCF, 0xFB, 0x8F, 0xE0, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF8, 0x3B, 0x8F, 0x3F, 0x63, 0xCC,
/* 'e' 0x65 */ 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x3C, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0xC0, 0x1C, 0x0D, 0xC3, 0x1F, 0xC1, 0xF0,
/* 'f' 0x66 */ 0x3B, 0xD8, 0xC6, 0x7F, 0xEC, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x00,
/* 'g' 0x67 */ 0x1E, 0x67, 0xFD, 0xC7, 0xF0, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x7C, 0x1D, 0xC7, 0x9F, 0xB1, 0xE6, 0x00, 0xC0, 0x3E, 0x0E, 0x7F, 0xC7, 0xE0,
/* 'h' 0x68 */ 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x33, 0xCD, 0xFB, 0xC7, 0xE0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x30,
/* 'i' 0x69 */ 0xF0, 0x3F, 0xFF, 0xFF, 0xF0,
/* 'j' 0x6A */ 0x33, 0x00, 0x03, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0xE0,
/* 'k' 0x6B */ 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x6C, 0x33, 0x18, 0xCC, 0x37, 0x0F, 0xC3, 0xB8, 0xC6, 0x31, 0xCC, 0x3B, 0x06, 0xC1, 0xF0, 0x30,
/* 'l' 0x6C */ 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
/* 'm' 0x6D */ 0xCF, 0x1F, 0x6F, 0xDF, 0xFC, 0x78, 0xFC, 0x18, 0x3C, 0x0C, 0x1E, 0x06, 0x0F, 0x03, 0x07, 0x81, 0x83, 0xC0, 0xC1, 0xE0, 0x60, 0xF0, 0x30, 0x78, 0x18, 0x3C, 0x0C, 0x18,
/* 'n' 0x6E */ 0xCF, 0x37, 0xEF, 0x1F, 0x83, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xC0,
/* 'o' 0x6F */ 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x7C, 0x1D, 0xC7, 0x1F, 0xC1, 0xF0,
/* 'p' 0x70 */ 0xCF, 0x8D, 0xFC, 0xF0, 0xEE, 0x06, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3E, 0x06, 0xF0, 0xEF, 0xFC, 0xCF, 0x8C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x00,
/* 'q' 0x71 */ 0x1E, 0x67, 0xFD, 0xC7, 0xF0, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x7C, 0x1D, 0xC7, 0x9F, 0xF1, 0xE6, 0x00, 0xC0, 0x18, 0x03, 0x00, 0x60,
/* 'r' 0x72 */ 0xCF, 0x7F, 0x38, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC0,
/* 's' 0x73 */ 0x3E, 0x1F, 0xEE, 0x1B, 0x00, 0xC0, 0x3C, 0x07, 0xF0, 0x3F, 0x01, 0xF0, 0x3E, 0x1D, 0xFE, 0x3F, 0x00,
/* 't' 0x74 */ 0x63, 0x19, 0xFF, 0xB1, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0xE7,
/* 'u' 0x75 */ 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x7E, 0x3D, 0xFB, 0x3C, 0xC0,
/* 'v' 0x76 */ 0xE0, 0x6C, 0x0D, 0x81, 0xB8, 0x63, 0x0C, 0x61, 0x8E, 0x60, 0xCC, 0x19, 0x83, 0xE0, 0x3C, 0x07, 0x00, 0xE0,
/* 'w' 0x77 */ 0xC1, 0xC1, 0xB0, 0xE1, 0xD8, 0x70, 0xCC, 0x2C, 0x66, 0x36, 0x31, 0x9B, 0x18, 0xCD, 0x98, 0x64, 0x6C, 0x16, 0x36, 0x0F, 0x1A, 0x07, 0x8F, 0x03, 0x83, 0x80, 0xC1, 0xC0,
/* 'x' 0x78 */ 0xC1, 0xF8, 0x66, 0x30, 0xCC, 0x3E, 0x07, 0x00, 0xC0, 0x78, 0x36, 0x0C, 0xC6, 0x3B, 0x06, 0xC0, 0xC0,
/* 'y' 0x79 */ 0xE0, 0x6C, 0x0D, 0x83, 0x38, 0x63, 0x0C, 0x63, 0x0C, 0x60, 0xCC, 0x1B, 0x03, 0x60, 0x3C, 0x07, 0x00, 0xE0, 0x18, 0x03, 0x00, 0xE0, 0x78, 0x0E, 0x00,
/* 'z' 0x7A */ 0xFF, 0xFF, 0xF0, 0x18, 0x0C, 0x07, 0x03, 0x81, 0xC0, 0x60, 0x30, 0x18, 0x0E, 0x03, 0xFF, 0xFF, 0xC0,
/* '{' 0x7B */ 0x19, 0xCC, 0x63, 0x18, 0xC6, 0x31, 0x99, 0x86, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x1C, 0x60,
/* '|' 0x7C */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
/* '}' 0x7D */ 0xC7, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x0C, 0x33, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x73, 0x00,
/* '~' 0x7E */ 0x70, 0x3E, 0x09, 0xE4, 0x1F, 0x03, 0x80,
/* 0x7F */
/* 0x80 */ 0x01, 0xF0, 0x1F, 0xF0, 0xE0, 0xC7, 0x00, 0x18, 0x00, 0xC0, 0x07, 0xFF, 0x3F, 0xFC, 0x30, 0x01, 0xFF, 0x8F, 0xFC, 0x0C, 0x00, 0x18, 0x00, 0x70, 0x00, 0xE0, 0x81, 0xFE, 0x03, 0xF0,
/* 0x81 */
/* 0x82 */ 0xF5, 0x80,
/* 0x83 */ 0x1C, 0xF3, 0x0C, 0x31, 0xF7, 0xCC, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x33, 0xCE, 0x00,
/* 0x84 */ 0xCF, 0x34, 0x51, 0x88,
/* 0x85 */ 0xC6, 0x3C, 0x63,
/* 0x86 */ 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x3F, 0xFF, 0xFC, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x00,
/* 0x87 */ 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x3F, 0xFF, 0xFC, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x0F, 0xFF, 0xFF, 0x0C, 0x03, 0x00, 0xC0, 0x30,
/* 0x88 */ 0x38, 0xD9, 0xB6, 0x30,
/* 0x89 */ 0x38, 0x18, 0x00, 0xF8, 0x30, 0x03, 0x18, 0xC0, 0x04, 0x11, 0x80, 0x0C, 0x66, 0x00, 0x0F, 0x8C, 0x00, 0x0E, 0x30, 0x00, 0x00, 0x40, 0x00, 0x01, 0x80, 0x00, 0x06, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x31, 0xC0, 0xE0, 0x67, 0xC3, 0xC1, 0x98, 0xCC, 0xC3, 0x20, 0x90, 0x8C, 0x63, 0x33, 0x10, 0x7C, 0x3C, 0x60, 0x70, 0x38,
/* 0x8A */ 0x0C, 0x40, 0x1F, 0x00, 0x38, 0x03, 0xF8, 0x1F, 0xF0, 0xE0, 0xE6, 0x01, 0xD8, 0x03, 0x60, 0x01, 0xC0, 0x07, 0x80, 0x0F, 0xE0, 0x0F, 0xF0, 0x03, 0xE0, 0x01, 0xF0, 0x03, 0xC0, 0x0F, 0x80, 0x37, 0x83, 0x8F, 0xFC, 0x0F, 0xE0,
/* 0x8B */ 0x2F, 0x49, 0x99,
/* 0x8C */ 0x07, 0xCF, 0xFC, 0x7F, 0xFF, 0xF3, 0x83, 0xC0, 0x18, 0x07, 0x00, 0x60, 0x0C, 0x03, 0x00, 0x30, 0x0C, 0x00, 0xC0, 0x30, 0x03, 0x00, 0xC0, 0x0F, 0xFF, 0x00, 0x3F, 0xFC, 0x00, 0xC0, 0x30, 0x03, 0x00, 0xC0, 0x0C, 0x01, 0x80, 0x30, 0x07, 0x01, 0xC0, 0x0E, 0x0F, 0x00, 0x1F, 0xEF, 0xFC, 0x1F, 0x3F, 0xF0,
/* 0x8D */
/* 0x8E */ 0x0C, 0xC0, 0x3C, 0x00, 0xE1, 0xFF, 0xFF, 0xFF, 0x80, 0x1C, 0x01, 0xC0, 0x1C, 0x00, 0xC0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0x60, 0x07, 0x00, 0x70, 0x07, 0x00, 0x30, 0x03, 0x80, 0x38, 0x01, 0xFF, 0xFF, 0xFF, 0x80,
/* 0x8F */
/* 0x90 */
/* 0x91 */ 0x6A, 0xF0,
/* 0x92 */ 0xF5, 0x60,
/* 0x93 */ 0x4E, 0x28, 0xA2, 0xCF, 0x30,
/* 0x94 */ 0xCF, 0x34, 0x51, 0x4E, 0x20,
/* 0x95 */ 0x7B, 0xFF, 0xFF, 0xFD, 0xE0,
/* 0x96 */ 0xFF, 0xFF, 0xF0,
/* 0x97 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
/* 0x98 */ 0x63, 0xFE, 0x70,
/* 0x99 */ 0xFF, 0x70, 0x1F, 0xFD, 0xC0, 0x71, 0x87, 0x83, 0xC6, 0x1E, 0x0F, 0x18, 0x68, 0x3C, 0x61, 0xB1, 0xB1, 0x86, 0xC6, 0xC6, 0x19, 0x1B, 0x18, 0x66, 0xCC, 0x61, 0x9B, 0x31, 0x86, 0x3C, 0xC6, 0x18, 0xE3, 0x18, 0x63, 0x8C,
/* 0x9A */ 0x63, 0x0D, 0x83, 0x60, 0x70, 0x00, 0x0F, 0x87, 0xFB, 0x86, 0xC0, 0x30, 0x0F, 0x01, 0xFC, 0x0F, 0xC0, 0x7C, 0x0F, 0x87, 0x7F, 0x8F, 0xC0,
/* 0x9B */ 0x99, 0x92, 0xF4,
/* 0x9C */ 0x1F, 0x0F, 0x83, 0xF9, 0xFC, 0x71, 0xF8, 0x6E, 0x0F, 0x03, 0xC0, 0x60, 0x3C, 0x07, 0xFF, 0xC0, 0x7F, 0xFC, 0x06, 0x00, 0xC0, 0x60, 0x0E, 0x0F, 0x03, 0x71, 0xF8, 0x63, 0xF9, 0xFC, 0x1F, 0x0F, 0x80,
/* 0x9D */
/* 0x9E */ 0x63, 0x0C, 0x83, 0x60, 0x70, 0x00, 0x3F, 0xFF, 0xFC, 0x06, 0x03, 0x01, 0xC0, 0xE0, 0x70, 0x18, 0x0C, 0x06, 0x03, 0x80, 0xFF, 0xFF, 0xF0,
/* 0x9F */ 0x0C, 0xC0, 0x33, 0x00, 0x00, 0x30, 0x03, 0xE0, 0x1D, 0x80, 0x67, 0x03, 0x0E, 0x1C, 0x18, 0x60, 0x73, 0x80, 0xCC, 0x03, 0xE0, 0x07, 0x80, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00,
/* 0xA0 */
/* 0xA1 */ 0xF0, 0xBF, 0xFF, 0xFF, 0xF0,
/* 0xA2 */ 0x04, 0x00, 0x80, 0x7C, 0x1F, 0xE7, 0x4C, 0xC8, 0xF1, 0x1E, 0x20, 0xC4, 0x18, 0x83, 0x10, 0x72, 0x37, 0x4E, 0x7F, 0x87, 0xC0, 0x20, 0x04, 0x00,
/* 0xA3 */ 0x0F, 0xC1, 0xFE, 0x38, 0x76, 0x03, 0x60, 0x36, 0x00, 0x70, 0x03, 0x80, 0xFF, 0x0F, 0xF0, 0x1C, 0x00, 0xC0, 0x0C, 0x01, 0x80, 0x10, 0x02, 0xF1, 0x7F, 0xF6, 0x1F,
/* 0xA4 */ 0xDD, 0xFF, 0xD8, 0xD8, 0x3C, 0x1E, 0x0F, 0x8D, 0xFF, 0xDD, 0x80,
/* 0xA5 */ 0xC0, 0x3E, 0x06, 0x60, 0x63, 0x0C, 0x30, 0xC1, 0x98, 0x19, 0x80, 0xF0, 0x0F, 0x07, 0xFE, 0x06, 0x00, 0x60, 0x7F, 0xE0, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00,
/* 0xA6 */ 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFC,
/* 0xA7 */ 0x0F, 0x03, 0xF0, 0xE7, 0x18, 0x63, 0x0C, 0x70, 0x07, 0x03, 0xF8, 0xC3, 0x98, 0x3B, 0x03, 0xF0, 0x37, 0x06, 0x78, 0xC7, 0xB0, 0x7C, 0x03, 0x80, 0x39, 0x83, 0x30, 0x67, 0x1C, 0x7F, 0x07, 0xC0,
/* 0xA8 */ 0xCF, 0x30,
/* 0xA9 */ 0x03, 0xF0, 0x03, 0xFF, 0x01, 0xE0, 0xE0, 0xE3, 0x1C, 0x73, 0xF3, 0x99, 0x86, 0x6C, 0xC1, 0x8F, 0x30, 0x03, 0xCC, 0x00, 0xF3, 0x00, 0x3C, 0xC1, 0x8D, 0x98, 0x66, 0x77, 0xF3, 0x8E, 0x79, 0xC1, 0xC0, 0xE0, 0x3F, 0xF0, 0x03, 0xF0, 0x00,
/* 0xAA */ 0x79, 0x08, 0x11, 0xEE, 0x50, 0xA3, 0x3B, 0x00, 0x03, 0xF8,
/* 0xAB */ 0x21, 0x63, 0xE7, 0x84, 0x84, 0xE7, 0x63, 0x21,
/* 0xAC */ 0xFF, 0xFF, 0xFF, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03,
/* 0xAD */ 0xFF, 0xF0,
/* 0xAE */ 0x03, 0xF0, 0x03, 0xFF, 0x01, 0xE0, 0xE0, 0xFF, 0x1C, 0x7F, 0xF3, 0x9B, 0x04, 0x6C, 0xC1, 0x8F, 0x30, 0x43, 0xCF, 0xF0, 0xF3, 0xFC, 0x3C, 0xC1, 0x0D, 0xB0, 0x66, 0x7C, 0x1B, 0x8F, 0x07, 0xC1, 0xC0, 0xE0, 0x3F, 0xF0, 0x03, 0xF0, 0x00,
/* 0xAF */ 0xFF, 0xF0,
/* 0xB0 */ 0x38, 0xFB, 0x1C, 0x18, 0x38, 0xDF, 0x1C,
/* 0xB1 */ 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x7F, 0xE7, 0xFE, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF0,
/* 0xB2 */ 0x7D, 0x8F, 0x18, 0x30, 0xC6, 0x18, 0x60, 0xFF, 0xFC,
/* 0xB3 */ 0x7D, 0x8F, 0x18, 0x31, 0x80, 0xC1, 0xE3, 0xC6, 0xF8,
/* 0xB4 */ 0x3B, 0x99, 0x80,
/* 0xB5 */ 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x0C, 0xC0, 0xCC, 0x1C, 0xE3, 0xCF, 0xEF, 0xFC, 0x7C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x00,
/* 0xB6 */ 0x1F, 0xE7, 0xFD, 0xF3, 0x7E, 0x6F, 0xCD, 0xF9, 0xBF, 0x37, 0xE6, 0x7C, 0xCF, 0x98, 0xF3, 0x06, 0x60, 0xCC, 0x19, 0x83, 0x30, 0x66, 0x0C, 0xC1, 0x98, 0x33, 0x06, 0x60, 0xCC,
/* 0xB7 */ 0xF0,
/* 0xB8 */ 0x10, 0xF0, 0xE3, 0x78,
/* 0xB9 */ 0x2F, 0xB6, 0xDB, 0x6C,
/* 0xBA */ 0x79, 0x38, 0x61, 0x86, 0x1C, 0xDE, 0x00, 0x0F, 0xC0,
/* 0xBB */ 0x88, 0xC6, 0xE7, 0x21, 0x21, 0xE7, 0xC6, 0x88,
/* 0xBC */ 0x20, 0x08, 0x30, 0x0C, 0x38, 0x04, 0x0C, 0x06, 0x06, 0x02, 0x03, 0x02, 0x01, 0x81, 0x00, 0xC1, 0x06, 0x61, 0x87, 0x30, 0x83, 0x80, 0xC2, 0xC0, 0x42, 0x60, 0x43, 0x30, 0x21, 0xFC, 0x20, 0x0C, 0x30, 0x06, 0x10, 0x03, 0x00,
/* 0xBD */ 0x20, 0x00, 0x08, 0x02, 0x06, 0x01, 0x83, 0x80, 0x40, 0x60, 0x20, 0x18, 0x18, 0x06, 0x04, 0x01, 0x83, 0x00, 0x61, 0x9F, 0x98, 0x4E, 0x76, 0x33, 0x0C, 0x08, 0x03, 0x04, 0x03, 0x83, 0x01, 0x80, 0x81, 0x80, 0x60, 0xC0, 0x30, 0x3F, 0xC8, 0x0F, 0xF0,
/* 0xBE */ 0x7C, 0x00, 0x18, 0xC0, 0x43, 0x18, 0x18, 0x03, 0x02, 0x00, 0x60, 0xC0, 0x30, 0x10, 0x01, 0x84, 0x00, 0x31, 0x80, 0xC6, 0x20, 0xD8, 0xC8, 0x39, 0xF1, 0x07, 0x00, 0x41, 0x60, 0x18, 0x4C, 0x02, 0x11, 0x80, 0x83, 0xF8, 0x10, 0x06, 0x04, 0x00, 0xC1, 0x00, 0x18,
/* 0xBF */ 0x0C, 0x06, 0x00, 0x00, 0x00, 0xC0, 0x60, 0x60, 0x30, 0x30, 0x38, 0x38, 0x18, 0x0C, 0x06, 0x0F, 0x07, 0xC7, 0x7F, 0x1F, 0x00,
/* 0xC0 */ 0x0C, 0xDB, 0xD3, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
/* 0xC1 */ 0x03, 0x80, 0x07, 0x00, 0x1B, 0x00, 0x36, 0x00, 0xEE, 0x01, 0x8C, 0x03, 0x18, 0x0C, 0x18, 0x18, 0x30, 0x30, 0x60, 0xFF, 0xE1, 0xFF, 0xC7, 0x01, 0xCC, 0x01, 0x98, 0x03, 0x60, 0x03, 0xC0, 0x06,
/* 0xC2 */ 0xFF, 0x87, 0xFF, 0x30, 0x1D, 0x80, 0x6C, 0x03, 0x60, 0x1B, 0x01, 0x9F, 0xFC, 0xFF, 0xE6, 0x03, 0xB0, 0x0F, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0xDF, 0xFE, 0xFF, 0xC0,
/* 0xC3 */ 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x00,
/* 0xC4 */ 0x01, 0xC0, 0x01, 0xC0, 0x03, 0x60, 0x03, 0x60, 0x07, 0x60, 0x06, 0x30, 0x06, 0x30, 0x0C, 0x18, 0x0C, 0x18, 0x1C, 0x18, 0x18, 0x0C, 0x18, 0x0C, 0x30, 0x06, 0x30, 0x06, 0x70, 0x06, 0x7F, 0xFF, 0x7F, 0xFF,
/* 0xC5 */ 0xFF, 0xFF, 0xFF, 0xF0, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x1F, 0xFE, 0xFF, 0xF6, 0x00, 0x30, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x1F, 0xFF, 0xFF, 0xF8,
/* 0xC6 */ 0x7F, 0xFD, 0xFF, 0xF0, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x03, 0x80, 0x1C, 0x00, 0x60, 0x03, 0x00, 0x18, 0x00, 0xE0, 0x07, 0x00, 0x18, 0x00, 0xC0, 0x06, 0x00, 0x3F, 0xFF, 0xFF, 0xFC,
/* 0xC7 */ 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x7F, 0xFF, 0xFF, 0xFE, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x18,
/* 0xC8 */ 0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0x07, 0x8E, 0x00, 0xE6, 0x00, 0x37, 0x00, 0x1F, 0x00, 0x07, 0x9F, 0xF3, 0xCF, 0xF9, 0xE0, 0x00, 0xF0, 0x00, 0x7C, 0x00, 0x76, 0x00, 0x33, 0x80, 0x38, 0xF0, 0x78, 0x3F, 0xF8, 0x07, 0xF0, 0x00,
/* 0xC9 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
/* 0xCA */ 0xC0, 0x3B, 0x01, 0xCC, 0x0E, 0x30, 0x70, 0xC3, 0x83, 0x1C, 0x0C, 0xE0, 0x37, 0x80, 0xFF, 0x03, 0xDC, 0x0E, 0x38, 0x30, 0x70, 0xC0, 0xE3, 0x03, 0x8C, 0x07, 0x30, 0x0E, 0xC0, 0x1C,
/* 0xCB */ 0x01, 0xC0, 0x00, 0xE0, 0x00, 0xD8, 0x00, 0x6C, 0x00, 0x37, 0x00, 0x31, 0x80, 0x18, 0xC0, 0x18, 0x30, 0x0C, 0x18, 0x0E, 0x0E, 0x06, 0x03, 0x03, 0x01, 0x83, 0x00, 0x61, 0x80, 0x31, 0xC0, 0x1C, 0xC0, 0x06, 0x60, 0x03, 0x00,
/* 0xCC */ 0xE0, 0x0F, 0xE0, 0x3F, 0xC0, 0x7F, 0x80, 0xFD, 0x83, 0x7B, 0x06, 0xF6, 0x0D, 0xE4, 0x13, 0xCC, 0x67, 0x98, 0xCF, 0x31, 0x9E, 0x36, 0x3C, 0x6C, 0x78, 0xD8, 0xF0, 0xA1, 0xE1, 0xC3, 0xC3, 0x86,
/* 0xCD */ 0xC0, 0x1F, 0x00, 0xFC, 0x07, 0xE0, 0x3D, 0x81, 0xEE, 0x0F, 0x30, 0x78, 0xC3, 0xC7, 0x1E, 0x18, 0xF0, 0x67, 0x83, 0xBC, 0x0D, 0xE0, 0x3F, 0x01, 0xF8, 0x07, 0xC0, 0x18,
/* 0xCE */ 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFE, 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFC,
/* 0xCF */ 0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0x07, 0x8E, 0x00, 0xE6, 0x00, 0x37, 0x00, 0x1F, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x7C, 0x00, 0x76, 0x00, 0x33, 0x80, 0x38, 0xF0, 0x78, 0x3F, 0xF8, 0x07, 0xF0, 0x00,
/* 0xD0 */ 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x18,
/* 0xD1 */ 0xFF, 0xC7, 0xFF, 0xB0, 0x0D, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x06, 0xFF, 0xF7, 0xFE, 0x30, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x18, 0x00, 0xC0, 0x00,
/* 0xD2 */
/* 0xD3 */ 0xFF, 0xEF, 0xFE, 0xC0, 0x06, 0x00, 0x30, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x0F, 0xFF, 0xFF, 0xF0,
/* 0xD4 */ 0xFF, 0xFF, 0xFF, 0xF0, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00,
/* 0xD5 */ 0xE0, 0x07, 0x60, 0x0E, 0x30, 0x1C, 0x38, 0x1C, 0x1C, 0x38, 0x0E, 0x70, 0x06, 0x60, 0x07, 0xE0, 0x03, 0xC0, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
/* 0xD6 */ 0x01, 0x80, 0x01, 0x80, 0x0F, 0xF0, 0x3F, 0xFC, 0x71, 0x8E, 0x61, 0x86, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0x61, 0x86, 0x71, 0x8E, 0x3F, 0xFC, 0x0F, 0xF0, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
/* 0xD7 */ 0x70, 0x1C, 0x70, 0x70, 0x61, 0xC0, 0xE3, 0x80, 0xEE, 0x00, 0xD8, 0x01, 0xF0, 0x01, 0xC0, 0x03, 0x80, 0x0D, 0x80, 0x3B, 0x80, 0x77, 0x01, 0xC7, 0x07, 0x07, 0x0E, 0x06, 0x38, 0x0E, 0xE0, 0x0E,
/* 0xD8 */ 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0x61, 0x86, 0x79, 0x9E, 0x3F, 0xFC, 0x0F, 0xF0, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
/* 0xD9 */ 0x07, 0xE0, 0x1F, 0xF8, 0x38, 0x3C, 0x70, 0x0E, 0x60, 0x06, 0xE0, 0x07, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0x60, 0x06, 0x60, 0x06, 0x30, 0x0C, 0x1C, 0x38, 0xFE, 0x7F, 0xFE, 0x7F,
/* 0xDA */ 0xCF, 0x30, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C,
/* 0xDB */ 0x06, 0x60, 0x06, 0x60, 0x00, 0x00, 0xE0, 0x07, 0x60, 0x0E, 0x30, 0x1C, 0x38, 0x1C, 0x1C, 0x38, 0x0E, 0x70, 0x06, 0x60, 0x07, 0xE0, 0x03, 0xC0, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
/* 0xDC */ 0x03, 0x80, 0x30, 0x06, 0x00, 0x00, 0x1E, 0x33, 0xFB, 0x71, 0xFE, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6E, 0x0E, 0x71, 0xF3, 0xFF, 0x1F, 0x30,
/* 0xDD */ 0x0C, 0x0C, 0x04, 0x00, 0x03, 0xE3, 0xFF, 0x8D, 0x80, 0xE0, 0x3E, 0x1F, 0x1C, 0x0C, 0x06, 0x0B, 0x8E, 0xFE, 0x3E, 0x00,
/* 0xDE */ 0x07, 0x01, 0x80, 0xC0, 0x00, 0xCF, 0x3F, 0xEE, 0x1F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30,
/* 0xDF */ 0x76, 0xC0, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60,
/* 0xE0 */ 0x0C, 0x1B, 0x66, 0x98, 0x00, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x36, 0x19, 0xFE, 0x1E, 0x00,
/* 0xE1 */ 0x1E, 0x33, 0xFB, 0x71, 0xFE, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x6E, 0x0E, 0x71, 0xF3, 0xFF, 0x1F, 0x30,
/* 0xE2 */ 0x1F, 0x0F, 0xF1, 0x87, 0x60, 0x6C, 0x0D, 0x83, 0x33, 0x86, 0x7C, 0xC1, 0xD8, 0x1F, 0x01, 0xE0, 0x3C, 0x07, 0xC0, 0xFC, 0x36, 0xFE, 0xCF, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x00,
/* 0xE3 */ 0x60, 0x66, 0x06, 0x60, 0x63, 0x0C, 0x30, 0xC3, 0x8C, 0x19, 0x81, 0x98, 0x1F, 0x80, 0xF0, 0x0F, 0x00, 0xF0, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60,
/* 0xE4 */ 0x7F, 0xCF, 0xF8, 0xE0, 0x07, 0x01, 0xF0, 0x7F, 0x1C, 0x77, 0x07, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0xC1, 0x9C, 0x71, 0xFC, 0x1F, 0x00,
/* 0xE5 */ 0x3E, 0x3F, 0xF8, 0xD8, 0x0E, 0x03, 0xE1, 0xF1, 0xC0, 0xC0, 0x60, 0xB8, 0xEF, 0xE3, 0xE0,
/* 0xE6 */ 0x3F, 0x9F, 0xC0, 0xC1, 0xC1, 0xC0, 0xC0, 0xC0, 0xC0, 0x60, 0x70, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x80, 0xFC, 0x3F, 0x80, 0xC0, 0x60, 0x70, 0xF0, 0x70,
/* 0xE7 */ 0xCF, 0x3F, 0xEE, 0x1F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30,
/* 0xE8 */ 0x1F, 0x07, 0xF1, 0xC7, 0x30, 0x6C, 0x07, 0x80, 0xF0, 0x1F, 0xFF, 0xFF, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x0E, 0xC1, 0x9C, 0x71, 0xFC, 0x1F, 0x00,
/* 0xE9 */ 0xFF, 0xFF, 0xFF, 0xC0,
/* 0xEA */ 0xC1, 0xB0, 0xCC, 0x63, 0x30, 0xD8, 0x3C, 0x0F, 0x83, 0x60, 0xCC, 0x31, 0x8C, 0x73, 0x0C, 0xC1, 0x80,
/* 0xEB */ 0x0C, 0x00, 0x60, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x01, 0x80, 0x1C, 0x00, 0xF0, 0x0D, 0x80, 0x6C, 0x06, 0x30, 0x31, 0x83, 0x8E, 0x18, 0x30, 0xC1, 0x8C, 0x06, 0x60, 0x30,
/* 0xEC */ 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF8, 0x7E, 0x1F, 0xFF, 0xDE, 0xF0, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x00,
/* 0xED */ 0xC0, 0x78, 0x0D, 0x83, 0x30, 0x66, 0x0C, 0x63, 0x0C, 0x60, 0xD8, 0x1B, 0x03, 0x60, 0x38, 0x07, 0x00, 0x40,
/* 0xEE */ 0x1F, 0x1F, 0x9C, 0x0C, 0x07, 0x01, 0xF8, 0x3C, 0x70, 0x70, 0x30, 0x30, 0x18, 0x0C, 0x06, 0x01, 0xC0, 0xFC, 0x1F, 0x00, 0xC0, 0x60, 0x70, 0xF0, 0x70,
/* 0xEF */ 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x7C, 0x1D, 0xC7, 0x1F, 0xC1, 0xF0,
/* 0xF0 */ 0xFF, 0xFF, 0xFF, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
/* 0xF1 */ 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x6C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x7C, 0x1F, 0xC7, 0x7F, 0xCD, 0xF1, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x00,
/* 0xF2 */ 0x07, 0xE3, 0xFC, 0xE0, 0x30, 0x06, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x1C, 0x01, 0xC0, 0x1F, 0x80, 0xF8, 0x03, 0x80, 0x30, 0x0E, 0x0F, 0x81, 0xE0,
/* 0xF3 */ 0x1F, 0xF9, 0xFF, 0xDC, 0x39, 0xC0, 0xCC, 0x03, 0x60, 0x1B, 0x00, 0xD8, 0x06, 0xC0, 0x37, 0x03, 0x9C, 0x38, 0x7F, 0x81, 0xF8, 0x00,
/* 0xF4 */ 0xFF, 0xF3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30,
/* 0xF5 */ 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x36, 0x19, 0xFE, 0x1E, 0x00,
/* 0xF6 */ 0x19, 0xE0, 0xEF, 0xC6, 0x31, 0xB8, 0xC3, 0xC3, 0x0F, 0x0C, 0x3C, 0x30, 0xF0, 0xC3, 0xE3, 0x1D, 0x8C, 0x67, 0xB7, 0x0F, 0xF8, 0x0F, 0xC0, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00,
/* 0xF7 */ 0x60, 0x33, 0x03, 0x8C, 0x18, 0x71, 0xC1, 0x8C, 0x0E, 0xC0, 0x36, 0x00, 0xE0, 0x07, 0x00, 0x38, 0x01, 0xC0, 0x1B, 0x00, 0xDC, 0x0C, 0x60, 0xE3, 0x86, 0x0C, 0x70, 0x33, 0x01, 0x80,
/* 0xF8 */ 0xC3, 0x0F, 0x0C, 0x3C, 0x30, 0xF0, 0xC3, 0xC3, 0x0F, 0x0C, 0x3C, 0x30, 0xF0, 0xC3, 0xC3, 0x0F, 0x8C, 0x77, 0x33, 0x8F, 0xFC, 0x1F, 0xE0, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00,
/* 0xF9 */ 0x30, 0x0C, 0x60, 0x06, 0x60, 0x06, 0xE1, 0x87, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xE1, 0x87, 0x63, 0xC6, 0x7E, 0x7E, 0x3C, 0x38,
/* 0xFA */ 0xCF, 0x30, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C,
/* 0xFB */ 0x33, 0x0C, 0xC0, 0x03, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xD8, 0x67, 0xF8, 0x78,
/* 0xFC */ 0x07, 0x00, 0xC0, 0x30, 0x00, 0x01, 0xF0, 0x7F, 0x1C, 0x77, 0x07, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0xC1, 0xDC, 0x71, 0xFC, 0x1F, 0x00,
/* 0xFD */ 0x06, 0x03, 0x00, 0x80, 0x00, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x36, 0x19, 0xFE, 0x1E, 0x00,
/* 0xFE */ 0x00, 0xC0, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x30, 0x0C, 0x60, 0x06, 0x60, 0x06, 0xE1, 0x87, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xE1, 0x87, 0x63, 0xC6, 0x7E, 0x7E, 0x3C, 0x38,
/* 0xFF */
};
const GFXglyph FreeSans12pt_Win1253Glyphs[] PROGMEM = {
/* 0x01 */ { 0, 19, 20, 21, 1, -17 },
/* 0x02 */ { 48, 19, 20, 21, 1, -17 },
/* 0x03 */ { 96, 21, 20, 23, 1, -17 },
/* 0x04 */ { 149, 21, 20, 23, 1, -17 },
/* 0x05 */ { 202, 20, 20, 22, 1, -17 },
/* 0x06 */ { 252, 20, 20, 22, 1, -17 },
/* 0x07 */ { 302, 0, 0, 8, 0, 0 },
/* 0x08 */ { 302, 23, 20, 25, 1, -17 },
/* 0x09 */ { 360, 23, 16, 25, 1, -16 },
/* 0x0A */ { 406, 0, 0, 8, 0, 0 },
/* 0x0B */ { 406, 21, 20, 23, 1, -17 },
/* 0x0C */ { 459, 19, 18, 21, 1, -15 },
/* 0x0D */ { 502, 0, 0, 8, 0, 0 },
/* 0x0E */ { 502, 20, 20, 22, 1, -17 },
/* 0x0F */ { 552, 21, 21, 23, 1, -18 },
/* 0x10 */ { 608, 19, 20, 21, 1, -17 },
/* 0x11 */ { 656, 21, 20, 23, 1, -17 },
/* 0x12 */ { 709, 20, 20, 22, 1, -17 },
/* 0x13 */ { 759, 21, 20, 23, 1, -17 },
/* 0x14 */ { 812, 21, 20, 23, 1, -17 },
/* 0x15 */ { 865, 22, 20, 24, 1, -17 },
/* 0x16 */ { 920, 16, 20, 18, 1, -17 },
/* 0x17 */ { 960, 21, 20, 23, 1, -17 },
/* 0x18 */ { 1013, 23, 20, 25, 1, -17 },
/* 0x19 */ { 1071, 21, 20, 23, 1, -17 },
/* 0x1A */ { 1124, 15, 19, 17, 1, -16 },
/* 0x1B */ { 1160, 24, 21, 26, 1, -18 },
/* 0x1C */ { 1223, 21, 20, 23, 1, -17 },
/* 0x1D */ { 1276, 21, 21, 23, 1, -18 },
/* 0x1E */ { 1332, 20, 20, 22, 1, -17 },
/* 0x1F */ { 1382, 15, 20, 17, 1, -17 },
/* ' ' 0x20 */ { 1420, 0, 0, 6, 0, 0 },
/* '!' 0x21 */ { 1420, 2, 18, 8, 3, -16 },
/* '"' 0x22 */ { 1425, 6, 6, 8, 1, -15 },
/* '#' 0x23 */ { 1430, 13, 16, 13, 0, -14 },
/* '$' 0x24 */ { 1456, 11, 20, 13, 1, -16 },
/* '%' 0x25 */ { 1484, 20, 17, 21, 1, -15 },
/* '&' 0x26 */ { 1527, 14, 17, 16, 1, -15 },
/* ''' 0x27 */ { 1557, 2, 6, 5, 1, -15 },
/* '(' 0x28 */ { 1559, 5, 23, 8, 2, -16 },
/* ')' 0x29 */ { 1574, 5, 23, 8, 1, -16 },
/* '*' 0x2A */ { 1589, 7, 7, 9, 1, -16 },
/* '+' 0x2B */ { 1596, 10, 11, 14, 2, -9 },
/* ',' 0x2C */ { 1610, 2, 6, 7, 2, 0 },
/* '-' 0x2D */ { 1612, 6, 2, 8, 1, -6 },
/* '.' 0x2E */ { 1614, 2, 2, 6, 2, 0 },
/* '/' 0x2F */ { 1615, 7, 18, 7, 0, -16 },
/* '0' 0x30 */ { 1631, 11, 17, 13, 1, -15 },
/* '1' 0x31 */ { 1655, 5, 17, 13, 3, -15 },
/* '2' 0x32 */ { 1666, 11, 17, 13, 1, -15 },
/* '3' 0x33 */ { 1690, 11, 17, 13, 1, -15 },
/* '4' 0x34 */ { 1714, 11, 17, 13, 1, -15 },
/* '5' 0x35 */ { 1738, 11, 17, 13, 1, -15 },
/* '6' 0x36 */ { 1762, 11, 17, 13, 1, -15 },
/* '7' 0x37 */ { 1786, 11, 17, 13, 1, -15 },
/* '8' 0x38 */ { 1810, 11, 17, 13, 1, -15 },
/* '9' 0x39 */ { 1834, 11, 17, 13, 1, -15 },
/* ':' 0x3A */ { 1858, 2, 13, 6, 2, -11 },
/* ';' 0x3B */ { 1862, 2, 16, 6, 2, -10 },
/* '<' 0x3C */ { 1866, 12, 11, 14, 1, -9 },
/* '=' 0x3D */ { 1883, 12, 6, 14, 1, -7 },
/* '>' 0x3E */ { 1892, 12, 11, 14, 1, -9 },
/* '?' 0x3F */ { 1909, 10, 18, 13, 2, -16 },
/* '@' 0x40 */ { 1932, 22, 21, 24, 1, -16 },
/* 'A' 0x41 */ { 1990, 14, 18, 16, 1, -16 },
/* 'B' 0x42 */ { 2022, 13, 18, 16, 2, -16 },
/* 'C' 0x43 */ { 2052, 15, 18, 17, 1, -16 },
/* 'D' 0x44 */ { 2086, 14, 18, 17, 2, -16 },
/* 'E' 0x45 */ { 2118, 12, 18, 15, 2, -16 },
/* 'F' 0x46 */ { 2145, 11, 18, 14, 2, -16 },
/* 'G' 0x47 */ { 2170, 16, 18, 18, 1, -16 },
/* 'H' 0x48 */ { 2206, 13, 18, 17, 2, -16 },
/* 'I' 0x49 */ { 2236, 2, 18, 7, 2, -16 },
/* 'J' 0x4A */ { 2241, 9, 18, 13, 1, -16 },
/* 'K' 0x4B */ { 2262, 13, 18, 16, 2, -16 },
/* 'L' 0x4C */ { 2292, 10, 18, 14, 2, -16 },
/* 'M' 0x4D */ { 2315, 16, 18, 20, 2, -16 },
/* 'N' 0x4E */ { 2351, 13, 18, 18, 2, -16 },
/* 'O' 0x4F */ { 2381, 17, 18, 19, 1, -16 },
/* 'P' 0x50 */ { 2420, 12, 18, 16, 2, -16 },
/* 'Q' 0x51 */ { 2447, 17, 19, 19, 1, -16 },
/* 'R' 0x52 */ { 2488, 14, 18, 17, 2, -16 },
/* 'S' 0x53 */ { 2520, 14, 18, 16, 1, -16 },
/* 'T' 0x54 */ { 2552, 12, 18, 15, 1, -16 },
/* 'U' 0x55 */ { 2579, 13, 18, 17, 2, -16 },
/* 'V' 0x56 */ { 2609, 14, 18, 15, 1, -16 },
/* 'W' 0x57 */ { 2641, 22, 18, 22, 0, -16 },
/* 'X' 0x58 */ { 2691, 14, 18, 16, 1, -16 },
/* 'Y' 0x59 */ { 2723, 14, 18, 16, 1, -16 },
/* 'Z' 0x5A */ { 2755, 13, 18, 15, 1, -16 },
/* '[' 0x5B */ { 2785, 4, 23, 7, 2, -16 },
/* '\' 0x5C */ { 2797, 7, 18, 7, 0, -16 },
/* ']' 0x5D */ { 2813, 4, 23, 7, 1, -16 },
/* '^' 0x5E */ { 2825, 9, 9, 11, 1, -15 },
/* '_' 0x5F */ { 2836, 15, 1, 13, -1, 5 },
/* '`' 0x60 */ { 2838, 5, 4, 6, 1, -16 },
/* 'a' 0x61 */ { 2841, 12, 13, 13, 1, -11 },
/* 'b' 0x62 */ { 2861, 12, 18, 13, 1, -16 },
/* 'c' 0x63 */ { 2888, 10, 13, 12, 1, -11 },
/* 'd' 0x64 */ { 2905, 11, 18, 13, 1, -16 },
/* 'e' 0x65 */ { 2930, 11, 13, 13, 1, -11 },
/* 'f' 0x66 */ { 2948, 5, 18, 7, 1, -16 },
/* 'g' 0x67 */ { 2960, 11, 18, 13, 1, -11 },
/* 'h' 0x68 */ { 2985, 10, 18, 13, 1, -16 },
/* 'i' 0x69 */ { 3008, 2, 18, 5, 2, -16 },
/* 'j' 0x6A */ { 3013, 4, 23, 6, 0, -16 },
/* 'k' 0x6B */ { 3025, 10, 18, 12, 1, -16 },
/* 'l' 0x6C */ { 3048, 2, 18, 5, 1, -16 },
/* 'm' 0x6D */ { 3053, 17, 13, 19, 1, -11 },
/* 'n' 0x6E */ { 3081, 10, 13, 13, 1, -11 },
/* 'o' 0x6F */ { 3098, 11, 13, 13, 1, -11 },
/* 'p' 0x70 */ { 3116, 12, 17, 13, 1, -11 },
/* 'q' 0x71 */ { 3142, 11, 17, 13, 1, -11 },
/* 'r' 0x72 */ { 3166, 6, 13, 8, 1, -11 },
/* 's' 0x73 */ { 3176, 10, 13, 12, 1, -11 },
/* 't' 0x74 */ { 3193, 5, 16, 7, 1, -14 },
/* 'u' 0x75 */ { 3203, 10, 13, 13, 1, -11 },
/* 'v' 0x76 */ { 3220, 11, 13, 12, 0, -11 },
/* 'w' 0x77 */ { 3238, 17, 13, 17, 0, -11 },
/* 'x' 0x78 */ { 3266, 10, 13, 11, 1, -11 },
/* 'y' 0x79 */ { 3283, 11, 18, 11, 0, -11 },
/* 'z' 0x7A */ { 3308, 10, 13, 12, 1, -11 },
/* '{' 0x7B */ { 3325, 5, 23, 8, 1, -16 },
/* '|' 0x7C */ { 3340, 2, 23, 6, 2, -16 },
/* '}' 0x7D */ { 3346, 5, 23, 8, 2, -16 },
/* '~' 0x7E */ { 3361, 10, 5, 12, 1, -9 },
/* 0x7F */ { 3368, 0, 0, 0, 0, 0 },
/* 0x80 */ { 3368, 14, 17, 16, 1, -15 },
/* 0x81 */ { 3398, 0, 0, 8, 0, 0 },
/* 0x82 */ { 3398, 2, 5, 6, 2, 0 },
/* 0x83 */ { 3400, 6, 23, 7, 0, -16 },
/* 0x84 */ { 3418, 6, 5, 10, 2, 0 },
/* 0x85 */ { 3422, 12, 2, 16, 2, 0 },
/* 0x86 */ { 3425, 10, 21, 13, 2, -15 },
/* 0x87 */ { 3452, 10, 20, 13, 2, -15 },
/* 0x88 */ { 3477, 7, 4, 8, 0, -16 },
/* 0x89 */ { 3481, 23, 18, 24, 0, -16 },
/* 0x8A */ { 3533, 14, 21, 16, 1, -19 },
/* 0x8B */ { 3570, 3, 8, 6, 1, -9 },
/* 0x8C */ { 3573, 22, 18, 24, 1, -16 },
/* 0x8D */ { 3623, 0, 0, 8, 0, 0 },
/* 0x8E */ { 3623, 13, 21, 15, 1, -19 },
/* 0x8F */ { 3658, 0, 0, 8, 0, 0 },
/* 0x90 */ { 3658, 0, 0, 8, 0, 0 },
/* 0x91 */ { 3658, 2, 6, 6, 2, -16 },
/* 0x92 */ { 3660, 2, 6, 6, 2, -16 },
/* 0x93 */ { 3662, 6, 6, 10, 2, -16 },
/* 0x94 */ { 3667, 6, 6, 10, 2, -16 },
/* 0x95 */ { 3672, 6, 6, 10, 2, -9 },
/* 0x96 */ { 3677, 10, 2, 12, 1, -6 },
/* 0x97 */ { 3680, 22, 2, 24, 1, -6 },
/* 0x98 */ { 3686, 7, 3, 8, 0, -16 },
/* 0x99 */ { 3689, 22, 13, 24, 2, -16 },
/* 0x9A */ { 3725, 10, 18, 12, 1, -16 },
/* 0x9B */ { 3748, 3, 8, 6, 2, -8 },
/* 0x9C */ { 3751, 20, 13, 22, 1, -11 },
/* 0x9D */ { 3784, 0, 0, 8, 0, 0 },
/* 0x9E */ { 3784, 10, 18, 12, 1, -16 },
/* 0x9F */ { 3807, 14, 21, 16, 1, -19 },
/* 0xA0 */ { 3844, 0, 0, 7, 0, 0 },
/* 0xA1 */ { 3844, 2, 18, 8, 3, -11 },
/* 0xA2 */ { 3849, 11, 17, 13, 1, -13 },
/* 0xA3 */ { 3873, 12, 18, 13, 0, -16 },
/* 0xA4 */ { 3900, 9, 9, 13, 2, -11 },
/* 0xA5 */ { 3911, 12, 17, 13, 1, -15 },
/* 0xA6 */ { 3937, 2, 23, 6, 2, -16 },
/* 0xA7 */ { 3943, 11, 23, 13, 1, -16 },
/* 0xA8 */ { 3975, 6, 2, 8, 1, -15 },
/* 0xA9 */ { 3977, 18, 17, 19, 1, -15 },
/* 0xAA */ { 4016, 7, 11, 9, 1, -16 },
/* 0xAB */ { 4026, 8, 8, 12, 2, -9 },
/* 0xAC */ { 4034, 12, 6, 14, 1, -7 },
/* 0xAD */ { 4043, 6, 2, 8, 1, -6 },
/* 0xAE */ { 4045, 18, 17, 19, 1, -15 },
/* 0xAF */ { 4084, 6, 2, 8, 1, -15 },
/* 0xB0 */ { 4086, 7, 8, 15, 4, -15 },
/* 0xB1 */ { 4093, 12, 15, 14, 1, -13 },
/* 0xB2 */ { 4116, 7, 10, 8, 1, -17 },
/* 0xB3 */ { 4125, 7, 10, 8, 1, -17 },
/* 0xB4 */ { 4134, 5, 4, 8, 2, -16 },
/* 0xB5 */ { 4137, 12, 17, 13, 2, -11 },
/* 0xB6 */ { 4163, 11, 21, 13, 2, -16 },
/* 0xB7 */ { 4192, 2, 2, 6, 2, -6 },
/* 0xB8 */ { 4193, 6, 5, 8, 1, 2 },
/* 0xB9 */ { 4197, 3, 10, 8, 3, -18 },
/* 0xBA */ { 4201, 6, 11, 9, 1, -16 },
/* 0xBB */ { 4210, 8, 8, 12, 2, -8 },
/* 0xBC */ { 4218, 17, 17, 21, 3, -15 },
/* 0xBD */ { 4255, 18, 18, 21, 3, -16 },
/* 0xBE */ { 4296, 19, 18, 21, 1, -16 },
/* 0xBF */ { 4339, 9, 18, 13, 3, -11 },
/* 0xC0 */ { 4360, 8, 18, 6, -1, -18 },
/* 0xC1 */ { 4378, 15, 17, 15, 0, -17 },
/* 0xC2 */ { 4410, 13, 17, 16, 2, -17 },
/* 0xC3 */ { 4438, 11, 17, 13, 2, -17 },
/* 0xC4 */ { 4462, 16, 17, 16, -1, -17 },
/* 0xC5 */ { 4496, 13, 17, 16, 2, -17 },
/* 0xC6 */ { 4524, 14, 17, 15, 0, -17 },
/* 0xC7 */ { 4554, 13, 17, 17, 2, -17 },
/* 0xC8 */ { 4582, 17, 17, 19, 1, -17 },
/* 0xC9 */ { 4619, 2, 17, 6, 2, -17 },
/* 0xCA */ { 4624, 14, 17, 16, 2, -17 },
/* 0xCB */ { 4654, 17, 17, 16, -1, -17 },
/* 0xCC */ { 4691, 15, 17, 19, 2, -17 },
/* 0xCD */ { 4723, 13, 17, 17, 2, -17 },
/* 0xCE */ { 4751, 14, 17, 16, 1, -17 },
/* 0xCF */ { 4781, 17, 17, 19, 1, -17 },
/* 0xD0 */ { 4818, 13, 17, 17, 2, -17 },
/* 0xD1 */ { 4846, 13, 17, 16, 2, -17 },
/* 0xD2 */ { 4874, 0, 0, 5, 0, 0 },
/* 0xD3 */ { 4874, 12, 17, 15, 2, -17 },
/* 0xD4 */ { 4900, 14, 17, 14, 0, -17 },
/* 0xD5 */ { 4930, 16, 17, 16, 0, -17 },
/* 0xD6 */ { 4964, 16, 17, 18, 1, -17 },
/* 0xD7 */ { 4998, 15, 17, 15, 0, -17 },
/* 0xD8 */ { 5030, 16, 17, 19, 2, -17 },
/* 0xD9 */ { 5064, 16, 17, 18, 1, -17 },
/* 0xDA */ { 5098, 6, 20, 6, 0, -20 },
/* 0xDB */ { 5113, 16, 20, 16, 0, -20 },
/* 0xDC */ { 5153, 12, 17, 14, 1, -17 },
/* 0xDD */ { 5179, 9, 17, 11, 1, -17 },
/* 0xDE */ { 5199, 10, 22, 14, 2, -17 },
/* 0xDF */ { 5227, 4, 17, 6, 1, -17 },
/* 0xE0 */ { 5236, 10, 17, 14, 2, -17 },
/* 0xE1 */ { 5258, 12, 13, 14, 1, -13 },
/* 0xE2 */ { 5278, 11, 22, 14, 2, -17 },
/* 0xE3 */ { 5309, 12, 18, 11, -1, -13 },
/* 0xE4 */ { 5336, 11, 17, 13, 1, -17 },
/* 0xE5 */ { 5360, 9, 13, 11, 1, -13 },
/* 0xE6 */ { 5375, 9, 22, 11, 1, -17 },
/* 0xE7 */ { 5400, 10, 18, 14, 2, -13 },
/* 0xE8 */ { 5423, 11, 17, 13, 1, -17 },
/* 0xE9 */ { 5447, 2, 13, 6, 2, -13 },
/* 0xEA */ { 5451, 10, 13, 12, 2, -13 },
/* 0xEB */ { 5468, 13, 17, 12, -1, -17 },
/* 0xEC */ { 5496, 10, 18, 14, 2, -13 },
/* 0xED */ { 5519, 11, 13, 11, 0, -13 },
/* 0xEE */ { 5537, 9, 22, 11, 1, -17 },
/* 0xEF */ { 5562, 11, 13, 13, 1, -13 },
/* 0xF0 */ { 5580, 16, 13, 17, 0, -13 },
/* 0xF1 */ { 5606, 11, 18, 14, 2, -13 },
/* 0xF2 */ { 5631, 11, 18, 12, 1, -13 },
/* 0xF3 */ { 5656, 13, 13, 15, 1, -13 },
/* 0xF4 */ { 5678, 6, 13, 9, 1, -13 },
/* 0xF5 */ { 5688, 10, 13, 14, 2, -13 },
/* 0xF6 */ { 5705, 14, 18, 16, 1, -13 },
/* 0xF7 */ { 5737, 13, 18, 13, 0, -13 },
/* 0xF8 */ { 5767, 14, 18, 18, 2, -13 },
/* 0xF9 */ { 5799, 16, 13, 18, 1, -13 },
/* 0xFA */ { 5825, 6, 16, 6, 0, -16 },
/* 0xFB */ { 5837, 10, 16, 14, 2, -16 },
/* 0xFC */ { 5857, 11, 17, 13, 1, -17 },
/* 0xFD */ { 5881, 10, 17, 14, 2, -17 },
/* 0xFE */ { 5903, 16, 17, 18, 1, -17 },
/* 0xFF */ { 5937, 0, 0, 5, 0, 0 },
};
const GFXfont FreeSans12pt_Win1253 PROGMEM = {
(uint8_t*)FreeSans12pt_Win1253Bitmaps,
(GFXglyph*)FreeSans12pt_Win1253Glyphs,
0x01, 0xFF, 19
};
@@ -0,0 +1,198 @@
#pragma once
const uint8_t FreeSans6pt7bBitmaps[] PROGMEM = {
/* ' ' 0x20 */
/* '!' 0x21 */ 0xFE, 0x80,
/* '"' 0x22 */ 0xB6, 0x80,
/* '#' 0x23 */ 0x24, 0x49, 0xF9, 0x42, 0x9F, 0x92, 0x28,
/* '$' 0x24 */ 0x23, 0xAB, 0x5A, 0x38, 0xB5, 0xAB, 0x88,
/* '%' 0x25 */ 0x71, 0x22, 0x88, 0xA2, 0x30, 0x74, 0x02, 0x60, 0xA4, 0x49, 0x11, 0x80,
/* '&' 0x26 */ 0x31, 0x24, 0x8C, 0x72, 0x58, 0xA3, 0x74,
/* ''' 0x27 */ 0xE0,
/* '(' 0x28 */ 0x5A, 0xAA, 0x94,
/* ')' 0x29 */ 0x89, 0x12, 0x49, 0x49, 0x00,
/* '*' 0x2A */ 0x5E, 0x80,
/* '+' 0x2B */ 0x21, 0x3E, 0x42, 0x00,
/* ',' 0x2C */ 0xE0,
/* '-' 0x2D */ 0xE0,
/* '.' 0x2E */ 0x80,
/* '/' 0x2F */ 0x25, 0x24, 0xA4, 0x80,
/* '0' 0x30 */ 0x76, 0xE3, 0x18, 0xC6, 0x3B, 0x70,
/* '1' 0x31 */ 0x5D, 0x55, 0x40,
/* '2' 0x32 */ 0x74, 0x42, 0x11, 0x11, 0x10, 0xF8,
/* '3' 0x33 */ 0x74, 0x42, 0x13, 0x04, 0x31, 0x70,
/* '4' 0x34 */ 0x11, 0x8C, 0xA9, 0x4B, 0xE2, 0x10,
/* '5' 0x35 */ 0x7D, 0x04, 0x1E, 0x4C, 0x10, 0x63, 0x78,
/* '6' 0x36 */ 0x72, 0x61, 0xE8, 0xC6, 0x39, 0x70,
/* '7' 0x37 */ 0xF8, 0x44, 0x22, 0x11, 0x08, 0x40,
/* '8' 0x38 */ 0x7A, 0x18, 0x61, 0x7A, 0x18, 0x61, 0x78,
/* '9' 0x39 */ 0x7B, 0x28, 0x61, 0xCD, 0xD0, 0x62, 0x70,
/* ':' 0x3A */ 0x82,
/* ';' 0x3B */ 0x87,
/* '<' 0x3C */ 0x3E, 0x30, 0x60, 0x80,
/* '=' 0x3D */ 0xF8, 0x3E,
/* '>' 0x3E */ 0xE0, 0xC6, 0xC8, 0x00,
/* '?' 0x3F */ 0x74, 0x42, 0x11, 0x10, 0x80, 0x20,
/* '@' 0x40 */ 0x0F, 0x06, 0x19, 0x3B, 0xC4, 0x99, 0x13, 0x22, 0x64, 0x96, 0x6E, 0x40, 0x04, 0x00, 0x7C, 0x00,
/* 'A' 0x41 */ 0x18, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0x42, 0xC3,
/* 'B' 0x42 */ 0xFA, 0x18, 0x61, 0xFA, 0x18, 0x61, 0xF8,
/* 'C' 0x43 */ 0x3E, 0x41, 0x80, 0x80, 0x80, 0x80, 0x81, 0x43, 0x3E,
/* 'D' 0x44 */ 0xF9, 0x0A, 0x0C, 0x18, 0x30, 0x60, 0xC2, 0xF8,
/* 'E' 0x45 */ 0xFE, 0x08, 0x20, 0xFA, 0x08, 0x20, 0xFC,
/* 'F' 0x46 */ 0xFC, 0x21, 0x0F, 0xC2, 0x10, 0x80,
/* 'G' 0x47 */ 0x3E, 0x41, 0x80, 0x80, 0x87, 0x81, 0xC1, 0x43, 0x3D,
/* 'H' 0x48 */ 0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60, 0xC1, 0x82,
/* 'I' 0x49 */ 0xFF, 0x80,
/* 'J' 0x4A */ 0x08, 0x42, 0x10, 0x86, 0x31, 0x70,
/* 'K' 0x4B */ 0x86, 0x29, 0x28, 0xD2, 0x48, 0xA1, 0x84,
/* 'L' 0x4C */ 0x84, 0x21, 0x08, 0x42, 0x10, 0xF8,
/* 'M' 0x4D */ 0xC3, 0xC3, 0xC3, 0xA5, 0xA5, 0xA5, 0x99, 0x99, 0x99,
/* 'N' 0x4E */ 0xC3, 0x86, 0x8D, 0x19, 0x33, 0x62, 0xC3, 0x86,
/* 'O' 0x4F */ 0x3E, 0x31, 0xB0, 0x70, 0x18, 0x0C, 0x07, 0x06, 0xC6, 0x3E, 0x00,
/* 'P' 0x50 */ 0xFA, 0x18, 0x61, 0xFA, 0x08, 0x20, 0x80,
/* 'Q' 0x51 */ 0x3E, 0x31, 0xB0, 0x70, 0x18, 0x0C, 0x07, 0x06, 0xC6, 0x3F, 0x00, 0x40,
/* 'R' 0x52 */ 0xF9, 0x0A, 0x14, 0x2F, 0x90, 0xA1, 0x42, 0x86,
/* 'S' 0x53 */ 0x7A, 0x18, 0x30, 0x78, 0x38, 0x71, 0x78,
/* 'T' 0x54 */ 0xFC, 0x41, 0x04, 0x10, 0x41, 0x04, 0x10,
/* 'U' 0x55 */ 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xE3, 0x7C,
/* 'V' 0x56 */ 0xC2, 0x85, 0x0B, 0x22, 0x44, 0x8E, 0x0C, 0x18,
/* 'W' 0x57 */ 0x84, 0x38, 0xCD, 0x29, 0x25, 0x24, 0xA4, 0xD2, 0x8C, 0x61, 0x8C, 0x31, 0x80,
/* 'X' 0x58 */ 0x87, 0x34, 0x8C, 0x30, 0xC4, 0xA3, 0x84,
/* 'Y' 0x59 */ 0x82, 0x89, 0x11, 0x43, 0x82, 0x04, 0x08, 0x10,
/* 'Z' 0x5A */ 0x7E, 0x0C, 0x30, 0x41, 0x06, 0x18, 0x20, 0xFE,
/* '[' 0x5B */ 0xEA, 0xAA, 0xAB,
/* '\' 0x5C */ 0x92, 0x24, 0x91, 0x20,
/* ']' 0x5D */ 0xD5, 0x55, 0x57,
/* '^' 0x5E */ 0x46, 0xA9, 0x10,
/* '_' 0x5F */ 0xFE,
/* '`' 0x60 */ 0x80,
/* 'a' 0x61 */ 0x79, 0x08, 0x11, 0xEC, 0x51, 0x9D, 0x80,
/* 'b' 0x62 */ 0x84, 0x3D, 0xB8, 0xC6, 0x3B, 0xF0,
/* 'c' 0x63 */ 0x7B, 0x18, 0x20, 0x83, 0x17, 0x80,
/* 'd' 0x64 */ 0x04, 0x17, 0xF3, 0x86, 0x18, 0x73, 0x74,
/* 'e' 0x65 */ 0x7B, 0x38, 0x7F, 0x83, 0x17, 0x80,
/* 'f' 0x66 */ 0x6B, 0xA4, 0x92, 0x40,
/* 'g' 0x67 */ 0x77, 0x38, 0x61, 0x87, 0x37, 0x41, 0x8D, 0xE0,
/* 'h' 0x68 */ 0x84, 0x2D, 0x98, 0xC6, 0x31, 0x88,
/* 'i' 0x69 */ 0xBF, 0x80,
/* 'j' 0x6A */ 0x45, 0x55, 0x57,
/* 'k' 0x6B */ 0x84, 0x25, 0x6E, 0x72, 0x52, 0x88,
/* 'l' 0x6C */ 0xFF, 0x80,
/* 'm' 0x6D */ 0xFF, 0x99, 0x91, 0x91, 0x91, 0x91, 0x91,
/* 'n' 0x6E */ 0xB6, 0x63, 0x18, 0xC6, 0x20,
/* 'o' 0x6F */ 0x7B, 0x38, 0x61, 0x87, 0x37, 0x80,
/* 'p' 0x70 */ 0xF6, 0xE3, 0x18, 0xEF, 0xD0, 0x80,
/* 'q' 0x71 */ 0x77, 0x38, 0x61, 0x87, 0x37, 0x41, 0x04,
/* 'r' 0x72 */ 0xBA, 0x49, 0x20,
/* 's' 0x73 */ 0x69, 0x8E, 0x19, 0x60,
/* 't' 0x74 */ 0x5D, 0x24, 0x93,
/* 'u' 0x75 */ 0x8C, 0x63, 0x18, 0xCD, 0xA0,
/* 'v' 0x76 */ 0x85, 0x24, 0x92, 0x30, 0xC3, 0x00,
/* 'w' 0x77 */ 0x89, 0x99, 0x59, 0x55, 0x56, 0x66, 0x26,
/* 'x' 0x78 */ 0x4A, 0x4C, 0x43, 0x27, 0x20,
/* 'y' 0x79 */ 0x85, 0x24, 0x92, 0x30, 0xC3, 0x08, 0x21, 0x80,
/* 'z' 0x7A */ 0x78, 0x44, 0x46, 0x23, 0xE0,
/* '{' 0x7B */ 0x69, 0x25, 0xB2, 0x49, 0x30,
/* '|' 0x7C */ 0xFF, 0xE0,
/* '}' 0x7D */ 0xC9, 0x24, 0xDA, 0x49, 0x60,
/* '~' 0x7E */ 0x66, 0x70,
};
const GFXglyph FreeSans6pt7bGlyphs[] PROGMEM = {
/* ' ' 0x20 */ {0, 0, 0, 3, 0, 0},
/* '!' 0x21 */ {0, 1, 9, 4, 2, -8},
/* '"' 0x22 */ {2, 3, 3, 4, 0, -8},
/* '#' 0x23 */ {4, 7, 8, 7, 0, -7},
/* '$' 0x24 */ {11, 5, 11, 7, 1, -9},
/* '%' 0x25 */ {18, 10, 9, 11, 0, -8},
/* '&' 0x26 */ {30, 6, 9, 8, 1, -8},
/* ''' 0x27 */ {37, 1, 3, 2, 1, -8},
/* '(' 0x28 */ {38, 2, 11, 4, 1, -8},
/* ')' 0x29 */ {41, 3, 11, 4, 0, -8},
/* '*' 0x2A */ {46, 3, 3, 5, 1, -8},
/* '+' 0x2B */ {48, 5, 5, 7, 1, -4},
/* ',' 0x2C */ {52, 1, 3, 3, 1, 0},
/* '-' 0x2D */ {53, 3, 1, 4, 1, -3},
/* '.' 0x2E */ {54, 1, 1, 3, 1, 0},
/* '/' 0x2F */ {55, 3, 9, 3, 0, -8},
/* '0' 0x30 */ {59, 5, 9, 7, 1, -8},
/* '1' 0x31 */ {65, 2, 9, 7, 2, -8},
/* '2' 0x32 */ {68, 5, 9, 7, 1, -8},
/* '3' 0x33 */ {74, 5, 9, 7, 1, -8},
/* '4' 0x34 */ {80, 5, 9, 7, 1, -8},
/* '5' 0x35 */ {86, 6, 9, 7, 0, -8},
/* '6' 0x36 */ {93, 5, 9, 7, 1, -8},
/* '7' 0x37 */ {99, 5, 9, 7, 1, -8},
/* '8' 0x38 */ {105, 6, 9, 7, 0, -8},
/* '9' 0x39 */ {112, 6, 9, 7, 0, -8},
/* ':' 0x3A */ {119, 1, 7, 3, 1, -6},
/* ';' 0x3B */ {120, 1, 8, 3, 1, -5},
/* '<' 0x3C */ {121, 5, 5, 7, 1, -4},
/* '=' 0x3D */ {125, 5, 3, 7, 1, -3},
/* '>' 0x3E */ {127, 5, 5, 7, 1, -4},
/* '?' 0x3F */ {131, 5, 9, 7, 1, -8},
/* '@' 0x40 */ {137, 11, 11, 12, 0, -8},
/* 'A' 0x41 */ {153, 8, 9, 8, 0, -8},
/* 'B' 0x42 */ {162, 6, 9, 8, 1, -8},
/* 'C' 0x43 */ {169, 8, 9, 9, 0, -8},
/* 'D' 0x44 */ {178, 7, 9, 8, 1, -8},
/* 'E' 0x45 */ {186, 6, 9, 8, 1, -8},
/* 'F' 0x46 */ {193, 5, 9, 7, 1, -8},
/* 'G' 0x47 */ {199, 8, 9, 9, 0, -8},
/* 'H' 0x48 */ {208, 7, 9, 9, 1, -8},
/* 'I' 0x49 */ {216, 1, 9, 3, 1, -8},
/* 'J' 0x4A */ {218, 5, 9, 6, 0, -8},
/* 'K' 0x4B */ {224, 6, 9, 8, 1, -8},
/* 'L' 0x4C */ {231, 5, 9, 7, 1, -8},
/* 'M' 0x4D */ {237, 8, 9, 10, 1, -8},
/* 'N' 0x4E */ {246, 7, 9, 9, 1, -8},
/* 'O' 0x4F */ {254, 9, 9, 9, 0, -8},
/* 'P' 0x50 */ {265, 6, 9, 8, 1, -8},
/* 'Q' 0x51 */ {272, 9, 10, 9, 0, -8},
/* 'R' 0x52 */ {284, 7, 9, 9, 1, -8},
/* 'S' 0x53 */ {292, 6, 9, 8, 1, -8},
/* 'T' 0x54 */ {299, 6, 9, 8, 0, -8},
/* 'U' 0x55 */ {306, 7, 9, 9, 1, -8},
/* 'V' 0x56 */ {314, 7, 9, 8, 0, -8},
/* 'W' 0x57 */ {322, 11, 9, 11, 0, -8},
/* 'X' 0x58 */ {335, 6, 9, 8, 1, -8},
/* 'Y' 0x59 */ {342, 7, 9, 8, 1, -8},
/* 'Z' 0x5A */ {350, 7, 9, 7, 0, -8},
/* '[' 0x5B */ {358, 2, 12, 3, 1, -8},
/* '\' 0x5C */ {361, 3, 9, 3, 0, -8},
/* ']' 0x5D */ {365, 2, 12, 3, 0, -8},
/* '^' 0x5E */ {368, 4, 5, 6, 1, -8},
/* '_' 0x5F */ {371, 7, 1, 7, 0, 2},
/* '`' 0x60 */ {372, 1, 1, 3, 1, -8},
/* 'a' 0x61 */ {373, 7, 7, 7, 0, -6},
/* 'b' 0x62 */ {380, 5, 9, 7, 1, -8},
/* 'c' 0x63 */ {386, 6, 7, 6, 0, -6},
/* 'd' 0x64 */ {392, 6, 9, 7, 0, -8},
/* 'e' 0x65 */ {399, 6, 7, 6, 0, -6},
/* 'f' 0x66 */ {405, 3, 9, 3, 0, -8},
/* 'g' 0x67 */ {409, 6, 10, 7, 0, -6},
/* 'h' 0x68 */ {417, 5, 9, 6, 1, -8},
/* 'i' 0x69 */ {423, 1, 9, 3, 1, -8},
/* 'j' 0x6A */ {425, 2, 12, 3, 0, -8},
/* 'k' 0x6B */ {428, 5, 9, 6, 1, -8},
/* 'l' 0x6C */ {434, 1, 9, 3, 1, -8},
/* 'm' 0x6D */ {436, 8, 7, 10, 1, -6},
/* 'n' 0x6E */ {443, 5, 7, 6, 1, -6},
/* 'o' 0x6F */ {448, 6, 7, 6, 0, -6},
/* 'p' 0x70 */ {454, 5, 9, 7, 1, -6},
/* 'q' 0x71 */ {460, 6, 9, 7, 0, -6},
/* 'r' 0x72 */ {467, 3, 7, 4, 1, -6},
/* 's' 0x73 */ {470, 4, 7, 6, 1, -6},
/* 't' 0x74 */ {474, 3, 8, 3, 0, -7},
/* 'u' 0x75 */ {477, 5, 7, 6, 1, -6},
/* 'v' 0x76 */ {482, 6, 7, 6, 0, -6},
/* 'w' 0x77 */ {488, 8, 7, 9, 0, -6},
/* 'x' 0x78 */ {495, 5, 7, 6, 0, -6},
/* 'y' 0x79 */ {500, 6, 10, 6, 0, -6},
/* 'z' 0x7A */ {508, 5, 7, 6, 0, -6},
/* '{' 0x7B */ {513, 3, 12, 4, 0, -8},
/* '|' 0x7C */ {518, 1, 11, 3, 1, -8},
/* '}' 0x7D */ {520, 3, 12, 4, 1, -8},
/* '~' 0x7E */ {525, 6, 2, 6, 0, -4},
};
const GFXfont FreeSans6pt7b PROGMEM = {(uint8_t *)FreeSans6pt7bBitmaps, (GFXglyph *)FreeSans6pt7bGlyphs, 0x20, 0x7E, 14};
@@ -0,0 +1,527 @@
// trunk-ignore-all(clang-format)
#pragma once
/* PROPERTIES
FONT_NAME FreeSans6pt_Win1250
*/
const uint8_t FreeSans6pt_Win1250Bitmaps[] PROGMEM = {
/* 0x01 */ 0x1C, 0x0A, 0x05, 0x04, 0xFE, 0x08, 0x1C, 0x02, 0x07, 0xE0, 0x9F, 0xC0,
/* 0x02 */ 0x3F, 0xF0, 0x40, 0xE0, 0x10, 0x3F, 0x04, 0x9E, 0x28, 0x14, 0x0E, 0x00,
/* 0x03 */ 0x3F, 0x10, 0x28, 0x06, 0x49, 0x80, 0x60, 0x19, 0x26, 0x31, 0x40, 0x8F, 0xC0,
/* 0x04 */ 0x3F, 0x10, 0x2A, 0x16, 0x49, 0xA1, 0x60, 0x19, 0xE6, 0x31, 0x40, 0x8F, 0xC0,
/* 0x05 */ 0x28, 0x15, 0x2A, 0xB5, 0x55, 0xA8, 0x54, 0x12, 0x04, 0x41, 0x08, 0x81, 0xC0,
/* 0x06 */ 0x04, 0x08, 0x88, 0x82, 0x07, 0x01, 0x11, 0xA2, 0xC4, 0x40, 0x70, 0x20, 0x88, 0x88, 0x10, 0x00,
/* 0x07 */
/* 0x08 */ 0x03, 0x83, 0x44, 0x48, 0x28, 0x01, 0x80, 0x17, 0xFE, 0x08, 0x45, 0x28, 0x84, 0x00,
/* 0x09 */ 0x01, 0xC0, 0x68, 0x82, 0x41, 0x10, 0x02, 0x80, 0x06, 0x00, 0x14, 0x00, 0x8F, 0xFC,
/* 0x0A */
/* 0x0B */ 0x22, 0x2A, 0xA2, 0x30, 0x18, 0x0A, 0x09, 0x04, 0x44, 0x14, 0x04, 0x00,
/* 0x0C */ 0x46, 0x00, 0x19, 0x03, 0x21, 0x20, 0x93, 0x04, 0x20, 0x11, 0x80, 0x50, 0x02, 0x7F, 0xE0,
/* 0x0D */
/* 0x0E */ 0x08, 0x0E, 0x08, 0x88, 0x24, 0x12, 0x09, 0x05, 0x01, 0xFF, 0x8A, 0x02, 0x00,
/* 0x0F */ 0x3F, 0x14, 0xAA, 0x16, 0x01, 0x92, 0x60, 0x18, 0xC6, 0x49, 0x40, 0x8F, 0xC0,
/* 0x10 */ 0x1B, 0x02, 0xA0, 0x54, 0x12, 0x42, 0x48, 0x49, 0x31, 0x1E, 0x23, 0xEA, 0xFE, 0x3C,
/* 0x11 */ 0x3F, 0x02, 0x00, 0x20, 0x6D, 0x27, 0xF8, 0x3F, 0xC1, 0xFE, 0x37, 0xD0, 0xBE, 0x40, 0xE1, 0xE2, 0x00,
/* 0x12 */ 0x12, 0x42, 0x20, 0x24, 0xC0, 0x29, 0x99, 0x05, 0x23, 0x30, 0xB0, 0x30, 0x00,
/* 0x13 */ 0x3F, 0x88, 0x0A, 0x44, 0xD5, 0x58, 0x03, 0x00, 0x67, 0xCC, 0x71, 0x40, 0x47, 0xF0,
/* 0x14 */ 0x3F, 0x18, 0x69, 0x26, 0x85, 0xA1, 0x6C, 0xD8, 0x06, 0x31, 0x40, 0x8F, 0xC0,
/* 0x15 */ 0x3F, 0x11, 0x00, 0xE8, 0x03, 0xA0, 0x1F, 0xB3, 0x7E, 0x00, 0xE9, 0xE0, 0x23, 0x00, 0x40, 0x40, 0xFE, 0x00,
/* 0x16 */ 0x30, 0x38, 0x3A, 0x3E, 0x6E, 0xEB, 0xC3, 0xC3, 0x66, 0x3C,
/* 0x17 */ 0x3F, 0x04, 0x00, 0x82, 0x88, 0x5C, 0xA4, 0x49, 0x22, 0x81, 0x98, 0xC4, 0x40, 0xA3, 0xF0,
/* 0x18 */ 0x07, 0x80, 0x42, 0x04, 0x08, 0x21, 0x41, 0x42, 0x60, 0x0E, 0x8C, 0xB2, 0x89, 0x50, 0x52, 0x82, 0x80,
/* 0x19 */ 0x3F, 0xC4, 0x02, 0x80, 0x18, 0x01, 0xB3, 0x1B, 0xB9, 0x80, 0x19, 0xE1, 0x40, 0x23, 0xFC,
/* 0x1A */ 0xFF, 0xC0, 0x67, 0x34, 0x58, 0x4C, 0x46, 0x03, 0x11, 0x80, 0xFF, 0xC0,
/* 0x1B */ 0x0F, 0xC0, 0x40, 0x82, 0x49, 0x08, 0x04, 0x00, 0x00, 0x12, 0x02, 0x31, 0x34, 0x0B, 0x88, 0x45, 0x00, 0x20,
/* 0x1C */ 0x3F, 0x88, 0x0A, 0x44, 0xC9, 0x19, 0x3B, 0x00, 0x60, 0x4C, 0x71, 0x40, 0x47, 0xF0,
/* 0x1D */ 0x3F, 0x8B, 0x0A, 0x00, 0xC8, 0x18, 0x13, 0x00, 0x48, 0xCA, 0xC1, 0x44, 0x53, 0x30,
/* 0x1E */ 0x19, 0xC2, 0x02, 0x50, 0x1E, 0x49, 0x80, 0x12, 0x01, 0x27, 0x92, 0x01, 0x10, 0x20, 0xFC,
/* 0x1F */ 0x30, 0x1C, 0x0C, 0x3E, 0x7E, 0xCF, 0x07, 0xC7, 0x7F, 0x3F,
/* ' ' 0x20 */
/* '!' 0x21 */ 0xFC, 0x80,
/* '"' 0x22 */ 0xB6, 0x80,
/* '#' 0x23 */ 0x24, 0x51, 0xF9, 0x42, 0x9F, 0x92, 0x28,
/* '$' 0x24 */ 0x10, 0xE5, 0x55, 0x50, 0xE1, 0x65, 0x55, 0xE1, 0x00,
/* '%' 0x25 */ 0x71, 0x24, 0x89, 0x22, 0x50, 0x74, 0x02, 0x70, 0xA4, 0x49, 0x11, 0xC0,
/* '&' 0x26 */ 0x71, 0x24, 0x9C, 0x62, 0x58, 0xA7, 0xF4,
/* ''' 0x27 */ 0xE0,
/* '(' 0x28 */ 0x5A, 0xAA, 0x94,
/* ')' 0x29 */ 0x89, 0x12, 0x49, 0x29, 0x00,
/* '*' 0x2A */ 0x5E, 0x80,
/* '+' 0x2B */ 0x21, 0x3E, 0x42, 0x00,
/* ',' 0x2C */ 0xE0,
/* '-' 0x2D */ 0xC0,
/* '.' 0x2E */ 0x80,
/* '/' 0x2F */ 0x24, 0xA4, 0xA4, 0x80,
/* '0' 0x30 */ 0x76, 0xE3, 0x18, 0xC6, 0x3B, 0x70,
/* '1' 0x31 */ 0x27, 0x92, 0x49, 0x20,
/* '2' 0x32 */ 0x79, 0x10, 0x41, 0x08, 0xC6, 0x10, 0xFC,
/* '3' 0x33 */ 0x79, 0x30, 0x43, 0x18, 0x10, 0x71, 0x78,
/* '4' 0x34 */ 0x08, 0x61, 0x8A, 0x49, 0x2F, 0xC2, 0x08,
/* '5' 0x35 */ 0xFC, 0x21, 0xE8, 0x84, 0x31, 0xF0,
/* '6' 0x36 */ 0x74, 0x61, 0xE8, 0xC6, 0x31, 0x70,
/* '7' 0x37 */ 0xF8, 0x44, 0x22, 0x11, 0x08, 0x40,
/* '8' 0x38 */ 0x39, 0x34, 0x53, 0x39, 0x1C, 0x51, 0x38,
/* '9' 0x39 */ 0x39, 0x3C, 0x71, 0x4C, 0xF0, 0x53, 0x78,
/* ':' 0x3A */ 0x82,
/* ';' 0x3B */ 0x87,
/* '<' 0x3C */ 0x3E, 0x30, 0x60, 0x80,
/* '=' 0x3D */ 0xF8, 0x3E,
/* '>' 0x3E */ 0xE0, 0xC6, 0xC8, 0x00,
/* '?' 0x3F */ 0x74, 0x42, 0x11, 0x10, 0x80, 0x20,
/* '@' 0x40 */ 0x0F, 0x86, 0x19, 0x9A, 0xA4, 0xD9, 0x13, 0x22, 0x56, 0xDA, 0x6E, 0x60, 0x06, 0x00, 0x3C, 0x00,
/* 'A' 0x41 */ 0x18, 0x18, 0x24, 0x24, 0x24, 0x7E, 0x42, 0x42, 0xC3,
/* 'B' 0x42 */ 0xFA, 0x18, 0x61, 0xFA, 0x18, 0x61, 0xFC,
/* 'C' 0x43 */ 0x3E, 0x63, 0x40, 0x40, 0xC0, 0x40, 0x41, 0x63, 0x3E,
/* 'D' 0x44 */ 0xF9, 0x0A, 0x1C, 0x18, 0x30, 0x61, 0xC2, 0xF8,
/* 'E' 0x45 */ 0xFE, 0x08, 0x20, 0xFE, 0x08, 0x20, 0xFC,
/* 'F' 0x46 */ 0xFE, 0x08, 0x20, 0xFA, 0x08, 0x20, 0x80,
/* 'G' 0x47 */ 0x1E, 0x61, 0x40, 0x40, 0xC7, 0x41, 0x41, 0x63, 0x1D,
/* 'H' 0x48 */ 0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60, 0xC1, 0x82,
/* 'I' 0x49 */ 0xFF, 0x80,
/* 'J' 0x4A */ 0x08, 0x42, 0x10, 0x87, 0x29, 0x70,
/* 'K' 0x4B */ 0x85, 0x12, 0x45, 0x0D, 0x13, 0x22, 0x42, 0x86,
/* 'L' 0x4C */ 0x84, 0x21, 0x08, 0x42, 0x10, 0xF8,
/* 'M' 0x4D */ 0xC3, 0xC3, 0xC3, 0xA5, 0xA5, 0xA5, 0x99, 0x99, 0x99,
/* 'N' 0x4E */ 0x83, 0x86, 0x8D, 0x19, 0x33, 0x62, 0xC3, 0x86,
/* 'O' 0x4F */ 0x1E, 0x31, 0x90, 0x68, 0x1C, 0x0A, 0x05, 0x06, 0xC6, 0x1E, 0x00,
/* 'P' 0x50 */ 0xFA, 0x18, 0x61, 0xFA, 0x08, 0x20, 0x80,
/* 'Q' 0x51 */ 0x1E, 0x31, 0x90, 0x68, 0x1C, 0x0A, 0x05, 0x16, 0xC6, 0x1F, 0x00, 0x40,
/* 'R' 0x52 */ 0xFD, 0x0E, 0x1C, 0x2F, 0x90, 0xA1, 0x42, 0x86,
/* 'S' 0x53 */ 0x7A, 0x18, 0x30, 0x78, 0x38, 0x61, 0x78,
/* 'T' 0x54 */ 0xFE, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10,
/* 'U' 0x55 */ 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xE2, 0x78,
/* 'V' 0x56 */ 0xC2, 0x85, 0x0B, 0x22, 0x44, 0x8E, 0x0C, 0x18,
/* 'W' 0x57 */ 0xC4, 0x28, 0xCD, 0x29, 0x25, 0x24, 0xA4, 0x52, 0x8C, 0x61, 0x8C, 0x31, 0x80,
/* 'X' 0x58 */ 0x87, 0x34, 0x8C, 0x30, 0xC4, 0xA3, 0x84,
/* 'Y' 0x59 */ 0xC3, 0x42, 0x24, 0x34, 0x18, 0x08, 0x08, 0x08, 0x08,
/* 'Z' 0x5A */ 0x7E, 0x0C, 0x30, 0x41, 0x06, 0x18, 0x20, 0xFE,
/* '[' 0x5B */ 0xEA, 0xAA, 0xAB,
/* '\' 0x5C */ 0x92, 0x24, 0x89, 0x20,
/* ']' 0x5D */ 0xD5, 0x55, 0x57,
/* '^' 0x5E */ 0x46, 0xA9,
/* '_' 0x5F */ 0xFE,
/* '`' 0x60 */ 0x80,
/* 'a' 0x61 */ 0x79, 0x20, 0x4F, 0xC6, 0x37, 0x40,
/* 'b' 0x62 */ 0x84, 0x3D, 0x18, 0xC6, 0x31, 0xF0,
/* 'c' 0x63 */ 0x39, 0x3C, 0x20, 0xC1, 0x33, 0x80,
/* 'd' 0x64 */ 0x04, 0x13, 0xD3, 0xC6, 0x1C, 0x53, 0x3C,
/* 'e' 0x65 */ 0x39, 0x38, 0x7F, 0x81, 0x13, 0x80,
/* 'f' 0x66 */ 0x6B, 0xA4, 0x92, 0x40,
/* 'g' 0x67 */ 0x35, 0x3C, 0x61, 0xC5, 0x33, 0x41, 0x4D, 0xE0,
/* 'h' 0x68 */ 0x84, 0x3D, 0x38, 0xC6, 0x31, 0x88,
/* 'i' 0x69 */ 0xBF, 0x80,
/* 'j' 0x6A */ 0x45, 0x55, 0x57,
/* 'k' 0x6B */ 0x84, 0x25, 0x4E, 0x52, 0xD2, 0x88,
/* 'l' 0x6C */ 0xFF, 0x80,
/* 'm' 0x6D */ 0xF7, 0x99, 0x91, 0x91, 0x91, 0x91, 0x91,
/* 'n' 0x6E */ 0xF4, 0x63, 0x18, 0xC6, 0x20,
/* 'o' 0x6F */ 0x39, 0x3C, 0x61, 0xC5, 0x33, 0x80,
/* 'p' 0x70 */ 0xF4, 0x63, 0x18, 0xC7, 0xD0, 0x80,
/* 'q' 0x71 */ 0x3D, 0x3C, 0x61, 0xC5, 0x37, 0x41, 0x04,
/* 'r' 0x72 */ 0xF2, 0x49, 0x20,
/* 's' 0x73 */ 0x7A, 0x50, 0xE0, 0xE5, 0xE0,
/* 't' 0x74 */ 0x5D, 0x24, 0x93,
/* 'u' 0x75 */ 0x8C, 0x63, 0x18, 0xCF, 0xA0,
/* 'v' 0x76 */ 0x85, 0x24, 0x92, 0x30, 0xC3, 0x00,
/* 'w' 0x77 */ 0x89, 0x59, 0x59, 0x55, 0x56, 0x26, 0x26,
/* 'x' 0x78 */ 0x4A, 0x4C, 0x43, 0x27, 0x20,
/* 'y' 0x79 */ 0x8A, 0x52, 0xA5, 0x18, 0x84, 0x22, 0x00,
/* 'z' 0x7A */ 0x78, 0x44, 0x46, 0x23, 0xE0,
/* '{' 0x7B */ 0x6A, 0xAA, 0xA9,
/* '|' 0x7C */ 0xFF, 0xE0,
/* '}' 0x7D */ 0x95, 0x55, 0x56,
/* '~' 0x7E */ 0x66, 0x60,
/* 0x7F */ 0xFF, 0xC0, 0x67, 0x34, 0x58, 0x4C, 0x46, 0x03, 0x11, 0x80, 0xFF, 0xC0,
/* 0x80 */ 0x1C, 0x45, 0x07, 0xE4, 0x1F, 0x10, 0x10, 0x1E,
/* 0x81 */
/* 0x82 */ 0xE0,
/* 0x83 */
/* 0x84 */ 0xB6, 0x80,
/* 0x85 */ 0xA8,
/* 0x86 */ 0x21, 0x09, 0xF2, 0x10, 0x84, 0x21, 0x08,
/* 0x87 */ 0x21, 0x09, 0xF2, 0x10, 0x84, 0xF9, 0x08,
/* 0x88 */
/* 0x89 */ 0x62, 0x09, 0x40, 0x98, 0x06, 0x80, 0x10, 0x01, 0x66, 0x29, 0x92, 0x99, 0x06, 0x60,
/* 0x8A */ 0x28, 0x47, 0xA1, 0x83, 0x07, 0x83, 0x87, 0x17, 0x80,
/* 0x8B */ 0x64,
/* 0x8C */ 0x10, 0x87, 0xA1, 0x83, 0x07, 0x83, 0x87, 0x17, 0x80,
/* 0x8D */ 0x28, 0x4F, 0xC4, 0x10, 0x41, 0x04, 0x10, 0x40,
/* 0x8E */ 0x14, 0x11, 0xF8, 0x30, 0xC1, 0x04, 0x18, 0x61, 0xFC,
/* 0x8F */ 0x08, 0x21, 0xF8, 0x30, 0xC1, 0x04, 0x18, 0x61, 0xFC,
/* 0x90 */
/* 0x91 */ 0xE0,
/* 0x92 */ 0xE0,
/* 0x93 */ 0xB6, 0x80,
/* 0x94 */ 0xB6, 0x80,
/* 0x95 */ 0xFF, 0x80,
/* 0x96 */ 0xFC,
/* 0x97 */ 0xFF, 0xF0,
/* 0x98 */
/* 0x99 */ 0xE6, 0x28, 0xCD, 0x19, 0xA3, 0x34, 0x6A, 0x8B, 0x51, 0x68,
/* 0x9A */ 0x52, 0x69, 0x8E, 0x19, 0x60,
/* 0x9B */ 0x98,
/* 0x9C */ 0x24, 0x06, 0x98, 0xE1, 0x96,
/* 0x9D */ 0x15, 0xE4, 0x44, 0x44, 0x60,
/* 0x9E */ 0x51, 0x00, 0xF0, 0x88, 0x8C, 0x47, 0xC0,
/* 0x9F */ 0x11, 0x00, 0xF0, 0x88, 0x8C, 0x47, 0xC0,
/* 0xA0 */
/* 0xA1 */ 0xA8,
/* 0xA2 */ 0x96,
/* 0xA3 */ 0x41, 0x05, 0x18, 0x43, 0x04, 0x10, 0x7C,
/* 0xA4 */ 0xFC, 0x63, 0xF0,
/* 0xA5 */ 0x30, 0x38, 0x28, 0x48, 0x4C, 0x7C, 0x84, 0x86, 0x82, 0x04, 0x07,
/* 0xA6 */ 0xF9, 0xF0,
/* 0xA7 */ 0x32, 0x91, 0xC9, 0x47, 0x26, 0x14, 0xA4, 0xC0,
/* 0xA8 */ 0xA0,
/* 0xA9 */ 0x3E, 0x3F, 0xB8, 0xF4, 0x1A, 0x0D, 0x17, 0x76, 0xC6, 0x3E, 0x00,
/* 0xAA */ 0x7A, 0x18, 0x30, 0x78, 0x38, 0x61, 0x78, 0xC1, 0x0C,
/* 0xAB */ 0x5A, 0xA5,
/* 0xAC */ 0xFC, 0x10, 0x40,
/* 0xAD */
/* 0xAE */ 0x3E, 0x31, 0xB7, 0x72, 0x99, 0xCC, 0xC7, 0x56, 0xC6, 0x3E, 0x00,
/* 0xAF */ 0x18, 0x31, 0xF8, 0x30, 0xC1, 0x04, 0x18, 0x61, 0xFC,
/* 0xB0 */ 0x69, 0x96,
/* 0xB1 */ 0x21, 0x3E, 0x42, 0x03, 0xE0,
/* 0xB2 */ 0x9C,
/* 0xB3 */ 0x49, 0x35, 0x92, 0x40,
/* 0xB4 */ 0x80,
/* 0xB5 */ 0x8A, 0x28, 0xA2, 0x8A, 0x6E, 0xE0, 0x80,
/* 0xB6 */ 0x7F, 0xAE, 0xBA, 0x68, 0xA2, 0x8A, 0x28, 0xA0,
/* 0xB7 */ 0x80,
/* 0xB8 */ 0x67, 0x80,
/* 0xB9 */ 0x78, 0x84, 0x04, 0x3C, 0xC4, 0x8C, 0x76, 0x04, 0x07,
/* 0xBA */ 0x69, 0x8E, 0x19, 0x66, 0x26,
/* 0xBB */ 0xA5, 0x5A,
/* 0xBC */ 0xA5, 0x21, 0x08, 0x42, 0x10, 0xF8,
/* 0xBD */ 0xA0,
/* 0xBE */ 0xBA, 0x49, 0x24, 0x90,
/* 0xBF */ 0x31, 0x9E, 0x11, 0x11, 0x88, 0xF8,
/* 0xC0 */ 0x10, 0x43, 0xE4, 0x28, 0x50, 0xBE, 0x42, 0x85, 0x0C,
/* 0xC1 */ 0x08, 0x10, 0x00, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0xC3,
/* 0xC2 */ 0x18, 0x24, 0x00, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0xC3,
/* 0xC3 */ 0x24, 0x18, 0x00, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0xC3,
/* 0xC4 */ 0x24, 0x00, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0x42, 0xC3,
/* 0xC5 */ 0x11, 0x21, 0x08, 0x42, 0x10, 0x87, 0xC0,
/* 0xC6 */ 0x08, 0x20, 0x01, 0xE4, 0x30, 0x20, 0x40, 0x82, 0x8C, 0xF0,
/* 0xC7 */ 0x3E, 0x61, 0xC0, 0x80, 0x80, 0x80, 0xC1, 0x63, 0x3E, 0x0C, 0x04, 0x1C,
/* 0xC8 */ 0x28, 0x20, 0x01, 0xE4, 0x30, 0x20, 0x40, 0x82, 0x8C, 0xF0,
/* 0xC9 */ 0x08, 0x40, 0x3F, 0x82, 0x0F, 0xA0, 0x83, 0xF0,
/* 0xCA */ 0xFD, 0x02, 0x04, 0x0F, 0xD0, 0x20, 0x40, 0xFC, 0x10, 0x38,
/* 0xCB */ 0x28, 0x0F, 0xE0, 0x83, 0xE8, 0x20, 0x83, 0xF0,
/* 0xCC */ 0x28, 0x40, 0x3F, 0x82, 0x0F, 0xA0, 0x82, 0x0F, 0xC0,
/* 0xCD */ 0x62, 0xAA, 0xA0,
/* 0xCE */ 0x54, 0x24, 0x92, 0x48,
/* 0xCF */ 0x50, 0x43, 0xE4, 0x28, 0x30, 0x60, 0xC1, 0x85, 0xF0,
/* 0xD0 */ 0x7C, 0x42, 0x41, 0x41, 0xF1, 0x41, 0x41, 0x42, 0x7C,
/* 0xD1 */ 0x08, 0x23, 0x0F, 0x1B, 0x32, 0x66, 0xC7, 0x87, 0x04,
/* 0xD2 */ 0x28, 0x23, 0x0F, 0x1B, 0x32, 0x66, 0xC7, 0x87, 0x04,
/* 0xD3 */ 0x04, 0x04, 0x0F, 0x8C, 0x6C, 0x1C, 0x06, 0x03, 0x83, 0x63, 0x1F, 0x00,
/* 0xD4 */ 0x08, 0x0A, 0x00, 0x07, 0xC6, 0x36, 0x0E, 0x03, 0x01, 0xC1, 0xB1, 0x8F, 0x80,
/* 0xD5 */ 0x0A, 0x0A, 0x00, 0x07, 0xC6, 0x36, 0x0E, 0x03, 0x01, 0xC1, 0xB1, 0x8F, 0x80,
/* 0xD6 */ 0x14, 0x00, 0x00, 0x07, 0xC6, 0x36, 0x0E, 0x03, 0x01, 0xC1, 0xB1, 0x8F, 0x80,
/* 0xD7 */ 0x8A, 0x88, 0xA8, 0x80,
/* 0xD8 */ 0x50, 0x43, 0xE4, 0x28, 0x50, 0xBE, 0x42, 0x85, 0x0C,
/* 0xD9 */ 0x10, 0x52, 0x4C, 0x18, 0x30, 0x60, 0xC1, 0xC6, 0xF8,
/* 0xDA */ 0x08, 0x22, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xC6, 0xF8,
/* 0xDB */ 0x14, 0x52, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xC6, 0xF8,
/* 0xDC */ 0x29, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xC6, 0xF8,
/* 0xDD */ 0x09, 0x25, 0x12, 0x22, 0x87, 0x04, 0x08, 0x10, 0x20,
/* 0xDE */ 0xFC, 0x41, 0x04, 0x10, 0x41, 0x04, 0x10, 0x60, 0x8E,
/* 0xDF */ 0x7A, 0x18, 0x61, 0x8A, 0x18, 0x61, 0xB8,
/* 0xE0 */ 0x42, 0xE9, 0x24, 0x80,
/* 0xE1 */ 0x10, 0x40, 0x03, 0xC8, 0x40, 0x8F, 0x62, 0x8C, 0xEC,
/* 0xE2 */ 0x10, 0x50, 0x03, 0xC8, 0x40, 0x8F, 0x62, 0x8C, 0xEC,
/* 0xE3 */ 0x48, 0x60, 0x03, 0xC8, 0x40, 0x8F, 0x62, 0x8C, 0xEC,
/* 0xE4 */ 0x28, 0x01, 0xE4, 0x20, 0x47, 0xB1, 0x46, 0x76,
/* 0xE5 */ 0x62, 0xAA, 0xA0,
/* 0xE6 */ 0x10, 0x80, 0x1E, 0xC6, 0x08, 0x20, 0xC5, 0xE0,
/* 0xE7 */ 0x7B, 0x18, 0x20, 0x83, 0x17, 0x8C, 0x11, 0xC0,
/* 0xE8 */ 0x28, 0x40, 0x1E, 0xC6, 0x08, 0x20, 0xC5, 0xE0,
/* 0xE9 */ 0x10, 0x80, 0x1E, 0xCE, 0x1F, 0xE0, 0xC5, 0xE0,
/* 0xEA */ 0x7B, 0x38, 0x7F, 0x83, 0x37, 0x84, 0x1C,
/* 0xEB */ 0x28, 0x07, 0xB3, 0x87, 0xF8, 0x31, 0x78,
/* 0xEC */ 0x28, 0x40, 0x1E, 0xCE, 0x1F, 0xE0, 0xC5, 0xE0,
/* 0xED */ 0x62, 0xAA, 0xA0,
/* 0xEE */ 0x54, 0x24, 0x92, 0x48,
/* 0xEF */ 0x02, 0x0C, 0x13, 0xEC, 0xD0, 0xA1, 0x42, 0xCC, 0xE8,
/* 0xF0 */ 0x04, 0x1D, 0xD6, 0x68, 0x50, 0xA1, 0x66, 0x74,
/* 0xF1 */ 0x11, 0x01, 0x6C, 0xC6, 0x31, 0x8C, 0x40,
/* 0xF2 */ 0x20, 0x81, 0x6C, 0xC6, 0x31, 0x8C, 0x40,
/* 0xF3 */ 0x10, 0x80, 0x1E, 0xCE, 0x18, 0x61, 0xCD, 0xE0,
/* 0xF4 */ 0x10, 0xA0, 0x1E, 0xCE, 0x18, 0x61, 0xCD, 0xE0,
/* 0xF5 */ 0x29, 0x40, 0x1E, 0xCE, 0x18, 0x61, 0xCD, 0xE0,
/* 0xF6 */ 0x28, 0x07, 0xB3, 0x86, 0x18, 0x73, 0x78,
/* 0xF7 */ 0x20, 0x3E, 0x02, 0x00,
/* 0xF8 */ 0xA8, 0x5D, 0x24, 0x90,
/* 0xF9 */ 0x22, 0x89, 0x18, 0xC6, 0x31, 0x9B, 0x40,
/* 0xFA */ 0x11, 0x23, 0x18, 0xC6, 0x33, 0x68,
/* 0xFB */ 0x2A, 0x81, 0x18, 0xC6, 0x31, 0x9B, 0x40,
/* 0xFC */ 0x50, 0x23, 0x18, 0xC6, 0x33, 0x68,
/* 0xFD */ 0x10, 0x88, 0x52, 0x49, 0x23, 0x0C, 0x30, 0x82, 0x18,
/* 0xFE */ 0x4E, 0x44, 0x44, 0x46, 0x31, 0x70,
/* 0xFF */ 0x80,
};
const GFXglyph FreeSans6pt_Win1250Glyphs[] PROGMEM = {
/* 0x01 */ { 0, 9, 10, 11, 1, -9 },
/* 0x02 */ { 12, 9, 10, 11, 1, -8 },
/* 0x03 */ { 24, 10, 10, 12, 1, -8 },
/* 0x04 */ { 37, 10, 10, 12, 1, -8 },
/* 0x05 */ { 50, 10, 10, 12, 1, -9 },
/* 0x06 */ { 63, 11, 11, 13, 1, -9 },
/* 0x07 */ { 79, 0, 0, 8, 0, 0 },
/* 0x08 */ { 79, 12, 9, 14, 1, -8 },
/* 0x09 */ { 93, 14, 8, 16, 1, -7 },
/* 0x0A */ { 107, 0, 0, 8, 0, 0 },
/* 0x0B */ { 107, 9, 10, 11, 1, -9 },
/* 0x0C */ { 119, 13, 9, 15, 1, -8 },
/* 0x0D */ { 134, 0, 0, 8, 0, 0 },
/* 0x0E */ { 134, 9, 11, 11, 1, -9 },
/* 0x0F */ { 147, 10, 10, 12, 1, -9 },
/* 0x10 */ { 160, 11, 10, 13, 1, -9 },
/* 0x11 */ { 174, 13, 10, 15, 1, -9 },
/* 0x12 */ { 191, 10, 10, 12, 1, -9 },
/* 0x13 */ { 204, 11, 10, 13, 1, -9 },
/* 0x14 */ { 218, 10, 10, 12, 1, -9 },
/* 0x15 */ { 231, 14, 10, 16, 1, -9 },
/* 0x16 */ { 249, 8, 10, 10, 1, -9 },
/* 0x17 */ { 259, 12, 10, 14, 1, -9 },
/* 0x18 */ { 274, 13, 10, 15, 1, -9 },
/* 0x19 */ { 291, 12, 10, 14, 1, -9 },
/* 0x1A */ { 306, 9, 10, 11, 1, -8 },
/* 0x1B */ { 318, 14, 10, 16, 1, -9 },
/* 0x1C */ { 336, 11, 10, 13, 1, -9 },
/* 0x1D */ { 350, 11, 10, 13, 1, -9 },
/* 0x1E */ { 364, 12, 10, 14, 1, -9 },
/* 0x1F */ { 379, 8, 10, 11, 2, -9 },
/* ' ' 0x20 */ { 389, 0, 0, 3, 0, 0 },
/* '!' 0x21 */ { 389, 1, 9, 4, 2, -8 },
/* '"' 0x22 */ { 391, 3, 3, 4, 0, -8 },
/* '#' 0x23 */ { 393, 7, 8, 7, 0, -7 },
/* '$' 0x24 */ { 400, 6, 11, 7, 0, -9 },
/* '%' 0x25 */ { 409, 10, 9, 11, 0, -8 },
/* '&' 0x26 */ { 421, 6, 9, 8, 1, -8 },
/* ''' 0x27 */ { 428, 1, 3, 2, 1, -8 },
/* '(' 0x28 */ { 429, 2, 11, 4, 1, -8 },
/* ')' 0x29 */ { 432, 3, 11, 4, 0, -8 },
/* '*' 0x2A */ { 437, 3, 3, 5, 1, -8 },
/* '+' 0x2B */ { 439, 5, 5, 7, 1, -4 },
/* ',' 0x2C */ { 443, 1, 3, 3, 1, 0 },
/* '-' 0x2D */ { 444, 2, 1, 4, 1, -3 },
/* '.' 0x2E */ { 445, 1, 1, 3, 1, 0 },
/* '/' 0x2F */ { 446, 3, 9, 3, 0, -8 },
/* '0' 0x30 */ { 450, 5, 9, 7, 1, -8 },
/* '1' 0x31 */ { 456, 3, 9, 7, 1, -8 },
/* '2' 0x32 */ { 460, 6, 9, 7, 0, -8 },
/* '3' 0x33 */ { 467, 6, 9, 7, 0, -8 },
/* '4' 0x34 */ { 474, 6, 9, 7, 0, -8 },
/* '5' 0x35 */ { 481, 5, 9, 7, 1, -8 },
/* '6' 0x36 */ { 487, 5, 9, 7, 1, -8 },
/* '7' 0x37 */ { 493, 5, 9, 7, 1, -8 },
/* '8' 0x38 */ { 499, 6, 9, 7, 0, -8 },
/* '9' 0x39 */ { 506, 6, 9, 7, 0, -8 },
/* ':' 0x3A */ { 513, 1, 7, 3, 1, -6 },
/* ';' 0x3B */ { 514, 1, 8, 3, 1, -5 },
/* '<' 0x3C */ { 515, 5, 5, 7, 1, -4 },
/* '=' 0x3D */ { 519, 5, 3, 7, 1, -3 },
/* '>' 0x3E */ { 521, 5, 5, 7, 1, -4 },
/* '?' 0x3F */ { 525, 5, 9, 7, 1, -8 },
/* '@' 0x40 */ { 531, 11, 11, 12, 0, -8 },
/* 'A' 0x41 */ { 547, 8, 9, 8, 0, -8 },
/* 'B' 0x42 */ { 556, 6, 9, 8, 1, -8 },
/* 'C' 0x43 */ { 563, 8, 9, 9, 0, -8 },
/* 'D' 0x44 */ { 572, 7, 9, 8, 1, -8 },
/* 'E' 0x45 */ { 580, 6, 9, 8, 1, -8 },
/* 'F' 0x46 */ { 587, 6, 9, 7, 1, -8 },
/* 'G' 0x47 */ { 594, 8, 9, 9, 0, -8 },
/* 'H' 0x48 */ { 603, 7, 9, 9, 1, -8 },
/* 'I' 0x49 */ { 611, 1, 9, 3, 1, -8 },
/* 'J' 0x4A */ { 613, 5, 9, 6, 0, -8 },
/* 'K' 0x4B */ { 619, 7, 9, 8, 1, -8 },
/* 'L' 0x4C */ { 627, 5, 9, 7, 1, -8 },
/* 'M' 0x4D */ { 633, 8, 9, 10, 1, -8 },
/* 'N' 0x4E */ { 642, 7, 9, 9, 1, -8 },
/* 'O' 0x4F */ { 650, 9, 9, 9, 0, -8 },
/* 'P' 0x50 */ { 661, 6, 9, 8, 1, -8 },
/* 'Q' 0x51 */ { 668, 9, 10, 9, 0, -8 },
/* 'R' 0x52 */ { 680, 7, 9, 9, 1, -8 },
/* 'S' 0x53 */ { 688, 6, 9, 8, 1, -8 },
/* 'T' 0x54 */ { 695, 7, 9, 8, 0, -8 },
/* 'U' 0x55 */ { 703, 7, 9, 9, 1, -8 },
/* 'V' 0x56 */ { 711, 7, 9, 8, 0, -8 },
/* 'W' 0x57 */ { 719, 11, 9, 11, 0, -8 },
/* 'X' 0x58 */ { 732, 6, 9, 8, 1, -8 },
/* 'Y' 0x59 */ { 739, 8, 9, 8, 0, -8 },
/* 'Z' 0x5A */ { 748, 7, 9, 7, 0, -8 },
/* '[' 0x5B */ { 756, 2, 12, 3, 1, -8 },
/* '\' 0x5C */ { 759, 3, 9, 3, 0, -8 },
/* ']' 0x5D */ { 763, 2, 12, 3, 0, -8 },
/* '^' 0x5E */ { 766, 4, 4, 6, 1, -8 },
/* '_' 0x5F */ { 768, 7, 1, 7, 0, 2 },
/* '`' 0x60 */ { 769, 1, 1, 3, 1, -8 },
/* 'a' 0x61 */ { 770, 6, 7, 7, 0, -6 },
/* 'b' 0x62 */ { 776, 5, 9, 7, 1, -8 },
/* 'c' 0x63 */ { 782, 6, 7, 6, 0, -6 },
/* 'd' 0x64 */ { 788, 6, 9, 7, 0, -8 },
/* 'e' 0x65 */ { 795, 6, 7, 6, 0, -6 },
/* 'f' 0x66 */ { 801, 3, 9, 3, 0, -8 },
/* 'g' 0x67 */ { 805, 6, 10, 7, 0, -6 },
/* 'h' 0x68 */ { 813, 5, 9, 6, 1, -8 },
/* 'i' 0x69 */ { 819, 1, 9, 3, 1, -8 },
/* 'j' 0x6A */ { 821, 2, 12, 3, 0, -8 },
/* 'k' 0x6B */ { 824, 5, 9, 6, 1, -8 },
/* 'l' 0x6C */ { 830, 1, 9, 3, 1, -8 },
/* 'm' 0x6D */ { 832, 8, 7, 10, 1, -6 },
/* 'n' 0x6E */ { 839, 5, 7, 6, 1, -6 },
/* 'o' 0x6F */ { 844, 6, 7, 6, 0, -6 },
/* 'p' 0x70 */ { 850, 5, 9, 7, 1, -6 },
/* 'q' 0x71 */ { 856, 6, 9, 7, 0, -6 },
/* 'r' 0x72 */ { 863, 3, 7, 4, 1, -6 },
/* 's' 0x73 */ { 866, 5, 7, 6, 0, -6 },
/* 't' 0x74 */ { 871, 3, 8, 3, 0, -7 },
/* 'u' 0x75 */ { 874, 5, 7, 6, 1, -6 },
/* 'v' 0x76 */ { 879, 6, 7, 6, 0, -6 },
/* 'w' 0x77 */ { 885, 8, 7, 9, 0, -6 },
/* 'x' 0x78 */ { 892, 5, 7, 6, 0, -6 },
/* 'y' 0x79 */ { 897, 5, 10, 6, 0, -6 },
/* 'z' 0x7A */ { 904, 5, 7, 6, 0, -6 },
/* '{' 0x7B */ { 909, 2, 12, 4, 1, -8 },
/* '|' 0x7C */ { 912, 1, 11, 3, 1, -8 },
/* '}' 0x7D */ { 914, 2, 12, 4, 1, -8 },
/* '~' 0x7E */ { 917, 6, 2, 6, 0, -4 },
/* 0x7F */ { 919, 9, 10, 0, 1, -8 },
/* 0x80 */ { 931, 7, 9, 8, 0, -8 },
/* 0x81 */ { 939, 0, 0, 8, 0, 0 },
/* 0x82 */ { 939, 1, 3, 3, 1, 0 },
/* 0x83 */ { 940, 0, 0, 8, 0, 0 },
/* 0x84 */ { 940, 3, 3, 5, 1, 0 },
/* 0x85 */ { 942, 5, 1, 7, 1, 0 },
/* 0x86 */ { 943, 5, 11, 7, 1, -8 },
/* 0x87 */ { 950, 5, 11, 7, 1, -8 },
/* 0x88 */ { 957, 0, 0, 8, 0, 0 },
/* 0x89 */ { 957, 12, 9, 12, 0, -8 },
/* 0x8A */ { 971, 6, 11, 8, 1, -9 },
/* 0x8B */ { 980, 2, 3, 4, 1, -4 },
/* 0x8C */ { 981, 6, 11, 8, 1, -10 },
/* 0x8D */ { 990, 6, 10, 8, 0, -9 },
/* 0x8E */ { 998, 7, 10, 7, 0, -9 },
/* 0x8F */ { 1007, 7, 10, 7, 0, -9 },
/* 0x90 */ { 1016, 0, 0, 8, 0, 0 },
/* 0x91 */ { 1016, 1, 3, 3, 1, -8 },
/* 0x92 */ { 1017, 1, 3, 2, 1, -8 },
/* 0x93 */ { 1018, 3, 3, 5, 1, -8 },
/* 0x94 */ { 1020, 3, 3, 5, 1, -8 },
/* 0x95 */ { 1022, 3, 3, 5, 1, -5 },
/* 0x96 */ { 1024, 6, 1, 6, 0, -3 },
/* 0x97 */ { 1025, 12, 1, 12, 0, -3 },
/* 0x98 */ { 1027, 0, 0, 8, 0, 0 },
/* 0x99 */ { 1027, 11, 7, 12, 1, -8 },
/* 0x9A */ { 1037, 4, 9, 6, 1, -8 },
/* 0x9B */ { 1042, 2, 3, 3, 1, -4 },
/* 0x9C */ { 1043, 4, 10, 6, 1, -9 },
/* 0x9D */ { 1048, 4, 9, 5, 0, -8 },
/* 0x9E */ { 1053, 5, 10, 6, 0, -9 },
/* 0x9F */ { 1060, 5, 10, 6, 0, -9 },
/* 0xA0 */ { 1067, 0, 0, 3, 0, 0 },
/* 0xA1 */ { 1067, 3, 2, 4, 0, -8 },
/* 0xA2 */ { 1068, 4, 2, 4, 0, -8 },
/* 0xA3 */ { 1069, 6, 9, 7, 0, -8 },
/* 0xA4 */ { 1076, 5, 4, 7, 1, -5 },
/* 0xA5 */ { 1079, 8, 11, 8, 1, -8 },
/* 0xA6 */ { 1090, 1, 12, 3, 1, -8 },
/* 0xA7 */ { 1092, 5, 12, 7, 1, -8 },
/* 0xA8 */ { 1100, 3, 1, 4, 0, -7 },
/* 0xA9 */ { 1101, 9, 9, 10, 0, -8 },
/* 0xAA */ { 1112, 6, 12, 8, 1, -8 },
/* 0xAB */ { 1121, 4, 4, 6, 1, -4 },
/* 0xAC */ { 1123, 6, 3, 7, 1, -4 },
/* 0xAD */ { 1126, 0, 0, 0, 0, 0 },
/* 0xAE */ { 1126, 9, 9, 10, 0, -8 },
/* 0xAF */ { 1137, 7, 10, 7, 0, -9 },
/* 0xB0 */ { 1146, 4, 4, 7, 2, -8 },
/* 0xB1 */ { 1148, 5, 7, 7, 1, -6 },
/* 0xB2 */ { 1153, 3, 2, 4, 1, 1 },
/* 0xB3 */ { 1154, 3, 9, 3, 0, -8 },
/* 0xB4 */ { 1158, 1, 1, 4, 1, -8 },
/* 0xB5 */ { 1159, 6, 9, 7, 1, -6 },
/* 0xB6 */ { 1166, 6, 10, 6, 1, -8 },
/* 0xB7 */ { 1174, 1, 1, 3, 1, -2 },
/* 0xB8 */ { 1175, 3, 3, 4, 1, 1 },
/* 0xB9 */ { 1177, 8, 9, 7, 0, -6 },
/* 0xBA */ { 1186, 4, 10, 6, 1, -6 },
/* 0xBB */ { 1191, 4, 4, 6, 1, -5 },
/* 0xBC */ { 1193, 5, 9, 7, 1, -8 },
/* 0xBD */ { 1199, 3, 1, 4, 0, -8 },
/* 0xBE */ { 1200, 3, 10, 3, 1, -9 },
/* 0xBF */ { 1204, 5, 9, 6, 0, -8 },
/* 0xC0 */ { 1210, 7, 10, 9, 1, -9 },
/* 0xC1 */ { 1219, 8, 10, 8, 0, -9 },
/* 0xC2 */ { 1229, 8, 10, 8, 0, -9 },
/* 0xC3 */ { 1239, 8, 10, 8, 0, -9 },
/* 0xC4 */ { 1249, 8, 10, 8, 0, -9 },
/* 0xC5 */ { 1259, 5, 10, 7, 1, -9 },
/* 0xC6 */ { 1266, 7, 11, 9, 0, -10 },
/* 0xC7 */ { 1276, 8, 12, 9, 0, -8 },
/* 0xC8 */ { 1288, 7, 11, 9, 0, -10 },
/* 0xC9 */ { 1298, 6, 10, 8, 1, -9 },
/* 0xCA */ { 1306, 7, 11, 8, 1, -8 },
/* 0xCB */ { 1316, 6, 10, 8, 1, -9 },
/* 0xCC */ { 1324, 6, 11, 8, 1, -10 },
/* 0xCD */ { 1333, 2, 10, 3, 1, -9 },
/* 0xCE */ { 1336, 3, 10, 4, 0, -9 },
/* 0xCF */ { 1340, 7, 10, 8, 1, -9 },
/* 0xD0 */ { 1349, 8, 9, 8, 0, -8 },
/* 0xD1 */ { 1358, 7, 10, 9, 1, -9 },
/* 0xD2 */ { 1367, 7, 10, 9, 1, -9 },
/* 0xD3 */ { 1376, 9, 10, 9, 0, -9 },
/* 0xD4 */ { 1388, 9, 11, 9, 0, -10 },
/* 0xD5 */ { 1401, 9, 11, 9, 0, -10 },
/* 0xD6 */ { 1414, 9, 11, 9, 0, -10 },
/* 0xD7 */ { 1427, 5, 5, 7, 1, -5 },
/* 0xD8 */ { 1431, 7, 10, 9, 1, -9 },
/* 0xD9 */ { 1440, 7, 10, 9, 1, -9 },
/* 0xDA */ { 1449, 7, 10, 9, 1, -9 },
/* 0xDB */ { 1458, 7, 10, 9, 1, -9 },
/* 0xDC */ { 1467, 7, 10, 9, 1, -9 },
/* 0xDD */ { 1476, 7, 10, 8, 1, -9 },
/* 0xDE */ { 1485, 6, 12, 7, 0, -8 },
/* 0xDF */ { 1494, 6, 9, 7, 1, -8 },
/* 0xE0 */ { 1501, 3, 9, 4, 1, -8 },
/* 0xE1 */ { 1505, 7, 10, 7, 0, -9 },
/* 0xE2 */ { 1514, 7, 10, 7, 0, -9 },
/* 0xE3 */ { 1523, 7, 10, 7, 0, -9 },
/* 0xE4 */ { 1532, 7, 9, 7, 0, -8 },
/* 0xE5 */ { 1540, 2, 10, 3, 1, -9 },
/* 0xE6 */ { 1543, 6, 10, 6, 0, -9 },
/* 0xE7 */ { 1551, 6, 10, 6, 0, -6 },
/* 0xE8 */ { 1559, 6, 10, 6, 0, -9 },
/* 0xE9 */ { 1567, 6, 10, 6, 0, -9 },
/* 0xEA */ { 1575, 6, 9, 6, 0, -6 },
/* 0xEB */ { 1582, 6, 9, 6, 0, -8 },
/* 0xEC */ { 1589, 6, 10, 6, 0, -9 },
/* 0xED */ { 1597, 2, 10, 3, 1, -9 },
/* 0xEE */ { 1600, 3, 10, 3, 0, -9 },
/* 0xEF */ { 1604, 7, 10, 7, 0, -9 },
/* 0xF0 */ { 1613, 7, 9, 7, 0, -8 },
/* 0xF1 */ { 1621, 5, 10, 6, 1, -9 },
/* 0xF2 */ { 1628, 5, 10, 6, 1, -9 },
/* 0xF3 */ { 1635, 6, 10, 6, 0, -9 },
/* 0xF4 */ { 1643, 6, 10, 6, 0, -9 },
/* 0xF5 */ { 1651, 6, 10, 6, 0, -9 },
/* 0xF6 */ { 1659, 6, 9, 6, 0, -8 },
/* 0xF7 */ { 1666, 5, 5, 7, 1, -5 },
/* 0xF8 */ { 1670, 3, 10, 4, 1, -9 },
/* 0xF9 */ { 1674, 5, 10, 6, 1, -9 },
/* 0xFA */ { 1681, 5, 9, 6, 1, -8 },
/* 0xFB */ { 1687, 5, 10, 6, 1, -9 },
/* 0xFC */ { 1694, 5, 9, 6, 1, -8 },
/* 0xFD */ { 1700, 6, 12, 6, 0, -8 },
/* 0xFE */ { 1709, 4, 11, 3, 0, -7 },
/* 0xFF */ { 1715, 1, 1, 4, 1, -7 },
};
const GFXfont FreeSans6pt_Win1250 PROGMEM = {
(uint8_t*)FreeSans6pt_Win1250Bitmaps,
(GFXglyph*)FreeSans6pt_Win1250Glyphs,
0x01, 0xFF, 14
};
@@ -0,0 +1,527 @@
// trunk-ignore-all(clang-format)
#pragma once
/* PROPERTIES
FONT_NAME FreeSans6pt_Win1251
*/
const uint8_t FreeSans6pt_Win1251Bitmaps[] PROGMEM = {
/* 0x01 */ 0x1C, 0x0A, 0x05, 0x04, 0xFE, 0x08, 0x1C, 0x02, 0x07, 0xE0, 0x9F, 0xC0,
/* 0x02 */ 0x3F, 0xF0, 0x40, 0xE0, 0x10, 0x3F, 0x04, 0x9E, 0x28, 0x14, 0x0E, 0x00,
/* 0x03 */ 0x3F, 0x10, 0x28, 0x06, 0x49, 0x80, 0x60, 0x19, 0x26, 0x31, 0x40, 0x8F, 0xC0,
/* 0x04 */ 0x3F, 0x10, 0x2A, 0x16, 0x49, 0xA1, 0x60, 0x19, 0xE6, 0x31, 0x40, 0x8F, 0xC0,
/* 0x05 */ 0x28, 0x15, 0x2A, 0xB5, 0x55, 0xA8, 0x54, 0x12, 0x04, 0x41, 0x08, 0x81, 0xC0,
/* 0x06 */ 0x04, 0x08, 0x88, 0x82, 0x07, 0x01, 0x11, 0xA2, 0xC4, 0x40, 0x70, 0x20, 0x88, 0x88, 0x10, 0x00,
/* 0x07 */
/* 0x08 */ 0x03, 0x83, 0x44, 0x48, 0x28, 0x01, 0x80, 0x17, 0xFE, 0x08, 0x45, 0x28, 0x84, 0x00,
/* 0x09 */ 0x01, 0xC0, 0x68, 0x82, 0x41, 0x10, 0x02, 0x80, 0x06, 0x00, 0x14, 0x00, 0x8F, 0xFC,
/* 0x0A */
/* 0x0B */ 0x22, 0x2A, 0xA2, 0x30, 0x18, 0x0A, 0x09, 0x04, 0x44, 0x14, 0x04, 0x00,
/* 0x0C */ 0x46, 0x00, 0x19, 0x03, 0x21, 0x20, 0x93, 0x04, 0x20, 0x11, 0x80, 0x50, 0x02, 0x7F, 0xE0,
/* 0x0D */
/* 0x0E */ 0x08, 0x0E, 0x08, 0x88, 0x24, 0x12, 0x09, 0x05, 0x01, 0xFF, 0x8A, 0x02, 0x00,
/* 0x0F */ 0x3F, 0x14, 0xAA, 0x16, 0x01, 0x92, 0x60, 0x18, 0xC6, 0x49, 0x40, 0x8F, 0xC0,
/* 0x10 */ 0x1B, 0x02, 0xA0, 0x54, 0x12, 0x42, 0x48, 0x49, 0x31, 0x1E, 0x23, 0xEA, 0xFE, 0x3C,
/* 0x11 */ 0x3F, 0x02, 0x00, 0x20, 0x6D, 0x27, 0xF8, 0x3F, 0xC1, 0xFE, 0x37, 0xD0, 0xBE, 0x40, 0xE1, 0xE2, 0x00,
/* 0x12 */ 0x12, 0x42, 0x20, 0x24, 0xC0, 0x29, 0x99, 0x05, 0x23, 0x30, 0xB0, 0x30, 0x00,
/* 0x13 */ 0x3F, 0x88, 0x0A, 0x44, 0xD5, 0x58, 0x03, 0x00, 0x67, 0xCC, 0x71, 0x40, 0x47, 0xF0,
/* 0x14 */ 0x3F, 0x18, 0x69, 0x26, 0x85, 0xA1, 0x6C, 0xD8, 0x06, 0x31, 0x40, 0x8F, 0xC0,
/* 0x15 */ 0x3F, 0x11, 0x00, 0xE8, 0x03, 0xA0, 0x1F, 0xB3, 0x7E, 0x00, 0xE9, 0xE0, 0x23, 0x00, 0x40, 0x40, 0xFE, 0x00,
/* 0x16 */ 0x30, 0x38, 0x3A, 0x3E, 0x6E, 0xEB, 0xC3, 0xC3, 0x66, 0x3C,
/* 0x17 */ 0x3F, 0x04, 0x00, 0x82, 0x88, 0x5C, 0xA4, 0x49, 0x22, 0x81, 0x98, 0xC4, 0x40, 0xA3, 0xF0,
/* 0x18 */ 0x07, 0x80, 0x42, 0x04, 0x08, 0x21, 0x41, 0x42, 0x60, 0x0E, 0x8C, 0xB2, 0x89, 0x50, 0x52, 0x82, 0x80,
/* 0x19 */ 0x3F, 0xC4, 0x02, 0x80, 0x18, 0x01, 0xB3, 0x1B, 0xB9, 0x80, 0x19, 0xE1, 0x40, 0x23, 0xFC,
/* 0x1A */ 0xFF, 0xC0, 0x67, 0x34, 0x58, 0x4C, 0x46, 0x03, 0x11, 0x80, 0xFF, 0xC0,
/* 0x1B */ 0x0F, 0xC0, 0x40, 0x82, 0x49, 0x08, 0x04, 0x00, 0x00, 0x12, 0x02, 0x31, 0x34, 0x0B, 0x88, 0x45, 0x00, 0x20,
/* 0x1C */ 0x3F, 0x88, 0x0A, 0x44, 0xC9, 0x19, 0x3B, 0x00, 0x60, 0x4C, 0x71, 0x40, 0x47, 0xF0,
/* 0x1D */ 0x3F, 0x8B, 0x0A, 0x00, 0xC8, 0x18, 0x13, 0x00, 0x48, 0xCA, 0xC1, 0x44, 0x53, 0x30,
/* 0x1E */ 0x19, 0xC2, 0x02, 0x50, 0x1E, 0x49, 0x80, 0x12, 0x01, 0x27, 0x92, 0x01, 0x10, 0x20, 0xFC,
/* 0x1F */ 0x30, 0x1C, 0x0C, 0x3E, 0x7E, 0xCF, 0x07, 0xC7, 0x7F, 0x3F,
/* ' ' 0x20 */
/* '!' 0x21 */ 0xFC, 0x80,
/* '"' 0x22 */ 0xB6, 0x80,
/* '#' 0x23 */ 0x24, 0x51, 0xF9, 0x42, 0x9F, 0x92, 0x28,
/* '$' 0x24 */ 0x10, 0xE5, 0x55, 0x50, 0xE1, 0x65, 0x55, 0xE1, 0x00,
/* '%' 0x25 */ 0x71, 0x24, 0x89, 0x22, 0x50, 0x74, 0x02, 0x70, 0xA4, 0x49, 0x11, 0xC0,
/* '&' 0x26 */ 0x71, 0x24, 0x9C, 0x62, 0x58, 0xA7, 0xF4,
/* ''' 0x27 */ 0xE0,
/* '(' 0x28 */ 0x5A, 0xAA, 0x94,
/* ')' 0x29 */ 0x89, 0x12, 0x49, 0x29, 0x00,
/* '*' 0x2A */ 0x5E, 0x80,
/* '+' 0x2B */ 0x21, 0x3E, 0x42, 0x00,
/* ',' 0x2C */ 0xE0,
/* '-' 0x2D */ 0xC0,
/* '.' 0x2E */ 0x80,
/* '/' 0x2F */ 0x24, 0xA4, 0xA4, 0x80,
/* '0' 0x30 */ 0x76, 0xE3, 0x18, 0xC6, 0x3B, 0x70,
/* '1' 0x31 */ 0x27, 0x92, 0x49, 0x20,
/* '2' 0x32 */ 0x79, 0x10, 0x41, 0x08, 0xC6, 0x10, 0xFC,
/* '3' 0x33 */ 0x79, 0x30, 0x43, 0x18, 0x10, 0x71, 0x78,
/* '4' 0x34 */ 0x08, 0x61, 0x8A, 0x49, 0x2F, 0xC2, 0x08,
/* '5' 0x35 */ 0xFC, 0x21, 0xE8, 0x84, 0x31, 0xF0,
/* '6' 0x36 */ 0x74, 0x61, 0xE8, 0xC6, 0x31, 0x70,
/* '7' 0x37 */ 0xF8, 0x44, 0x22, 0x11, 0x08, 0x40,
/* '8' 0x38 */ 0x39, 0x34, 0x53, 0x39, 0x1C, 0x51, 0x38,
/* '9' 0x39 */ 0x39, 0x3C, 0x71, 0x4C, 0xF0, 0x53, 0x78,
/* ':' 0x3A */ 0x82,
/* ';' 0x3B */ 0x87,
/* '<' 0x3C */ 0x3E, 0x30, 0x60, 0x80,
/* '=' 0x3D */ 0xF8, 0x3E,
/* '>' 0x3E */ 0xE0, 0xC6, 0xC8, 0x00,
/* '?' 0x3F */ 0x74, 0x42, 0x11, 0x10, 0x80, 0x20,
/* '@' 0x40 */ 0x0F, 0x86, 0x19, 0x9A, 0xA4, 0xD9, 0x13, 0x22, 0x56, 0xDA, 0x6E, 0x60, 0x06, 0x00, 0x3C, 0x00,
/* 'A' 0x41 */ 0x18, 0x18, 0x24, 0x24, 0x24, 0x7E, 0x42, 0x42, 0xC3,
/* 'B' 0x42 */ 0xFA, 0x18, 0x61, 0xFA, 0x18, 0x61, 0xFC,
/* 'C' 0x43 */ 0x3E, 0x63, 0x40, 0x40, 0xC0, 0x40, 0x41, 0x63, 0x3E,
/* 'D' 0x44 */ 0xF9, 0x0A, 0x1C, 0x18, 0x30, 0x61, 0xC2, 0xF8,
/* 'E' 0x45 */ 0xFE, 0x08, 0x20, 0xFE, 0x08, 0x20, 0xFC,
/* 'F' 0x46 */ 0xFE, 0x08, 0x20, 0xFA, 0x08, 0x20, 0x80,
/* 'G' 0x47 */ 0x1E, 0x61, 0x40, 0x40, 0xC7, 0x41, 0x41, 0x63, 0x1D,
/* 'H' 0x48 */ 0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60, 0xC1, 0x82,
/* 'I' 0x49 */ 0xFF, 0x80,
/* 'J' 0x4A */ 0x08, 0x42, 0x10, 0x87, 0x29, 0x70,
/* 'K' 0x4B */ 0x85, 0x12, 0x45, 0x0D, 0x13, 0x22, 0x42, 0x86,
/* 'L' 0x4C */ 0x84, 0x21, 0x08, 0x42, 0x10, 0xF8,
/* 'M' 0x4D */ 0xC3, 0xC3, 0xC3, 0xA5, 0xA5, 0xA5, 0x99, 0x99, 0x99,
/* 'N' 0x4E */ 0x83, 0x86, 0x8D, 0x19, 0x33, 0x62, 0xC3, 0x86,
/* 'O' 0x4F */ 0x1E, 0x31, 0x90, 0x68, 0x1C, 0x0A, 0x05, 0x06, 0xC6, 0x1E, 0x00,
/* 'P' 0x50 */ 0xFA, 0x18, 0x61, 0xFA, 0x08, 0x20, 0x80,
/* 'Q' 0x51 */ 0x1E, 0x31, 0x90, 0x68, 0x1C, 0x0A, 0x05, 0x16, 0xC6, 0x1F, 0x00, 0x40,
/* 'R' 0x52 */ 0xFD, 0x0E, 0x1C, 0x2F, 0x90, 0xA1, 0x42, 0x86,
/* 'S' 0x53 */ 0x7A, 0x18, 0x30, 0x78, 0x38, 0x61, 0x78,
/* 'T' 0x54 */ 0xFE, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10,
/* 'U' 0x55 */ 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xE2, 0x78,
/* 'V' 0x56 */ 0xC2, 0x85, 0x0B, 0x22, 0x44, 0x8E, 0x0C, 0x18,
/* 'W' 0x57 */ 0xC4, 0x28, 0xCD, 0x29, 0x25, 0x24, 0xA4, 0x52, 0x8C, 0x61, 0x8C, 0x31, 0x80,
/* 'X' 0x58 */ 0x87, 0x34, 0x8C, 0x30, 0xC4, 0xA3, 0x84,
/* 'Y' 0x59 */ 0xC3, 0x42, 0x24, 0x34, 0x18, 0x08, 0x08, 0x08, 0x08,
/* 'Z' 0x5A */ 0x7E, 0x0C, 0x30, 0x41, 0x06, 0x18, 0x20, 0xFE,
/* '[' 0x5B */ 0xEA, 0xAA, 0xAB,
/* '\' 0x5C */ 0x92, 0x24, 0x89, 0x20,
/* ']' 0x5D */ 0xD5, 0x55, 0x57,
/* '^' 0x5E */ 0x46, 0xA9,
/* '_' 0x5F */ 0xFE,
/* '`' 0x60 */ 0x80,
/* 'a' 0x61 */ 0x79, 0x20, 0x4F, 0xC6, 0x37, 0x40,
/* 'b' 0x62 */ 0x84, 0x3D, 0x18, 0xC6, 0x31, 0xF0,
/* 'c' 0x63 */ 0x39, 0x3C, 0x20, 0xC1, 0x33, 0x80,
/* 'd' 0x64 */ 0x04, 0x13, 0xD3, 0xC6, 0x1C, 0x53, 0x3C,
/* 'e' 0x65 */ 0x39, 0x38, 0x7F, 0x81, 0x13, 0x80,
/* 'f' 0x66 */ 0x6B, 0xA4, 0x92, 0x40,
/* 'g' 0x67 */ 0x35, 0x3C, 0x61, 0xC5, 0x33, 0x41, 0x4D, 0xE0,
/* 'h' 0x68 */ 0x84, 0x3D, 0x38, 0xC6, 0x31, 0x88,
/* 'i' 0x69 */ 0xBF, 0x80,
/* 'j' 0x6A */ 0x45, 0x55, 0x57,
/* 'k' 0x6B */ 0x84, 0x25, 0x4E, 0x52, 0xD2, 0x88,
/* 'l' 0x6C */ 0xFF, 0x80,
/* 'm' 0x6D */ 0xF7, 0x99, 0x91, 0x91, 0x91, 0x91, 0x91,
/* 'n' 0x6E */ 0xF4, 0x63, 0x18, 0xC6, 0x20,
/* 'o' 0x6F */ 0x39, 0x3C, 0x61, 0xC5, 0x33, 0x80,
/* 'p' 0x70 */ 0xF4, 0x63, 0x18, 0xC7, 0xD0, 0x80,
/* 'q' 0x71 */ 0x3D, 0x3C, 0x61, 0xC5, 0x37, 0x41, 0x04,
/* 'r' 0x72 */ 0xF2, 0x49, 0x20,
/* 's' 0x73 */ 0x7A, 0x50, 0xE0, 0xE5, 0xE0,
/* 't' 0x74 */ 0x5D, 0x24, 0x93,
/* 'u' 0x75 */ 0x8C, 0x63, 0x18, 0xCF, 0xA0,
/* 'v' 0x76 */ 0x85, 0x24, 0x92, 0x30, 0xC3, 0x00,
/* 'w' 0x77 */ 0x89, 0x59, 0x59, 0x55, 0x56, 0x26, 0x26,
/* 'x' 0x78 */ 0x4A, 0x4C, 0x43, 0x27, 0x20,
/* 'y' 0x79 */ 0x8A, 0x52, 0xA5, 0x18, 0x84, 0x22, 0x00,
/* 'z' 0x7A */ 0x78, 0x44, 0x46, 0x23, 0xE0,
/* '{' 0x7B */ 0x6A, 0xAA, 0xA9,
/* '|' 0x7C */ 0xFF, 0xE0,
/* '}' 0x7D */ 0x95, 0x55, 0x56,
/* '~' 0x7E */ 0x66, 0x60,
/* 0x7F */
/* 0x80 */ 0xFC, 0x08, 0x04, 0x02, 0x01, 0xF0, 0x8C, 0x46, 0x23, 0x11, 0x80, 0xC0, 0xC0,
/* 0x81 */ 0x10, 0x8F, 0xE0, 0x82, 0x08, 0x20, 0x82, 0x00,
/* 0x82 */ 0xE0,
/* 0x83 */ 0x24, 0x0F, 0x88, 0x88, 0x80,
/* 0x84 */ 0xB6, 0x80,
/* 0x85 */ 0xA8,
/* 0x86 */ 0x21, 0x09, 0xF2, 0x10, 0x84, 0x21, 0x08,
/* 0x87 */ 0x21, 0x09, 0xF2, 0x10, 0x84, 0xF9, 0x08,
/* 0x88 */ 0x1C, 0x45, 0x07, 0xE4, 0x1F, 0x10, 0x10, 0x1E,
/* 0x89 */ 0x62, 0x09, 0x40, 0x98, 0x06, 0x80, 0x10, 0x01, 0x66, 0x29, 0x92, 0x99, 0x06, 0x60,
/* 0x8A */ 0x7C, 0x08, 0x81, 0x10, 0x22, 0x04, 0x7C, 0x88, 0x51, 0x0A, 0x21, 0x87, 0xC0,
/* 0x8B */ 0x64,
/* 0x8C */ 0x84, 0x10, 0x82, 0x10, 0x42, 0x0F, 0xFD, 0x08, 0xA1, 0x0C, 0x23, 0x87, 0xC0,
/* 0x8D */ 0x10, 0x88, 0xE6, 0xB3, 0x8C, 0x28, 0x92, 0x28, 0xC0,
/* 0x8E */ 0xFC, 0x08, 0x04, 0x02, 0x01, 0xF0, 0x8C, 0x46, 0x23, 0x11, 0x80,
/* 0x8F */ 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xFE, 0x20, 0x40,
/* 0x90 */ 0x43, 0xC4, 0x1F, 0x45, 0x14, 0x51, 0x44, 0x11, 0x80,
/* 0x91 */ 0xE0,
/* 0x92 */ 0xE0,
/* 0x93 */ 0xB6, 0x80,
/* 0x94 */ 0xB6, 0x80,
/* 0x95 */ 0xFF, 0x80,
/* 0x96 */ 0xFC,
/* 0x97 */ 0xFF, 0xF0,
/* 0x98 */
/* 0x99 */ 0xE6, 0x28, 0xCD, 0x19, 0xA3, 0x34, 0x6A, 0x8B, 0x51, 0x68,
/* 0x9A */ 0x78, 0x24, 0x13, 0xC9, 0x14, 0x8E, 0x7C,
/* 0x9B */ 0x98,
/* 0x9C */ 0x88, 0x44, 0x3F, 0xD1, 0x38, 0x8C, 0x78,
/* 0x9D */ 0x24, 0x09, 0xAC, 0xCA, 0x90,
/* 0x9E */ 0x43, 0xC4, 0x1F, 0x45, 0x14, 0x51, 0x44,
/* 0x9F */ 0x8C, 0x63, 0x18, 0xFC, 0x80,
/* 0xA0 */
/* 0xA1 */ 0x24, 0x33, 0x0A, 0x36, 0x45, 0x8E, 0x0C, 0x10, 0x60, 0x80,
/* 0xA2 */ 0x51, 0x22, 0x95, 0xA8, 0xC4, 0x23, 0x10,
/* 0xA3 */ 0x08, 0x42, 0x10, 0x86, 0x31, 0x78,
/* 0xA4 */ 0xFC, 0x63, 0xF0,
/* 0xA5 */ 0x07, 0xF8, 0x20, 0x82, 0x08, 0x20, 0x82, 0x00,
/* 0xA6 */ 0xF9, 0xF0,
/* 0xA7 */ 0x32, 0x91, 0xC9, 0x47, 0x26, 0x14, 0xA4, 0xC0,
/* 0xA8 */ 0x28, 0x0F, 0xE0, 0x82, 0x0F, 0xE0, 0x82, 0x0F, 0xC0,
/* 0xA9 */ 0x3E, 0x3F, 0xB8, 0xF4, 0x1A, 0x0D, 0x17, 0x76, 0xC6, 0x3E, 0x00,
/* 0xAA */ 0x38, 0x8A, 0x0C, 0x0F, 0x90, 0x20, 0xE3, 0x7C,
/* 0xAB */ 0x5A, 0xA5,
/* 0xAC */ 0x51, 0x55, 0x56,
/* 0xAD */
/* 0xAE */ 0x3E, 0x31, 0xB7, 0x72, 0x99, 0xCC, 0xC7, 0x56, 0xC6, 0x3E, 0x00,
/* 0xAF */ 0xA1, 0x24, 0x92, 0x49, 0x00,
/* 0xB0 */ 0x69, 0x96,
/* 0xB1 */ 0x21, 0x3E, 0x42, 0x03, 0xE0,
/* 0xB2 */ 0xFF, 0x80,
/* 0xB3 */ 0xDF, 0x80,
/* 0xB4 */ 0x27, 0xC9, 0x24,
/* 0xB5 */ 0x8A, 0x28, 0xA2, 0x8A, 0x6E, 0xE0, 0x80,
/* 0xB6 */ 0x7F, 0xAE, 0xBA, 0x68, 0xA2, 0x8A, 0x28, 0xA0,
/* 0xB7 */ 0x80,
/* 0xB8 */ 0x28, 0xA0, 0x1E, 0x47, 0xFC, 0x11, 0x78,
/* 0xB9 */ 0x88, 0x44, 0x32, 0x59, 0xDA, 0xCD, 0x66, 0x6B, 0x32, 0x8B, 0x80,
/* 0xBA */ 0x79, 0x1F, 0x30, 0x45, 0xE0,
/* 0xBB */ 0xA5, 0x5A,
/* 0xBC */ 0x45, 0x55, 0x57,
/* 0xBD */ 0x7A, 0x18, 0x70, 0x78, 0x38, 0x61, 0x7C,
/* 0xBE */ 0x7A, 0x1C, 0x1C, 0xBC,
/* 0xBF */ 0xB4, 0x24, 0x92, 0x40,
/* 0xC0 */ 0x18, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0x42, 0xC3,
/* 0xC1 */ 0xFE, 0x08, 0x20, 0xFA, 0x18, 0x61, 0xF8,
/* 0xC2 */ 0xFA, 0x18, 0x61, 0xFA, 0x18, 0x61, 0xFC,
/* 0xC3 */ 0xFE, 0x08, 0x20, 0x82, 0x08, 0x20, 0x80,
/* 0xC4 */ 0x1F, 0x08, 0x84, 0x42, 0x21, 0x10, 0x88, 0x44, 0x42, 0xFF, 0xC0, 0x60, 0x20,
/* 0xC5 */ 0xFE, 0x08, 0x20, 0xFE, 0x08, 0x20, 0xFC,
/* 0xC6 */ 0x88, 0xA4, 0x9A, 0x87, 0xC1, 0xC1, 0xF1, 0xAD, 0x92, 0x88, 0x80,
/* 0xC7 */ 0x7A, 0x18, 0x41, 0x38, 0x18, 0x61, 0x7C,
/* 0xC8 */ 0x87, 0x0E, 0x2C, 0x59, 0x34, 0x68, 0xE1, 0xC2,
/* 0xC9 */ 0x28, 0x22, 0x1C, 0x38, 0xB1, 0x64, 0xD1, 0xA3, 0x87, 0x08,
/* 0xCA */ 0x8E, 0x6B, 0x38, 0xC2, 0x89, 0x22, 0x8C,
/* 0xCB */ 0x3E, 0x44, 0x89, 0x12, 0x24, 0x58, 0xA1, 0xC2,
/* 0xCC */ 0xC3, 0xC3, 0xC3, 0xA5, 0xA5, 0xA5, 0x99, 0x99, 0x99,
/* 0xCD */ 0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60, 0xC1, 0x82,
/* 0xCE */ 0x3C, 0x42, 0x81, 0x81, 0x81, 0x81, 0x81, 0xC2, 0x7C,
/* 0xCF */ 0xFF, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x82,
/* 0xD0 */ 0xFA, 0x18, 0x61, 0xFE, 0x08, 0x20, 0x80,
/* 0xD1 */ 0x38, 0x8A, 0x0C, 0x08, 0x10, 0x20, 0xE3, 0x7C,
/* 0xD2 */ 0xFE, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10,
/* 0xD3 */ 0xC2, 0x8D, 0x91, 0x63, 0x83, 0x04, 0x18, 0x20,
/* 0xD4 */ 0x08, 0x1F, 0x32, 0x71, 0x18, 0x8C, 0x47, 0x26, 0xFE, 0x08, 0x00,
/* 0xD5 */ 0x87, 0x34, 0x8C, 0x30, 0xC4, 0xB3, 0x84,
/* 0xD6 */ 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xFF, 0x01, 0x01,
/* 0xD7 */ 0x8E, 0x38, 0xE3, 0x8D, 0xF0, 0xC3, 0x0C,
/* 0xD8 */ 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xFF,
/* 0xD9 */ 0x99, 0x4C, 0xA6, 0x53, 0x29, 0x94, 0xCA, 0x65, 0x32, 0xFF, 0x80, 0x40, 0x20,
/* 0xDA */ 0xF0, 0x04, 0x01, 0x00, 0x40, 0x1F, 0x84, 0x21, 0x0C, 0x42, 0x1F, 0x00,
/* 0xDB */ 0x81, 0xC0, 0xE0, 0x70, 0x3F, 0xDC, 0x2E, 0x17, 0x0B, 0xF9, 0x80,
/* 0xDC */ 0x82, 0x08, 0x20, 0xFE, 0x18, 0x61, 0xF8,
/* 0xDD */ 0x79, 0x8A, 0x18, 0x13, 0xE0, 0x60, 0xC2, 0x7C,
/* 0xDE */ 0x87, 0x26, 0x39, 0x06, 0x41, 0xF0, 0x64, 0x19, 0x06, 0x63, 0x8F, 0x80,
/* 0xDF */ 0x7E, 0x18, 0x61, 0x7C, 0xD6, 0x71, 0x84,
/* 0xE0 */ 0x79, 0x11, 0xD9, 0xCD, 0xD0,
/* 0xE1 */ 0x0D, 0xC4, 0x1E, 0x47, 0x1C, 0x51, 0x78,
/* 0xE2 */ 0xF4, 0xBD, 0x29, 0xF8,
/* 0xE3 */ 0xF8, 0x88, 0x88,
/* 0xE4 */ 0x3C, 0x48, 0x91, 0x22, 0x5F, 0xE0, 0x80,
/* 0xE5 */ 0x79, 0x1F, 0xF0, 0x45, 0xE0,
/* 0xE6 */ 0x92, 0x54, 0x38, 0x3C, 0x56, 0x93,
/* 0xE7 */ 0x78, 0x23, 0x82, 0xCD, 0xE0,
/* 0xE8 */ 0x9C, 0xEB, 0x5C, 0xC4,
/* 0xE9 */ 0x70, 0x27, 0x3A, 0xD7, 0x31,
/* 0xEA */ 0x9A, 0xCC, 0xA9,
/* 0xEB */ 0x7A, 0x52, 0x94, 0xE4,
/* 0xEC */ 0x8F, 0x3D, 0x6D, 0xA6, 0x90,
/* 0xED */ 0x8C, 0x7F, 0x18, 0xC4,
/* 0xEE */ 0x79, 0x1C, 0x71, 0x45, 0xE0,
/* 0xEF */ 0xFC, 0x63, 0x18, 0xC4,
/* 0xF0 */ 0xFC, 0x63, 0x18, 0xFA, 0x10, 0x80,
/* 0xF1 */ 0x79, 0x1C, 0x30, 0x45, 0xE0,
/* 0xF2 */ 0xF9, 0x08, 0x42, 0x10,
/* 0xF3 */ 0x8A, 0x56, 0xA3, 0x10, 0x8C, 0x40,
/* 0xF4 */ 0x04, 0x01, 0x07, 0xF9, 0x31, 0xC4, 0x71, 0x14, 0xC5, 0xFE, 0x04, 0x01, 0x00, 0x40,
/* 0xF5 */ 0x4B, 0x8C, 0x65, 0xE4,
/* 0xF6 */ 0x8A, 0x28, 0xA2, 0x8B, 0xF0, 0x40,
/* 0xF7 */ 0x99, 0x97, 0x11,
/* 0xF8 */ 0x96, 0x59, 0x65, 0x97, 0xF0,
/* 0xF9 */ 0x95, 0x2A, 0x54, 0xA9, 0x5F, 0xC0, 0x80,
/* 0xFA */ 0xF0, 0x20, 0x78, 0x91, 0x23, 0xC0,
/* 0xFB */ 0x86, 0x1F, 0x63, 0x8F, 0xD0,
/* 0xFC */ 0x84, 0x3D, 0x18, 0xF8,
/* 0xFD */ 0xF4, 0xDE, 0x19, 0xF8,
/* 0xFE */ 0x9E, 0xA2, 0xE1, 0xA1, 0xA2, 0x9E,
/* 0xFF */ 0xFC, 0x7E, 0xD4, 0xC4,
};
const GFXglyph FreeSans6pt_Win1251Glyphs[] PROGMEM = {
/* 0x01 */ { 0, 9, 10, 11, 1, -9 },
/* 0x02 */ { 12, 9, 10, 11, 1, -8 },
/* 0x03 */ { 24, 10, 10, 12, 1, -8 },
/* 0x04 */ { 37, 10, 10, 12, 1, -8 },
/* 0x05 */ { 50, 10, 10, 12, 1, -9 },
/* 0x06 */ { 63, 11, 11, 13, 1, -9 },
/* 0x07 */ { 79, 0, 0, 8, 0, 0 },
/* 0x08 */ { 79, 12, 9, 14, 1, -8 },
/* 0x09 */ { 93, 14, 8, 16, 1, -7 },
/* 0x0A */ { 107, 0, 0, 8, 0, 0 },
/* 0x0B */ { 107, 9, 10, 11, 1, -9 },
/* 0x0C */ { 119, 13, 9, 15, 1, -8 },
/* 0x0D */ { 134, 0, 0, 8, 0, 0 },
/* 0x0E */ { 134, 9, 11, 11, 1, -9 },
/* 0x0F */ { 147, 10, 10, 12, 1, -9 },
/* 0x10 */ { 160, 11, 10, 13, 1, -9 },
/* 0x11 */ { 174, 13, 10, 15, 1, -9 },
/* 0x12 */ { 191, 10, 10, 12, 1, -9 },
/* 0x13 */ { 204, 11, 10, 13, 1, -9 },
/* 0x14 */ { 218, 10, 10, 12, 1, -9 },
/* 0x15 */ { 231, 14, 10, 16, 1, -9 },
/* 0x16 */ { 249, 8, 10, 10, 1, -9 },
/* 0x17 */ { 259, 12, 10, 14, 1, -9 },
/* 0x18 */ { 274, 13, 10, 15, 1, -9 },
/* 0x19 */ { 291, 12, 10, 14, 1, -9 },
/* 0x1A */ { 306, 9, 10, 11, 1, -8 },
/* 0x1B */ { 318, 14, 10, 16, 1, -9 },
/* 0x1C */ { 336, 11, 10, 13, 1, -9 },
/* 0x1D */ { 350, 11, 10, 13, 1, -9 },
/* 0x1E */ { 364, 12, 10, 14, 1, -9 },
/* 0x1F */ { 379, 8, 10, 11, 2, -9 },
/* ' ' 0x20 */ { 389, 0, 0, 3, 0, 0 },
/* '!' 0x21 */ { 389, 1, 9, 4, 2, -8 },
/* '"' 0x22 */ { 391, 3, 3, 4, 0, -8 },
/* '#' 0x23 */ { 393, 7, 8, 7, 0, -7 },
/* '$' 0x24 */ { 400, 6, 11, 7, 0, -9 },
/* '%' 0x25 */ { 409, 10, 9, 11, 0, -8 },
/* '&' 0x26 */ { 421, 6, 9, 8, 1, -8 },
/* ''' 0x27 */ { 428, 1, 3, 2, 1, -8 },
/* '(' 0x28 */ { 429, 2, 11, 4, 1, -8 },
/* ')' 0x29 */ { 432, 3, 11, 4, 0, -8 },
/* '*' 0x2A */ { 437, 3, 3, 5, 1, -8 },
/* '+' 0x2B */ { 439, 5, 5, 7, 1, -4 },
/* ',' 0x2C */ { 443, 1, 3, 3, 1, 0 },
/* '-' 0x2D */ { 444, 2, 1, 4, 1, -3 },
/* '.' 0x2E */ { 445, 1, 1, 3, 1, 0 },
/* '/' 0x2F */ { 446, 3, 9, 3, 0, -8 },
/* '0' 0x30 */ { 450, 5, 9, 7, 1, -8 },
/* '1' 0x31 */ { 456, 3, 9, 7, 1, -8 },
/* '2' 0x32 */ { 460, 6, 9, 7, 0, -8 },
/* '3' 0x33 */ { 467, 6, 9, 7, 0, -8 },
/* '4' 0x34 */ { 474, 6, 9, 7, 0, -8 },
/* '5' 0x35 */ { 481, 5, 9, 7, 1, -8 },
/* '6' 0x36 */ { 487, 5, 9, 7, 1, -8 },
/* '7' 0x37 */ { 493, 5, 9, 7, 1, -8 },
/* '8' 0x38 */ { 499, 6, 9, 7, 0, -8 },
/* '9' 0x39 */ { 506, 6, 9, 7, 0, -8 },
/* ':' 0x3A */ { 513, 1, 7, 3, 1, -6 },
/* ';' 0x3B */ { 514, 1, 8, 3, 1, -5 },
/* '<' 0x3C */ { 515, 5, 5, 7, 1, -4 },
/* '=' 0x3D */ { 519, 5, 3, 7, 1, -3 },
/* '>' 0x3E */ { 521, 5, 5, 7, 1, -4 },
/* '?' 0x3F */ { 525, 5, 9, 7, 1, -8 },
/* '@' 0x40 */ { 531, 11, 11, 12, 0, -8 },
/* 'A' 0x41 */ { 547, 8, 9, 8, 0, -8 },
/* 'B' 0x42 */ { 556, 6, 9, 8, 1, -8 },
/* 'C' 0x43 */ { 563, 8, 9, 9, 0, -8 },
/* 'D' 0x44 */ { 572, 7, 9, 8, 1, -8 },
/* 'E' 0x45 */ { 580, 6, 9, 8, 1, -8 },
/* 'F' 0x46 */ { 587, 6, 9, 7, 1, -8 },
/* 'G' 0x47 */ { 594, 8, 9, 9, 0, -8 },
/* 'H' 0x48 */ { 603, 7, 9, 9, 1, -8 },
/* 'I' 0x49 */ { 611, 1, 9, 3, 1, -8 },
/* 'J' 0x4A */ { 613, 5, 9, 6, 0, -8 },
/* 'K' 0x4B */ { 619, 7, 9, 8, 1, -8 },
/* 'L' 0x4C */ { 627, 5, 9, 7, 1, -8 },
/* 'M' 0x4D */ { 633, 8, 9, 10, 1, -8 },
/* 'N' 0x4E */ { 642, 7, 9, 9, 1, -8 },
/* 'O' 0x4F */ { 650, 9, 9, 9, 0, -8 },
/* 'P' 0x50 */ { 661, 6, 9, 8, 1, -8 },
/* 'Q' 0x51 */ { 668, 9, 10, 9, 0, -8 },
/* 'R' 0x52 */ { 680, 7, 9, 9, 1, -8 },
/* 'S' 0x53 */ { 688, 6, 9, 8, 1, -8 },
/* 'T' 0x54 */ { 695, 7, 9, 8, 0, -8 },
/* 'U' 0x55 */ { 703, 7, 9, 9, 1, -8 },
/* 'V' 0x56 */ { 711, 7, 9, 8, 0, -8 },
/* 'W' 0x57 */ { 719, 11, 9, 11, 0, -8 },
/* 'X' 0x58 */ { 732, 6, 9, 8, 1, -8 },
/* 'Y' 0x59 */ { 739, 8, 9, 8, 0, -8 },
/* 'Z' 0x5A */ { 748, 7, 9, 7, 0, -8 },
/* '[' 0x5B */ { 756, 2, 12, 3, 1, -8 },
/* '\' 0x5C */ { 759, 3, 9, 3, 0, -8 },
/* ']' 0x5D */ { 763, 2, 12, 3, 0, -8 },
/* '^' 0x5E */ { 766, 4, 4, 6, 1, -8 },
/* '_' 0x5F */ { 768, 7, 1, 7, 0, 2 },
/* '`' 0x60 */ { 769, 1, 1, 3, 1, -8 },
/* 'a' 0x61 */ { 770, 6, 7, 7, 0, -6 },
/* 'b' 0x62 */ { 776, 5, 9, 7, 1, -8 },
/* 'c' 0x63 */ { 782, 6, 7, 6, 0, -6 },
/* 'd' 0x64 */ { 788, 6, 9, 7, 0, -8 },
/* 'e' 0x65 */ { 795, 6, 7, 6, 0, -6 },
/* 'f' 0x66 */ { 801, 3, 9, 3, 0, -8 },
/* 'g' 0x67 */ { 805, 6, 10, 7, 0, -6 },
/* 'h' 0x68 */ { 813, 5, 9, 6, 1, -8 },
/* 'i' 0x69 */ { 819, 1, 9, 3, 1, -8 },
/* 'j' 0x6A */ { 821, 2, 12, 3, 0, -8 },
/* 'k' 0x6B */ { 824, 5, 9, 6, 1, -8 },
/* 'l' 0x6C */ { 830, 1, 9, 3, 1, -8 },
/* 'm' 0x6D */ { 832, 8, 7, 10, 1, -6 },
/* 'n' 0x6E */ { 839, 5, 7, 6, 1, -6 },
/* 'o' 0x6F */ { 844, 6, 7, 6, 0, -6 },
/* 'p' 0x70 */ { 850, 5, 9, 7, 1, -6 },
/* 'q' 0x71 */ { 856, 6, 9, 7, 0, -6 },
/* 'r' 0x72 */ { 863, 3, 7, 4, 1, -6 },
/* 's' 0x73 */ { 866, 5, 7, 6, 0, -6 },
/* 't' 0x74 */ { 871, 3, 8, 3, 0, -7 },
/* 'u' 0x75 */ { 874, 5, 7, 6, 1, -6 },
/* 'v' 0x76 */ { 879, 6, 7, 6, 0, -6 },
/* 'w' 0x77 */ { 885, 8, 7, 9, 0, -6 },
/* 'x' 0x78 */ { 892, 5, 7, 6, 0, -6 },
/* 'y' 0x79 */ { 897, 5, 10, 6, 0, -6 },
/* 'z' 0x7A */ { 904, 5, 7, 6, 0, -6 },
/* '{' 0x7B */ { 909, 2, 12, 4, 1, -8 },
/* '|' 0x7C */ { 912, 1, 11, 3, 1, -8 },
/* '}' 0x7D */ { 914, 2, 12, 4, 1, -8 },
/* '~' 0x7E */ { 917, 6, 2, 6, 0, -4 },
/* 0x7F */ { 919, 0, 0, 0, 0, 0 },
/* 0x80 */ { 919, 9, 11, 9, 0, -8 },
/* 0x81 */ { 932, 6, 10, 7, 1, -9 },
/* 0x82 */ { 940, 1, 3, 3, 1, 0 },
/* 0x83 */ { 941, 4, 9, 5, 1, -8 },
/* 0x84 */ { 946, 3, 3, 5, 1, 0 },
/* 0x85 */ { 948, 5, 1, 7, 1, 0 },
/* 0x86 */ { 949, 5, 11, 7, 1, -8 },
/* 0x87 */ { 956, 5, 11, 7, 1, -8 },
/* 0x88 */ { 963, 7, 9, 8, 0, -8 },
/* 0x89 */ { 971, 12, 9, 12, 0, -8 },
/* 0x8A */ { 985, 11, 9, 13, 1, -8 },
/* 0x8B */ { 998, 2, 3, 4, 1, -4 },
/* 0x8C */ { 999, 11, 9, 12, 1, -8 },
/* 0x8D */ { 1012, 6, 11, 8, 1, -10 },
/* 0x8E */ { 1021, 9, 9, 9, 0, -8 },
/* 0x8F */ { 1032, 7, 11, 9, 1, -8 },
/* 0x90 */ { 1042, 6, 11, 7, 0, -8 },
/* 0x91 */ { 1051, 1, 3, 3, 1, -8 },
/* 0x92 */ { 1052, 1, 3, 2, 1, -8 },
/* 0x93 */ { 1053, 3, 3, 5, 1, -8 },
/* 0x94 */ { 1055, 3, 3, 5, 1, -8 },
/* 0x95 */ { 1057, 3, 3, 5, 1, -5 },
/* 0x96 */ { 1059, 6, 1, 6, 0, -3 },
/* 0x97 */ { 1060, 12, 1, 12, 0, -3 },
/* 0x98 */ { 1062, 0, 0, 8, 0, 0 },
/* 0x99 */ { 1062, 11, 7, 12, 1, -8 },
/* 0x9A */ { 1072, 9, 6, 10, 0, -5 },
/* 0x9B */ { 1079, 2, 3, 3, 1, -4 },
/* 0x9C */ { 1080, 9, 6, 10, 1, -5 },
/* 0x9D */ { 1087, 4, 9, 6, 1, -8 },
/* 0x9E */ { 1092, 6, 9, 7, 0, -8 },
/* 0x9F */ { 1099, 5, 7, 7, 1, -5 },
/* 0xA0 */ { 1104, 0, 0, 3, 0, 0 },
/* 0xA1 */ { 1104, 7, 11, 7, 0, -10 },
/* 0xA2 */ { 1114, 5, 11, 6, 0, -7 },
/* 0xA3 */ { 1121, 5, 9, 6, 0, -8 },
/* 0xA4 */ { 1127, 5, 4, 7, 1, -5 },
/* 0xA5 */ { 1130, 6, 10, 7, 1, -9 },
/* 0xA6 */ { 1138, 1, 12, 3, 1, -8 },
/* 0xA7 */ { 1140, 5, 12, 7, 1, -8 },
/* 0xA8 */ { 1148, 6, 11, 8, 1, -10 },
/* 0xA9 */ { 1157, 9, 9, 10, 0, -8 },
/* 0xAA */ { 1168, 7, 9, 9, 1, -8 },
/* 0xAB */ { 1176, 4, 4, 6, 1, -4 },
/* 0xAC */ { 1178, 2, 12, 3, 0, -8 },
/* 0xAD */ { 1181, 0, 0, 0, 0, 0 },
/* 0xAE */ { 1181, 9, 9, 10, 0, -8 },
/* 0xAF */ { 1192, 3, 11, 3, 0, -10 },
/* 0xB0 */ { 1197, 4, 4, 7, 2, -8 },
/* 0xB1 */ { 1199, 5, 7, 7, 1, -6 },
/* 0xB2 */ { 1204, 1, 9, 3, 1, -8 },
/* 0xB3 */ { 1206, 1, 9, 3, 1, -8 },
/* 0xB4 */ { 1208, 3, 8, 5, 1, -7 },
/* 0xB5 */ { 1211, 6, 9, 7, 1, -6 },
/* 0xB6 */ { 1218, 6, 10, 6, 1, -8 },
/* 0xB7 */ { 1226, 1, 1, 3, 1, -2 },
/* 0xB8 */ { 1227, 6, 9, 7, 0, -8 },
/* 0xB9 */ { 1234, 9, 9, 11, 1, -8 },
/* 0xBA */ { 1245, 6, 6, 6, 0, -5 },
/* 0xBB */ { 1250, 4, 4, 6, 1, -5 },
/* 0xBC */ { 1252, 2, 12, 3, 0, -8 },
/* 0xBD */ { 1255, 6, 9, 8, 1, -8 },
/* 0xBE */ { 1262, 5, 6, 6, 0, -5 },
/* 0xBF */ { 1266, 3, 9, 3, 0, -8 },
/* 0xC0 */ { 1270, 8, 9, 8, 0, -8 },
/* 0xC1 */ { 1279, 6, 9, 8, 1, -8 },
/* 0xC2 */ { 1286, 6, 9, 8, 1, -8 },
/* 0xC3 */ { 1293, 6, 9, 7, 1, -8 },
/* 0xC4 */ { 1300, 9, 11, 10, 0, -8 },
/* 0xC5 */ { 1313, 6, 9, 8, 1, -8 },
/* 0xC6 */ { 1320, 9, 9, 11, 1, -8 },
/* 0xC7 */ { 1331, 6, 9, 8, 1, -8 },
/* 0xC8 */ { 1338, 7, 9, 9, 1, -8 },
/* 0xC9 */ { 1346, 7, 11, 9, 1, -10 },
/* 0xCA */ { 1356, 6, 9, 8, 1, -8 },
/* 0xCB */ { 1363, 7, 9, 8, 0, -8 },
/* 0xCC */ { 1371, 8, 9, 10, 1, -8 },
/* 0xCD */ { 1380, 7, 9, 9, 1, -8 },
/* 0xCE */ { 1388, 8, 9, 10, 1, -8 },
/* 0xCF */ { 1397, 7, 9, 9, 1, -8 },
/* 0xD0 */ { 1405, 6, 9, 8, 1, -8 },
/* 0xD1 */ { 1412, 7, 9, 9, 1, -8 },
/* 0xD2 */ { 1420, 7, 9, 7, 0, -8 },
/* 0xD3 */ { 1428, 7, 9, 7, 0, -8 },
/* 0xD4 */ { 1436, 9, 9, 10, 1, -8 },
/* 0xD5 */ { 1447, 6, 9, 8, 1, -8 },
/* 0xD6 */ { 1454, 8, 11, 9, 1, -8 },
/* 0xD7 */ { 1465, 6, 9, 8, 1, -8 },
/* 0xD8 */ { 1472, 8, 9, 10, 1, -8 },
/* 0xD9 */ { 1481, 9, 11, 10, 1, -8 },
/* 0xDA */ { 1494, 10, 9, 10, 0, -8 },
/* 0xDB */ { 1506, 9, 9, 10, 1, -8 },
/* 0xDC */ { 1517, 6, 9, 8, 1, -8 },
/* 0xDD */ { 1524, 7, 9, 9, 1, -8 },
/* 0xDE */ { 1532, 10, 9, 12, 1, -8 },
/* 0xDF */ { 1544, 6, 9, 8, 1, -8 },
/* 0xE0 */ { 1551, 6, 6, 7, 0, -5 },
/* 0xE1 */ { 1556, 6, 9, 7, 0, -8 },
/* 0xE2 */ { 1563, 5, 6, 6, 1, -5 },
/* 0xE3 */ { 1567, 4, 6, 5, 1, -5 },
/* 0xE4 */ { 1570, 7, 7, 7, 0, -5 },
/* 0xE5 */ { 1577, 6, 6, 7, 0, -5 },
/* 0xE6 */ { 1582, 8, 6, 9, 1, -5 },
/* 0xE7 */ { 1588, 6, 6, 6, 0, -5 },
/* 0xE8 */ { 1593, 5, 6, 7, 1, -5 },
/* 0xE9 */ { 1597, 5, 8, 7, 1, -7 },
/* 0xEA */ { 1602, 4, 6, 6, 1, -5 },
/* 0xEB */ { 1605, 5, 6, 6, 0, -5 },
/* 0xEC */ { 1609, 6, 6, 7, 1, -5 },
/* 0xED */ { 1614, 5, 6, 7, 1, -5 },
/* 0xEE */ { 1618, 6, 6, 7, 0, -5 },
/* 0xEF */ { 1623, 5, 6, 7, 1, -5 },
/* 0xF0 */ { 1627, 5, 9, 7, 1, -5 },
/* 0xF1 */ { 1633, 6, 6, 6, 0, -5 },
/* 0xF2 */ { 1638, 5, 6, 5, 0, -5 },
/* 0xF3 */ { 1642, 5, 9, 6, 0, -5 },
/* 0xF4 */ { 1648, 10, 11, 10, 0, -7 },
/* 0xF5 */ { 1662, 5, 6, 6, 0, -5 },
/* 0xF6 */ { 1666, 6, 7, 7, 1, -5 },
/* 0xF7 */ { 1672, 4, 6, 6, 1, -5 },
/* 0xF8 */ { 1675, 6, 6, 8, 1, -5 },
/* 0xF9 */ { 1680, 7, 7, 9, 1, -5 },
/* 0xFA */ { 1687, 7, 6, 8, 0, -5 },
/* 0xFB */ { 1693, 6, 6, 8, 1, -5 },
/* 0xFC */ { 1698, 5, 6, 6, 1, -5 },
/* 0xFD */ { 1702, 5, 6, 6, 1, -5 },
/* 0xFE */ { 1706, 8, 6, 9, 1, -5 },
/* 0xFF */ { 1712, 5, 6, 7, 1, -5 },
};
const GFXfont FreeSans6pt_Win1251 PROGMEM = {
(uint8_t*)FreeSans6pt_Win1251Bitmaps,
(GFXglyph*)FreeSans6pt_Win1251Glyphs,
0x01, 0xFF, 14
};
@@ -0,0 +1,527 @@
// trunk-ignore-all(clang-format)
#pragma once
/* PROPERTIES
FONT_NAME FreeSans6pt_Win1252
*/
const uint8_t FreeSans6pt_Win1252Bitmaps[] PROGMEM = {
/* 0x01 */ 0x1C, 0x0A, 0x05, 0x04, 0xFE, 0x08, 0x1C, 0x02, 0x07, 0xE0, 0x9F, 0xC0,
/* 0x02 */ 0x3F, 0xF0, 0x40, 0xE0, 0x10, 0x3F, 0x04, 0x9E, 0x28, 0x14, 0x0E, 0x00,
/* 0x03 */ 0x3F, 0x10, 0x28, 0x06, 0x49, 0x80, 0x60, 0x19, 0x26, 0x31, 0x40, 0x8F, 0xC0,
/* 0x04 */ 0x3F, 0x10, 0x2A, 0x16, 0x49, 0xA1, 0x60, 0x19, 0xE6, 0x31, 0x40, 0x8F, 0xC0,
/* 0x05 */ 0x28, 0x15, 0x2A, 0xB5, 0x55, 0xA8, 0x54, 0x12, 0x04, 0x41, 0x08, 0x81, 0xC0,
/* 0x06 */ 0x04, 0x08, 0x88, 0x82, 0x07, 0x01, 0x11, 0xA2, 0xC4, 0x40, 0x70, 0x20, 0x88, 0x88, 0x10, 0x00,
/* 0x07 */
/* 0x08 */ 0x03, 0x83, 0x44, 0x48, 0x28, 0x01, 0x80, 0x17, 0xFE, 0x08, 0x45, 0x28, 0x84, 0x00,
/* 0x09 */ 0x01, 0xC0, 0x68, 0x82, 0x41, 0x10, 0x02, 0x80, 0x06, 0x00, 0x14, 0x00, 0x8F, 0xFC,
/* 0x0A */
/* 0x0B */ 0x22, 0x2A, 0xA2, 0x30, 0x18, 0x0A, 0x09, 0x04, 0x44, 0x14, 0x04, 0x00,
/* 0x0C */ 0x46, 0x00, 0x19, 0x03, 0x21, 0x20, 0x93, 0x04, 0x20, 0x11, 0x80, 0x50, 0x02, 0x7F, 0xE0,
/* 0x0D */
/* 0x0E */ 0x08, 0x0E, 0x08, 0x88, 0x24, 0x12, 0x09, 0x05, 0x01, 0xFF, 0x8A, 0x02, 0x00,
/* 0x0F */ 0x3F, 0x14, 0xAA, 0x16, 0x01, 0x92, 0x60, 0x18, 0xC6, 0x49, 0x40, 0x8F, 0xC0,
/* 0x10 */ 0x1B, 0x02, 0xA0, 0x54, 0x12, 0x42, 0x48, 0x49, 0x31, 0x1E, 0x23, 0xEA, 0xFE, 0x3C,
/* 0x11 */ 0x3F, 0x02, 0x00, 0x20, 0x6D, 0x27, 0xF8, 0x3F, 0xC1, 0xFE, 0x37, 0xD0, 0xBE, 0x40, 0xE1, 0xE2, 0x00,
/* 0x12 */ 0x12, 0x42, 0x20, 0x24, 0xC0, 0x29, 0x99, 0x05, 0x23, 0x30, 0xB0, 0x30, 0x00,
/* 0x13 */ 0x3F, 0x88, 0x0A, 0x44, 0xD5, 0x58, 0x03, 0x00, 0x67, 0xCC, 0x71, 0x40, 0x47, 0xF0,
/* 0x14 */ 0x3F, 0x18, 0x69, 0x26, 0x85, 0xA1, 0x6C, 0xD8, 0x06, 0x31, 0x40, 0x8F, 0xC0,
/* 0x15 */ 0x3F, 0x11, 0x00, 0xE8, 0x03, 0xA0, 0x1F, 0xB3, 0x7E, 0x00, 0xE9, 0xE0, 0x23, 0x00, 0x40, 0x40, 0xFE, 0x00,
/* 0x16 */ 0x30, 0x38, 0x3A, 0x3E, 0x6E, 0xEB, 0xC3, 0xC3, 0x66, 0x3C,
/* 0x17 */ 0x3F, 0x04, 0x00, 0x82, 0x88, 0x5C, 0xA4, 0x49, 0x22, 0x81, 0x98, 0xC4, 0x40, 0xA3, 0xF0,
/* 0x18 */ 0x07, 0x80, 0x42, 0x04, 0x08, 0x21, 0x41, 0x42, 0x60, 0x0E, 0x8C, 0xB2, 0x89, 0x50, 0x52, 0x82, 0x80,
/* 0x19 */ 0x3F, 0xC4, 0x02, 0x80, 0x18, 0x01, 0xB3, 0x1B, 0xB9, 0x80, 0x19, 0xE1, 0x40, 0x23, 0xFC,
/* 0x1A */ 0xFF, 0xC0, 0x67, 0x34, 0x58, 0x4C, 0x46, 0x03, 0x11, 0x80, 0xFF, 0xC0,
/* 0x1B */ 0x0F, 0xC0, 0x40, 0x82, 0x49, 0x08, 0x04, 0x00, 0x00, 0x12, 0x02, 0x31, 0x34, 0x0B, 0x88, 0x45, 0x00, 0x20,
/* 0x1C */ 0x3F, 0x88, 0x0A, 0x44, 0xC9, 0x19, 0x3B, 0x00, 0x60, 0x4C, 0x71, 0x40, 0x47, 0xF0,
/* 0x1D */ 0x3F, 0x8B, 0x0A, 0x00, 0xC8, 0x18, 0x13, 0x00, 0x48, 0xCA, 0xC1, 0x44, 0x53, 0x30,
/* 0x1E */ 0x19, 0xC2, 0x02, 0x50, 0x1E, 0x49, 0x80, 0x12, 0x01, 0x27, 0x92, 0x01, 0x10, 0x20, 0xFC,
/* 0x1F */ 0x30, 0x1C, 0x0C, 0x3E, 0x7E, 0xCF, 0x07, 0xC7, 0x7F, 0x3F,
/* ' ' 0x20 */
/* '!' 0x21 */ 0xFC, 0x80,
/* '"' 0x22 */ 0xB6, 0x80,
/* '#' 0x23 */ 0x24, 0x51, 0xF9, 0x42, 0x9F, 0x92, 0x28,
/* '$' 0x24 */ 0x10, 0xE5, 0x55, 0x50, 0xE1, 0x65, 0x55, 0xE1, 0x00,
/* '%' 0x25 */ 0x71, 0x24, 0x89, 0x22, 0x50, 0x74, 0x02, 0x70, 0xA4, 0x49, 0x11, 0xC0,
/* '&' 0x26 */ 0x71, 0x24, 0x9C, 0x62, 0x58, 0xA7, 0xF4,
/* ''' 0x27 */ 0xE0,
/* '(' 0x28 */ 0x5A, 0xAA, 0x94,
/* ')' 0x29 */ 0x89, 0x12, 0x49, 0x29, 0x00,
/* '*' 0x2A */ 0x5E, 0x80,
/* '+' 0x2B */ 0x21, 0x3E, 0x42, 0x00,
/* ',' 0x2C */ 0xE0,
/* '-' 0x2D */ 0xC0,
/* '.' 0x2E */ 0x80,
/* '/' 0x2F */ 0x24, 0xA4, 0xA4, 0x80,
/* '0' 0x30 */ 0x76, 0xE3, 0x18, 0xC6, 0x3B, 0x70,
/* '1' 0x31 */ 0x27, 0x92, 0x49, 0x20,
/* '2' 0x32 */ 0x79, 0x10, 0x41, 0x08, 0xC6, 0x10, 0xFC,
/* '3' 0x33 */ 0x79, 0x30, 0x43, 0x18, 0x10, 0x71, 0x78,
/* '4' 0x34 */ 0x08, 0x61, 0x8A, 0x49, 0x2F, 0xC2, 0x08,
/* '5' 0x35 */ 0xFC, 0x21, 0xE8, 0x84, 0x31, 0xF0,
/* '6' 0x36 */ 0x74, 0x61, 0xE8, 0xC6, 0x31, 0x70,
/* '7' 0x37 */ 0xF8, 0x44, 0x22, 0x11, 0x08, 0x40,
/* '8' 0x38 */ 0x39, 0x34, 0x53, 0x39, 0x1C, 0x51, 0x38,
/* '9' 0x39 */ 0x39, 0x3C, 0x71, 0x4C, 0xF0, 0x53, 0x78,
/* ':' 0x3A */ 0x82,
/* ';' 0x3B */ 0x87,
/* '<' 0x3C */ 0x3E, 0x30, 0x60, 0x80,
/* '=' 0x3D */ 0xF8, 0x3E,
/* '>' 0x3E */ 0xE0, 0xC6, 0xC8, 0x00,
/* '?' 0x3F */ 0x74, 0x42, 0x11, 0x10, 0x80, 0x20,
/* '@' 0x40 */ 0x0F, 0x86, 0x19, 0x9A, 0xA4, 0xD9, 0x13, 0x22, 0x56, 0xDA, 0x6E, 0x60, 0x06, 0x00, 0x3C, 0x00,
/* 'A' 0x41 */ 0x18, 0x18, 0x24, 0x24, 0x24, 0x7E, 0x42, 0x42, 0xC3,
/* 'B' 0x42 */ 0xFA, 0x18, 0x61, 0xFA, 0x18, 0x61, 0xFC,
/* 'C' 0x43 */ 0x3E, 0x63, 0x40, 0x40, 0xC0, 0x40, 0x41, 0x63, 0x3E,
/* 'D' 0x44 */ 0xF9, 0x0A, 0x1C, 0x18, 0x30, 0x61, 0xC2, 0xF8,
/* 'E' 0x45 */ 0xFE, 0x08, 0x20, 0xFE, 0x08, 0x20, 0xFC,
/* 'F' 0x46 */ 0xFE, 0x08, 0x20, 0xFA, 0x08, 0x20, 0x80,
/* 'G' 0x47 */ 0x1E, 0x61, 0x40, 0x40, 0xC7, 0x41, 0x41, 0x63, 0x1D,
/* 'H' 0x48 */ 0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60, 0xC1, 0x82,
/* 'I' 0x49 */ 0xFF, 0x80,
/* 'J' 0x4A */ 0x08, 0x42, 0x10, 0x87, 0x29, 0x70,
/* 'K' 0x4B */ 0x85, 0x12, 0x45, 0x0D, 0x13, 0x22, 0x42, 0x86,
/* 'L' 0x4C */ 0x84, 0x21, 0x08, 0x42, 0x10, 0xF8,
/* 'M' 0x4D */ 0xC3, 0xC3, 0xC3, 0xA5, 0xA5, 0xA5, 0x99, 0x99, 0x99,
/* 'N' 0x4E */ 0x83, 0x86, 0x8D, 0x19, 0x33, 0x62, 0xC3, 0x86,
/* 'O' 0x4F */ 0x1E, 0x31, 0x90, 0x68, 0x1C, 0x0A, 0x05, 0x06, 0xC6, 0x1E, 0x00,
/* 'P' 0x50 */ 0xFA, 0x18, 0x61, 0xFA, 0x08, 0x20, 0x80,
/* 'Q' 0x51 */ 0x1E, 0x31, 0x90, 0x68, 0x1C, 0x0A, 0x05, 0x16, 0xC6, 0x1F, 0x00, 0x40,
/* 'R' 0x52 */ 0xFD, 0x0E, 0x1C, 0x2F, 0x90, 0xA1, 0x42, 0x86,
/* 'S' 0x53 */ 0x7A, 0x18, 0x30, 0x78, 0x38, 0x61, 0x78,
/* 'T' 0x54 */ 0xFE, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10,
/* 'U' 0x55 */ 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xE2, 0x78,
/* 'V' 0x56 */ 0xC2, 0x85, 0x0B, 0x22, 0x44, 0x8E, 0x0C, 0x18,
/* 'W' 0x57 */ 0xC4, 0x28, 0xCD, 0x29, 0x25, 0x24, 0xA4, 0x52, 0x8C, 0x61, 0x8C, 0x31, 0x80,
/* 'X' 0x58 */ 0x87, 0x34, 0x8C, 0x30, 0xC4, 0xA3, 0x84,
/* 'Y' 0x59 */ 0xC3, 0x42, 0x24, 0x34, 0x18, 0x08, 0x08, 0x08, 0x08,
/* 'Z' 0x5A */ 0x7E, 0x0C, 0x30, 0x41, 0x06, 0x18, 0x20, 0xFE,
/* '[' 0x5B */ 0xEA, 0xAA, 0xAB,
/* '\' 0x5C */ 0x92, 0x24, 0x89, 0x20,
/* ']' 0x5D */ 0xD5, 0x55, 0x57,
/* '^' 0x5E */ 0x46, 0xA9,
/* '_' 0x5F */ 0xFE,
/* '`' 0x60 */ 0x80,
/* 'a' 0x61 */ 0x79, 0x20, 0x4F, 0xC6, 0x37, 0x40,
/* 'b' 0x62 */ 0x84, 0x3D, 0x18, 0xC6, 0x31, 0xF0,
/* 'c' 0x63 */ 0x39, 0x3C, 0x20, 0xC1, 0x33, 0x80,
/* 'd' 0x64 */ 0x04, 0x13, 0xD3, 0xC6, 0x1C, 0x53, 0x3C,
/* 'e' 0x65 */ 0x39, 0x38, 0x7F, 0x81, 0x13, 0x80,
/* 'f' 0x66 */ 0x6B, 0xA4, 0x92, 0x40,
/* 'g' 0x67 */ 0x35, 0x3C, 0x61, 0xC5, 0x33, 0x41, 0x4D, 0xE0,
/* 'h' 0x68 */ 0x84, 0x3D, 0x38, 0xC6, 0x31, 0x88,
/* 'i' 0x69 */ 0xBF, 0x80,
/* 'j' 0x6A */ 0x45, 0x55, 0x57,
/* 'k' 0x6B */ 0x84, 0x25, 0x4E, 0x52, 0xD2, 0x88,
/* 'l' 0x6C */ 0xFF, 0x80,
/* 'm' 0x6D */ 0xF7, 0x99, 0x91, 0x91, 0x91, 0x91, 0x91,
/* 'n' 0x6E */ 0xF4, 0x63, 0x18, 0xC6, 0x20,
/* 'o' 0x6F */ 0x39, 0x3C, 0x61, 0xC5, 0x33, 0x80,
/* 'p' 0x70 */ 0xF4, 0x63, 0x18, 0xC7, 0xD0, 0x80,
/* 'q' 0x71 */ 0x3D, 0x3C, 0x61, 0xC5, 0x37, 0x41, 0x04,
/* 'r' 0x72 */ 0xF2, 0x49, 0x20,
/* 's' 0x73 */ 0x7A, 0x50, 0xE0, 0xE5, 0xE0,
/* 't' 0x74 */ 0x5D, 0x24, 0x93,
/* 'u' 0x75 */ 0x8C, 0x63, 0x18, 0xCF, 0xA0,
/* 'v' 0x76 */ 0x85, 0x24, 0x92, 0x30, 0xC3, 0x00,
/* 'w' 0x77 */ 0x89, 0x59, 0x59, 0x55, 0x56, 0x26, 0x26,
/* 'x' 0x78 */ 0x4A, 0x4C, 0x43, 0x27, 0x20,
/* 'y' 0x79 */ 0x8A, 0x52, 0xA5, 0x18, 0x84, 0x22, 0x00,
/* 'z' 0x7A */ 0x78, 0x44, 0x46, 0x23, 0xE0,
/* '{' 0x7B */ 0x6A, 0xAA, 0xA9,
/* '|' 0x7C */ 0xFF, 0xE0,
/* '}' 0x7D */ 0x95, 0x55, 0x56,
/* '~' 0x7E */ 0x66, 0x60,
/* 0x7F */
/* 0x80 */ 0x1C, 0x45, 0x07, 0xE4, 0x1F, 0x10, 0x10, 0x1E,
/* 0x81 */
/* 0x82 */ 0xE0,
/* 0x83 */ 0x6B, 0xA4, 0x92, 0x49, 0x60,
/* 0x84 */ 0xB6, 0x80,
/* 0x85 */ 0xA8,
/* 0x86 */ 0x21, 0x09, 0xF2, 0x10, 0x84, 0x21, 0x08,
/* 0x87 */ 0x21, 0x09, 0xF2, 0x10, 0x84, 0xF9, 0x08,
/* 0x88 */ 0x54,
/* 0x89 */ 0x62, 0x09, 0x40, 0x98, 0x06, 0x80, 0x10, 0x01, 0x66, 0x29, 0x92, 0x99, 0x06, 0x60,
/* 0x8A */ 0x28, 0x47, 0xA1, 0x83, 0x07, 0x83, 0x87, 0x17, 0x80,
/* 0x8B */ 0x64,
/* 0x8C */ 0x3B, 0xE8, 0xC2, 0x08, 0x41, 0x08, 0x3F, 0x04, 0x20, 0x82, 0x30, 0x3B, 0xE0,
/* 0x8D */
/* 0x8E */ 0x14, 0x11, 0xF8, 0x30, 0xC1, 0x04, 0x18, 0x61, 0xFC,
/* 0x8F */
/* 0x90 */
/* 0x91 */ 0xE0,
/* 0x92 */ 0xE0,
/* 0x93 */ 0xB6, 0x80,
/* 0x94 */ 0xB6, 0x80,
/* 0x95 */ 0xFF, 0x80,
/* 0x96 */ 0xFC,
/* 0x97 */ 0xFF, 0xF0,
/* 0x98 */ 0xDB,
/* 0x99 */ 0xE6, 0x28, 0xCD, 0x19, 0xA3, 0x34, 0x6A, 0x8B, 0x51, 0x68,
/* 0x9A */ 0x52, 0x69, 0x8E, 0x19, 0x60,
/* 0x9B */ 0x98,
/* 0x9C */ 0x7B, 0xD9, 0xCE, 0x10, 0xC3, 0xF8, 0x41, 0x9C, 0x5E, 0xF0,
/* 0x9D */
/* 0x9E */ 0x51, 0x1E, 0x11, 0x11, 0x88, 0xF8,
/* 0x9F */ 0x29, 0x05, 0x12, 0x22, 0x87, 0x04, 0x08, 0x10, 0x20,
/* 0xA0 */
/* 0xA1 */ 0xBF, 0x80,
/* 0xA2 */ 0x23, 0xAB, 0x4A, 0x52, 0xAE, 0x20,
/* 0xA3 */ 0x39, 0x14, 0x10, 0xF0, 0x82, 0x1C, 0x4C,
/* 0xA4 */ 0xFC, 0x63, 0xF0,
/* 0xA5 */ 0x8C, 0x54, 0xAF, 0x93, 0xE4, 0x20,
/* 0xA6 */ 0xF9, 0xF0,
/* 0xA7 */ 0x32, 0x91, 0xC9, 0x47, 0x26, 0x14, 0xA4, 0xC0,
/* 0xA8 */ 0xA0,
/* 0xA9 */ 0x3E, 0x3F, 0xB8, 0xF4, 0x1A, 0x0D, 0x17, 0x76, 0xC6, 0x3E, 0x00,
/* 0xAA */ 0x61, 0x79, 0x60,
/* 0xAB */ 0x5A, 0xA5,
/* 0xAC */ 0xFC, 0x10, 0x40,
/* 0xAD */
/* 0xAE */ 0x3E, 0x31, 0xB7, 0x72, 0x99, 0xCC, 0xC7, 0x56, 0xC6, 0x3E, 0x00,
/* 0xAF */ 0xE0,
/* 0xB0 */ 0x69, 0x96,
/* 0xB1 */ 0x21, 0x3E, 0x42, 0x03, 0xE0,
/* 0xB2 */ 0x69, 0x3C, 0xF0,
/* 0xB3 */ 0x79, 0x29, 0x70,
/* 0xB4 */ 0x80,
/* 0xB5 */ 0x8A, 0x28, 0xA2, 0x8A, 0x6E, 0xE0, 0x80,
/* 0xB6 */ 0x7F, 0xAE, 0xBA, 0x68, 0xA2, 0x8A, 0x28, 0xA0,
/* 0xB7 */ 0x80,
/* 0xB8 */ 0x67, 0x80,
/* 0xB9 */ 0x75, 0x50,
/* 0xBA */ 0x69, 0x96, 0xF0,
/* 0xBB */ 0xA5, 0x5A,
/* 0xBC */ 0x42, 0x30, 0x84, 0x41, 0x10, 0x48, 0x82, 0x61, 0x28, 0x8F, 0x20, 0x80,
/* 0xBD */ 0x40, 0x63, 0x11, 0x09, 0x74, 0xA8, 0x84, 0x44, 0x44, 0x43, 0x80,
/* 0xBE */ 0x71, 0x24, 0x82, 0x20, 0x50, 0x98, 0x9A, 0x61, 0x28, 0x4F, 0x20, 0x80,
/* 0xBF */ 0x20, 0x08, 0x44, 0x42, 0x11, 0x70,
/* 0xC0 */ 0x10, 0x08, 0x00, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0xC3,
/* 0xC1 */ 0x08, 0x10, 0x00, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0xC3,
/* 0xC2 */ 0x18, 0x24, 0x00, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0xC3,
/* 0xC3 */ 0x34, 0x2C, 0x00, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0xC3,
/* 0xC4 */ 0x24, 0x00, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0x42, 0xC3,
/* 0xC5 */ 0x18, 0x24, 0x18, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0xC3,
/* 0xC6 */ 0x1F, 0xC5, 0x02, 0x40, 0x90, 0x47, 0xDF, 0x04, 0x42, 0x10, 0x87, 0xC0,
/* 0xC7 */ 0x3E, 0x61, 0xC0, 0x80, 0x80, 0x80, 0xC1, 0x63, 0x3E, 0x0C, 0x04, 0x1C,
/* 0xC8 */ 0x20, 0x40, 0x3F, 0x82, 0x0F, 0xA0, 0x83, 0xF0,
/* 0xC9 */ 0x08, 0x40, 0x3F, 0x82, 0x0F, 0xA0, 0x83, 0xF0,
/* 0xCA */ 0x10, 0xA0, 0x3F, 0x82, 0x0F, 0xA0, 0x83, 0xF0,
/* 0xCB */ 0x28, 0x0F, 0xE0, 0x83, 0xE8, 0x20, 0x83, 0xF0,
/* 0xCC */ 0x91, 0x55, 0x50,
/* 0xCD */ 0x62, 0xAA, 0xA0,
/* 0xCE */ 0x54, 0x24, 0x92, 0x48,
/* 0xCF */ 0xA1, 0x24, 0x92, 0x48,
/* 0xD0 */ 0x7C, 0x42, 0x41, 0x41, 0xF1, 0x41, 0x41, 0x42, 0x7C,
/* 0xD1 */ 0x14, 0x53, 0x0F, 0x1B, 0x32, 0x66, 0xC7, 0x87, 0x04,
/* 0xD2 */ 0x10, 0x04, 0x0F, 0x8C, 0x6C, 0x1C, 0x06, 0x03, 0x83, 0x63, 0x1F, 0x00,
/* 0xD3 */ 0x04, 0x04, 0x0F, 0x8C, 0x6C, 0x1C, 0x06, 0x03, 0x83, 0x63, 0x1F, 0x00,
/* 0xD4 */ 0x08, 0x0A, 0x00, 0x07, 0xC6, 0x36, 0x0E, 0x03, 0x01, 0xC1, 0xB1, 0x8F, 0x80,
/* 0xD5 */ 0x1A, 0x0B, 0x00, 0x07, 0xC6, 0x36, 0x0E, 0x03, 0x01, 0xC1, 0xB1, 0x8F, 0x80,
/* 0xD6 */ 0x14, 0x00, 0x00, 0x07, 0xC6, 0x36, 0x0E, 0x03, 0x01, 0xC1, 0xB1, 0x8F, 0x80,
/* 0xD7 */ 0x8A, 0x88, 0xA8, 0x80,
/* 0xD8 */ 0x3E, 0xB1, 0xB0, 0xF0, 0x98, 0x8C, 0x87, 0x86, 0xC6, 0xBE, 0x00,
/* 0xD9 */ 0x20, 0x22, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xC6, 0xF8,
/* 0xDA */ 0x08, 0x22, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xC6, 0xF8,
/* 0xDB */ 0x10, 0x52, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xC6, 0xF8,
/* 0xDC */ 0x29, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xC6, 0xF8,
/* 0xDD */ 0x09, 0x25, 0x12, 0x22, 0x87, 0x04, 0x08, 0x10, 0x20,
/* 0xDE */ 0x83, 0xE8, 0x61, 0x87, 0xE8, 0x20, 0x80,
/* 0xDF */ 0x7A, 0x18, 0x61, 0x8A, 0x18, 0x61, 0xB8,
/* 0xE0 */ 0x20, 0x20, 0x03, 0xC8, 0x40, 0x8F, 0x62, 0x8C, 0xEC,
/* 0xE1 */ 0x10, 0x40, 0x03, 0xC8, 0x40, 0x8F, 0x62, 0x8C, 0xEC,
/* 0xE2 */ 0x10, 0x50, 0x03, 0xC8, 0x40, 0x8F, 0x62, 0x8C, 0xEC,
/* 0xE3 */ 0x68, 0xB0, 0x03, 0xC8, 0x40, 0x8F, 0x62, 0x8C, 0xEC,
/* 0xE4 */ 0x28, 0x01, 0xE4, 0x20, 0x47, 0xB1, 0x46, 0x76,
/* 0xE5 */ 0x10, 0x50, 0x43, 0xC8, 0x40, 0x8F, 0x62, 0x8C, 0xEC,
/* 0xE6 */ 0x7B, 0xA1, 0x90, 0x45, 0xFF, 0x84, 0x23, 0x17, 0x38,
/* 0xE7 */ 0x7B, 0x18, 0x20, 0x83, 0x17, 0x8C, 0x11, 0xC0,
/* 0xE8 */ 0x20, 0x40, 0x1E, 0xCE, 0x1F, 0xE0, 0xC5, 0xE0,
/* 0xE9 */ 0x10, 0x80, 0x1E, 0xCE, 0x1F, 0xE0, 0xC5, 0xE0,
/* 0xEA */ 0x10, 0xA0, 0x1E, 0xCE, 0x1F, 0xE0, 0xC5, 0xE0,
/* 0xEB */ 0x28, 0x07, 0xB3, 0x87, 0xF8, 0x31, 0x78,
/* 0xEC */ 0x91, 0x55, 0x50,
/* 0xED */ 0x62, 0xAA, 0xA0,
/* 0xEE */ 0x54, 0x24, 0x92, 0x48,
/* 0xEF */ 0xA1, 0x24, 0x92, 0x40,
/* 0xF0 */ 0x28, 0x42, 0x8F, 0x46, 0x18, 0x52, 0x30,
/* 0xF1 */ 0x6A, 0xC1, 0x6C, 0xC6, 0x31, 0x8C, 0x40,
/* 0xF2 */ 0x20, 0x40, 0x1E, 0xCE, 0x18, 0x61, 0xCD, 0xE0,
/* 0xF3 */ 0x10, 0x80, 0x1E, 0xCE, 0x18, 0x61, 0xCD, 0xE0,
/* 0xF4 */ 0x10, 0xA0, 0x1E, 0xCE, 0x18, 0x61, 0xCD, 0xE0,
/* 0xF5 */ 0x69, 0x60, 0x1E, 0xCE, 0x18, 0x61, 0xCD, 0xE0,
/* 0xF6 */ 0x28, 0x07, 0xB3, 0x86, 0x18, 0x73, 0x78,
/* 0xF7 */ 0x20, 0x3E, 0x02, 0x00,
/* 0xF8 */ 0x7F, 0x39, 0x69, 0xC7, 0x3F, 0x80,
/* 0xF9 */ 0x41, 0x23, 0x18, 0xC6, 0x33, 0x68,
/* 0xFA */ 0x11, 0x23, 0x18, 0xC6, 0x33, 0x68,
/* 0xFB */ 0x22, 0x81, 0x18, 0xC6, 0x31, 0x9B, 0x40,
/* 0xFC */ 0x50, 0x23, 0x18, 0xC6, 0x33, 0x68,
/* 0xFD */ 0x10, 0x88, 0x52, 0x49, 0x23, 0x0C, 0x30, 0x82, 0x18,
/* 0xFE */ 0x84, 0x3D, 0xB8, 0xC6, 0x3B, 0xF4, 0x20,
/* 0xFF */ 0x28, 0x08, 0x52, 0x49, 0x23, 0x0C, 0x30, 0x82, 0x18,
};
const GFXglyph FreeSans6pt_Win1252Glyphs[] PROGMEM = {
/* 0x01 */ { 0, 9, 10, 11, 1, -9 },
/* 0x02 */ { 12, 9, 10, 11, 1, -8 },
/* 0x03 */ { 24, 10, 10, 12, 1, -8 },
/* 0x04 */ { 37, 10, 10, 12, 1, -8 },
/* 0x05 */ { 50, 10, 10, 12, 1, -9 },
/* 0x06 */ { 63, 11, 11, 13, 1, -9 },
/* 0x07 */ { 79, 0, 0, 8, 0, 0 },
/* 0x08 */ { 79, 12, 9, 14, 1, -8 },
/* 0x09 */ { 93, 14, 8, 16, 1, -7 },
/* 0x0A */ { 107, 0, 0, 8, 0, 0 },
/* 0x0B */ { 107, 9, 10, 11, 1, -9 },
/* 0x0C */ { 119, 13, 9, 15, 1, -8 },
/* 0x0D */ { 134, 0, 0, 8, 0, 0 },
/* 0x0E */ { 134, 9, 11, 11, 1, -9 },
/* 0x0F */ { 147, 10, 10, 12, 1, -9 },
/* 0x10 */ { 160, 11, 10, 13, 1, -9 },
/* 0x11 */ { 174, 13, 10, 15, 1, -9 },
/* 0x12 */ { 191, 10, 10, 12, 1, -9 },
/* 0x13 */ { 204, 11, 10, 13, 1, -9 },
/* 0x14 */ { 218, 10, 10, 12, 1, -9 },
/* 0x15 */ { 231, 14, 10, 16, 1, -9 },
/* 0x16 */ { 249, 8, 10, 10, 1, -9 },
/* 0x17 */ { 259, 12, 10, 14, 1, -9 },
/* 0x18 */ { 274, 13, 10, 15, 1, -9 },
/* 0x19 */ { 291, 12, 10, 14, 1, -9 },
/* 0x1A */ { 306, 9, 10, 11, 1, -8 },
/* 0x1B */ { 318, 14, 10, 16, 1, -9 },
/* 0x1C */ { 336, 11, 10, 13, 1, -9 },
/* 0x1D */ { 350, 11, 10, 13, 1, -9 },
/* 0x1E */ { 364, 12, 10, 14, 1, -9 },
/* 0x1F */ { 379, 8, 10, 11, 2, -9 },
/* ' ' 0x20 */ { 389, 0, 0, 3, 0, 0 },
/* '!' 0x21 */ { 389, 1, 9, 4, 2, -8 },
/* '"' 0x22 */ { 391, 3, 3, 4, 0, -8 },
/* '#' 0x23 */ { 393, 7, 8, 7, 0, -7 },
/* '$' 0x24 */ { 400, 6, 11, 7, 0, -9 },
/* '%' 0x25 */ { 409, 10, 9, 11, 0, -8 },
/* '&' 0x26 */ { 421, 6, 9, 8, 1, -8 },
/* ''' 0x27 */ { 428, 1, 3, 2, 1, -8 },
/* '(' 0x28 */ { 429, 2, 11, 4, 1, -8 },
/* ')' 0x29 */ { 432, 3, 11, 4, 0, -8 },
/* '*' 0x2A */ { 437, 3, 3, 5, 1, -8 },
/* '+' 0x2B */ { 439, 5, 5, 7, 1, -4 },
/* ',' 0x2C */ { 443, 1, 3, 3, 1, 0 },
/* '-' 0x2D */ { 444, 2, 1, 4, 1, -3 },
/* '.' 0x2E */ { 445, 1, 1, 3, 1, 0 },
/* '/' 0x2F */ { 446, 3, 9, 3, 0, -8 },
/* '0' 0x30 */ { 450, 5, 9, 7, 1, -8 },
/* '1' 0x31 */ { 456, 3, 9, 7, 1, -8 },
/* '2' 0x32 */ { 460, 6, 9, 7, 0, -8 },
/* '3' 0x33 */ { 467, 6, 9, 7, 0, -8 },
/* '4' 0x34 */ { 474, 6, 9, 7, 0, -8 },
/* '5' 0x35 */ { 481, 5, 9, 7, 1, -8 },
/* '6' 0x36 */ { 487, 5, 9, 7, 1, -8 },
/* '7' 0x37 */ { 493, 5, 9, 7, 1, -8 },
/* '8' 0x38 */ { 499, 6, 9, 7, 0, -8 },
/* '9' 0x39 */ { 506, 6, 9, 7, 0, -8 },
/* ':' 0x3A */ { 513, 1, 7, 3, 1, -6 },
/* ';' 0x3B */ { 514, 1, 8, 3, 1, -5 },
/* '<' 0x3C */ { 515, 5, 5, 7, 1, -4 },
/* '=' 0x3D */ { 519, 5, 3, 7, 1, -3 },
/* '>' 0x3E */ { 521, 5, 5, 7, 1, -4 },
/* '?' 0x3F */ { 525, 5, 9, 7, 1, -8 },
/* '@' 0x40 */ { 531, 11, 11, 12, 0, -8 },
/* 'A' 0x41 */ { 547, 8, 9, 8, 0, -8 },
/* 'B' 0x42 */ { 556, 6, 9, 8, 1, -8 },
/* 'C' 0x43 */ { 563, 8, 9, 9, 0, -8 },
/* 'D' 0x44 */ { 572, 7, 9, 8, 1, -8 },
/* 'E' 0x45 */ { 580, 6, 9, 8, 1, -8 },
/* 'F' 0x46 */ { 587, 6, 9, 7, 1, -8 },
/* 'G' 0x47 */ { 594, 8, 9, 9, 0, -8 },
/* 'H' 0x48 */ { 603, 7, 9, 9, 1, -8 },
/* 'I' 0x49 */ { 611, 1, 9, 3, 1, -8 },
/* 'J' 0x4A */ { 613, 5, 9, 6, 0, -8 },
/* 'K' 0x4B */ { 619, 7, 9, 8, 1, -8 },
/* 'L' 0x4C */ { 627, 5, 9, 7, 1, -8 },
/* 'M' 0x4D */ { 633, 8, 9, 10, 1, -8 },
/* 'N' 0x4E */ { 642, 7, 9, 9, 1, -8 },
/* 'O' 0x4F */ { 650, 9, 9, 9, 0, -8 },
/* 'P' 0x50 */ { 661, 6, 9, 8, 1, -8 },
/* 'Q' 0x51 */ { 668, 9, 10, 9, 0, -8 },
/* 'R' 0x52 */ { 680, 7, 9, 9, 1, -8 },
/* 'S' 0x53 */ { 688, 6, 9, 8, 1, -8 },
/* 'T' 0x54 */ { 695, 7, 9, 8, 0, -8 },
/* 'U' 0x55 */ { 703, 7, 9, 9, 1, -8 },
/* 'V' 0x56 */ { 711, 7, 9, 8, 0, -8 },
/* 'W' 0x57 */ { 719, 11, 9, 11, 0, -8 },
/* 'X' 0x58 */ { 732, 6, 9, 8, 1, -8 },
/* 'Y' 0x59 */ { 739, 8, 9, 8, 0, -8 },
/* 'Z' 0x5A */ { 748, 7, 9, 7, 0, -8 },
/* '[' 0x5B */ { 756, 2, 12, 3, 1, -8 },
/* '\' 0x5C */ { 759, 3, 9, 3, 0, -8 },
/* ']' 0x5D */ { 763, 2, 12, 3, 0, -8 },
/* '^' 0x5E */ { 766, 4, 4, 6, 1, -8 },
/* '_' 0x5F */ { 768, 7, 1, 7, 0, 2 },
/* '`' 0x60 */ { 769, 1, 1, 3, 1, -8 },
/* 'a' 0x61 */ { 770, 6, 7, 7, 0, -6 },
/* 'b' 0x62 */ { 776, 5, 9, 7, 1, -8 },
/* 'c' 0x63 */ { 782, 6, 7, 6, 0, -6 },
/* 'd' 0x64 */ { 788, 6, 9, 7, 0, -8 },
/* 'e' 0x65 */ { 795, 6, 7, 6, 0, -6 },
/* 'f' 0x66 */ { 801, 3, 9, 3, 0, -8 },
/* 'g' 0x67 */ { 805, 6, 10, 7, 0, -6 },
/* 'h' 0x68 */ { 813, 5, 9, 6, 1, -8 },
/* 'i' 0x69 */ { 819, 1, 9, 3, 1, -8 },
/* 'j' 0x6A */ { 821, 2, 12, 3, 0, -8 },
/* 'k' 0x6B */ { 824, 5, 9, 6, 1, -8 },
/* 'l' 0x6C */ { 830, 1, 9, 3, 1, -8 },
/* 'm' 0x6D */ { 832, 8, 7, 10, 1, -6 },
/* 'n' 0x6E */ { 839, 5, 7, 6, 1, -6 },
/* 'o' 0x6F */ { 844, 6, 7, 6, 0, -6 },
/* 'p' 0x70 */ { 850, 5, 9, 7, 1, -6 },
/* 'q' 0x71 */ { 856, 6, 9, 7, 0, -6 },
/* 'r' 0x72 */ { 863, 3, 7, 4, 1, -6 },
/* 's' 0x73 */ { 866, 5, 7, 6, 0, -6 },
/* 't' 0x74 */ { 871, 3, 8, 3, 0, -7 },
/* 'u' 0x75 */ { 874, 5, 7, 6, 1, -6 },
/* 'v' 0x76 */ { 879, 6, 7, 6, 0, -6 },
/* 'w' 0x77 */ { 885, 8, 7, 9, 0, -6 },
/* 'x' 0x78 */ { 892, 5, 7, 6, 0, -6 },
/* 'y' 0x79 */ { 897, 5, 10, 6, 0, -6 },
/* 'z' 0x7A */ { 904, 5, 7, 6, 0, -6 },
/* '{' 0x7B */ { 909, 2, 12, 4, 1, -8 },
/* '|' 0x7C */ { 912, 1, 11, 3, 1, -8 },
/* '}' 0x7D */ { 914, 2, 12, 4, 1, -8 },
/* '~' 0x7E */ { 917, 6, 2, 6, 0, -4 },
/* 0x7F */ { 919, 0, 0, 0, 0, 0 },
/* 0x80 */ { 919, 7, 9, 8, 0, -8 },
/* 0x81 */ { 927, 0, 0, 8, 0, 0 },
/* 0x82 */ { 927, 1, 3, 3, 1, 0 },
/* 0x83 */ { 928, 3, 12, 3, 0, -8 },
/* 0x84 */ { 933, 3, 3, 5, 1, 0 },
/* 0x85 */ { 935, 5, 1, 7, 1, 0 },
/* 0x86 */ { 936, 5, 11, 7, 1, -8 },
/* 0x87 */ { 943, 5, 11, 7, 1, -8 },
/* 0x88 */ { 950, 3, 2, 4, 0, -9 },
/* 0x89 */ { 951, 12, 9, 12, 0, -8 },
/* 0x8A */ { 965, 6, 11, 8, 1, -9 },
/* 0x8B */ { 974, 2, 3, 4, 1, -4 },
/* 0x8C */ { 975, 11, 9, 12, 0, -8 },
/* 0x8D */ { 988, 0, 0, 8, 0, 0 },
/* 0x8E */ { 988, 7, 10, 7, 0, -9 },
/* 0x8F */ { 997, 0, 0, 8, 0, 0 },
/* 0x90 */ { 997, 0, 0, 8, 0, 0 },
/* 0x91 */ { 997, 1, 3, 3, 1, -8 },
/* 0x92 */ { 998, 1, 3, 2, 1, -8 },
/* 0x93 */ { 999, 3, 3, 5, 1, -8 },
/* 0x94 */ { 1001, 3, 3, 5, 1, -8 },
/* 0x95 */ { 1003, 3, 3, 5, 1, -5 },
/* 0x96 */ { 1005, 6, 1, 6, 0, -3 },
/* 0x97 */ { 1006, 12, 1, 12, 0, -3 },
/* 0x98 */ { 1008, 4, 2, 4, 0, -8 },
/* 0x99 */ { 1009, 11, 7, 12, 1, -8 },
/* 0x9A */ { 1019, 4, 9, 6, 1, -8 },
/* 0x9B */ { 1024, 2, 3, 3, 1, -4 },
/* 0x9C */ { 1025, 11, 7, 11, 0, -6 },
/* 0x9D */ { 1035, 0, 0, 8, 0, 0 },
/* 0x9E */ { 1035, 5, 9, 6, 0, -8 },
/* 0x9F */ { 1041, 7, 10, 8, 1, -9 },
/* 0xA0 */ { 1050, 0, 0, 3, 0, 0 },
/* 0xA1 */ { 1050, 1, 9, 4, 1, -5 },
/* 0xA2 */ { 1052, 5, 9, 7, 1, -7 },
/* 0xA3 */ { 1058, 6, 9, 7, 0, -8 },
/* 0xA4 */ { 1065, 5, 4, 7, 1, -5 },
/* 0xA5 */ { 1068, 5, 9, 7, 1, -8 },
/* 0xA6 */ { 1074, 1, 12, 3, 1, -8 },
/* 0xA7 */ { 1076, 5, 12, 7, 1, -8 },
/* 0xA8 */ { 1084, 3, 1, 4, 0, -7 },
/* 0xA9 */ { 1085, 9, 9, 10, 0, -8 },
/* 0xAA */ { 1096, 4, 5, 4, 0, -8 },
/* 0xAB */ { 1099, 4, 4, 6, 1, -4 },
/* 0xAC */ { 1101, 6, 3, 7, 1, -4 },
/* 0xAD */ { 1104, 0, 0, 0, 0, 0 },
/* 0xAE */ { 1104, 9, 9, 10, 0, -8 },
/* 0xAF */ { 1115, 3, 1, 4, 0, -8 },
/* 0xB0 */ { 1116, 4, 4, 7, 2, -8 },
/* 0xB1 */ { 1118, 5, 7, 7, 1, -6 },
/* 0xB2 */ { 1123, 4, 5, 4, 0, -9 },
/* 0xB3 */ { 1126, 4, 5, 4, 0, -9 },
/* 0xB4 */ { 1129, 1, 1, 4, 1, -8 },
/* 0xB5 */ { 1130, 6, 9, 7, 1, -6 },
/* 0xB6 */ { 1137, 6, 10, 6, 1, -8 },
/* 0xB7 */ { 1145, 1, 1, 3, 1, -2 },
/* 0xB8 */ { 1146, 3, 3, 4, 1, 1 },
/* 0xB9 */ { 1148, 2, 6, 4, 1, -9 },
/* 0xBA */ { 1150, 4, 5, 4, 0, -8 },
/* 0xBB */ { 1153, 4, 4, 6, 1, -5 },
/* 0xBC */ { 1155, 10, 9, 10, 1, -8 },
/* 0xBD */ { 1167, 9, 9, 10, 1, -8 },
/* 0xBE */ { 1178, 10, 9, 11, 0, -8 },
/* 0xBF */ { 1190, 5, 9, 7, 1, -5 },
/* 0xC0 */ { 1196, 8, 10, 8, 0, -9 },
/* 0xC1 */ { 1206, 8, 10, 8, 0, -9 },
/* 0xC2 */ { 1216, 8, 10, 8, 0, -9 },
/* 0xC3 */ { 1226, 8, 10, 8, 0, -9 },
/* 0xC4 */ { 1236, 8, 10, 8, 0, -9 },
/* 0xC5 */ { 1246, 8, 10, 8, 0, -9 },
/* 0xC6 */ { 1256, 10, 9, 12, 1, -8 },
/* 0xC7 */ { 1268, 8, 12, 9, 0, -8 },
/* 0xC8 */ { 1280, 6, 10, 8, 1, -9 },
/* 0xC9 */ { 1288, 6, 10, 8, 1, -9 },
/* 0xCA */ { 1296, 6, 10, 8, 1, -9 },
/* 0xCB */ { 1304, 6, 10, 8, 1, -9 },
/* 0xCC */ { 1312, 2, 10, 3, 0, -9 },
/* 0xCD */ { 1315, 2, 10, 3, 1, -9 },
/* 0xCE */ { 1318, 3, 10, 4, 0, -9 },
/* 0xCF */ { 1322, 3, 10, 4, 0, -9 },
/* 0xD0 */ { 1326, 8, 9, 8, 0, -8 },
/* 0xD1 */ { 1335, 7, 10, 9, 1, -9 },
/* 0xD2 */ { 1344, 9, 10, 9, 0, -9 },
/* 0xD3 */ { 1356, 9, 10, 9, 0, -9 },
/* 0xD4 */ { 1368, 9, 11, 9, 0, -10 },
/* 0xD5 */ { 1381, 9, 11, 9, 0, -10 },
/* 0xD6 */ { 1394, 9, 11, 9, 0, -10 },
/* 0xD7 */ { 1407, 5, 5, 7, 1, -5 },
/* 0xD8 */ { 1411, 9, 9, 9, 0, -8 },
/* 0xD9 */ { 1422, 7, 10, 9, 1, -9 },
/* 0xDA */ { 1431, 7, 10, 9, 1, -9 },
/* 0xDB */ { 1440, 7, 10, 9, 1, -9 },
/* 0xDC */ { 1449, 7, 10, 9, 1, -9 },
/* 0xDD */ { 1458, 7, 10, 8, 1, -9 },
/* 0xDE */ { 1467, 6, 9, 8, 1, -8 },
/* 0xDF */ { 1474, 6, 9, 7, 1, -8 },
/* 0xE0 */ { 1481, 7, 10, 7, 0, -9 },
/* 0xE1 */ { 1490, 7, 10, 7, 0, -9 },
/* 0xE2 */ { 1499, 7, 10, 7, 0, -9 },
/* 0xE3 */ { 1508, 7, 10, 7, 0, -9 },
/* 0xE4 */ { 1517, 7, 9, 7, 0, -8 },
/* 0xE5 */ { 1525, 7, 10, 7, 0, -9 },
/* 0xE6 */ { 1534, 10, 7, 10, 0, -6 },
/* 0xE7 */ { 1543, 6, 10, 6, 0, -6 },
/* 0xE8 */ { 1551, 6, 10, 6, 0, -9 },
/* 0xE9 */ { 1559, 6, 10, 6, 0, -9 },
/* 0xEA */ { 1567, 6, 10, 6, 0, -9 },
/* 0xEB */ { 1575, 6, 9, 6, 0, -8 },
/* 0xEC */ { 1582, 2, 10, 3, 0, -9 },
/* 0xED */ { 1585, 2, 10, 3, 1, -9 },
/* 0xEE */ { 1588, 3, 10, 3, 0, -9 },
/* 0xEF */ { 1592, 3, 9, 3, 0, -8 },
/* 0xF0 */ { 1596, 6, 9, 6, 0, -8 },
/* 0xF1 */ { 1603, 5, 10, 6, 1, -9 },
/* 0xF2 */ { 1610, 6, 10, 6, 0, -9 },
/* 0xF3 */ { 1618, 6, 10, 6, 0, -9 },
/* 0xF4 */ { 1626, 6, 10, 6, 0, -9 },
/* 0xF5 */ { 1634, 6, 10, 6, 0, -9 },
/* 0xF6 */ { 1642, 6, 9, 6, 0, -8 },
/* 0xF7 */ { 1649, 5, 5, 7, 1, -5 },
/* 0xF8 */ { 1653, 6, 7, 6, 0, -6 },
/* 0xF9 */ { 1659, 5, 9, 6, 1, -8 },
/* 0xFA */ { 1665, 5, 9, 6, 1, -8 },
/* 0xFB */ { 1671, 5, 10, 6, 1, -9 },
/* 0xFC */ { 1678, 5, 9, 6, 1, -8 },
/* 0xFD */ { 1684, 6, 12, 6, 0, -8 },
/* 0xFE */ { 1693, 5, 11, 7, 1, -8 },
/* 0xFF */ { 1700, 6, 12, 6, 0, -8 },
};
const GFXfont FreeSans6pt_Win1252 PROGMEM = {
(uint8_t*)FreeSans6pt_Win1252Bitmaps,
(GFXglyph*)FreeSans6pt_Win1252Glyphs,
0x01, 0xFF, 10
};
@@ -0,0 +1,527 @@
// trunk-ignore-all(clang-format)
#pragma once
/* PROPERTIES
FONT_NAME FreeSans6pt_Win1253
*/
const uint8_t FreeSans6pt_Win1253Bitmaps[] PROGMEM = {
/* 0x01 */ 0x1C, 0x0A, 0x05, 0x04, 0xFE, 0x08, 0x1C, 0x02, 0x07, 0xE0, 0x9F, 0xC0,
/* 0x02 */ 0x3F, 0xF0, 0x40, 0xE0, 0x10, 0x3F, 0x04, 0x9E, 0x28, 0x14, 0x0E, 0x00,
/* 0x03 */ 0x3F, 0x10, 0x28, 0x06, 0x49, 0x80, 0x60, 0x19, 0x26, 0x31, 0x40, 0x8F, 0xC0,
/* 0x04 */ 0x3F, 0x10, 0x2A, 0x16, 0x49, 0xA1, 0x60, 0x19, 0xE6, 0x31, 0x40, 0x8F, 0xC0,
/* 0x05 */ 0x28, 0x15, 0x2A, 0xB5, 0x55, 0xA8, 0x54, 0x12, 0x04, 0x41, 0x08, 0x81, 0xC0,
/* 0x06 */ 0x04, 0x08, 0x88, 0x82, 0x07, 0x01, 0x11, 0xA2, 0xC4, 0x40, 0x70, 0x20, 0x88, 0x88, 0x10, 0x00,
/* 0x07 */
/* 0x08 */ 0x03, 0x83, 0x44, 0x48, 0x28, 0x01, 0x80, 0x17, 0xFE, 0x08, 0x45, 0x28, 0x84, 0x00,
/* 0x09 */ 0x01, 0xC0, 0x68, 0x82, 0x41, 0x10, 0x02, 0x80, 0x06, 0x00, 0x14, 0x00, 0x8F, 0xFC,
/* 0x0A */
/* 0x0B */ 0x22, 0x2A, 0xA2, 0x30, 0x18, 0x0A, 0x09, 0x04, 0x44, 0x14, 0x04, 0x00,
/* 0x0C */ 0x46, 0x00, 0x19, 0x03, 0x21, 0x20, 0x93, 0x04, 0x20, 0x11, 0x80, 0x50, 0x02, 0x7F, 0xE0,
/* 0x0D */
/* 0x0E */ 0x08, 0x0E, 0x08, 0x88, 0x24, 0x12, 0x09, 0x05, 0x01, 0xFF, 0x8A, 0x02, 0x00,
/* 0x0F */ 0x3F, 0x14, 0xAA, 0x16, 0x01, 0x92, 0x60, 0x18, 0xC6, 0x49, 0x40, 0x8F, 0xC0,
/* 0x10 */ 0x1B, 0x02, 0xA0, 0x54, 0x12, 0x42, 0x48, 0x49, 0x31, 0x1E, 0x23, 0xEA, 0xFE, 0x3C,
/* 0x11 */ 0x3F, 0x02, 0x00, 0x20, 0x6D, 0x27, 0xF8, 0x3F, 0xC1, 0xFE, 0x37, 0xD0, 0xBE, 0x40, 0xE1, 0xE2, 0x00,
/* 0x12 */ 0x12, 0x42, 0x20, 0x24, 0xC0, 0x29, 0x99, 0x05, 0x23, 0x30, 0xB0, 0x30, 0x00,
/* 0x13 */ 0x3F, 0x88, 0x0A, 0x44, 0xD5, 0x58, 0x03, 0x00, 0x67, 0xCC, 0x71, 0x40, 0x47, 0xF0,
/* 0x14 */ 0x3F, 0x18, 0x69, 0x26, 0x85, 0xA1, 0x6C, 0xD8, 0x06, 0x31, 0x40, 0x8F, 0xC0,
/* 0x15 */ 0x3F, 0x11, 0x00, 0xE8, 0x03, 0xA0, 0x1F, 0xB3, 0x7E, 0x00, 0xE9, 0xE0, 0x23, 0x00, 0x40, 0x40, 0xFE, 0x00,
/* 0x16 */ 0x30, 0x38, 0x3A, 0x3E, 0x6E, 0xEB, 0xC3, 0xC3, 0x66, 0x3C,
/* 0x17 */ 0x3F, 0x04, 0x00, 0x82, 0x88, 0x5C, 0xA4, 0x49, 0x22, 0x81, 0x98, 0xC4, 0x40, 0xA3, 0xF0,
/* 0x18 */ 0x07, 0x80, 0x42, 0x04, 0x08, 0x21, 0x41, 0x42, 0x60, 0x0E, 0x8C, 0xB2, 0x89, 0x50, 0x52, 0x82, 0x80,
/* 0x19 */ 0x3F, 0xC4, 0x02, 0x80, 0x18, 0x01, 0xB3, 0x1B, 0xB9, 0x80, 0x19, 0xE1, 0x40, 0x23, 0xFC,
/* 0x1A */ 0xFF, 0xC0, 0x67, 0x34, 0x58, 0x4C, 0x46, 0x03, 0x11, 0x80, 0xFF, 0xC0,
/* 0x1B */ 0x0F, 0xC0, 0x40, 0x82, 0x49, 0x08, 0x04, 0x00, 0x00, 0x12, 0x02, 0x31, 0x34, 0x0B, 0x88, 0x45, 0x00, 0x20,
/* 0x1C */ 0x3F, 0x88, 0x0A, 0x44, 0xC9, 0x19, 0x3B, 0x00, 0x60, 0x4C, 0x71, 0x40, 0x47, 0xF0,
/* 0x1D */ 0x3F, 0x8B, 0x0A, 0x00, 0xC8, 0x18, 0x13, 0x00, 0x48, 0xCA, 0xC1, 0x44, 0x53, 0x30,
/* 0x1E */ 0x19, 0xC2, 0x02, 0x50, 0x1E, 0x49, 0x80, 0x12, 0x01, 0x27, 0x92, 0x01, 0x10, 0x20, 0xFC,
/* 0x1F */ 0x30, 0x1C, 0x0C, 0x3E, 0x7E, 0xCF, 0x07, 0xC7, 0x7F, 0x3F,
/* ' ' 0x20 */
/* '!' 0x21 */ 0xFC, 0x80,
/* '"' 0x22 */ 0xB6, 0x80,
/* '#' 0x23 */ 0x24, 0x51, 0xF9, 0x42, 0x9F, 0x92, 0x28,
/* '$' 0x24 */ 0x10, 0xE5, 0x55, 0x50, 0xE1, 0x65, 0x55, 0xE1, 0x00,
/* '%' 0x25 */ 0x71, 0x24, 0x89, 0x22, 0x50, 0x74, 0x02, 0x70, 0xA4, 0x49, 0x11, 0xC0,
/* '&' 0x26 */ 0x71, 0x24, 0x9C, 0x62, 0x58, 0xA7, 0xF4,
/* ''' 0x27 */ 0xE0,
/* '(' 0x28 */ 0x5A, 0xAA, 0x94,
/* ')' 0x29 */ 0x89, 0x12, 0x49, 0x29, 0x00,
/* '*' 0x2A */ 0x5E, 0x80,
/* '+' 0x2B */ 0x21, 0x3E, 0x42, 0x00,
/* ',' 0x2C */ 0xE0,
/* '-' 0x2D */ 0xC0,
/* '.' 0x2E */ 0x80,
/* '/' 0x2F */ 0x24, 0xA4, 0xA4, 0x80,
/* '0' 0x30 */ 0x76, 0xE3, 0x18, 0xC6, 0x3B, 0x70,
/* '1' 0x31 */ 0x27, 0x92, 0x49, 0x20,
/* '2' 0x32 */ 0x79, 0x10, 0x41, 0x08, 0xC6, 0x10, 0xFC,
/* '3' 0x33 */ 0x79, 0x30, 0x43, 0x18, 0x10, 0x71, 0x78,
/* '4' 0x34 */ 0x08, 0x61, 0x8A, 0x49, 0x2F, 0xC2, 0x08,
/* '5' 0x35 */ 0xFC, 0x21, 0xE8, 0x84, 0x31, 0xF0,
/* '6' 0x36 */ 0x74, 0x61, 0xE8, 0xC6, 0x31, 0x70,
/* '7' 0x37 */ 0xF8, 0x44, 0x22, 0x11, 0x08, 0x40,
/* '8' 0x38 */ 0x39, 0x34, 0x53, 0x39, 0x1C, 0x51, 0x38,
/* '9' 0x39 */ 0x39, 0x3C, 0x71, 0x4C, 0xF0, 0x53, 0x78,
/* ':' 0x3A */ 0x82,
/* ';' 0x3B */ 0x87,
/* '<' 0x3C */ 0x3E, 0x30, 0x60, 0x80,
/* '=' 0x3D */ 0xF8, 0x3E,
/* '>' 0x3E */ 0xE0, 0xC6, 0xC8, 0x00,
/* '?' 0x3F */ 0x74, 0x42, 0x11, 0x10, 0x80, 0x20,
/* '@' 0x40 */ 0x0F, 0x86, 0x19, 0x9A, 0xA4, 0xD9, 0x13, 0x22, 0x56, 0xDA, 0x6E, 0x60, 0x06, 0x00, 0x3C, 0x00,
/* 'A' 0x41 */ 0x18, 0x18, 0x24, 0x24, 0x24, 0x7E, 0x42, 0x42, 0xC3,
/* 'B' 0x42 */ 0xFA, 0x18, 0x61, 0xFA, 0x18, 0x61, 0xFC,
/* 'C' 0x43 */ 0x3E, 0x63, 0x40, 0x40, 0xC0, 0x40, 0x41, 0x63, 0x3E,
/* 'D' 0x44 */ 0xF9, 0x0A, 0x1C, 0x18, 0x30, 0x61, 0xC2, 0xF8,
/* 'E' 0x45 */ 0xFE, 0x08, 0x20, 0xFE, 0x08, 0x20, 0xFC,
/* 'F' 0x46 */ 0xFE, 0x08, 0x20, 0xFA, 0x08, 0x20, 0x80,
/* 'G' 0x47 */ 0x1E, 0x61, 0x40, 0x40, 0xC7, 0x41, 0x41, 0x63, 0x1D,
/* 'H' 0x48 */ 0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60, 0xC1, 0x82,
/* 'I' 0x49 */ 0xFF, 0x80,
/* 'J' 0x4A */ 0x08, 0x42, 0x10, 0x87, 0x29, 0x70,
/* 'K' 0x4B */ 0x85, 0x12, 0x45, 0x0D, 0x13, 0x22, 0x42, 0x86,
/* 'L' 0x4C */ 0x84, 0x21, 0x08, 0x42, 0x10, 0xF8,
/* 'M' 0x4D */ 0xC3, 0xC3, 0xC3, 0xA5, 0xA5, 0xA5, 0x99, 0x99, 0x99,
/* 'N' 0x4E */ 0x83, 0x86, 0x8D, 0x19, 0x33, 0x62, 0xC3, 0x86,
/* 'O' 0x4F */ 0x1E, 0x31, 0x90, 0x68, 0x1C, 0x0A, 0x05, 0x06, 0xC6, 0x1E, 0x00,
/* 'P' 0x50 */ 0xFA, 0x18, 0x61, 0xFA, 0x08, 0x20, 0x80,
/* 'Q' 0x51 */ 0x1E, 0x31, 0x90, 0x68, 0x1C, 0x0A, 0x05, 0x16, 0xC6, 0x1F, 0x00, 0x40,
/* 'R' 0x52 */ 0xFD, 0x0E, 0x1C, 0x2F, 0x90, 0xA1, 0x42, 0x86,
/* 'S' 0x53 */ 0x7A, 0x18, 0x30, 0x78, 0x38, 0x61, 0x78,
/* 'T' 0x54 */ 0xFE, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10,
/* 'U' 0x55 */ 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xE2, 0x78,
/* 'V' 0x56 */ 0xC2, 0x85, 0x0B, 0x22, 0x44, 0x8E, 0x0C, 0x18,
/* 'W' 0x57 */ 0xC4, 0x28, 0xCD, 0x29, 0x25, 0x24, 0xA4, 0x52, 0x8C, 0x61, 0x8C, 0x31, 0x80,
/* 'X' 0x58 */ 0x87, 0x34, 0x8C, 0x30, 0xC4, 0xA3, 0x84,
/* 'Y' 0x59 */ 0xC3, 0x42, 0x24, 0x34, 0x18, 0x08, 0x08, 0x08, 0x08,
/* 'Z' 0x5A */ 0x7E, 0x0C, 0x30, 0x41, 0x06, 0x18, 0x20, 0xFE,
/* '[' 0x5B */ 0xEA, 0xAA, 0xAB,
/* '\' 0x5C */ 0x92, 0x24, 0x89, 0x20,
/* ']' 0x5D */ 0xD5, 0x55, 0x57,
/* '^' 0x5E */ 0x46, 0xA9,
/* '_' 0x5F */ 0xFE,
/* '`' 0x60 */ 0x80,
/* 'a' 0x61 */ 0x79, 0x20, 0x4F, 0xC6, 0x37, 0x40,
/* 'b' 0x62 */ 0x84, 0x3D, 0x18, 0xC6, 0x31, 0xF0,
/* 'c' 0x63 */ 0x39, 0x3C, 0x20, 0xC1, 0x33, 0x80,
/* 'd' 0x64 */ 0x04, 0x13, 0xD3, 0xC6, 0x1C, 0x53, 0x3C,
/* 'e' 0x65 */ 0x39, 0x38, 0x7F, 0x81, 0x13, 0x80,
/* 'f' 0x66 */ 0x6B, 0xA4, 0x92, 0x40,
/* 'g' 0x67 */ 0x35, 0x3C, 0x61, 0xC5, 0x33, 0x41, 0x4D, 0xE0,
/* 'h' 0x68 */ 0x84, 0x3D, 0x38, 0xC6, 0x31, 0x88,
/* 'i' 0x69 */ 0xBF, 0x80,
/* 'j' 0x6A */ 0x45, 0x55, 0x57,
/* 'k' 0x6B */ 0x84, 0x25, 0x4E, 0x52, 0xD2, 0x88,
/* 'l' 0x6C */ 0xFF, 0x80,
/* 'm' 0x6D */ 0xF7, 0x99, 0x91, 0x91, 0x91, 0x91, 0x91,
/* 'n' 0x6E */ 0xF4, 0x63, 0x18, 0xC6, 0x20,
/* 'o' 0x6F */ 0x39, 0x3C, 0x61, 0xC5, 0x33, 0x80,
/* 'p' 0x70 */ 0xF4, 0x63, 0x18, 0xC7, 0xD0, 0x80,
/* 'q' 0x71 */ 0x3D, 0x3C, 0x61, 0xC5, 0x37, 0x41, 0x04,
/* 'r' 0x72 */ 0xF2, 0x49, 0x20,
/* 's' 0x73 */ 0x7A, 0x50, 0xE0, 0xE5, 0xE0,
/* 't' 0x74 */ 0x5D, 0x24, 0x93,
/* 'u' 0x75 */ 0x8C, 0x63, 0x18, 0xCF, 0xA0,
/* 'v' 0x76 */ 0x85, 0x24, 0x92, 0x30, 0xC3, 0x00,
/* 'w' 0x77 */ 0x89, 0x59, 0x59, 0x55, 0x56, 0x26, 0x26,
/* 'x' 0x78 */ 0x4A, 0x4C, 0x43, 0x27, 0x20,
/* 'y' 0x79 */ 0x8A, 0x52, 0xA5, 0x18, 0x84, 0x22, 0x00,
/* 'z' 0x7A */ 0x78, 0x44, 0x46, 0x23, 0xE0,
/* '{' 0x7B */ 0x6A, 0xAA, 0xA9,
/* '|' 0x7C */ 0xFF, 0xE0,
/* '}' 0x7D */ 0x95, 0x55, 0x56,
/* '~' 0x7E */ 0x66, 0x60,
/* 0x7F */
/* 0x80 */ 0x1C, 0x45, 0x07, 0xE4, 0x1F, 0x10, 0x10, 0x1E,
/* 0x81 */
/* 0x82 */ 0xE0,
/* 0x83 */ 0x6B, 0xA4, 0x92, 0x49, 0x60,
/* 0x84 */ 0xB6, 0x80,
/* 0x85 */ 0xA8,
/* 0x86 */ 0x21, 0x09, 0xF2, 0x10, 0x84, 0x21, 0x08,
/* 0x87 */ 0x21, 0x09, 0xF2, 0x10, 0x84, 0xF9, 0x08,
/* 0x88 */ 0x54,
/* 0x89 */ 0x62, 0x09, 0x40, 0x98, 0x06, 0x80, 0x10, 0x01, 0x66, 0x29, 0x92, 0x99, 0x06, 0x60,
/* 0x8A */ 0x28, 0x47, 0xA1, 0x83, 0x07, 0x83, 0x87, 0x17, 0x80,
/* 0x8B */ 0x64,
/* 0x8C */ 0x3B, 0xE8, 0xC2, 0x08, 0x41, 0x08, 0x3F, 0x04, 0x20, 0x82, 0x30, 0x3B, 0xE0,
/* 0x8D */
/* 0x8E */ 0x14, 0x11, 0xF8, 0x30, 0xC1, 0x04, 0x18, 0x61, 0xFC,
/* 0x8F */
/* 0x90 */
/* 0x91 */ 0xE0,
/* 0x92 */ 0xE0,
/* 0x93 */ 0xB6, 0x80,
/* 0x94 */ 0xB6, 0x80,
/* 0x95 */ 0xFF, 0x80,
/* 0x96 */ 0xFC,
/* 0x97 */ 0xFF, 0xF0,
/* 0x98 */ 0xDB,
/* 0x99 */ 0xE6, 0x28, 0xCD, 0x19, 0xA3, 0x34, 0x6A, 0x8B, 0x51, 0x68,
/* 0x9A */ 0x52, 0x69, 0x8E, 0x19, 0x60,
/* 0x9B */ 0x98,
/* 0x9C */ 0x7B, 0xD9, 0xCE, 0x10, 0xC3, 0xF8, 0x41, 0x9C, 0x5E, 0xF0,
/* 0x9D */
/* 0x9E */ 0x51, 0x1E, 0x11, 0x11, 0x88, 0xF8,
/* 0x9F */ 0x29, 0x05, 0x12, 0x22, 0x87, 0x04, 0x08, 0x10, 0x20,
/* 0xA0 */
/* 0xA1 */ 0xBF, 0x80,
/* 0xA2 */ 0x23, 0xAB, 0x4A, 0x52, 0xAE, 0x20,
/* 0xA3 */ 0x39, 0x14, 0x10, 0xF0, 0x82, 0x1C, 0x4C,
/* 0xA4 */ 0xFC, 0x63, 0xF0,
/* 0xA5 */ 0x8C, 0x54, 0xAF, 0x93, 0xE4, 0x20,
/* 0xA6 */ 0xF9, 0xF0,
/* 0xA7 */ 0x32, 0x91, 0xC9, 0x47, 0x26, 0x14, 0xA4, 0xC0,
/* 0xA8 */ 0xA0,
/* 0xA9 */ 0x3E, 0x3F, 0xB8, 0xF4, 0x1A, 0x0D, 0x17, 0x76, 0xC6, 0x3E, 0x00,
/* 0xAA */ 0x61, 0x79, 0x60,
/* 0xAB */ 0x5A, 0xA5,
/* 0xAC */ 0xFC, 0x10, 0x40,
/* 0xAD */
/* 0xAE */ 0x3E, 0x31, 0xB7, 0x72, 0x99, 0xCC, 0xC7, 0x56, 0xC6, 0x3E, 0x00,
/* 0xAF */ 0xE0,
/* 0xB0 */ 0x69, 0x96,
/* 0xB1 */ 0x21, 0x3E, 0x42, 0x03, 0xE0,
/* 0xB2 */ 0x69, 0x3C, 0xF0,
/* 0xB3 */ 0x79, 0x29, 0x70,
/* 0xB4 */ 0x80,
/* 0xB5 */ 0x8A, 0x28, 0xA2, 0x8A, 0x6E, 0xE0, 0x80,
/* 0xB6 */ 0x7F, 0xAE, 0xBA, 0x68, 0xA2, 0x8A, 0x28, 0xA0,
/* 0xB7 */ 0x80,
/* 0xB8 */ 0x67, 0x80,
/* 0xB9 */ 0x75, 0x50,
/* 0xBA */ 0x69, 0x96, 0xF0,
/* 0xBB */ 0xA5, 0x5A,
/* 0xBC */ 0x42, 0x30, 0x84, 0x41, 0x10, 0x48, 0x82, 0x61, 0x28, 0x8F, 0x20, 0x80,
/* 0xBD */ 0x40, 0x63, 0x11, 0x09, 0x74, 0xA8, 0x84, 0x44, 0x44, 0x43, 0x80,
/* 0xBE */ 0x71, 0x24, 0x82, 0x20, 0x50, 0x98, 0x9A, 0x61, 0x28, 0x4F, 0x20, 0x80,
/* 0xBF */ 0x20, 0x08, 0x44, 0x42, 0x11, 0x70,
/* 0xC0 */ 0x2D, 0x02, 0x22, 0x22, 0x22,
/* 0xC1 */ 0x10, 0x50, 0xA1, 0x44, 0x4F, 0x91, 0x41, 0x82,
/* 0xC2 */ 0xFA, 0x18, 0x61, 0xFE, 0x18, 0x61, 0xF8,
/* 0xC3 */ 0xFE, 0x08, 0x20, 0x82, 0x08, 0x20, 0x80,
/* 0xC4 */ 0x08, 0x0A, 0x05, 0x02, 0x82, 0x21, 0x11, 0x04, 0x82, 0x7F, 0x00,
/* 0xC5 */ 0xFE, 0x08, 0x20, 0xFE, 0x08, 0x20, 0xFC,
/* 0xC6 */ 0x7E, 0x08, 0x20, 0x41, 0x04, 0x08, 0x20, 0xFE,
/* 0xC7 */ 0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60, 0xC1, 0x82,
/* 0xC8 */ 0x38, 0x8A, 0x0C, 0x1B, 0xB0, 0x60, 0xA2, 0x38,
/* 0xC9 */ 0xFF, 0x80,
/* 0xCA */ 0x83, 0x0A, 0x24, 0x8A, 0x1A, 0x22, 0x42, 0x82,
/* 0xCB */ 0x08, 0x0A, 0x05, 0x02, 0x82, 0x21, 0x11, 0x04, 0x82, 0x41, 0x00,
/* 0xCC */ 0x83, 0x8F, 0x1D, 0x5A, 0xB5, 0x6A, 0xC9, 0x92,
/* 0xCD */ 0x83, 0x86, 0x8D, 0x19, 0x31, 0x62, 0xC3, 0x82,
/* 0xCE */ 0xFC, 0x00, 0x00, 0x78, 0x00, 0x00, 0xFC,
/* 0xCF */ 0x38, 0x8A, 0x0C, 0x18, 0x30, 0x60, 0xA2, 0x38,
/* 0xD0 */ 0xFF, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x82,
/* 0xD1 */ 0xFA, 0x18, 0x61, 0xFA, 0x08, 0x20, 0x80,
/* 0xD2 */
/* 0xD3 */ 0xFE, 0x04, 0x08, 0x10, 0x84, 0x20, 0xFC,
/* 0xD4 */ 0xFE, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10,
/* 0xD5 */ 0x82, 0x89, 0x11, 0x41, 0x02, 0x04, 0x08, 0x10,
/* 0xD6 */ 0x10, 0xFA, 0x4C, 0x99, 0x32, 0x64, 0xBE, 0x10,
/* 0xD7 */ 0x82, 0x89, 0x11, 0x41, 0x05, 0x11, 0x22, 0x82,
/* 0xD8 */ 0x93, 0x26, 0x4C, 0x99, 0x2F, 0x84, 0x08, 0x10,
/* 0xD9 */ 0x38, 0x8A, 0x0C, 0x18, 0x30, 0x60, 0xA2, 0xEE,
/* 0xDA */ 0xA1, 0x24, 0x92, 0x49, 0x00,
/* 0xDB */ 0x28, 0x02, 0x0A, 0x24, 0x45, 0x04, 0x08, 0x10, 0x20, 0x40,
/* 0xDC */ 0x11, 0x00, 0xD9, 0x4A, 0x52, 0x93, 0x40,
/* 0xDD */ 0x11, 0x00, 0xF8, 0x41, 0x90, 0x83, 0xC0,
/* 0xDE */ 0x11, 0x01, 0x6C, 0xC6, 0x31, 0x8C, 0x42, 0x10,
/* 0xDF */ 0x62, 0xAA, 0xA0,
/* 0xE0 */ 0x25, 0x81, 0x18, 0xC6, 0x31, 0x8B, 0x80,
/* 0xE1 */ 0x6C, 0xA5, 0x29, 0x49, 0xA0,
/* 0xE2 */ 0x74, 0x63, 0x1B, 0x46, 0x39, 0xB4, 0x20,
/* 0xE3 */ 0x44, 0x89, 0x11, 0x42, 0x85, 0x04, 0x08, 0x10,
/* 0xE4 */ 0x71, 0x1D, 0x18, 0xC6, 0x31, 0x70,
/* 0xE5 */ 0x7C, 0x20, 0xC8, 0x41, 0xE0,
/* 0xE6 */ 0x72, 0x44, 0x88, 0x88, 0x71, 0x20,
/* 0xE7 */ 0xB6, 0x63, 0x18, 0xC6, 0x21, 0x08,
/* 0xE8 */ 0x74, 0x63, 0x1F, 0xC6, 0x31, 0x70,
/* 0xE9 */ 0xFE,
/* 0xEA */ 0x8A, 0x4A, 0x38, 0x92, 0x48, 0x80,
/* 0xEB */ 0x20, 0x41, 0x04, 0x28, 0xA2, 0x91, 0x44,
/* 0xEC */ 0x8C, 0x63, 0x18, 0xC7, 0xF0, 0x80,
/* 0xED */ 0x8C, 0x54, 0xA5, 0x10, 0x80,
/* 0xEE */ 0x68, 0x86, 0x48, 0x88, 0x71, 0x20,
/* 0xEF */ 0x74, 0x63, 0x18, 0xC5, 0xC0,
/* 0xF0 */ 0xFF, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
/* 0xF1 */ 0x74, 0x63, 0x18, 0xC7, 0xD0, 0x80,
/* 0xF2 */ 0x34, 0x88, 0x88, 0x71, 0x60,
/* 0xF3 */ 0x7F, 0x12, 0x24, 0x48, 0x91, 0x1C, 0x00,
/* 0xF4 */ 0xE9, 0x24, 0x90,
/* 0xF5 */ 0x8C, 0x63, 0x18, 0xC5, 0xC0,
/* 0xF6 */ 0x5A, 0x59, 0x65, 0x95, 0x53, 0x84, 0x10,
/* 0xF7 */ 0x49, 0x24, 0x8C, 0x30, 0xC4, 0x92, 0x48,
/* 0xF8 */ 0x93, 0x26, 0x4C, 0x99, 0x32, 0x5F, 0x08, 0x10,
/* 0xF9 */ 0x45, 0x06, 0x4C, 0x99, 0x32, 0x5B, 0x00,
/* 0xFA */ 0xA1, 0x24, 0x92, 0x40,
/* 0xFB */ 0x50, 0x23, 0x18, 0xC6, 0x31, 0x70,
/* 0xFC */ 0x11, 0x00, 0xE8, 0xC6, 0x31, 0x8B, 0x80,
/* 0xFD */ 0x21, 0x01, 0x18, 0xC6, 0x31, 0x8B, 0x80,
/* 0xFE */ 0x08, 0x20, 0x02, 0x28, 0x32, 0x64, 0xC9, 0x92, 0xD8,
/* 0xFF */
};
const GFXglyph FreeSans6pt_Win1253Glyphs[] PROGMEM = {
/* 0x01 */ { 0, 9, 10, 11, 1, -9 },
/* 0x02 */ { 12, 9, 10, 11, 1, -8 },
/* 0x03 */ { 24, 10, 10, 12, 1, -8 },
/* 0x04 */ { 37, 10, 10, 12, 1, -8 },
/* 0x05 */ { 50, 10, 10, 12, 1, -9 },
/* 0x06 */ { 63, 11, 11, 13, 1, -9 },
/* 0x07 */ { 79, 0, 0, 8, 0, 0 },
/* 0x08 */ { 79, 12, 9, 14, 1, -8 },
/* 0x09 */ { 93, 14, 8, 16, 1, -7 },
/* 0x0A */ { 107, 0, 0, 8, 0, 0 },
/* 0x0B */ { 107, 9, 10, 11, 1, -9 },
/* 0x0C */ { 119, 13, 9, 15, 1, -8 },
/* 0x0D */ { 134, 0, 0, 8, 0, 0 },
/* 0x0E */ { 134, 9, 11, 11, 1, -9 },
/* 0x0F */ { 147, 10, 10, 12, 1, -9 },
/* 0x10 */ { 160, 11, 10, 13, 1, -9 },
/* 0x11 */ { 174, 13, 10, 15, 1, -9 },
/* 0x12 */ { 191, 10, 10, 12, 1, -9 },
/* 0x13 */ { 204, 11, 10, 13, 1, -9 },
/* 0x14 */ { 218, 10, 10, 12, 1, -9 },
/* 0x15 */ { 231, 14, 10, 16, 1, -9 },
/* 0x16 */ { 249, 8, 10, 10, 1, -9 },
/* 0x17 */ { 259, 12, 10, 14, 1, -9 },
/* 0x18 */ { 274, 13, 10, 15, 1, -9 },
/* 0x19 */ { 291, 12, 10, 14, 1, -9 },
/* 0x1A */ { 306, 9, 10, 11, 1, -8 },
/* 0x1B */ { 318, 14, 10, 16, 1, -9 },
/* 0x1C */ { 336, 11, 10, 13, 1, -9 },
/* 0x1D */ { 350, 11, 10, 13, 1, -9 },
/* 0x1E */ { 364, 12, 10, 14, 1, -9 },
/* 0x1F */ { 379, 8, 10, 11, 2, -9 },
/* ' ' 0x20 */ { 389, 0, 0, 3, 0, 0 },
/* '!' 0x21 */ { 389, 1, 9, 4, 2, -8 },
/* '"' 0x22 */ { 391, 3, 3, 4, 0, -8 },
/* '#' 0x23 */ { 393, 7, 8, 7, 0, -7 },
/* '$' 0x24 */ { 400, 6, 11, 7, 0, -9 },
/* '%' 0x25 */ { 409, 10, 9, 11, 0, -8 },
/* '&' 0x26 */ { 421, 6, 9, 8, 1, -8 },
/* ''' 0x27 */ { 428, 1, 3, 2, 1, -8 },
/* '(' 0x28 */ { 429, 2, 11, 4, 1, -8 },
/* ')' 0x29 */ { 432, 3, 11, 4, 0, -8 },
/* '*' 0x2A */ { 437, 3, 3, 5, 1, -8 },
/* '+' 0x2B */ { 439, 5, 5, 7, 1, -4 },
/* ',' 0x2C */ { 443, 1, 3, 3, 1, 0 },
/* '-' 0x2D */ { 444, 2, 1, 4, 1, -3 },
/* '.' 0x2E */ { 445, 1, 1, 3, 1, 0 },
/* '/' 0x2F */ { 446, 3, 9, 3, 0, -8 },
/* '0' 0x30 */ { 450, 5, 9, 7, 1, -8 },
/* '1' 0x31 */ { 456, 3, 9, 7, 1, -8 },
/* '2' 0x32 */ { 460, 6, 9, 7, 0, -8 },
/* '3' 0x33 */ { 467, 6, 9, 7, 0, -8 },
/* '4' 0x34 */ { 474, 6, 9, 7, 0, -8 },
/* '5' 0x35 */ { 481, 5, 9, 7, 1, -8 },
/* '6' 0x36 */ { 487, 5, 9, 7, 1, -8 },
/* '7' 0x37 */ { 493, 5, 9, 7, 1, -8 },
/* '8' 0x38 */ { 499, 6, 9, 7, 0, -8 },
/* '9' 0x39 */ { 506, 6, 9, 7, 0, -8 },
/* ':' 0x3A */ { 513, 1, 7, 3, 1, -6 },
/* ';' 0x3B */ { 514, 1, 8, 3, 1, -5 },
/* '<' 0x3C */ { 515, 5, 5, 7, 1, -4 },
/* '=' 0x3D */ { 519, 5, 3, 7, 1, -3 },
/* '>' 0x3E */ { 521, 5, 5, 7, 1, -4 },
/* '?' 0x3F */ { 525, 5, 9, 7, 1, -8 },
/* '@' 0x40 */ { 531, 11, 11, 12, 0, -8 },
/* 'A' 0x41 */ { 547, 8, 9, 8, 0, -8 },
/* 'B' 0x42 */ { 556, 6, 9, 8, 1, -8 },
/* 'C' 0x43 */ { 563, 8, 9, 9, 0, -8 },
/* 'D' 0x44 */ { 572, 7, 9, 8, 1, -8 },
/* 'E' 0x45 */ { 580, 6, 9, 8, 1, -8 },
/* 'F' 0x46 */ { 587, 6, 9, 7, 1, -8 },
/* 'G' 0x47 */ { 594, 8, 9, 9, 0, -8 },
/* 'H' 0x48 */ { 603, 7, 9, 9, 1, -8 },
/* 'I' 0x49 */ { 611, 1, 9, 3, 1, -8 },
/* 'J' 0x4A */ { 613, 5, 9, 6, 0, -8 },
/* 'K' 0x4B */ { 619, 7, 9, 8, 1, -8 },
/* 'L' 0x4C */ { 627, 5, 9, 7, 1, -8 },
/* 'M' 0x4D */ { 633, 8, 9, 10, 1, -8 },
/* 'N' 0x4E */ { 642, 7, 9, 9, 1, -8 },
/* 'O' 0x4F */ { 650, 9, 9, 9, 0, -8 },
/* 'P' 0x50 */ { 661, 6, 9, 8, 1, -8 },
/* 'Q' 0x51 */ { 668, 9, 10, 9, 0, -8 },
/* 'R' 0x52 */ { 680, 7, 9, 9, 1, -8 },
/* 'S' 0x53 */ { 688, 6, 9, 8, 1, -8 },
/* 'T' 0x54 */ { 695, 7, 9, 8, 0, -8 },
/* 'U' 0x55 */ { 703, 7, 9, 9, 1, -8 },
/* 'V' 0x56 */ { 711, 7, 9, 8, 0, -8 },
/* 'W' 0x57 */ { 719, 11, 9, 11, 0, -8 },
/* 'X' 0x58 */ { 732, 6, 9, 8, 1, -8 },
/* 'Y' 0x59 */ { 739, 8, 9, 8, 0, -8 },
/* 'Z' 0x5A */ { 748, 7, 9, 7, 0, -8 },
/* '[' 0x5B */ { 756, 2, 12, 3, 1, -8 },
/* '\' 0x5C */ { 759, 3, 9, 3, 0, -8 },
/* ']' 0x5D */ { 763, 2, 12, 3, 0, -8 },
/* '^' 0x5E */ { 766, 4, 4, 6, 1, -8 },
/* '_' 0x5F */ { 768, 7, 1, 7, 0, 2 },
/* '`' 0x60 */ { 769, 1, 1, 3, 1, -8 },
/* 'a' 0x61 */ { 770, 6, 7, 7, 0, -6 },
/* 'b' 0x62 */ { 776, 5, 9, 7, 1, -8 },
/* 'c' 0x63 */ { 782, 6, 7, 6, 0, -6 },
/* 'd' 0x64 */ { 788, 6, 9, 7, 0, -8 },
/* 'e' 0x65 */ { 795, 6, 7, 6, 0, -6 },
/* 'f' 0x66 */ { 801, 3, 9, 3, 0, -8 },
/* 'g' 0x67 */ { 805, 6, 10, 7, 0, -6 },
/* 'h' 0x68 */ { 813, 5, 9, 6, 1, -8 },
/* 'i' 0x69 */ { 819, 1, 9, 3, 1, -8 },
/* 'j' 0x6A */ { 821, 2, 12, 3, 0, -8 },
/* 'k' 0x6B */ { 824, 5, 9, 6, 1, -8 },
/* 'l' 0x6C */ { 830, 1, 9, 3, 1, -8 },
/* 'm' 0x6D */ { 832, 8, 7, 10, 1, -6 },
/* 'n' 0x6E */ { 839, 5, 7, 6, 1, -6 },
/* 'o' 0x6F */ { 844, 6, 7, 6, 0, -6 },
/* 'p' 0x70 */ { 850, 5, 9, 7, 1, -6 },
/* 'q' 0x71 */ { 856, 6, 9, 7, 0, -6 },
/* 'r' 0x72 */ { 863, 3, 7, 4, 1, -6 },
/* 's' 0x73 */ { 866, 5, 7, 6, 0, -6 },
/* 't' 0x74 */ { 871, 3, 8, 3, 0, -7 },
/* 'u' 0x75 */ { 874, 5, 7, 6, 1, -6 },
/* 'v' 0x76 */ { 879, 6, 7, 6, 0, -6 },
/* 'w' 0x77 */ { 885, 8, 7, 9, 0, -6 },
/* 'x' 0x78 */ { 892, 5, 7, 6, 0, -6 },
/* 'y' 0x79 */ { 897, 5, 10, 6, 0, -6 },
/* 'z' 0x7A */ { 904, 5, 7, 6, 0, -6 },
/* '{' 0x7B */ { 909, 2, 12, 4, 1, -8 },
/* '|' 0x7C */ { 912, 1, 11, 3, 1, -8 },
/* '}' 0x7D */ { 914, 2, 12, 4, 1, -8 },
/* '~' 0x7E */ { 917, 6, 2, 6, 0, -4 },
/* 0x7F */ { 919, 0, 0, 0, 0, 0 },
/* 0x80 */ { 919, 7, 9, 8, 0, -8 },
/* 0x81 */ { 927, 0, 0, 8, 0, 0 },
/* 0x82 */ { 927, 1, 3, 3, 1, 0 },
/* 0x83 */ { 928, 3, 12, 3, 0, -8 },
/* 0x84 */ { 933, 3, 3, 5, 1, 0 },
/* 0x85 */ { 935, 5, 1, 7, 1, 0 },
/* 0x86 */ { 936, 5, 11, 7, 1, -8 },
/* 0x87 */ { 943, 5, 11, 7, 1, -8 },
/* 0x88 */ { 950, 3, 2, 4, 0, -9 },
/* 0x89 */ { 951, 12, 9, 12, 0, -8 },
/* 0x8A */ { 965, 6, 11, 8, 1, -9 },
/* 0x8B */ { 974, 2, 3, 4, 1, -4 },
/* 0x8C */ { 975, 11, 9, 12, 0, -8 },
/* 0x8D */ { 988, 0, 0, 8, 0, 0 },
/* 0x8E */ { 988, 7, 10, 7, 0, -9 },
/* 0x8F */ { 997, 0, 0, 8, 0, 0 },
/* 0x90 */ { 997, 0, 0, 8, 0, 0 },
/* 0x91 */ { 997, 1, 3, 3, 1, -8 },
/* 0x92 */ { 998, 1, 3, 2, 1, -8 },
/* 0x93 */ { 999, 3, 3, 5, 1, -8 },
/* 0x94 */ { 1001, 3, 3, 5, 1, -8 },
/* 0x95 */ { 1003, 3, 3, 5, 1, -5 },
/* 0x96 */ { 1005, 6, 1, 6, 0, -3 },
/* 0x97 */ { 1006, 12, 1, 12, 0, -3 },
/* 0x98 */ { 1008, 4, 2, 4, 0, -8 },
/* 0x99 */ { 1009, 11, 7, 12, 1, -8 },
/* 0x9A */ { 1019, 4, 9, 6, 1, -8 },
/* 0x9B */ { 1024, 2, 3, 3, 1, -4 },
/* 0x9C */ { 1025, 11, 7, 11, 0, -6 },
/* 0x9D */ { 1035, 0, 0, 8, 0, 0 },
/* 0x9E */ { 1035, 5, 9, 6, 0, -8 },
/* 0x9F */ { 1041, 7, 10, 8, 1, -9 },
/* 0xA0 */ { 1050, 0, 0, 3, 0, 0 },
/* 0xA1 */ { 1050, 1, 9, 4, 1, -5 },
/* 0xA2 */ { 1052, 5, 9, 7, 1, -7 },
/* 0xA3 */ { 1058, 6, 9, 7, 0, -8 },
/* 0xA4 */ { 1065, 5, 4, 7, 1, -5 },
/* 0xA5 */ { 1068, 5, 9, 7, 1, -8 },
/* 0xA6 */ { 1074, 1, 12, 3, 1, -8 },
/* 0xA7 */ { 1076, 5, 12, 7, 1, -8 },
/* 0xA8 */ { 1084, 3, 1, 4, 0, -7 },
/* 0xA9 */ { 1085, 9, 9, 10, 0, -8 },
/* 0xAA */ { 1096, 4, 5, 4, 0, -8 },
/* 0xAB */ { 1099, 4, 4, 6, 1, -4 },
/* 0xAC */ { 1101, 6, 3, 7, 1, -4 },
/* 0xAD */ { 1104, 0, 0, 0, 0, 0 },
/* 0xAE */ { 1104, 9, 9, 10, 0, -8 },
/* 0xAF */ { 1115, 3, 1, 4, 0, -8 },
/* 0xB0 */ { 1116, 4, 4, 7, 2, -8 },
/* 0xB1 */ { 1118, 5, 7, 7, 1, -6 },
/* 0xB2 */ { 1123, 4, 5, 4, 0, -9 },
/* 0xB3 */ { 1126, 4, 5, 4, 0, -9 },
/* 0xB4 */ { 1129, 1, 1, 4, 1, -8 },
/* 0xB5 */ { 1130, 6, 9, 7, 1, -6 },
/* 0xB6 */ { 1137, 6, 10, 6, 1, -8 },
/* 0xB7 */ { 1145, 1, 1, 3, 1, -2 },
/* 0xB8 */ { 1146, 3, 3, 4, 1, 1 },
/* 0xB9 */ { 1148, 2, 6, 4, 1, -9 },
/* 0xBA */ { 1150, 4, 5, 4, 0, -8 },
/* 0xBB */ { 1153, 4, 4, 6, 1, -5 },
/* 0xBC */ { 1155, 10, 9, 10, 1, -8 },
/* 0xBD */ { 1167, 9, 9, 10, 1, -8 },
/* 0xBE */ { 1178, 10, 9, 11, 0, -8 },
/* 0xBF */ { 1190, 5, 9, 7, 1, -5 },
/* 0xC0 */ { 1196, 4, 10, 3, -1, -10 },
/* 0xC1 */ { 1201, 7, 9, 7, 0, -9 },
/* 0xC2 */ { 1209, 6, 9, 8, 1, -9 },
/* 0xC3 */ { 1216, 6, 9, 7, 1, -9 },
/* 0xC4 */ { 1223, 9, 9, 7, -1, -9 },
/* 0xC5 */ { 1234, 6, 9, 8, 1, -9 },
/* 0xC6 */ { 1241, 7, 9, 7, 0, -9 },
/* 0xC7 */ { 1249, 7, 9, 9, 1, -9 },
/* 0xC8 */ { 1257, 7, 9, 9, 1, -9 },
/* 0xC9 */ { 1265, 1, 9, 3, 1, -9 },
/* 0xCA */ { 1267, 7, 9, 8, 1, -9 },
/* 0xCB */ { 1275, 9, 9, 7, -1, -9 },
/* 0xCC */ { 1286, 7, 9, 9, 1, -9 },
/* 0xCD */ { 1294, 7, 9, 9, 1, -9 },
/* 0xCE */ { 1302, 6, 9, 8, 1, -9 },
/* 0xCF */ { 1309, 7, 9, 9, 1, -9 },
/* 0xD0 */ { 1317, 7, 9, 9, 1, -9 },
/* 0xD1 */ { 1325, 6, 9, 8, 1, -9 },
/* 0xD2 */ { 1332, 0, 0, 5, 0, 0 },
/* 0xD3 */ { 1332, 6, 9, 7, 1, -9 },
/* 0xD4 */ { 1339, 7, 9, 7, 0, -9 },
/* 0xD5 */ { 1347, 7, 9, 7, 0, -9 },
/* 0xD6 */ { 1355, 7, 9, 9, 1, -9 },
/* 0xD7 */ { 1363, 7, 9, 7, 0, -9 },
/* 0xD8 */ { 1371, 7, 9, 9, 1, -9 },
/* 0xD9 */ { 1379, 7, 9, 9, 1, -9 },
/* 0xDA */ { 1387, 3, 11, 3, 0, -11 },
/* 0xDB */ { 1392, 7, 11, 7, 0, -11 },
/* 0xDC */ { 1402, 5, 10, 7, 1, -10 },
/* 0xDD */ { 1409, 5, 10, 5, 0, -10 },
/* 0xDE */ { 1416, 5, 12, 7, 1, -10 },
/* 0xDF */ { 1424, 2, 10, 3, 1, -10 },
/* 0xE0 */ { 1427, 5, 10, 7, 1, -10 },
/* 0xE1 */ { 1434, 5, 7, 7, 1, -7 },
/* 0xE2 */ { 1439, 5, 11, 7, 1, -9 },
/* 0xE3 */ { 1446, 7, 9, 5, -1, -7 },
/* 0xE4 */ { 1454, 5, 9, 7, 1, -9 },
/* 0xE5 */ { 1460, 5, 7, 5, 0, -7 },
/* 0xE6 */ { 1465, 4, 11, 5, 1, -9 },
/* 0xE7 */ { 1471, 5, 9, 7, 1, -7 },
/* 0xE8 */ { 1477, 5, 9, 7, 1, -9 },
/* 0xE9 */ { 1483, 1, 7, 3, 1, -7 },
/* 0xEA */ { 1484, 6, 7, 7, 1, -7 },
/* 0xEB */ { 1490, 6, 9, 5, -1, -9 },
/* 0xEC */ { 1497, 5, 9, 7, 1, -7 },
/* 0xED */ { 1503, 5, 7, 5, 0, -7 },
/* 0xEE */ { 1508, 4, 11, 5, 1, -9 },
/* 0xEF */ { 1514, 5, 7, 7, 1, -7 },
/* 0xF0 */ { 1519, 8, 7, 8, 0, -7 },
/* 0xF1 */ { 1526, 5, 9, 7, 1, -7 },
/* 0xF2 */ { 1532, 4, 9, 6, 1, -7 },
/* 0xF3 */ { 1537, 7, 7, 7, 1, -7 },
/* 0xF4 */ { 1544, 3, 7, 5, 1, -7 },
/* 0xF5 */ { 1547, 5, 7, 7, 1, -7 },
/* 0xF6 */ { 1552, 6, 9, 8, 1, -7 },
/* 0xF7 */ { 1559, 6, 9, 6, 0, -7 },
/* 0xF8 */ { 1566, 7, 9, 9, 1, -7 },
/* 0xF9 */ { 1574, 7, 7, 9, 1, -7 },
/* 0xFA */ { 1581, 3, 9, 3, 0, -9 },
/* 0xFB */ { 1585, 5, 9, 7, 1, -9 },
/* 0xFC */ { 1591, 5, 10, 7, 1, -10 },
/* 0xFD */ { 1598, 5, 10, 7, 1, -10 },
/* 0xFE */ { 1605, 7, 10, 9, 1, -10 },
/* 0xFF */ { 1614, 0, 0, 5, 0, 0 },
};
const GFXfont FreeSans6pt_Win1253 PROGMEM = {
(uint8_t*)FreeSans6pt_Win1253Bitmaps,
(GFXglyph*)FreeSans6pt_Win1253Glyphs,
0x01, 0xFF, 10
};
@@ -0,0 +1,527 @@
// trunk-ignore-all(clang-format)
#pragma once
/* PROPERTIES
FONT_NAME FreeSans9pt_Win1250
*/
const uint8_t FreeSans9pt_Win1250Bitmaps[] PROGMEM = {
/* 0x01 */ 0x07, 0x00, 0x0A, 0x00, 0x24, 0x00, 0x48, 0x01, 0x10, 0x04, 0x40, 0x10, 0xFF, 0x20, 0x02, 0x81, 0xFD, 0x00, 0x06, 0x07, 0xF4, 0x08, 0x24, 0x0F, 0x88, 0x11, 0x0F, 0xDC, 0x00,
/* 0x02 */ 0x3F, 0x70, 0x81, 0x11, 0x03, 0xE4, 0x08, 0x28, 0x1F, 0xD0, 0x00, 0x60, 0x7F, 0x20, 0x02, 0x43, 0xFC, 0x44, 0x00, 0x44, 0x00, 0x48, 0x00, 0x90, 0x00, 0xA0, 0x01, 0xC0, 0x00,
/* 0x03 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x00, 0x31, 0x8C, 0x63, 0x18, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x20, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x04 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x82, 0x30, 0x88, 0x62, 0x08, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x3F, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x05 */ 0x0B, 0x10, 0x14, 0xA8, 0x12, 0x50, 0x29, 0x42, 0x24, 0xA5, 0x32, 0x95, 0x5A, 0x09, 0x48, 0x09, 0x24, 0x01, 0x10, 0x01, 0x48, 0x02, 0xA4, 0x02, 0x42, 0x04, 0x01, 0x98, 0x00, 0x60,
/* 0x06 */ 0x00, 0x80, 0x22, 0x80, 0x65, 0x00, 0xBE, 0xE1, 0x82, 0x4E, 0x03, 0x24, 0x04, 0x28, 0x06, 0x30, 0x12, 0x20, 0x3C, 0xA0, 0xC3, 0xFE, 0x80, 0x4D, 0x00, 0xA6, 0x01, 0x80, 0x00,
/* 0x07 */
/* 0x08 */ 0x00, 0xF8, 0x00, 0x82, 0x00, 0x80, 0x83, 0xE0, 0x41, 0x10, 0x21, 0x04, 0x1B, 0x00, 0x03, 0x00, 0x01, 0x80, 0x00, 0xE0, 0x00, 0x4F, 0xE1, 0xC0, 0x0F, 0x02, 0x00, 0x03, 0x01, 0x00, 0x09, 0x88, 0x0C, 0x0C,
/* 0x09 */ 0x00, 0xF8, 0x00, 0x82, 0x00, 0x80, 0x83, 0xE0, 0x41, 0x10, 0x21, 0x04, 0x1B, 0x00, 0x03, 0x00, 0x01, 0x80, 0x00, 0xE0, 0x00, 0x4F, 0xE1, 0xC0, 0x0F, 0x00,
/* 0x0A */
/* 0x0B */ 0x1C, 0x1C, 0x31, 0xB1, 0x90, 0x50, 0x50, 0x10, 0x18, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x02, 0x80, 0x02, 0x40, 0x01, 0x10, 0x01, 0x04, 0x01, 0x01, 0x01, 0x00, 0x41, 0x00, 0x11, 0x00, 0x07, 0x00, 0x01, 0x00,
/* 0x0C */ 0x06, 0x00, 0x0A, 0x00, 0x12, 0x00, 0x32, 0x01, 0x84, 0x04, 0x10, 0x08, 0x98, 0x1C, 0x18, 0x40, 0x48, 0x82, 0x11, 0xF0, 0x74, 0x02, 0x18, 0x70, 0x2F, 0x9F, 0x80,
/* 0x0D */
/* 0x0E */ 0x01, 0x00, 0x05, 0x00, 0x0A, 0x00, 0x3E, 0x00, 0x82, 0x02, 0x82, 0x06, 0x04, 0x10, 0x04, 0x20, 0x08, 0x40, 0x10, 0xFF, 0x22, 0x00, 0x29, 0xFF, 0x3F, 0x8F, 0xDF, 0x9F, 0x01, 0xC0,
/* 0x0F */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x82, 0x36, 0x03, 0x60, 0x00, 0xCC, 0x19, 0xA4, 0x4B, 0x00, 0x06, 0x8E, 0x2B, 0x22, 0x66, 0x7C, 0xCC, 0x71, 0x98, 0x03, 0x00,
/* 0x10 */ 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x1E, 0x00, 0x54, 0x00, 0xA8, 0x01, 0x50, 0x02, 0xA0, 0x05, 0x20, 0x32, 0x61, 0xC4, 0x74, 0x49, 0x10, 0x6C, 0x00, 0xD8, 0x01, 0x10, 0x00,
/* 0x11 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x40, 0x29, 0x00, 0x31, 0x84, 0x63, 0x18, 0xC0, 0x00, 0x80, 0x15, 0x03, 0x7E, 0x02, 0xFA, 0x04, 0xE4, 0x18, 0x84, 0x00, 0x06, 0x0C, 0x03, 0xE0,
/* 0x12 */ 0x02, 0x08, 0x01, 0x08, 0x40, 0x10, 0xC0, 0x08, 0xC0, 0x60, 0x80, 0x28, 0x04, 0x12, 0x4C, 0x10, 0x80, 0x08, 0x23, 0x0E, 0x08, 0xC4, 0x82, 0x04, 0x20, 0x83, 0x09, 0x82, 0x47, 0x01, 0x1C, 0x01, 0x30, 0x00, 0xE0, 0x00, 0x00,
/* 0x13 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x00, 0x31, 0x08, 0x65, 0x28, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x3F, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x14 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x22, 0x29, 0x83, 0x30, 0x00, 0x65, 0x14, 0xD3, 0x4D, 0xBA, 0xEB, 0x38, 0xE6, 0x00, 0x0A, 0x00, 0x24, 0x38, 0x44, 0x01, 0x07, 0x1C, 0x01, 0xC0,
/* 0x15 */ 0x07, 0xC0, 0x30, 0x18, 0x80, 0x32, 0x00, 0xF8, 0x01, 0xF1, 0x09, 0xA5, 0x28, 0x40, 0x01, 0x80, 0x03, 0x00, 0x06, 0x3F, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x16 */ 0x0C, 0x00, 0xC0, 0x1C, 0x03, 0x80, 0xF8, 0xBB, 0x36, 0xC7, 0x99, 0xF3, 0xFE, 0x3F, 0xC3, 0xF0, 0x7E, 0x0E, 0xC1, 0x8E, 0xE0, 0x20,
/* 0x17 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x00, 0x10, 0x01, 0x20, 0x1D, 0x44, 0x42, 0x84, 0x85, 0x00, 0x86, 0x00, 0xC4, 0x00, 0x44, 0x7C, 0x44, 0x00, 0x06, 0x0C, 0x03, 0xE0,
/* 0x18 */ 0x01, 0xE0, 0x00, 0x84, 0x00, 0x40, 0x80, 0x20, 0x10, 0x08, 0x24, 0x02, 0x41, 0x00, 0x86, 0x03, 0x12, 0x03, 0xB4, 0x03, 0x52, 0x81, 0x23, 0x80, 0x70, 0xA0, 0x14, 0x28, 0x05, 0x0A, 0x01, 0x42, 0x80, 0x50,
/* 0x19 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x00, 0x33, 0x18, 0x60, 0x00, 0xDC, 0xE1, 0xB9, 0xC3, 0x7B, 0xC6, 0x63, 0x0A, 0x00, 0x24, 0xF0, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x1A */ 0xFF, 0xFC, 0x00, 0x63, 0xE3, 0x31, 0x99, 0x04, 0xC8, 0x66, 0x06, 0x30, 0x61, 0x82, 0x0C, 0x10, 0x60, 0x03, 0x04, 0x18, 0x00, 0xFF, 0xFC,
/* 0x1B */ 0x07, 0xF0, 0x06, 0x0C, 0x04, 0x01, 0x04, 0x00, 0x44, 0x22, 0x12, 0x2A, 0x89, 0x00, 0x04, 0x80, 0x02, 0x44, 0x11, 0x01, 0xF0, 0x04, 0x01, 0x0D, 0x01, 0x6A, 0x41, 0x2C, 0x00, 0x05, 0xC0, 0x0E, 0x18, 0x18,
/* 0x1C */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0xC0, 0x2A, 0x00, 0x33, 0x00, 0x66, 0x00, 0xCC, 0x39, 0x80, 0x83, 0x00, 0x06, 0x00, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x1D */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x70, 0x28, 0x00, 0x31, 0x80, 0x63, 0x18, 0xC0, 0x31, 0x80, 0x03, 0x00, 0x06, 0x60, 0x0D, 0x33, 0x12, 0x10, 0x48, 0x21, 0x23, 0x8C, 0x00,
/* 0x1E */ 0x03, 0x00, 0x07, 0x9E, 0x07, 0x00, 0x86, 0x00, 0x27, 0xC0, 0x0F, 0xC0, 0x07, 0x8C, 0x62, 0x06, 0x31, 0x20, 0x00, 0x90, 0x00, 0x48, 0x00, 0x24, 0x3E, 0x11, 0x00, 0x10, 0x40, 0x10, 0x18, 0x30, 0x03, 0xE0,
/* 0x1F */ 0x18, 0x02, 0x80, 0x4C, 0x16, 0x41, 0x24, 0x3C, 0x88, 0x6E, 0x65, 0xF2, 0x78, 0x46, 0x88, 0xCF, 0x18, 0x02, 0x80, 0x8C, 0x60, 0x70,
/* ' ' 0x20 */
/* '!' 0x21 */ 0xFF, 0xFF, 0xF0, 0xC0,
/* '"' 0x22 */ 0xDE, 0xF7, 0x20,
/* '#' 0x23 */ 0x09, 0x86, 0x41, 0x91, 0xFF, 0x13, 0x04, 0xC3, 0x20, 0xC8, 0xFF, 0x89, 0x82, 0x61, 0x90,
/* '$' 0x24 */ 0x10, 0x1F, 0x14, 0xDA, 0x3D, 0x1E, 0x83, 0x40, 0x78, 0x17, 0x08, 0xF4, 0x7A, 0x35, 0x33, 0xF0, 0x40, 0x20,
/* '%' 0x25 */ 0x38, 0x10, 0xEC, 0x20, 0xC6, 0x20, 0xC6, 0x40, 0xC6, 0x40, 0x6C, 0x80, 0x39, 0x00, 0x01, 0x3C, 0x02, 0x77, 0x02, 0x63, 0x04, 0x63, 0x04, 0x77, 0x08, 0x3C,
/* '&' 0x26 */ 0x0E, 0x0C, 0xC3, 0x30, 0xCC, 0x1E, 0x03, 0x03, 0xC1, 0x9B, 0xC2, 0xF0, 0xEC, 0x19, 0x8F, 0x3C, 0x40,
/* ''' 0x27 */ 0xFE,
/* '(' 0x28 */ 0x13, 0x26, 0x6C, 0xCC, 0xCC, 0xC4, 0x66, 0x23, 0x10,
/* ')' 0x29 */ 0x8C, 0x46, 0x63, 0x33, 0x33, 0x32, 0x66, 0x4C, 0x80,
/* '*' 0x2A */ 0x25, 0x7E, 0xA5, 0x00,
/* '+' 0x2B */ 0x30, 0xC3, 0x3F, 0x30, 0xC3, 0x0C,
/* ',' 0x2C */ 0xD6,
/* '-' 0x2D */ 0xF0,
/* '.' 0x2E */ 0xC0,
/* '/' 0x2F */ 0x08, 0x44, 0x21, 0x10, 0x84, 0x42, 0x11, 0x08, 0x00,
/* '0' 0x30 */ 0x3C, 0x66, 0x42, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x42, 0x66, 0x3C,
/* '1' 0x31 */ 0x11, 0x3F, 0x33, 0x33, 0x33, 0x33, 0x30,
/* '2' 0x32 */ 0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x1C, 0x1C, 0x1C, 0x18, 0x18, 0x10, 0x08, 0x07, 0xF8,
/* '3' 0x33 */ 0x3C, 0x66, 0xC3, 0xC3, 0x03, 0x06, 0x1C, 0x07, 0x03, 0xC3, 0xC3, 0x66, 0x3C,
/* '4' 0x34 */ 0x0C, 0x18, 0x71, 0x62, 0xC9, 0xA3, 0x46, 0xFE, 0x18, 0x30, 0x60, 0xC0,
/* '5' 0x35 */ 0x7F, 0x20, 0x10, 0x08, 0x08, 0x07, 0xF3, 0x8C, 0x03, 0x01, 0x80, 0xF0, 0x6C, 0x63, 0xE0,
/* '6' 0x36 */ 0x1E, 0x31, 0x98, 0x78, 0x0C, 0x06, 0xF3, 0x8D, 0x83, 0xC1, 0xE0, 0xD0, 0x6C, 0x63, 0xE0,
/* '7' 0x37 */ 0xFF, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x18, 0x18, 0x18, 0x10, 0x30, 0x30,
/* '8' 0x38 */ 0x3E, 0x31, 0xB0, 0x78, 0x3C, 0x1B, 0x18, 0xF8, 0xC6, 0xC1, 0xE0, 0xF0, 0x6C, 0x63, 0xE0,
/* '9' 0x39 */ 0x3C, 0x66, 0xC2, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0xC2, 0x66, 0x3C,
/* ':' 0x3A */ 0xC0, 0x00, 0x30,
/* ';' 0x3B */ 0xC0, 0x00, 0x00, 0x64, 0xA0,
/* '<' 0x3C */ 0x00, 0x81, 0xC7, 0x8E, 0x0C, 0x07, 0x80, 0x70, 0x0E, 0x01, 0x80,
/* '=' 0x3D */ 0xFF, 0x80, 0x00, 0x1F, 0xF0,
/* '>' 0x3E */ 0xE0, 0x1C, 0x03, 0x80, 0x30, 0x70, 0xE3, 0x81, 0x00,
/* '?' 0x3F */ 0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x18, 0x38, 0x18, 0x18, 0x0C, 0x00, 0x00, 0x01, 0x80,
/* '@' 0x40 */ 0x03, 0xF0, 0x06, 0x0E, 0x06, 0x01, 0x86, 0x00, 0x66, 0x1D, 0xBB, 0x31, 0xCF, 0x18, 0xC7, 0x98, 0x63, 0xCC, 0x31, 0xE6, 0x11, 0xB3, 0x99, 0xCC, 0xF7, 0x86, 0x00, 0x01, 0x80, 0x00, 0x70, 0x40, 0x0F, 0xE0,
/* 'A' 0x41 */ 0x06, 0x00, 0xF0, 0x0F, 0x00, 0x90, 0x19, 0x81, 0x98, 0x10, 0x83, 0x0C, 0x3F, 0xC2, 0x04, 0x60, 0x66, 0x06, 0xC0, 0x30,
/* 'B' 0x42 */ 0xFF, 0x18, 0x33, 0x03, 0x60, 0x6C, 0x0D, 0x83, 0x3F, 0xC6, 0x06, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x6F, 0xF8,
/* 'C' 0x43 */ 0x1F, 0x86, 0x19, 0x81, 0xA0, 0x3C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0x61, 0xF0,
/* 'D' 0x44 */ 0xFF, 0x18, 0x33, 0x03, 0x60, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x03, 0x60, 0xCF, 0xF0,
/* 'E' 0x45 */ 0xFF, 0xE0, 0x30, 0x18, 0x0C, 0x06, 0x03, 0xFD, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0F, 0xF8,
/* 'F' 0x46 */ 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
/* 'G' 0x47 */ 0x0F, 0x83, 0x0E, 0x60, 0x66, 0x03, 0xC0, 0x0C, 0x00, 0xC1, 0xFC, 0x03, 0xC0, 0x36, 0x03, 0x60, 0x73, 0x0F, 0x0F, 0x10,
/* 'H' 0x48 */ 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xFF, 0xFE, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x06,
/* 'I' 0x49 */ 0xFF, 0xFF, 0xFF, 0xC0,
/* 'J' 0x4A */ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x07, 0x8F, 0x1E, 0x27, 0x80,
/* 'K' 0x4B */ 0xC0, 0xF0, 0x6C, 0x33, 0x18, 0xCC, 0x37, 0x0F, 0xC3, 0x98, 0xC3, 0x30, 0xCC, 0x1B, 0x03, 0xC0, 0xC0,
/* 'L' 0x4C */ 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF,
/* 'M' 0x4D */ 0xE0, 0x3F, 0x01, 0xFC, 0x1F, 0xE0, 0xFD, 0x05, 0xEC, 0x6F, 0x63, 0x79, 0x13, 0xCD, 0x9E, 0x6C, 0xF1, 0x47, 0x8E, 0x3C, 0x71, 0x80,
/* 'N' 0x4E */ 0xE0, 0x7C, 0x0F, 0xC1, 0xE8, 0x3D, 0x87, 0x98, 0xF1, 0x1E, 0x33, 0xC3, 0x78, 0x6F, 0x07, 0xE0, 0x7C, 0x0E,
/* 'O' 0x4F */ 0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x0C, 0x60, 0xC0, 0xF8, 0x00,
/* 'P' 0x50 */ 0xFF, 0x30, 0x6C, 0x0F, 0x03, 0xC0, 0xF0, 0x6F, 0xF3, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x00,
/* 'Q' 0x51 */ 0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x6C, 0x60, 0xC0, 0xFB, 0x00, 0x08,
/* 'R' 0x52 */ 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x0C, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x70,
/* 'S' 0x53 */ 0x3F, 0x18, 0x6C, 0x0F, 0x03, 0xC0, 0x1E, 0x01, 0xF0, 0x0E, 0x00, 0xF0, 0x3C, 0x0D, 0x86, 0x3F, 0x00,
/* 'T' 0x54 */ 0xFF, 0x86, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0,
/* 'U' 0x55 */ 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xB0, 0x61, 0xF0,
/* 'V' 0x56 */ 0xC0, 0x6C, 0x0D, 0x81, 0x10, 0x63, 0x0C, 0x61, 0x04, 0x60, 0xCC, 0x19, 0x01, 0x60, 0x3C, 0x07, 0x00, 0x60,
/* 'W' 0x57 */ 0xC1, 0x81, 0x61, 0xC3, 0x61, 0xC3, 0x61, 0x43, 0x62, 0x62, 0x22, 0x66, 0x32, 0x26, 0x36, 0x26, 0x14, 0x34, 0x14, 0x34, 0x1C, 0x1C, 0x18, 0x1C, 0x08, 0x18,
/* 'X' 0x58 */ 0xC0, 0xD8, 0x66, 0x18, 0xCC, 0x1E, 0x07, 0x00, 0xC0, 0x78, 0x32, 0x0C, 0xC6, 0x1B, 0x07, 0xC0, 0xC0,
/* 'Y' 0x59 */ 0xC0, 0x36, 0x06, 0x30, 0xC3, 0x0C, 0x19, 0x81, 0xD8, 0x0F, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00,
/* 'Z' 0x5A */ 0xFF, 0xC0, 0x60, 0x30, 0x0C, 0x06, 0x03, 0x01, 0xC0, 0x60, 0x30, 0x18, 0x06, 0x03, 0x00, 0xFF, 0xC0,
/* '[' 0x5B */ 0xFB, 0x6D, 0xB6, 0xDB, 0x6D, 0xB6, 0xE0,
/* '\' 0x5C */ 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x80,
/* ']' 0x5D */ 0xED, 0xB6, 0xDB, 0x6D, 0xB6, 0xDB, 0xE0,
/* '^' 0x5E */ 0x30, 0x60, 0xA2, 0x44, 0xD8, 0xA1, 0x80,
/* '_' 0x5F */ 0xFF, 0xC0,
/* '`' 0x60 */ 0xC6, 0x30,
/* 'a' 0x61 */ 0x7E, 0x71, 0xB0, 0xC0, 0x60, 0xF3, 0xDB, 0x0D, 0x86, 0xC7, 0x3D, 0xC0,
/* 'b' 0x62 */ 0xC0, 0x60, 0x30, 0x1B, 0xCE, 0x36, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x7C, 0x6D, 0xE0,
/* 'c' 0x63 */ 0x3C, 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 'd' 0x64 */ 0x03, 0x03, 0x03, 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B,
/* 'e' 0x65 */ 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 'f' 0x66 */ 0x36, 0x6F, 0x66, 0x66, 0x66, 0x66, 0x60,
/* 'g' 0x67 */ 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0xC6, 0x7C,
/* 'h' 0x68 */ 0xC0, 0xC0, 0xC0, 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
/* 'i' 0x69 */ 0xC3, 0xFF, 0xFF, 0xC0,
/* 'j' 0x6A */ 0x30, 0x03, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xE0,
/* 'k' 0x6B */ 0xC0, 0xC0, 0xC0, 0xC2, 0xC4, 0xCC, 0xD8, 0xF8, 0xEC, 0xC4, 0xC6, 0xC3, 0xC3,
/* 'l' 0x6C */ 0xFF, 0xFF, 0xFF, 0xC0,
/* 'm' 0x6D */ 0xDE, 0xF7, 0x1C, 0xF0, 0xC7, 0x86, 0x3C, 0x31, 0xE1, 0x8F, 0x0C, 0x78, 0x63, 0xC3, 0x1E, 0x18, 0xC0,
/* 'n' 0x6E */ 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
/* 'o' 0x6F */ 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C,
/* 'p' 0x70 */ 0xDE, 0x71, 0xB0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xE3, 0x6F, 0x30, 0x18, 0x0C, 0x00,
/* 'q' 0x71 */ 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0x03,
/* 'r' 0x72 */ 0xDF, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x00,
/* 's' 0x73 */ 0x3E, 0xE3, 0xC0, 0xC0, 0xE0, 0x3C, 0x07, 0xC3, 0xE3, 0x7E,
/* 't' 0x74 */ 0x66, 0xF6, 0x66, 0x66, 0x66, 0x67,
/* 'u' 0x75 */ 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B,
/* 'v' 0x76 */ 0xC1, 0xA0, 0x98, 0xCC, 0x42, 0x21, 0xB0, 0xD0, 0x28, 0x1C, 0x0C, 0x00,
/* 'w' 0x77 */ 0xC6, 0x1E, 0x38, 0x91, 0xC4, 0xCA, 0x66, 0xD3, 0x16, 0xD0, 0xA6, 0x87, 0x1C, 0x38, 0xC0, 0xC6, 0x00,
/* 'x' 0x78 */ 0x87, 0x89, 0xB1, 0xC3, 0x07, 0x1E, 0x26, 0xC5, 0x0C,
/* 'y' 0x79 */ 0xC1, 0x43, 0x63, 0x62, 0x26, 0x36, 0x34, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x60,
/* 'z' 0x7A */ 0xFE, 0x0C, 0x30, 0xC1, 0x86, 0x18, 0x20, 0xC1, 0xFC,
/* '{' 0x7B */ 0x36, 0x66, 0x66, 0x6E, 0xCE, 0x66, 0x66, 0x66, 0x30,
/* '|' 0x7C */ 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
/* '}' 0x7D */ 0xC6, 0x66, 0x66, 0x67, 0x37, 0x66, 0x66, 0x66, 0xC0,
/* '~' 0x7E */ 0x61, 0x24, 0x38,
/* 0x7F */ 0xFF, 0xFC, 0x00, 0x63, 0xE3, 0x31, 0x99, 0x04, 0xC8, 0x66, 0x06, 0x30, 0x61, 0x83, 0x0C, 0x18, 0x60, 0x03, 0x06, 0x18, 0x00, 0xFF, 0xFC,
/* 0x80 */ 0x07, 0xC6, 0x13, 0x00, 0xC0, 0x60, 0x3F, 0xE6, 0x03, 0xFC, 0x60, 0x0C, 0x03, 0x00, 0x61, 0x07, 0xC0,
/* 0x81 */
/* 0x82 */ 0xDC,
/* 0x83 */
/* 0x84 */ 0xDA, 0x76,
/* 0x85 */ 0xCC, 0xC0,
/* 0x86 */ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
/* 0x87 */ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18,
/* 0x88 */
/* 0x89 */ 0x70, 0x80, 0x22, 0x20, 0x08, 0x90, 0x02, 0x24, 0x00, 0x72, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x10, 0x00, 0x09, 0xC7, 0x84, 0x8B, 0x31, 0x22, 0x84, 0x88, 0xB3, 0x21, 0xC7, 0x80,
/* 0x8A */ 0x1B, 0x03, 0x83, 0xF1, 0x86, 0xC0, 0xF0, 0x3C, 0x01, 0xE0, 0x1F, 0x00, 0xE0, 0x0F, 0x03, 0xC0, 0xD8, 0x63, 0xF0,
/* 0x8B */ 0x69,
/* 0x8C */ 0x06, 0x03, 0x03, 0xF1, 0x86, 0xC0, 0xF0, 0x3C, 0x01, 0xE0, 0x1F, 0x00, 0xE0, 0x0F, 0x03, 0xC0, 0xD8, 0x63, 0xF0,
/* 0x8D */ 0x33, 0x0F, 0x3F, 0xE1, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30,
/* 0x8E */ 0x1B, 0x03, 0x8F, 0xFC, 0x06, 0x03, 0x00, 0xC0, 0x60, 0x30, 0x1C, 0x06, 0x03, 0x01, 0x80, 0x60, 0x30, 0x0F, 0xFC,
/* 0x8F */ 0x0C, 0x06, 0x0F, 0xFC, 0x06, 0x03, 0x00, 0xC0, 0x60, 0x30, 0x1C, 0x06, 0x03, 0x01, 0x80, 0x60, 0x30, 0x0F, 0xFC,
/* 0x90 */
/* 0x91 */ 0x6B,
/* 0x92 */ 0xD6,
/* 0x93 */ 0x4C, 0xA5, 0xB0,
/* 0x94 */ 0xDA, 0x53, 0x20,
/* 0x95 */ 0x6F, 0xFF, 0x60,
/* 0x96 */ 0xFE,
/* 0x97 */ 0xFF, 0xFF,
/* 0x98 */
/* 0x99 */ 0xFC, 0xE1, 0xCC, 0x38, 0x73, 0x0E, 0x1C, 0xC3, 0x8F, 0x30, 0xD2, 0xCC, 0x34, 0xB3, 0x0D, 0x6C, 0xC3, 0x53, 0x30, 0xCC, 0xCC, 0x33, 0x30,
/* 0x9A */ 0x24, 0x3C, 0x18, 0x7E, 0xE3, 0xC0, 0xC0, 0x60, 0x3C, 0x07, 0xC3, 0xE3, 0x7E,
/* 0x9B */ 0x96,
/* 0x9C */ 0x0C, 0x18, 0x10, 0x3E, 0xE3, 0xC0, 0xC0, 0xE0, 0x3C, 0x07, 0xC3, 0xE3, 0x7E,
/* 0x9D */ 0x0D, 0xA7, 0x3C, 0x61, 0x86, 0x18, 0x61, 0x86, 0x18, 0x70,
/* 0x9E */ 0x48, 0xF0, 0xC7, 0xF0, 0x61, 0x86, 0x0C, 0x30, 0xC1, 0x06, 0x0F, 0xE0,
/* 0x9F */ 0x0C, 0x10, 0x47, 0xF0, 0x61, 0x86, 0x0C, 0x30, 0xC1, 0x06, 0x0F, 0xE0,
/* 0xA0 */
/* 0xA1 */ 0x8A, 0x9C,
/* 0xA2 */ 0x85, 0xE0,
/* 0xA3 */ 0x60, 0x30, 0x18, 0x0C, 0x86, 0xC3, 0xC1, 0xC1, 0xC0, 0xE0, 0x30, 0x18, 0x0C, 0x07, 0xF8,
/* 0xA4 */ 0xFF, 0xDF, 0x1E, 0x3E, 0xFF, 0xC0,
/* 0xA5 */ 0x06, 0x00, 0xF0, 0x0F, 0x01, 0x30, 0x13, 0x81, 0x38, 0x21, 0x82, 0x1C, 0x3F, 0xC6, 0x04, 0x60, 0x66, 0x06, 0xC0, 0x30, 0x06, 0x00, 0xC0, 0x0C, 0x00, 0x70,
/* 0xA6 */ 0xFF, 0xFC, 0x0F, 0xFF, 0xC0,
/* 0xA7 */ 0x0C, 0x09, 0x0C, 0xC6, 0x63, 0x81, 0xE3, 0x19, 0x87, 0xE1, 0xB8, 0xC6, 0x41, 0xC0, 0x73, 0x19, 0x8C, 0x66, 0x1E, 0x00,
/* 0xA8 */ 0xCC,
/* 0xA9 */ 0x0F, 0xC0, 0x61, 0x87, 0x03, 0x9B, 0xC6, 0xD9, 0x8F, 0x60, 0x3D, 0x00, 0xF4, 0x03, 0xD8, 0x0D, 0xE6, 0x67, 0xF3, 0x86, 0x18, 0x0F, 0xC0,
/* 0xAA */ 0x3F, 0x18, 0x6C, 0x0F, 0x03, 0xC0, 0x1E, 0x01, 0xF0, 0x0E, 0x00, 0xF0, 0x3C, 0x0D, 0x86, 0x3F, 0x02, 0x00, 0xE0, 0x18, 0x1C, 0x00,
/* 0xAB */ 0x22, 0xCF, 0x26, 0x46, 0x64, 0x40,
/* 0xAC */ 0xFF, 0x80, 0xC0, 0x60, 0x30, 0x18,
/* 0xAD */
/* 0xAE */ 0x0F, 0xC0, 0x61, 0x87, 0x03, 0x9F, 0xE6, 0xD0, 0x8F, 0x42, 0x3D, 0xF0, 0xF4, 0x23, 0xD0, 0x8D, 0xC2, 0x67, 0x0B, 0x86, 0x18, 0x0F, 0xC0,
/* 0xAF */ 0x0C, 0x00, 0x0F, 0xFC, 0x06, 0x03, 0x00, 0xC0, 0x60, 0x30, 0x1C, 0x06, 0x03, 0x01, 0x80, 0x60, 0x30, 0x0F, 0xFC,
/* 0xB0 */ 0x74, 0x63, 0x17, 0x00,
/* 0xB1 */ 0x0C, 0x06, 0x03, 0x07, 0xE0, 0xC0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x3F, 0xE0,
/* 0xB2 */ 0x6C, 0xC7,
/* 0xB3 */ 0x66, 0x66, 0x67, 0x6E, 0x66, 0x66, 0x60,
/* 0xB4 */ 0x36, 0xC0,
/* 0xB5 */ 0xC3, 0x61, 0xB0, 0xD8, 0x6C, 0x36, 0x1B, 0x0D, 0x86, 0xE7, 0x7D, 0xF0, 0x18, 0x0C, 0x00,
/* 0xB6 */ 0x3F, 0x7E, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0x72, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
/* 0xB7 */ 0xE0,
/* 0xB8 */ 0x21, 0xC7, 0xE0,
/* 0xB9 */ 0x7E, 0x38, 0xCC, 0x30, 0x0C, 0x0F, 0x1E, 0xCC, 0x33, 0x0C, 0xC7, 0x1E, 0xE0, 0x10, 0x0C, 0x03, 0x00, 0x70,
/* 0xBA */ 0x3E, 0xE3, 0xC0, 0xC0, 0xE0, 0x3C, 0x07, 0xC3, 0xC3, 0x7E, 0x10, 0x1C, 0x0C, 0x38,
/* 0xBB */ 0x89, 0x98, 0x99, 0x3C, 0xD1, 0x00,
/* 0xBC */ 0xC6, 0xC4, 0xC8, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF,
/* 0xBD */ 0x6F, 0x69, 0x00,
/* 0xBE */ 0xDE, 0xB9, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x00,
/* 0xBF */ 0x30, 0x03, 0xF8, 0x30, 0xC3, 0x06, 0x18, 0x60, 0x83, 0x07, 0xF0,
/* 0xC0 */ 0x06, 0x00, 0xC0, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x0C, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x70,
/* 0xC1 */ 0x06, 0x03, 0x00, 0x00, 0x30, 0x1E, 0x07, 0x81, 0x20, 0xCC, 0x33, 0x0F, 0xC6, 0x19, 0x86, 0x40, 0xB0, 0x30,
/* 0xC2 */ 0x0C, 0x04, 0x80, 0x00, 0x30, 0x1E, 0x07, 0x81, 0x20, 0xCC, 0x33, 0x0F, 0xC6, 0x19, 0x86, 0x40, 0xB0, 0x30,
/* 0xC3 */ 0x21, 0x07, 0x80, 0x00, 0x30, 0x1E, 0x07, 0x81, 0x20, 0xCC, 0x33, 0x0F, 0xC6, 0x19, 0x86, 0x40, 0xB0, 0x30,
/* 0xC4 */ 0x33, 0x00, 0x00, 0xC0, 0x78, 0x1E, 0x04, 0x83, 0x30, 0xCC, 0x33, 0x1F, 0xE6, 0x19, 0x02, 0xC0, 0xF0, 0x30,
/* 0xC5 */ 0x30, 0x60, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF,
/* 0xC6 */ 0x06, 0x01, 0x80, 0x00, 0x0F, 0xC3, 0x0C, 0xC0, 0xD0, 0x1E, 0x00, 0xC0, 0x18, 0x03, 0x01, 0xA0, 0x36, 0x0C, 0x61, 0x87, 0xC0,
/* 0xC7 */ 0x1F, 0x06, 0x19, 0x83, 0xA0, 0x3C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0xE1, 0xF0, 0x08, 0x01, 0xC0, 0x18, 0x0E, 0x00,
/* 0xC8 */ 0x19, 0x81, 0xE0, 0x00, 0x0F, 0xC3, 0x0C, 0xC0, 0xF0, 0x1E, 0x00, 0xC0, 0x18, 0x03, 0x01, 0xA0, 0x36, 0x0C, 0x61, 0x87, 0xC0,
/* 0xC9 */ 0x0C, 0x0C, 0x00, 0x1F, 0xFC, 0x06, 0x03, 0x01, 0x80, 0xFF, 0x60, 0x30, 0x18, 0x0C, 0x07, 0xFC,
/* 0xCA */ 0xFF, 0xD8, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x3F, 0xF6, 0x00, 0xC0, 0x18, 0x03, 0x00, 0x60, 0x0F, 0xFC, 0x01, 0x80, 0x60, 0x0C, 0x00, 0xE0,
/* 0xCB */ 0x33, 0x00, 0x3F, 0xF8, 0x0C, 0x06, 0x03, 0x01, 0xFE, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x07, 0xFC,
/* 0xCC */ 0x33, 0x0F, 0x00, 0x1F, 0xFC, 0x06, 0x03, 0x01, 0x80, 0xFF, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0xFE,
/* 0xCD */ 0x78, 0x36, 0xDB, 0x6D, 0xB6, 0xC0,
/* 0xCE */ 0x76, 0xC0, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18,
/* 0xCF */ 0x66, 0x0F, 0x00, 0x03, 0xF8, 0xC3, 0x30, 0x6C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC1, 0xB0, 0xEF, 0xE0,
/* 0xD0 */ 0x7F, 0x0C, 0x31, 0x83, 0x30, 0x36, 0x06, 0xC0, 0xFE, 0x1B, 0x03, 0x60, 0x6C, 0x0D, 0x83, 0x30, 0xE7, 0xF0,
/* 0xD1 */ 0x03, 0x01, 0x83, 0x81, 0xF0, 0x3F, 0x07, 0xA0, 0xF6, 0x1E, 0x63, 0xC4, 0x78, 0xCF, 0x0D, 0xE1, 0xBC, 0x1F, 0x81, 0xC0,
/* 0xD2 */ 0x19, 0x81, 0xE3, 0x81, 0xF0, 0x3F, 0x07, 0xA0, 0xF6, 0x1E, 0x63, 0xC4, 0x78, 0xCF, 0x0D, 0xE1, 0xBC, 0x1F, 0x81, 0xC0,
/* 0xD3 */ 0x03, 0x00, 0x60, 0x00, 0x00, 0xF0, 0x39, 0xC6, 0x06, 0x60, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x60, 0x63, 0x9C, 0x0F, 0x00,
/* 0xD4 */ 0x0F, 0x01, 0x98, 0x00, 0x00, 0xF0, 0x39, 0xC6, 0x06, 0x60, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x60, 0x63, 0x9C, 0x0F, 0x00,
/* 0xD5 */ 0x0D, 0x81, 0xB0, 0x00, 0x00, 0xF0, 0x39, 0xC6, 0x06, 0x60, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x60, 0x63, 0x9C, 0x0F, 0x00,
/* 0xD6 */ 0x19, 0x81, 0x98, 0x00, 0x00, 0xF0, 0x39, 0xC6, 0x06, 0x60, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x60, 0x63, 0x9C, 0x0F, 0x00,
/* 0xD7 */ 0x83, 0x89, 0xA1, 0x83, 0x89, 0xA1, 0x80,
/* 0xD8 */ 0x33, 0x01, 0xE0, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x0C, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x70,
/* 0xD9 */ 0x04, 0x01, 0x43, 0x11, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x36, 0x0C, 0x3E, 0x00,
/* 0xDA */ 0x06, 0x01, 0x83, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x36, 0x0C, 0x3E, 0x00,
/* 0xDB */ 0x0D, 0x83, 0x63, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x36, 0x0C, 0x3E, 0x00,
/* 0xDC */ 0x1B, 0x00, 0x03, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x36, 0x0C, 0x3E, 0x00,
/* 0xDD */ 0x03, 0x0C, 0x63, 0x60, 0x63, 0x0C, 0x30, 0xC1, 0x98, 0x1D, 0x80, 0xF0, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60,
/* 0xDE */ 0xFF, 0x86, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x40, 0x3C, 0x06, 0x1E, 0x00,
/* 0xDF */ 0x3C, 0x33, 0x30, 0xD8, 0x6C, 0x36, 0x33, 0x39, 0x86, 0xC1, 0xE0, 0xF0, 0x78, 0x6D, 0xE0,
/* 0xE0 */ 0x19, 0x89, 0xBE, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x00,
/* 0xE1 */ 0x0C, 0x04, 0x04, 0x0F, 0xCE, 0x36, 0x18, 0x0C, 0x1E, 0x7B, 0x61, 0xB0, 0xD8, 0xE7, 0xB8,
/* 0xE2 */ 0x10, 0x14, 0x1B, 0x0F, 0xCE, 0x36, 0x18, 0x0C, 0x1E, 0x7B, 0x61, 0xB0, 0xD8, 0xE7, 0xB8,
/* 0xE3 */ 0x66, 0x1E, 0x00, 0x0F, 0xCE, 0x36, 0x18, 0x0C, 0x1E, 0x7B, 0x61, 0xB0, 0xD8, 0xE7, 0xB8,
/* 0xE4 */ 0x66, 0x00, 0x1F, 0x9C, 0x6C, 0x30, 0x18, 0x3C, 0xF6, 0xC3, 0x61, 0xB1, 0xCF, 0x70,
/* 0xE5 */ 0x78, 0x36, 0xDB, 0x6D, 0xB6, 0xD8,
/* 0xE6 */ 0x0C, 0x08, 0x10, 0x3C, 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 0xE7 */ 0x3C, 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, 0x10, 0x1C, 0x0C, 0x38,
/* 0xE8 */ 0x44, 0x28, 0x38, 0x3C, 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 0xE9 */ 0x0C, 0x08, 0x18, 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 0xEA */ 0x3C, 0x62, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3E, 0x04, 0x0C, 0x0C, 0x06,
/* 0xEB */ 0x66, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 0xEC */ 0x64, 0x2C, 0x18, 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 0xED */ 0x7A, 0x6D, 0xB6, 0xDB, 0x6C,
/* 0xEE */ 0x69, 0x06, 0x66, 0x66, 0x66, 0x66, 0x60,
/* 0xEF */ 0x03, 0x30, 0x32, 0x03, 0x43, 0xB0, 0x67, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x06, 0x70, 0x3B, 0x00,
/* 0xF0 */ 0x03, 0x07, 0xC0, 0xC7, 0x66, 0x76, 0x1B, 0x0D, 0x86, 0xC3, 0x61, 0xB0, 0xCC, 0xE3, 0xB0,
/* 0xF1 */ 0x0C, 0x18, 0x00, 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
/* 0xF2 */ 0x66, 0x3C, 0x00, 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
/* 0xF3 */ 0x0C, 0x18, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C,
/* 0xF4 */ 0x18, 0x24, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C,
/* 0xF5 */ 0x36, 0x6C, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C,
/* 0xF6 */ 0x66, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C,
/* 0xF7 */ 0x18, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x00, 0x30,
/* 0xF8 */ 0xDB, 0x81, 0xBE, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x00,
/* 0xF9 */ 0x10, 0x28, 0x10, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B,
/* 0xFA */ 0x06, 0x0C, 0x18, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B,
/* 0xFB */ 0x36, 0x6C, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B,
/* 0xFC */ 0x66, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B,
/* 0xFD */ 0x06, 0x04, 0x08, 0xC1, 0x43, 0x63, 0x62, 0x26, 0x36, 0x34, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x60,
/* 0xFE */ 0x63, 0x3C, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xE2, 0x1C, 0x6F,
/* 0xFF */ 0xC0,
};
const GFXglyph FreeSans9pt_Win1250Glyphs[] PROGMEM = {
/* 0x01 */ { 0, 15, 15, 17, 1, -13 },
/* 0x02 */ { 29, 15, 15, 17, 1, -13 },
/* 0x03 */ { 58, 15, 16, 17, 1, -14 },
/* 0x04 */ { 88, 15, 16, 17, 1, -14 },
/* 0x05 */ { 118, 16, 15, 18, 1, -13 },
/* 0x06 */ { 148, 15, 15, 17, 1, -13 },
/* 0x07 */ { 177, 0, 0, 8, 0, 0 },
/* 0x08 */ { 177, 17, 16, 19, 1, -14 },
/* 0x09 */ { 211, 17, 12, 19, 1, -12 },
/* 0x0A */ { 237, 0, 0, 8, 0, 0 },
/* 0x0B */ { 237, 17, 16, 19, 1, -14 },
/* 0x0C */ { 271, 15, 14, 17, 1, -12 },
/* 0x0D */ { 298, 0, 0, 8, 0, 0 },
/* 0x0E */ { 298, 15, 16, 17, 1, -14 },
/* 0x0F */ { 328, 15, 15, 17, 1, -13 },
/* 0x10 */ { 357, 15, 15, 17, 1, -13 },
/* 0x11 */ { 386, 15, 16, 17, 1, -14 },
/* 0x12 */ { 416, 17, 17, 19, 1, -15 },
/* 0x13 */ { 453, 15, 16, 17, 1, -14 },
/* 0x14 */ { 483, 15, 16, 17, 1, -14 },
/* 0x15 */ { 513, 15, 16, 17, 1, -14 },
/* 0x16 */ { 543, 11, 16, 13, 1, -14 },
/* 0x17 */ { 565, 15, 16, 17, 1, -14 },
/* 0x18 */ { 595, 18, 15, 20, 1, -13 },
/* 0x19 */ { 629, 15, 16, 17, 1, -14 },
/* 0x1A */ { 659, 13, 14, 15, 1, -12 },
/* 0x1B */ { 682, 17, 16, 19, 1, -14 },
/* 0x1C */ { 716, 15, 16, 17, 1, -14 },
/* 0x1D */ { 746, 15, 15, 17, 1, -13 },
/* 0x1E */ { 775, 17, 16, 19, 1, -14 },
/* 0x1F */ { 809, 11, 16, 13, 1, -14 },
/* ' ' 0x20 */ { 831, 0, 0, 5, 0, 0 },
/* '!' 0x21 */ { 831, 2, 13, 6, 2, -12 },
/* '"' 0x22 */ { 835, 5, 4, 6, 1, -12 },
/* '#' 0x23 */ { 838, 10, 12, 10, 0, -11 },
/* '$' 0x24 */ { 853, 9, 16, 10, 1, -13 },
/* '%' 0x25 */ { 871, 16, 13, 16, 1, -12 },
/* '&' 0x26 */ { 897, 10, 13, 12, 1, -12 },
/* ''' 0x27 */ { 914, 2, 4, 4, 1, -12 },
/* '(' 0x28 */ { 915, 4, 17, 6, 1, -12 },
/* ')' 0x29 */ { 924, 4, 17, 6, 1, -12 },
/* '*' 0x2A */ { 933, 5, 5, 7, 1, -12 },
/* '+' 0x2B */ { 937, 6, 8, 11, 3, -7 },
/* ',' 0x2C */ { 943, 2, 4, 5, 2, 0 },
/* '-' 0x2D */ { 944, 4, 1, 6, 1, -4 },
/* '.' 0x2E */ { 945, 2, 1, 5, 1, 0 },
/* '/' 0x2F */ { 946, 5, 13, 5, 0, -12 },
/* '0' 0x30 */ { 955, 8, 13, 10, 1, -12 },
/* '1' 0x31 */ { 968, 4, 13, 10, 3, -12 },
/* '2' 0x32 */ { 975, 9, 13, 10, 1, -12 },
/* '3' 0x33 */ { 990, 8, 13, 10, 1, -12 },
/* '4' 0x34 */ { 1003, 7, 13, 10, 2, -12 },
/* '5' 0x35 */ { 1015, 9, 13, 10, 1, -12 },
/* '6' 0x36 */ { 1030, 9, 13, 10, 1, -12 },
/* '7' 0x37 */ { 1045, 8, 13, 10, 0, -12 },
/* '8' 0x38 */ { 1058, 9, 13, 10, 1, -12 },
/* '9' 0x39 */ { 1073, 8, 13, 10, 1, -12 },
/* ':' 0x3A */ { 1086, 2, 10, 5, 1, -9 },
/* ';' 0x3B */ { 1089, 3, 12, 5, 1, -8 },
/* '<' 0x3C */ { 1094, 9, 9, 11, 1, -8 },
/* '=' 0x3D */ { 1105, 9, 4, 11, 1, -5 },
/* '>' 0x3E */ { 1110, 9, 8, 11, 1, -7 },
/* '?' 0x3F */ { 1119, 9, 13, 10, 1, -12 },
/* '@' 0x40 */ { 1134, 17, 16, 18, 1, -12 },
/* 'A' 0x41 */ { 1168, 12, 13, 12, 0, -12 },
/* 'B' 0x42 */ { 1188, 11, 13, 12, 1, -12 },
/* 'C' 0x43 */ { 1206, 11, 13, 13, 1, -12 },
/* 'D' 0x44 */ { 1224, 11, 13, 13, 1, -12 },
/* 'E' 0x45 */ { 1242, 9, 13, 11, 1, -12 },
/* 'F' 0x46 */ { 1257, 8, 13, 11, 1, -12 },
/* 'G' 0x47 */ { 1270, 12, 13, 14, 1, -12 },
/* 'H' 0x48 */ { 1290, 11, 13, 13, 1, -12 },
/* 'I' 0x49 */ { 1308, 2, 13, 5, 2, -12 },
/* 'J' 0x4A */ { 1312, 7, 13, 10, 1, -12 },
/* 'K' 0x4B */ { 1324, 10, 13, 12, 1, -12 },
/* 'L' 0x4C */ { 1341, 8, 13, 10, 1, -12 },
/* 'M' 0x4D */ { 1354, 13, 13, 15, 1, -12 },
/* 'N' 0x4E */ { 1376, 11, 13, 13, 1, -12 },
/* 'O' 0x4F */ { 1394, 13, 13, 14, 1, -12 },
/* 'P' 0x50 */ { 1416, 10, 13, 12, 1, -12 },
/* 'Q' 0x51 */ { 1433, 13, 14, 14, 1, -12 },
/* 'R' 0x52 */ { 1456, 12, 13, 13, 1, -12 },
/* 'S' 0x53 */ { 1476, 10, 13, 12, 1, -12 },
/* 'T' 0x54 */ { 1493, 9, 13, 11, 1, -12 },
/* 'U' 0x55 */ { 1508, 11, 13, 13, 1, -12 },
/* 'V' 0x56 */ { 1526, 11, 13, 11, 0, -12 },
/* 'W' 0x57 */ { 1544, 16, 13, 17, 0, -12 },
/* 'X' 0x58 */ { 1570, 10, 13, 12, 1, -12 },
/* 'Y' 0x59 */ { 1587, 12, 13, 12, 0, -12 },
/* 'Z' 0x5A */ { 1607, 10, 13, 11, 1, -12 },
/* '[' 0x5B */ { 1624, 3, 17, 5, 1, -12 },
/* '\' 0x5C */ { 1631, 5, 13, 5, 0, -12 },
/* ']' 0x5D */ { 1640, 3, 17, 5, 0, -12 },
/* '^' 0x5E */ { 1647, 7, 7, 8, 1, -12 },
/* '_' 0x5F */ { 1654, 10, 1, 10, 0, 3 },
/* '`' 0x60 */ { 1656, 4, 3, 5, 0, -12 },
/* 'a' 0x61 */ { 1658, 9, 10, 10, 1, -9 },
/* 'b' 0x62 */ { 1670, 9, 13, 10, 1, -12 },
/* 'c' 0x63 */ { 1685, 8, 10, 9, 1, -9 },
/* 'd' 0x64 */ { 1695, 8, 13, 10, 1, -12 },
/* 'e' 0x65 */ { 1708, 8, 10, 10, 1, -9 },
/* 'f' 0x66 */ { 1718, 4, 13, 5, 1, -12 },
/* 'g' 0x67 */ { 1725, 8, 14, 10, 1, -9 },
/* 'h' 0x68 */ { 1739, 8, 13, 10, 1, -12 },
/* 'i' 0x69 */ { 1752, 2, 13, 4, 1, -12 },
/* 'j' 0x6A */ { 1756, 4, 17, 4, 0, -12 },
/* 'k' 0x6B */ { 1765, 8, 13, 9, 1, -12 },
/* 'l' 0x6C */ { 1778, 2, 13, 4, 1, -12 },
/* 'm' 0x6D */ { 1782, 13, 10, 15, 1, -9 },
/* 'n' 0x6E */ { 1799, 8, 10, 10, 1, -9 },
/* 'o' 0x6F */ { 1809, 8, 10, 10, 1, -9 },
/* 'p' 0x70 */ { 1819, 9, 13, 10, 1, -9 },
/* 'q' 0x71 */ { 1834, 8, 13, 10, 1, -9 },
/* 'r' 0x72 */ { 1847, 5, 10, 6, 1, -9 },
/* 's' 0x73 */ { 1854, 8, 10, 9, 1, -9 },
/* 't' 0x74 */ { 1864, 4, 12, 5, 1, -11 },
/* 'u' 0x75 */ { 1870, 8, 10, 10, 1, -9 },
/* 'v' 0x76 */ { 1880, 9, 10, 9, 0, -9 },
/* 'w' 0x77 */ { 1892, 13, 10, 13, 0, -9 },
/* 'x' 0x78 */ { 1909, 7, 10, 9, 1, -9 },
/* 'y' 0x79 */ { 1918, 8, 14, 9, 0, -9 },
/* 'z' 0x7A */ { 1932, 7, 10, 9, 1, -9 },
/* '{' 0x7B */ { 1941, 4, 17, 6, 1, -12 },
/* '|' 0x7C */ { 1950, 2, 17, 4, 2, -12 },
/* '}' 0x7D */ { 1955, 4, 17, 6, 1, -12 },
/* '~' 0x7E */ { 1964, 7, 3, 9, 1, -7 },
/* 0x7F */ { 1967, 13, 14, 15, 1, -12 },
/* 0x80 */ { 1990, 10, 13, 12, 1, -12 },
/* 0x81 */ { 2007, 0, 0, 0, 0, 0 },
/* 0x82 */ { 2007, 2, 3, 5, 1, 0 },
/* 0x83 */ { 2008, 0, 0, 0, 0, 0 },
/* 0x84 */ { 2008, 5, 3, 7, 1, 0 },
/* 0x85 */ { 2010, 10, 1, 12, 1, 0 },
/* 0x86 */ { 2012, 8, 16, 10, 1, -12 },
/* 0x87 */ { 2028, 8, 16, 10, 1, -12 },
/* 0x88 */ { 2044, 0, 0, 0, 0, 0 },
/* 0x89 */ { 2044, 18, 13, 18, 0, -12 },
/* 0x8A */ { 2074, 10, 15, 12, 1, -14 },
/* 0x8B */ { 2093, 2, 4, 4, 1, -6 },
/* 0x8C */ { 2094, 10, 15, 12, 1, -14 },
/* 0x8D */ { 2113, 9, 15, 11, 1, -14 },
/* 0x8E */ { 2130, 10, 15, 11, 1, -14 },
/* 0x8F */ { 2149, 10, 15, 11, 1, -14 },
/* 0x90 */ { 2168, 0, 0, 0, 0, 0 },
/* 0x91 */ { 2168, 2, 4, 4, 2, -12 },
/* 0x92 */ { 2169, 2, 4, 4, 1, -12 },
/* 0x93 */ { 2170, 5, 4, 7, 2, -12 },
/* 0x94 */ { 2173, 5, 4, 7, 1, -12 },
/* 0x95 */ { 2176, 4, 5, 7, 1, -8 },
/* 0x96 */ { 2179, 7, 1, 9, 1, -4 },
/* 0x97 */ { 2180, 16, 1, 18, 1, -4 },
/* 0x98 */ { 2182, 0, 0, 0, 0, 0 },
/* 0x99 */ { 2182, 18, 10, 18, 1, -13 },
/* 0x9A */ { 2205, 8, 13, 9, 1, -12 },
/* 0x9B */ { 2218, 2, 4, 5, 2, -6 },
/* 0x9C */ { 2219, 8, 13, 9, 1, -12 },
/* 0x9D */ { 2232, 6, 13, 8, 1, -12 },
/* 0x9E */ { 2242, 7, 13, 9, 1, -12 },
/* 0x9F */ { 2254, 7, 13, 9, 1, -12 },
/* 0xA0 */ { 2266, 0, 0, 5, 0, 0 },
/* 0xA1 */ { 2266, 5, 3, 6, 0, -12 },
/* 0xA2 */ { 2268, 6, 2, 6, 0, -12 },
/* 0xA3 */ { 2270, 9, 13, 11, 1, -12 },
/* 0xA4 */ { 2285, 7, 6, 10, 2, -8 },
/* 0xA5 */ { 2291, 12, 17, 12, 1, -12 },
/* 0xA6 */ { 2317, 2, 17, 5, 2, -12 },
/* 0xA7 */ { 2322, 9, 17, 10, 1, -12 },
/* 0xA8 */ { 2342, 6, 1, 6, 0, -11 },
/* 0xA9 */ { 2343, 14, 13, 14, 1, -12 },
/* 0xAA */ { 2366, 10, 17, 12, 1, -12 },
/* 0xAB */ { 2388, 7, 6, 9, 1, -7 },
/* 0xAC */ { 2394, 9, 5, 11, 2, -5 },
/* 0xAD */ { 2400, 0, 0, 0, 0, 0 },
/* 0xAE */ { 2400, 14, 13, 14, 1, -12 },
/* 0xAF */ { 2423, 10, 15, 11, 1, -14 },
/* 0xB0 */ { 2442, 5, 5, 11, 3, -11 },
/* 0xB1 */ { 2446, 9, 11, 11, 1, -10 },
/* 0xB2 */ { 2459, 4, 4, 6, 1, 1 },
/* 0xB3 */ { 2461, 4, 13, 5, 1, -12 },
/* 0xB4 */ { 2468, 4, 3, 6, 2, -12 },
/* 0xB5 */ { 2470, 9, 13, 10, 1, -9 },
/* 0xB6 */ { 2485, 8, 16, 10, 2, -12 },
/* 0xB7 */ { 2501, 3, 1, 5, 1, -4 },
/* 0xB8 */ { 2502, 5, 4, 6, 1, 1 },
/* 0xB9 */ { 2505, 10, 14, 10, 1, -9 },
/* 0xBA */ { 2523, 8, 14, 9, 1, -9 },
/* 0xBB */ { 2537, 7, 6, 9, 1, -7 },
/* 0xBC */ { 2543, 8, 13, 10, 1, -12 },
/* 0xBD */ { 2556, 6, 3, 6, 0, -12 },
/* 0xBE */ { 2559, 5, 13, 7, 1, -12 },
/* 0xBF */ { 2568, 7, 12, 9, 1, -11 },
/* 0xC0 */ { 2579, 12, 15, 13, 1, -14 },
/* 0xC1 */ { 2602, 10, 14, 12, 1, -13 },
/* 0xC2 */ { 2620, 10, 14, 12, 1, -13 },
/* 0xC3 */ { 2638, 10, 14, 12, 1, -13 },
/* 0xC4 */ { 2656, 10, 14, 12, 1, -13 },
/* 0xC5 */ { 2674, 8, 14, 10, 1, -13 },
/* 0xC6 */ { 2688, 11, 15, 13, 1, -14 },
/* 0xC7 */ { 2709, 11, 17, 13, 1, -12 },
/* 0xC8 */ { 2733, 11, 15, 13, 1, -14 },
/* 0xC9 */ { 2754, 9, 14, 11, 1, -13 },
/* 0xCA */ { 2770, 11, 17, 12, 1, -12 },
/* 0xCB */ { 2794, 9, 14, 11, 1, -13 },
/* 0xCC */ { 2810, 9, 15, 11, 1, -14 },
/* 0xCD */ { 2827, 3, 14, 5, 1, -13 },
/* 0xCE */ { 2833, 5, 14, 5, 0, -13 },
/* 0xCF */ { 2842, 10, 15, 13, 2, -14 },
/* 0xD0 */ { 2861, 11, 13, 13, 1, -12 },
/* 0xD1 */ { 2879, 11, 14, 13, 1, -13 },
/* 0xD2 */ { 2899, 11, 14, 13, 1, -13 },
/* 0xD3 */ { 2919, 12, 15, 13, 1, -14 },
/* 0xD4 */ { 2942, 12, 15, 13, 1, -14 },
/* 0xD5 */ { 2965, 12, 15, 13, 1, -14 },
/* 0xD6 */ { 2988, 12, 15, 13, 1, -14 },
/* 0xD7 */ { 3011, 7, 7, 11, 2, -7 },
/* 0xD8 */ { 3018, 12, 15, 13, 1, -14 },
/* 0xD9 */ { 3041, 11, 14, 13, 1, -13 },
/* 0xDA */ { 3061, 11, 14, 13, 1, -13 },
/* 0xDB */ { 3081, 11, 14, 13, 1, -13 },
/* 0xDC */ { 3101, 11, 14, 13, 1, -13 },
/* 0xDD */ { 3121, 12, 14, 12, 0, -13 },
/* 0xDE */ { 3142, 9, 17, 11, 1, -12 },
/* 0xDF */ { 3162, 9, 13, 11, 1, -12 },
/* 0xE0 */ { 3177, 5, 13, 6, 1, -12 },
/* 0xE1 */ { 3186, 9, 13, 10, 1, -12 },
/* 0xE2 */ { 3201, 9, 13, 10, 1, -12 },
/* 0xE3 */ { 3216, 9, 13, 10, 1, -12 },
/* 0xE4 */ { 3231, 9, 12, 10, 1, -11 },
/* 0xE5 */ { 3245, 3, 15, 4, 0, -14 },
/* 0xE6 */ { 3251, 8, 13, 9, 1, -12 },
/* 0xE7 */ { 3264, 8, 14, 9, 1, -9 },
/* 0xE8 */ { 3278, 8, 13, 9, 1, -12 },
/* 0xE9 */ { 3291, 8, 13, 10, 1, -12 },
/* 0xEA */ { 3304, 8, 14, 10, 1, -9 },
/* 0xEB */ { 3318, 8, 12, 10, 1, -11 },
/* 0xEC */ { 3330, 8, 13, 10, 1, -12 },
/* 0xED */ { 3343, 3, 13, 4, 1, -12 },
/* 0xEE */ { 3348, 4, 13, 5, 0, -12 },
/* 0xEF */ { 3355, 12, 13, 12, 1, -12 },
/* 0xF0 */ { 3375, 9, 13, 10, 1, -12 },
/* 0xF1 */ { 3390, 8, 13, 10, 1, -12 },
/* 0xF2 */ { 3403, 8, 13, 10, 1, -12 },
/* 0xF3 */ { 3416, 8, 13, 10, 1, -12 },
/* 0xF4 */ { 3429, 8, 13, 10, 1, -12 },
/* 0xF5 */ { 3442, 8, 13, 10, 1, -12 },
/* 0xF6 */ { 3455, 8, 12, 10, 1, -11 },
/* 0xF7 */ { 3467, 9, 8, 11, 1, -7 },
/* 0xF8 */ { 3476, 5, 13, 6, 1, -12 },
/* 0xF9 */ { 3485, 8, 13, 10, 1, -12 },
/* 0xFA */ { 3498, 8, 13, 10, 1, -12 },
/* 0xFB */ { 3511, 8, 13, 10, 1, -12 },
/* 0xFC */ { 3524, 8, 12, 10, 1, -11 },
/* 0xFD */ { 3536, 8, 17, 9, 0, -12 },
/* 0xFE */ { 3553, 5, 16, 5, 1, -11 },
/* 0xFF */ { 3563, 2, 1, 6, 2, -11 },
};
const GFXfont FreeSans9pt_Win1250 PROGMEM = {
(uint8_t*)FreeSans9pt_Win1250Bitmaps,
(GFXglyph*)FreeSans9pt_Win1250Glyphs,
0x01, 0xFF, 21
};
@@ -0,0 +1,527 @@
// trunk-ignore-all(clang-format)
#pragma once
/* PROPERTIES
FONT_NAME FreeSans9pt_Win1251
*/
const uint8_t FreeSans9pt_Win1251Bitmaps[] PROGMEM = {
/* 0x01 */ 0x07, 0x00, 0x0A, 0x00, 0x24, 0x00, 0x48, 0x01, 0x10, 0x04, 0x40, 0x10, 0xFF, 0x20, 0x02, 0x81, 0xFD, 0x00, 0x06, 0x07, 0xF4, 0x08, 0x24, 0x0F, 0x88, 0x11, 0x0F, 0xDC, 0x00,
/* 0x02 */ 0x3F, 0x70, 0x81, 0x11, 0x03, 0xE4, 0x08, 0x28, 0x1F, 0xD0, 0x00, 0x60, 0x7F, 0x20, 0x02, 0x43, 0xFC, 0x44, 0x00, 0x44, 0x00, 0x48, 0x00, 0x90, 0x00, 0xA0, 0x01, 0xC0, 0x00,
/* 0x03 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x00, 0x31, 0x8C, 0x63, 0x18, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x20, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x04 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x82, 0x30, 0x88, 0x62, 0x08, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x3F, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x05 */ 0x0B, 0x10, 0x14, 0xA8, 0x12, 0x50, 0x29, 0x42, 0x24, 0xA5, 0x32, 0x95, 0x5A, 0x09, 0x48, 0x09, 0x24, 0x01, 0x10, 0x01, 0x48, 0x02, 0xA4, 0x02, 0x42, 0x04, 0x01, 0x98, 0x00, 0x60,
/* 0x06 */ 0x00, 0x80, 0x22, 0x80, 0x65, 0x00, 0xBE, 0xE1, 0x82, 0x4E, 0x03, 0x24, 0x04, 0x28, 0x06, 0x30, 0x12, 0x20, 0x3C, 0xA0, 0xC3, 0xFE, 0x80, 0x4D, 0x00, 0xA6, 0x01, 0x80, 0x00,
/* 0x07 */
/* 0x08 */ 0x00, 0xF8, 0x00, 0x82, 0x00, 0x80, 0x83, 0xE0, 0x41, 0x10, 0x21, 0x04, 0x1B, 0x00, 0x03, 0x00, 0x01, 0x80, 0x00, 0xE0, 0x00, 0x4F, 0xE1, 0xC0, 0x0F, 0x02, 0x00, 0x03, 0x01, 0x00, 0x09, 0x88, 0x0C, 0x0C,
/* 0x09 */ 0x00, 0xF8, 0x00, 0x82, 0x00, 0x80, 0x83, 0xE0, 0x41, 0x10, 0x21, 0x04, 0x1B, 0x00, 0x03, 0x00, 0x01, 0x80, 0x00, 0xE0, 0x00, 0x4F, 0xE1, 0xC0, 0x0F, 0x00,
/* 0x0A */
/* 0x0B */ 0x1C, 0x1C, 0x31, 0xB1, 0x90, 0x50, 0x50, 0x10, 0x18, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x02, 0x80, 0x02, 0x40, 0x01, 0x10, 0x01, 0x04, 0x01, 0x01, 0x01, 0x00, 0x41, 0x00, 0x11, 0x00, 0x07, 0x00, 0x01, 0x00,
/* 0x0C */ 0x06, 0x00, 0x0A, 0x00, 0x12, 0x00, 0x32, 0x01, 0x84, 0x04, 0x10, 0x08, 0x98, 0x1C, 0x18, 0x40, 0x48, 0x82, 0x11, 0xF0, 0x74, 0x02, 0x18, 0x70, 0x2F, 0x9F, 0x80,
/* 0x0D */
/* 0x0E */ 0x01, 0x00, 0x05, 0x00, 0x0A, 0x00, 0x3E, 0x00, 0x82, 0x02, 0x82, 0x06, 0x04, 0x10, 0x04, 0x20, 0x08, 0x40, 0x10, 0xFF, 0x22, 0x00, 0x29, 0xFF, 0x3F, 0x8F, 0xDF, 0x9F, 0x01, 0xC0,
/* 0x0F */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x82, 0x36, 0x03, 0x60, 0x00, 0xCC, 0x19, 0xA4, 0x4B, 0x00, 0x06, 0x8E, 0x2B, 0x22, 0x66, 0x7C, 0xCC, 0x71, 0x98, 0x03, 0x00,
/* 0x10 */ 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x1E, 0x00, 0x54, 0x00, 0xA8, 0x01, 0x50, 0x02, 0xA0, 0x05, 0x20, 0x32, 0x61, 0xC4, 0x74, 0x49, 0x10, 0x6C, 0x00, 0xD8, 0x01, 0x10, 0x00,
/* 0x11 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x40, 0x29, 0x00, 0x31, 0x84, 0x63, 0x18, 0xC0, 0x00, 0x80, 0x15, 0x03, 0x7E, 0x02, 0xFA, 0x04, 0xE4, 0x18, 0x84, 0x00, 0x06, 0x0C, 0x03, 0xE0,
/* 0x12 */ 0x02, 0x08, 0x01, 0x08, 0x40, 0x10, 0xC0, 0x08, 0xC0, 0x60, 0x80, 0x28, 0x04, 0x12, 0x4C, 0x10, 0x80, 0x08, 0x23, 0x0E, 0x08, 0xC4, 0x82, 0x04, 0x20, 0x83, 0x09, 0x82, 0x47, 0x01, 0x1C, 0x01, 0x30, 0x00, 0xE0, 0x00, 0x00,
/* 0x13 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x00, 0x31, 0x08, 0x65, 0x28, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x3F, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x14 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x22, 0x29, 0x83, 0x30, 0x00, 0x65, 0x14, 0xD3, 0x4D, 0xBA, 0xEB, 0x38, 0xE6, 0x00, 0x0A, 0x00, 0x24, 0x38, 0x44, 0x01, 0x07, 0x1C, 0x01, 0xC0,
/* 0x15 */ 0x07, 0xC0, 0x30, 0x18, 0x80, 0x32, 0x00, 0xF8, 0x01, 0xF1, 0x09, 0xA5, 0x28, 0x40, 0x01, 0x80, 0x03, 0x00, 0x06, 0x3F, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x16 */ 0x0C, 0x00, 0xC0, 0x1C, 0x03, 0x80, 0xF8, 0xBB, 0x36, 0xC7, 0x99, 0xF3, 0xFE, 0x3F, 0xC3, 0xF0, 0x7E, 0x0E, 0xC1, 0x8E, 0xE0, 0x20,
/* 0x17 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x00, 0x10, 0x01, 0x20, 0x1D, 0x44, 0x42, 0x84, 0x85, 0x00, 0x86, 0x00, 0xC4, 0x00, 0x44, 0x7C, 0x44, 0x00, 0x06, 0x0C, 0x03, 0xE0,
/* 0x18 */ 0x01, 0xE0, 0x00, 0x84, 0x00, 0x40, 0x80, 0x20, 0x10, 0x08, 0x24, 0x02, 0x41, 0x00, 0x86, 0x03, 0x12, 0x03, 0xB4, 0x03, 0x52, 0x81, 0x23, 0x80, 0x70, 0xA0, 0x14, 0x28, 0x05, 0x0A, 0x01, 0x42, 0x80, 0x50,
/* 0x19 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x00, 0x33, 0x18, 0x60, 0x00, 0xDC, 0xE1, 0xB9, 0xC3, 0x7B, 0xC6, 0x63, 0x0A, 0x00, 0x24, 0xF0, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x1A */ 0xFF, 0xFC, 0x00, 0x63, 0xE3, 0x31, 0x99, 0x04, 0xC8, 0x66, 0x06, 0x30, 0x61, 0x82, 0x0C, 0x10, 0x60, 0x03, 0x04, 0x18, 0x00, 0xFF, 0xFC,
/* 0x1B */ 0x07, 0xF0, 0x06, 0x0C, 0x04, 0x01, 0x04, 0x00, 0x44, 0x22, 0x12, 0x2A, 0x89, 0x00, 0x04, 0x80, 0x02, 0x44, 0x11, 0x01, 0xF0, 0x04, 0x01, 0x0D, 0x01, 0x6A, 0x41, 0x2C, 0x00, 0x05, 0xC0, 0x0E, 0x18, 0x18,
/* 0x1C */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0xC0, 0x2A, 0x00, 0x33, 0x00, 0x66, 0x00, 0xCC, 0x39, 0x80, 0x83, 0x00, 0x06, 0x00, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x1D */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x70, 0x28, 0x00, 0x31, 0x80, 0x63, 0x18, 0xC0, 0x31, 0x80, 0x03, 0x00, 0x06, 0x60, 0x0D, 0x33, 0x12, 0x10, 0x48, 0x21, 0x23, 0x8C, 0x00,
/* 0x1E */ 0x03, 0x00, 0x07, 0x9E, 0x07, 0x00, 0x86, 0x00, 0x27, 0xC0, 0x0F, 0xC0, 0x07, 0x8C, 0x62, 0x06, 0x31, 0x20, 0x00, 0x90, 0x00, 0x48, 0x00, 0x24, 0x3E, 0x11, 0x00, 0x10, 0x40, 0x10, 0x18, 0x30, 0x03, 0xE0,
/* 0x1F */ 0x18, 0x02, 0x80, 0x4C, 0x16, 0x41, 0x24, 0x3C, 0x88, 0x6E, 0x65, 0xF2, 0x78, 0x46, 0x88, 0xCF, 0x18, 0x02, 0x80, 0x8C, 0x60, 0x70,
/* ' ' 0x20 */
/* '!' 0x21 */ 0xFF, 0xFF, 0xF0, 0xC0,
/* '"' 0x22 */ 0xDE, 0xF7, 0x20,
/* '#' 0x23 */ 0x09, 0x86, 0x41, 0x91, 0xFF, 0x13, 0x04, 0xC3, 0x20, 0xC8, 0xFF, 0x89, 0x82, 0x61, 0x90,
/* '$' 0x24 */ 0x10, 0x1F, 0x14, 0xDA, 0x3D, 0x1E, 0x83, 0x40, 0x78, 0x17, 0x08, 0xF4, 0x7A, 0x35, 0x33, 0xF0, 0x40, 0x20,
/* '%' 0x25 */ 0x38, 0x10, 0xEC, 0x20, 0xC6, 0x20, 0xC6, 0x40, 0xC6, 0x40, 0x6C, 0x80, 0x39, 0x00, 0x01, 0x3C, 0x02, 0x77, 0x02, 0x63, 0x04, 0x63, 0x04, 0x77, 0x08, 0x3C,
/* '&' 0x26 */ 0x0E, 0x0C, 0xC3, 0x30, 0xCC, 0x1E, 0x03, 0x03, 0xC1, 0x9B, 0xC2, 0xF0, 0xEC, 0x19, 0x8F, 0x3C, 0x40,
/* ''' 0x27 */ 0xFE,
/* '(' 0x28 */ 0x13, 0x26, 0x6C, 0xCC, 0xCC, 0xC4, 0x66, 0x23, 0x10,
/* ')' 0x29 */ 0x8C, 0x46, 0x63, 0x33, 0x33, 0x32, 0x66, 0x4C, 0x80,
/* '*' 0x2A */ 0x25, 0x7E, 0xA5, 0x00,
/* '+' 0x2B */ 0x30, 0xC3, 0x3F, 0x30, 0xC3, 0x0C,
/* ',' 0x2C */ 0xD6,
/* '-' 0x2D */ 0xF0,
/* '.' 0x2E */ 0xC0,
/* '/' 0x2F */ 0x08, 0x44, 0x21, 0x10, 0x84, 0x42, 0x11, 0x08, 0x00,
/* '0' 0x30 */ 0x3C, 0x66, 0x42, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x42, 0x66, 0x3C,
/* '1' 0x31 */ 0x11, 0x3F, 0x33, 0x33, 0x33, 0x33, 0x30,
/* '2' 0x32 */ 0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x1C, 0x1C, 0x1C, 0x18, 0x18, 0x10, 0x08, 0x07, 0xF8,
/* '3' 0x33 */ 0x3C, 0x66, 0xC3, 0xC3, 0x03, 0x06, 0x1C, 0x07, 0x03, 0xC3, 0xC3, 0x66, 0x3C,
/* '4' 0x34 */ 0x0C, 0x18, 0x71, 0x62, 0xC9, 0xA3, 0x46, 0xFE, 0x18, 0x30, 0x60, 0xC0,
/* '5' 0x35 */ 0x7F, 0x20, 0x10, 0x08, 0x08, 0x07, 0xF3, 0x8C, 0x03, 0x01, 0x80, 0xF0, 0x6C, 0x63, 0xE0,
/* '6' 0x36 */ 0x1E, 0x31, 0x98, 0x78, 0x0C, 0x06, 0xF3, 0x8D, 0x83, 0xC1, 0xE0, 0xD0, 0x6C, 0x63, 0xE0,
/* '7' 0x37 */ 0xFF, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x18, 0x18, 0x18, 0x10, 0x30, 0x30,
/* '8' 0x38 */ 0x3E, 0x31, 0xB0, 0x78, 0x3C, 0x1B, 0x18, 0xF8, 0xC6, 0xC1, 0xE0, 0xF0, 0x6C, 0x63, 0xE0,
/* '9' 0x39 */ 0x3C, 0x66, 0xC2, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0xC2, 0x66, 0x3C,
/* ':' 0x3A */ 0xC0, 0x00, 0x30,
/* ';' 0x3B */ 0xC0, 0x00, 0x00, 0x64, 0xA0,
/* '<' 0x3C */ 0x00, 0x81, 0xC7, 0x8E, 0x0C, 0x07, 0x80, 0x70, 0x0E, 0x01, 0x80,
/* '=' 0x3D */ 0xFF, 0x80, 0x00, 0x1F, 0xF0,
/* '>' 0x3E */ 0xE0, 0x1C, 0x03, 0x80, 0x30, 0x70, 0xE3, 0x81, 0x00,
/* '?' 0x3F */ 0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x18, 0x38, 0x18, 0x18, 0x0C, 0x00, 0x00, 0x01, 0x80,
/* '@' 0x40 */ 0x03, 0xF0, 0x06, 0x0E, 0x06, 0x01, 0x86, 0x00, 0x66, 0x1D, 0xBB, 0x31, 0xCF, 0x18, 0xC7, 0x98, 0x63, 0xCC, 0x31, 0xE6, 0x11, 0xB3, 0x99, 0xCC, 0xF7, 0x86, 0x00, 0x01, 0x80, 0x00, 0x70, 0x40, 0x0F, 0xE0,
/* 'A' 0x41 */ 0x06, 0x00, 0xF0, 0x0F, 0x00, 0x90, 0x19, 0x81, 0x98, 0x10, 0x83, 0x0C, 0x3F, 0xC2, 0x04, 0x60, 0x66, 0x06, 0xC0, 0x30,
/* 'B' 0x42 */ 0xFF, 0x18, 0x33, 0x03, 0x60, 0x6C, 0x0D, 0x83, 0x3F, 0xC6, 0x06, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x6F, 0xF8,
/* 'C' 0x43 */ 0x1F, 0x86, 0x19, 0x81, 0xA0, 0x3C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0x61, 0xF0,
/* 'D' 0x44 */ 0xFF, 0x18, 0x33, 0x03, 0x60, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x03, 0x60, 0xCF, 0xF0,
/* 'E' 0x45 */ 0xFF, 0xE0, 0x30, 0x18, 0x0C, 0x06, 0x03, 0xFD, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0F, 0xF8,
/* 'F' 0x46 */ 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
/* 'G' 0x47 */ 0x0F, 0x83, 0x0E, 0x60, 0x66, 0x03, 0xC0, 0x0C, 0x00, 0xC1, 0xFC, 0x03, 0xC0, 0x36, 0x03, 0x60, 0x73, 0x0F, 0x0F, 0x10,
/* 'H' 0x48 */ 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xFF, 0xFE, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x06,
/* 'I' 0x49 */ 0xFF, 0xFF, 0xFF, 0xC0,
/* 'J' 0x4A */ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x07, 0x8F, 0x1E, 0x27, 0x80,
/* 'K' 0x4B */ 0xC0, 0xF0, 0x6C, 0x33, 0x18, 0xCC, 0x37, 0x0F, 0xC3, 0x98, 0xC3, 0x30, 0xCC, 0x1B, 0x03, 0xC0, 0xC0,
/* 'L' 0x4C */ 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF,
/* 'M' 0x4D */ 0xE0, 0x3F, 0x01, 0xFC, 0x1F, 0xE0, 0xFD, 0x05, 0xEC, 0x6F, 0x63, 0x79, 0x13, 0xCD, 0x9E, 0x6C, 0xF1, 0x47, 0x8E, 0x3C, 0x71, 0x80,
/* 'N' 0x4E */ 0xE0, 0x7C, 0x0F, 0xC1, 0xE8, 0x3D, 0x87, 0x98, 0xF1, 0x1E, 0x33, 0xC3, 0x78, 0x6F, 0x07, 0xE0, 0x7C, 0x0E,
/* 'O' 0x4F */ 0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x0C, 0x60, 0xC0, 0xF8, 0x00,
/* 'P' 0x50 */ 0xFF, 0x30, 0x6C, 0x0F, 0x03, 0xC0, 0xF0, 0x6F, 0xF3, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x00,
/* 'Q' 0x51 */ 0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x6C, 0x60, 0xC0, 0xFB, 0x00, 0x08,
/* 'R' 0x52 */ 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x0C, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x70,
/* 'S' 0x53 */ 0x3F, 0x18, 0x6C, 0x0F, 0x03, 0xC0, 0x1E, 0x01, 0xF0, 0x0E, 0x00, 0xF0, 0x3C, 0x0D, 0x86, 0x3F, 0x00,
/* 'T' 0x54 */ 0xFF, 0x86, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0,
/* 'U' 0x55 */ 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xB0, 0x61, 0xF0,
/* 'V' 0x56 */ 0xC0, 0x6C, 0x0D, 0x81, 0x10, 0x63, 0x0C, 0x61, 0x04, 0x60, 0xCC, 0x19, 0x01, 0x60, 0x3C, 0x07, 0x00, 0x60,
/* 'W' 0x57 */ 0xC1, 0x81, 0x61, 0xC3, 0x61, 0xC3, 0x61, 0x43, 0x62, 0x62, 0x22, 0x66, 0x32, 0x26, 0x36, 0x26, 0x14, 0x34, 0x14, 0x34, 0x1C, 0x1C, 0x18, 0x1C, 0x08, 0x18,
/* 'X' 0x58 */ 0xC0, 0xD8, 0x66, 0x18, 0xCC, 0x1E, 0x07, 0x00, 0xC0, 0x78, 0x32, 0x0C, 0xC6, 0x1B, 0x07, 0xC0, 0xC0,
/* 'Y' 0x59 */ 0xC0, 0x36, 0x06, 0x30, 0xC3, 0x0C, 0x19, 0x81, 0xD8, 0x0F, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00,
/* 'Z' 0x5A */ 0xFF, 0xC0, 0x60, 0x30, 0x0C, 0x06, 0x03, 0x01, 0xC0, 0x60, 0x30, 0x18, 0x06, 0x03, 0x00, 0xFF, 0xC0,
/* '[' 0x5B */ 0xFB, 0x6D, 0xB6, 0xDB, 0x6D, 0xB6, 0xE0,
/* '\' 0x5C */ 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x80,
/* ']' 0x5D */ 0xED, 0xB6, 0xDB, 0x6D, 0xB6, 0xDB, 0xE0,
/* '^' 0x5E */ 0x30, 0x60, 0xA2, 0x44, 0xD8, 0xA1, 0x80,
/* '_' 0x5F */ 0xFF, 0xC0,
/* '`' 0x60 */ 0xC6, 0x30,
/* 'a' 0x61 */ 0x7E, 0x71, 0xB0, 0xC0, 0x60, 0xF3, 0xDB, 0x0D, 0x86, 0xC7, 0x3D, 0xC0,
/* 'b' 0x62 */ 0xC0, 0x60, 0x30, 0x1B, 0xCE, 0x36, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x7C, 0x6D, 0xE0,
/* 'c' 0x63 */ 0x3C, 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 'd' 0x64 */ 0x03, 0x03, 0x03, 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B,
/* 'e' 0x65 */ 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 'f' 0x66 */ 0x36, 0x6F, 0x66, 0x66, 0x66, 0x66, 0x60,
/* 'g' 0x67 */ 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0xC6, 0x7C,
/* 'h' 0x68 */ 0xC0, 0xC0, 0xC0, 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
/* 'i' 0x69 */ 0xC3, 0xFF, 0xFF, 0xC0,
/* 'j' 0x6A */ 0x30, 0x03, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xE0,
/* 'k' 0x6B */ 0xC0, 0xC0, 0xC0, 0xC2, 0xC4, 0xCC, 0xD8, 0xF8, 0xEC, 0xC4, 0xC6, 0xC3, 0xC3,
/* 'l' 0x6C */ 0xFF, 0xFF, 0xFF, 0xC0,
/* 'm' 0x6D */ 0xDE, 0xF7, 0x1C, 0xF0, 0xC7, 0x86, 0x3C, 0x31, 0xE1, 0x8F, 0x0C, 0x78, 0x63, 0xC3, 0x1E, 0x18, 0xC0,
/* 'n' 0x6E */ 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
/* 'o' 0x6F */ 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C,
/* 'p' 0x70 */ 0xDE, 0x71, 0xB0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xE3, 0x6F, 0x30, 0x18, 0x0C, 0x00,
/* 'q' 0x71 */ 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0x03,
/* 'r' 0x72 */ 0xDF, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x00,
/* 's' 0x73 */ 0x3E, 0xE3, 0xC0, 0xC0, 0xE0, 0x3C, 0x07, 0xC3, 0xE3, 0x7E,
/* 't' 0x74 */ 0x66, 0xF6, 0x66, 0x66, 0x66, 0x67,
/* 'u' 0x75 */ 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B,
/* 'v' 0x76 */ 0xC1, 0xA0, 0x98, 0xCC, 0x42, 0x21, 0xB0, 0xD0, 0x28, 0x1C, 0x0C, 0x00,
/* 'w' 0x77 */ 0xC6, 0x1E, 0x38, 0x91, 0xC4, 0xCA, 0x66, 0xD3, 0x16, 0xD0, 0xA6, 0x87, 0x1C, 0x38, 0xC0, 0xC6, 0x00,
/* 'x' 0x78 */ 0x87, 0x89, 0xB1, 0xC3, 0x07, 0x1E, 0x26, 0xC5, 0x0C,
/* 'y' 0x79 */ 0xC1, 0x43, 0x63, 0x62, 0x26, 0x36, 0x34, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x60,
/* 'z' 0x7A */ 0xFE, 0x0C, 0x30, 0xC1, 0x86, 0x18, 0x20, 0xC1, 0xFC,
/* '{' 0x7B */ 0x36, 0x66, 0x66, 0x6E, 0xCE, 0x66, 0x66, 0x66, 0x30,
/* '|' 0x7C */ 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
/* '}' 0x7D */ 0xC6, 0x66, 0x66, 0x67, 0x37, 0x66, 0x66, 0x66, 0xC0,
/* '~' 0x7E */ 0x61, 0x24, 0x38,
/* 0x7F */ 0xFF, 0xFC, 0x00, 0x63, 0xE3, 0x31, 0x99, 0x04, 0xC8, 0x66, 0x06, 0x30, 0x61, 0x83, 0x0C, 0x18, 0x60, 0x03, 0x06, 0x18, 0x00, 0xFF, 0xFC,
/* 0x80 */ 0xFF, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0xFE, 0x18, 0x31, 0x83, 0x18, 0x31, 0x83, 0x18, 0x31, 0x83, 0x18, 0x30, 0x03, 0x00, 0x30, 0x0E,
/* 0x81 */ 0x0C, 0x18, 0x00, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
/* 0x82 */ 0xDC,
/* 0x83 */ 0x18, 0x89, 0xFC, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x00,
/* 0x84 */ 0xDA, 0x76,
/* 0x85 */ 0xCC, 0xC0,
/* 0x86 */ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
/* 0x87 */ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18,
/* 0x88 */ 0x07, 0xC6, 0x13, 0x00, 0xC0, 0x60, 0x3F, 0xE6, 0x03, 0xFC, 0x60, 0x0C, 0x03, 0x00, 0x61, 0x07, 0xC0,
/* 0x89 */ 0x70, 0x80, 0x22, 0x20, 0x08, 0x90, 0x02, 0x24, 0x00, 0x72, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x10, 0x00, 0x09, 0xC7, 0x84, 0x8B, 0x31, 0x22, 0x84, 0x88, 0xB3, 0x21, 0xC7, 0x80,
/* 0x8A */ 0x3F, 0x80, 0x18, 0xC0, 0x0C, 0x60, 0x06, 0x30, 0x03, 0x18, 0x01, 0x8C, 0x00, 0xC7, 0xF8, 0x63, 0x06, 0x31, 0x81, 0x90, 0xC0, 0xD8, 0x60, 0x6C, 0x30, 0x6C, 0x1F, 0xE0,
/* 0x8B */ 0x69,
/* 0x8C */ 0xC0, 0xC0, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0C, 0x0C, 0x06, 0x06, 0x03, 0xFF, 0xF9, 0x81, 0x86, 0xC0, 0xC1, 0xE0, 0x60, 0xF0, 0x30, 0x78, 0x18, 0x6C, 0x0F, 0xE0,
/* 0x8D */ 0x0C, 0x06, 0x0C, 0x1B, 0x0C, 0xC6, 0x33, 0x0D, 0x83, 0xC0, 0xF0, 0x3E, 0x0D, 0xC3, 0x38, 0xC7, 0x30, 0xEC, 0x1C,
/* 0x8E */ 0xFF, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0xFE, 0x18, 0x31, 0x83, 0x18, 0x31, 0x83, 0x18, 0x31, 0x83, 0x18, 0x30,
/* 0x8F */ 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3F, 0xFE, 0x0C, 0x01, 0x80,
/* 0x90 */ 0x60, 0x7C, 0x18, 0x0D, 0xE7, 0x1B, 0x0D, 0x86, 0xC3, 0x61, 0xB0, 0xD8, 0x6C, 0x36, 0x18, 0x18, 0x08, 0x08,
/* 0x91 */ 0x6B,
/* 0x92 */ 0xD6,
/* 0x93 */ 0x4C, 0xA5, 0xB0,
/* 0x94 */ 0xDA, 0x53, 0x20,
/* 0x95 */ 0x6F, 0xFF, 0x60,
/* 0x96 */ 0xFE,
/* 0x97 */ 0xFF, 0xFF,
/* 0x98 */
/* 0x99 */ 0xFC, 0xE1, 0xCC, 0x38, 0x73, 0x0E, 0x1C, 0xC3, 0x8F, 0x30, 0xD2, 0xCC, 0x34, 0xB3, 0x0D, 0x6C, 0xC3, 0x53, 0x30, 0xCC, 0xCC, 0x33, 0x30,
/* 0x9A */ 0x7E, 0x03, 0x30, 0x19, 0x80, 0xCC, 0x06, 0x60, 0x33, 0xF9, 0x98, 0x6C, 0xC3, 0x46, 0x1E, 0x3F, 0x80,
/* 0x9B */ 0x96,
/* 0x9C */ 0xC3, 0x03, 0x0C, 0x0C, 0x30, 0x30, 0xC0, 0xC3, 0x03, 0xFF, 0xEC, 0x30, 0xF0, 0xC3, 0xC3, 0x0F, 0x0F, 0xE0,
/* 0x9D */ 0x0C, 0x30, 0x46, 0x3C, 0xDB, 0x34, 0x70, 0xF1, 0xB3, 0x36, 0x3C, 0x20,
/* 0x9E */ 0x60, 0x7C, 0x18, 0x0D, 0xE7, 0x3B, 0x0D, 0x86, 0xC3, 0x61, 0xB0, 0xD8, 0x6C, 0x36, 0x18,
/* 0x9F */ 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0x18, 0x18,
/* 0xA0 */
/* 0xA1 */ 0x21, 0x07, 0x8C, 0x0F, 0x06, 0x61, 0x98, 0xC3, 0x30, 0xD8, 0x1E, 0x07, 0x00, 0xC0, 0x60, 0x18, 0x0C, 0x03, 0x00,
/* 0xA2 */ 0x66, 0x18, 0xC1, 0x43, 0x63, 0x62, 0x26, 0x36, 0x34, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x60,
/* 0xA3 */ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x07, 0x8F, 0x1E, 0x27, 0x80,
/* 0xA4 */ 0xFF, 0xDF, 0x1E, 0x3E, 0xFF, 0xC0,
/* 0xA5 */ 0x00, 0xC0, 0x3F, 0xFF, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x00,
/* 0xA6 */ 0xFF, 0xFC, 0x0F, 0xFF, 0xC0,
/* 0xA7 */ 0x0C, 0x09, 0x0C, 0xC6, 0x63, 0x81, 0xE3, 0x19, 0x87, 0xE1, 0xB8, 0xC6, 0x41, 0xC0, 0x73, 0x19, 0x8C, 0x66, 0x1E, 0x00,
/* 0xA8 */ 0x33, 0x00, 0x3F, 0xF8, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xFF, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0xFE,
/* 0xA9 */ 0x0F, 0xC0, 0x61, 0x87, 0x03, 0x9B, 0xC6, 0xD9, 0x8F, 0x60, 0x3D, 0x00, 0xF4, 0x03, 0xD8, 0x0D, 0xE6, 0x67, 0xF3, 0x86, 0x18, 0x0F, 0xC0,
/* 0xAA */ 0x1F, 0x86, 0x19, 0x81, 0xB0, 0x3C, 0x01, 0x80, 0x3F, 0xC6, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0x61, 0xF0,
/* 0xAB */ 0x22, 0xCF, 0x26, 0x46, 0x64, 0x40,
/* 0xAC */ 0xFF, 0x80, 0xC0, 0x60, 0x30, 0x18,
/* 0xAD */
/* 0xAE */ 0x0F, 0xC0, 0x61, 0x87, 0x03, 0x9F, 0xE6, 0xD0, 0x8F, 0x42, 0x3D, 0xF0, 0xF4, 0x23, 0xD0, 0x8D, 0xC2, 0x67, 0x0B, 0x86, 0x18, 0x0F, 0xC0,
/* 0xAF */ 0xCC, 0x03, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x00,
/* 0xB0 */ 0x74, 0x63, 0x17, 0x00,
/* 0xB1 */ 0x0C, 0x06, 0x03, 0x07, 0xE0, 0xC0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x3F, 0xE0,
/* 0xB2 */ 0xFF, 0xFF, 0xFF, 0xC0,
/* 0xB3 */ 0xC3, 0xFF, 0xFF, 0xC0,
/* 0xB4 */ 0x0C, 0x3F, 0xF0, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30,
/* 0xB5 */ 0xC3, 0x61, 0xB0, 0xD8, 0x6C, 0x36, 0x1B, 0x0D, 0x86, 0xE7, 0x7D, 0xF0, 0x18, 0x0C, 0x00,
/* 0xB6 */ 0x3F, 0x7E, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0x72, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
/* 0xB7 */ 0xE0,
/* 0xB8 */ 0x66, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 0xB9 */ 0xC1, 0x81, 0x83, 0x03, 0x86, 0x05, 0x0C, 0xEB, 0x1A, 0x32, 0x34, 0x66, 0x68, 0xC4, 0xD1, 0x8D, 0xB3, 0x0B, 0x3A, 0x1E, 0x04, 0x1C, 0x08, 0x1B, 0xC0,
/* 0xBA */ 0x3C, 0x46, 0xC3, 0x80, 0xF8, 0x80, 0x80, 0xC3, 0x46, 0x3C,
/* 0xBB */ 0x89, 0x98, 0x99, 0x3C, 0xD1, 0x00,
/* 0xBC */ 0x30, 0x03, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xE0,
/* 0xBD */ 0x3F, 0x18, 0x6C, 0x0F, 0x03, 0xC0, 0x1E, 0x01, 0xF0, 0x0E, 0x00, 0xF0, 0x3C, 0x0D, 0x86, 0x3F, 0x00,
/* 0xBE */ 0x3E, 0xE3, 0xC0, 0xC0, 0x60, 0x3C, 0x07, 0xC3, 0xE3, 0x7E,
/* 0xBF */ 0xCC, 0x03, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C,
/* 0xC0 */ 0x06, 0x00, 0xF0, 0x0F, 0x00, 0x90, 0x19, 0x81, 0x98, 0x10, 0x83, 0x0C, 0x3F, 0xC2, 0x04, 0x60, 0x66, 0x06, 0xC0, 0x30,
/* 0xC1 */ 0xFF, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x3F, 0xE6, 0x06, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x6F, 0xF8,
/* 0xC2 */ 0xFF, 0x18, 0x33, 0x03, 0x60, 0x6C, 0x0D, 0x83, 0x3F, 0xC6, 0x06, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x6F, 0xF8,
/* 0xC3 */ 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
/* 0xC4 */ 0x1F, 0xF0, 0x60, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x03, 0x0C, 0x0C, 0xFF, 0xFF, 0x00, 0x3C, 0x00, 0xF0, 0x03,
/* 0xC5 */ 0xFF, 0xE0, 0x30, 0x18, 0x0C, 0x06, 0x03, 0xFD, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0F, 0xF8,
/* 0xC6 */ 0x61, 0x86, 0x31, 0x8C, 0x19, 0x98, 0x19, 0x98, 0x0D, 0xB0, 0x07, 0xE0, 0x03, 0xC0, 0x07, 0xE0, 0x0D, 0xB0, 0x19, 0x98, 0x31, 0x8C, 0x61, 0x86, 0xC1, 0x83,
/* 0xC7 */ 0x3F, 0x18, 0x6C, 0x0F, 0x03, 0x00, 0xC0, 0x60, 0xF0, 0x06, 0x00, 0xF0, 0x3C, 0x0D, 0x86, 0x3F, 0x00,
/* 0xC8 */ 0xC0, 0xF8, 0x1F, 0x07, 0xE0, 0xBC, 0x37, 0x8C, 0xF1, 0x1E, 0x63, 0xD8, 0x7A, 0x0F, 0xC1, 0xF0, 0x3E, 0x06,
/* 0xC9 */ 0x11, 0x03, 0xE0, 0x00, 0x60, 0x7C, 0x0F, 0x83, 0xF0, 0x5E, 0x1B, 0xC6, 0x78, 0x8F, 0x31, 0xEC, 0x3D, 0x07, 0xE0, 0xF8, 0x1F, 0x03,
/* 0xCA */ 0xC1, 0xB0, 0xCC, 0x63, 0x30, 0xD8, 0x3C, 0x0F, 0x03, 0xE0, 0xDC, 0x33, 0x8C, 0x73, 0x0E, 0xC1, 0xC0,
/* 0xCB */ 0x3F, 0xCC, 0x33, 0x0C, 0xC3, 0x30, 0xCC, 0x33, 0x0C, 0xC3, 0x30, 0xC8, 0x36, 0x0D, 0x83, 0xC0, 0xC0,
/* 0xCC */ 0xE0, 0x3F, 0x01, 0xFC, 0x1F, 0xE0, 0xFD, 0x05, 0xEC, 0x6F, 0x63, 0x79, 0x13, 0xCD, 0x9E, 0x6C, 0xF1, 0x47, 0x8E, 0x3C, 0x71, 0x80,
/* 0xCD */ 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xFF, 0xFE, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x06,
/* 0xCE */ 0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x0C, 0x60, 0xC0, 0xF8, 0x00,
/* 0xCF */ 0xFF, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x06,
/* 0xD0 */ 0xFF, 0x30, 0x6C, 0x0F, 0x03, 0xC0, 0xF0, 0x6F, 0xF3, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x00,
/* 0xD1 */ 0x1F, 0x86, 0x19, 0x81, 0xA0, 0x3C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0x61, 0xF0,
/* 0xD2 */ 0xFF, 0x86, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0,
/* 0xD3 */ 0xC0, 0xF0, 0x66, 0x19, 0x8C, 0x33, 0x0D, 0x81, 0xE0, 0x70, 0x0C, 0x06, 0x01, 0x80, 0xC0, 0x30, 0x00,
/* 0xD4 */ 0x03, 0x00, 0x0C, 0x01, 0xFE, 0x1C, 0xCE, 0xE3, 0x1F, 0x0C, 0x3C, 0x30, 0xF0, 0xC3, 0xE3, 0x1D, 0xCC, 0xE3, 0xFF, 0x00, 0xC0, 0x03, 0x00,
/* 0xD5 */ 0xC0, 0xD8, 0x66, 0x18, 0xCC, 0x1E, 0x07, 0x00, 0xC0, 0x78, 0x32, 0x0C, 0xC6, 0x1B, 0x07, 0xC0, 0xC0,
/* 0xD6 */ 0xC0, 0x66, 0x03, 0x30, 0x19, 0x80, 0xCC, 0x06, 0x60, 0x33, 0x01, 0x98, 0x0C, 0xC0, 0x66, 0x03, 0x30, 0x19, 0x80, 0xCF, 0xFF, 0x80, 0x0C, 0x00, 0x60,
/* 0xD7 */ 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x06, 0xFF, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18,
/* 0xD8 */ 0xC3, 0x1E, 0x18, 0xF0, 0xC7, 0x86, 0x3C, 0x31, 0xE1, 0x8F, 0x0C, 0x78, 0x63, 0xC3, 0x1E, 0x18, 0xF0, 0xC7, 0x86, 0x3F, 0xFF, 0x80,
/* 0xD9 */ 0xC3, 0x19, 0x86, 0x33, 0x0C, 0x66, 0x18, 0xCC, 0x31, 0x98, 0x63, 0x30, 0xC6, 0x61, 0x8C, 0xC3, 0x19, 0x86, 0x33, 0x0C, 0x66, 0x18, 0xCF, 0xFF, 0xE0, 0x00, 0xC0, 0x01, 0x80,
/* 0xDA */ 0xF8, 0x00, 0xC0, 0x06, 0x00, 0x30, 0x01, 0x80, 0x0F, 0xF0, 0x60, 0xC3, 0x03, 0x18, 0x18, 0xC0, 0xC6, 0x06, 0x30, 0x61, 0xFE, 0x00,
/* 0xDB */ 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0xFE, 0x3C, 0x0C, 0xF0, 0x1B, 0xC0, 0x6F, 0x01, 0xBC, 0x06, 0xF0, 0x33, 0xFF, 0x8C,
/* 0xDC */ 0xC0, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0xFF, 0x30, 0x36, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x6F, 0xF8,
/* 0xDD */ 0x3F, 0x0C, 0x33, 0x83, 0x60, 0x20, 0x06, 0x00, 0x47, 0xF8, 0x01, 0xC0, 0x78, 0x0D, 0x81, 0x30, 0xC1, 0xF0,
/* 0xDE */ 0xC0, 0xF8, 0x61, 0x83, 0x31, 0x80, 0xD8, 0xC0, 0x6C, 0xC0, 0x1E, 0x60, 0x0F, 0xF0, 0x07, 0x98, 0x03, 0xCC, 0x01, 0xE3, 0x01, 0xB1, 0x80, 0xD8, 0x60, 0xCC, 0x0F, 0x80,
/* 0xDF */ 0x3F, 0xD8, 0x3C, 0x0F, 0x03, 0xC0, 0xD8, 0x33, 0xFC, 0x33, 0x18, 0xCC, 0x36, 0x0D, 0x83, 0xC0, 0xC0,
/* 0xE0 */ 0x7E, 0x71, 0xB0, 0xC0, 0x60, 0xF3, 0xDB, 0x0D, 0x86, 0xC7, 0x3D, 0xC0,
/* 0xE1 */ 0x03, 0x1F, 0x78, 0x40, 0xFC, 0xE6, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C,
/* 0xE2 */ 0xFD, 0x8F, 0x0E, 0x3F, 0xDF, 0xB1, 0xE1, 0xC7, 0xF8,
/* 0xE3 */ 0xFE, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x00,
/* 0xE4 */ 0x1F, 0x83, 0x30, 0x66, 0x0C, 0xC1, 0x98, 0x33, 0x06, 0x61, 0x8C, 0x31, 0x9F, 0xFF, 0x01, 0xE0, 0x30,
/* 0xE5 */ 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 0xE6 */ 0xC6, 0x36, 0x66, 0x36, 0xC1, 0xF8, 0x0F, 0x01, 0xF8, 0x36, 0xC6, 0x66, 0xC6, 0x38, 0x61,
/* 0xE7 */ 0x79, 0x8C, 0x18, 0x30, 0x43, 0x01, 0xE3, 0xC6, 0xF8,
/* 0xE8 */ 0xC7, 0xC7, 0xCF, 0xCB, 0xCB, 0xD3, 0xD3, 0xF3, 0xE3, 0xE3,
/* 0xE9 */ 0x66, 0x18, 0xC7, 0xC7, 0xCF, 0xCB, 0xCB, 0xD3, 0xD3, 0xF3, 0xE3, 0xE3,
/* 0xEA */ 0xC7, 0x9B, 0x66, 0x8E, 0x1E, 0x36, 0x66, 0xC7, 0x84,
/* 0xEB */ 0x7E, 0xCD, 0x9B, 0x36, 0x6C, 0xD9, 0xA3, 0xC7, 0x0C,
/* 0xEC */ 0xE3, 0xF1, 0xF8, 0xFE, 0xFF, 0x7E, 0xAF, 0x77, 0x93, 0xC9, 0xE0, 0xC0,
/* 0xED */ 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3,
/* 0xEE */ 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C,
/* 0xEF */ 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
/* 0xF0 */ 0xDE, 0x71, 0xB0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xE3, 0x6F, 0x30, 0x18, 0x0C, 0x00,
/* 0xF1 */ 0x3C, 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 0xF2 */ 0xFC, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC0,
/* 0xF3 */ 0xC1, 0x43, 0x63, 0x62, 0x26, 0x36, 0x34, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x60,
/* 0xF4 */ 0x03, 0x00, 0x0C, 0x03, 0xB7, 0x19, 0xE6, 0xC3, 0x0F, 0x0C, 0x3C, 0x30, 0xF0, 0xC3, 0xC3, 0x0F, 0x0C, 0x36, 0x79, 0x8E, 0xDC, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00,
/* 0xF5 */ 0x87, 0x89, 0xB1, 0xC3, 0x07, 0x1E, 0x26, 0xC5, 0x0C,
/* 0xF6 */ 0xC3, 0x30, 0xCC, 0x33, 0x0C, 0xC3, 0x30, 0xCC, 0x33, 0x0C, 0xC3, 0x3F, 0xF0, 0x0C, 0x03,
/* 0xF7 */ 0xC7, 0x8F, 0x1E, 0x3C, 0x6F, 0xC1, 0x83, 0x06, 0x0C,
/* 0xF8 */ 0xCC, 0xF3, 0x3C, 0xCF, 0x33, 0xCC, 0xF3, 0x3C, 0xCF, 0x33, 0xCC, 0xFF, 0xF0,
/* 0xF9 */ 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCF, 0xFF, 0x00, 0x30, 0x03,
/* 0xFA */ 0xF0, 0x18, 0x0C, 0x06, 0x03, 0xF1, 0x8C, 0xC6, 0x63, 0x31, 0x9F, 0x80,
/* 0xFB */ 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xFE, 0xF0, 0xFC, 0x3F, 0x0F, 0xC3, 0xFF, 0xB0,
/* 0xFC */ 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0xC3, 0xC3, 0xC3, 0xC3, 0xFE,
/* 0xFD */ 0x3C, 0x62, 0xC3, 0x01, 0x1F, 0x01, 0x01, 0xC3, 0x62, 0x3C,
/* 0xFE */ 0xC7, 0xCC, 0xC6, 0xD8, 0x3D, 0x83, 0xF8, 0x3D, 0x83, 0xD8, 0x3C, 0xC2, 0xCC, 0x6C, 0x7C,
/* 0xFF */ 0x7F, 0xC3, 0xC3, 0xC3, 0x7F, 0x13, 0x33, 0x63, 0xC3, 0x83,
};
const GFXglyph FreeSans9pt_Win1251Glyphs[] PROGMEM = {
/* 0x01 */ { 0, 15, 15, 17, 1, -13 },
/* 0x02 */ { 29, 15, 15, 17, 1, -13 },
/* 0x03 */ { 58, 15, 16, 17, 1, -14 },
/* 0x04 */ { 88, 15, 16, 17, 1, -14 },
/* 0x05 */ { 118, 16, 15, 18, 1, -13 },
/* 0x06 */ { 148, 15, 15, 17, 1, -13 },
/* 0x07 */ { 177, 0, 0, 8, 0, 0 },
/* 0x08 */ { 177, 17, 16, 19, 1, -14 },
/* 0x09 */ { 211, 17, 12, 19, 1, -12 },
/* 0x0A */ { 237, 0, 0, 8, 0, 0 },
/* 0x0B */ { 237, 17, 16, 19, 1, -14 },
/* 0x0C */ { 271, 15, 14, 17, 1, -12 },
/* 0x0D */ { 298, 0, 0, 8, 0, 0 },
/* 0x0E */ { 298, 15, 16, 17, 1, -14 },
/* 0x0F */ { 328, 15, 15, 17, 1, -13 },
/* 0x10 */ { 357, 15, 15, 17, 1, -13 },
/* 0x11 */ { 386, 15, 16, 17, 1, -14 },
/* 0x12 */ { 416, 17, 17, 19, 1, -15 },
/* 0x13 */ { 453, 15, 16, 17, 1, -14 },
/* 0x14 */ { 483, 15, 16, 17, 1, -14 },
/* 0x15 */ { 513, 15, 16, 17, 1, -14 },
/* 0x16 */ { 543, 11, 16, 13, 1, -14 },
/* 0x17 */ { 565, 15, 16, 17, 1, -14 },
/* 0x18 */ { 595, 18, 15, 20, 1, -13 },
/* 0x19 */ { 629, 15, 16, 17, 1, -14 },
/* 0x1A */ { 659, 13, 14, 15, 1, -12 },
/* 0x1B */ { 682, 17, 16, 19, 1, -14 },
/* 0x1C */ { 716, 15, 16, 17, 1, -14 },
/* 0x1D */ { 746, 15, 15, 17, 1, -13 },
/* 0x1E */ { 775, 17, 16, 19, 1, -14 },
/* 0x1F */ { 809, 11, 16, 13, 1, -14 },
/* ' ' 0x20 */ { 831, 0, 0, 5, 0, 0 },
/* '!' 0x21 */ { 831, 2, 13, 6, 2, -12 },
/* '"' 0x22 */ { 835, 5, 4, 6, 1, -12 },
/* '#' 0x23 */ { 838, 10, 12, 10, 0, -11 },
/* '$' 0x24 */ { 853, 9, 16, 10, 1, -13 },
/* '%' 0x25 */ { 871, 16, 13, 16, 1, -12 },
/* '&' 0x26 */ { 897, 10, 13, 12, 1, -12 },
/* ''' 0x27 */ { 914, 2, 4, 4, 1, -12 },
/* '(' 0x28 */ { 915, 4, 17, 6, 1, -12 },
/* ')' 0x29 */ { 924, 4, 17, 6, 1, -12 },
/* '*' 0x2A */ { 933, 5, 5, 7, 1, -12 },
/* '+' 0x2B */ { 937, 6, 8, 11, 3, -7 },
/* ',' 0x2C */ { 943, 2, 4, 5, 2, 0 },
/* '-' 0x2D */ { 944, 4, 1, 6, 1, -4 },
/* '.' 0x2E */ { 945, 2, 1, 5, 1, 0 },
/* '/' 0x2F */ { 946, 5, 13, 5, 0, -12 },
/* '0' 0x30 */ { 955, 8, 13, 10, 1, -12 },
/* '1' 0x31 */ { 968, 4, 13, 10, 3, -12 },
/* '2' 0x32 */ { 975, 9, 13, 10, 1, -12 },
/* '3' 0x33 */ { 990, 8, 13, 10, 1, -12 },
/* '4' 0x34 */ { 1003, 7, 13, 10, 2, -12 },
/* '5' 0x35 */ { 1015, 9, 13, 10, 1, -12 },
/* '6' 0x36 */ { 1030, 9, 13, 10, 1, -12 },
/* '7' 0x37 */ { 1045, 8, 13, 10, 0, -12 },
/* '8' 0x38 */ { 1058, 9, 13, 10, 1, -12 },
/* '9' 0x39 */ { 1073, 8, 13, 10, 1, -12 },
/* ':' 0x3A */ { 1086, 2, 10, 5, 1, -9 },
/* ';' 0x3B */ { 1089, 3, 12, 5, 1, -8 },
/* '<' 0x3C */ { 1094, 9, 9, 11, 1, -8 },
/* '=' 0x3D */ { 1105, 9, 4, 11, 1, -5 },
/* '>' 0x3E */ { 1110, 9, 8, 11, 1, -7 },
/* '?' 0x3F */ { 1119, 9, 13, 10, 1, -12 },
/* '@' 0x40 */ { 1134, 17, 16, 18, 1, -12 },
/* 'A' 0x41 */ { 1168, 12, 13, 12, 0, -12 },
/* 'B' 0x42 */ { 1188, 11, 13, 12, 1, -12 },
/* 'C' 0x43 */ { 1206, 11, 13, 13, 1, -12 },
/* 'D' 0x44 */ { 1224, 11, 13, 13, 1, -12 },
/* 'E' 0x45 */ { 1242, 9, 13, 11, 1, -12 },
/* 'F' 0x46 */ { 1257, 8, 13, 11, 1, -12 },
/* 'G' 0x47 */ { 1270, 12, 13, 14, 1, -12 },
/* 'H' 0x48 */ { 1290, 11, 13, 13, 1, -12 },
/* 'I' 0x49 */ { 1308, 2, 13, 5, 2, -12 },
/* 'J' 0x4A */ { 1312, 7, 13, 10, 1, -12 },
/* 'K' 0x4B */ { 1324, 10, 13, 12, 1, -12 },
/* 'L' 0x4C */ { 1341, 8, 13, 10, 1, -12 },
/* 'M' 0x4D */ { 1354, 13, 13, 15, 1, -12 },
/* 'N' 0x4E */ { 1376, 11, 13, 13, 1, -12 },
/* 'O' 0x4F */ { 1394, 13, 13, 14, 1, -12 },
/* 'P' 0x50 */ { 1416, 10, 13, 12, 1, -12 },
/* 'Q' 0x51 */ { 1433, 13, 14, 14, 1, -12 },
/* 'R' 0x52 */ { 1456, 12, 13, 13, 1, -12 },
/* 'S' 0x53 */ { 1476, 10, 13, 12, 1, -12 },
/* 'T' 0x54 */ { 1493, 9, 13, 11, 1, -12 },
/* 'U' 0x55 */ { 1508, 11, 13, 13, 1, -12 },
/* 'V' 0x56 */ { 1526, 11, 13, 11, 0, -12 },
/* 'W' 0x57 */ { 1544, 16, 13, 17, 0, -12 },
/* 'X' 0x58 */ { 1570, 10, 13, 12, 1, -12 },
/* 'Y' 0x59 */ { 1587, 12, 13, 12, 0, -12 },
/* 'Z' 0x5A */ { 1607, 10, 13, 11, 1, -12 },
/* '[' 0x5B */ { 1624, 3, 17, 5, 1, -12 },
/* '\' 0x5C */ { 1631, 5, 13, 5, 0, -12 },
/* ']' 0x5D */ { 1640, 3, 17, 5, 0, -12 },
/* '^' 0x5E */ { 1647, 7, 7, 8, 1, -12 },
/* '_' 0x5F */ { 1654, 10, 1, 10, 0, 3 },
/* '`' 0x60 */ { 1656, 4, 3, 5, 0, -12 },
/* 'a' 0x61 */ { 1658, 9, 10, 10, 1, -9 },
/* 'b' 0x62 */ { 1670, 9, 13, 10, 1, -12 },
/* 'c' 0x63 */ { 1685, 8, 10, 9, 1, -9 },
/* 'd' 0x64 */ { 1695, 8, 13, 10, 1, -12 },
/* 'e' 0x65 */ { 1708, 8, 10, 10, 1, -9 },
/* 'f' 0x66 */ { 1718, 4, 13, 5, 1, -12 },
/* 'g' 0x67 */ { 1725, 8, 14, 10, 1, -9 },
/* 'h' 0x68 */ { 1739, 8, 13, 10, 1, -12 },
/* 'i' 0x69 */ { 1752, 2, 13, 4, 1, -12 },
/* 'j' 0x6A */ { 1756, 4, 17, 4, 0, -12 },
/* 'k' 0x6B */ { 1765, 8, 13, 9, 1, -12 },
/* 'l' 0x6C */ { 1778, 2, 13, 4, 1, -12 },
/* 'm' 0x6D */ { 1782, 13, 10, 15, 1, -9 },
/* 'n' 0x6E */ { 1799, 8, 10, 10, 1, -9 },
/* 'o' 0x6F */ { 1809, 8, 10, 10, 1, -9 },
/* 'p' 0x70 */ { 1819, 9, 13, 10, 1, -9 },
/* 'q' 0x71 */ { 1834, 8, 13, 10, 1, -9 },
/* 'r' 0x72 */ { 1847, 5, 10, 6, 1, -9 },
/* 's' 0x73 */ { 1854, 8, 10, 9, 1, -9 },
/* 't' 0x74 */ { 1864, 4, 12, 5, 1, -11 },
/* 'u' 0x75 */ { 1870, 8, 10, 10, 1, -9 },
/* 'v' 0x76 */ { 1880, 9, 10, 9, 0, -9 },
/* 'w' 0x77 */ { 1892, 13, 10, 13, 0, -9 },
/* 'x' 0x78 */ { 1909, 7, 10, 9, 1, -9 },
/* 'y' 0x79 */ { 1918, 8, 14, 9, 0, -9 },
/* 'z' 0x7A */ { 1932, 7, 10, 9, 1, -9 },
/* '{' 0x7B */ { 1941, 4, 17, 6, 1, -12 },
/* '|' 0x7C */ { 1950, 2, 17, 4, 2, -12 },
/* '}' 0x7D */ { 1955, 4, 17, 6, 1, -12 },
/* '~' 0x7E */ { 1964, 7, 3, 9, 1, -7 },
/* 0x7F */ { 1967, 13, 14, 15, 1, -12 },
/* 0x80 */ { 1990, 12, 16, 14, 1, -12 },
/* 0x81 */ { 2014, 8, 15, 11, 1, -14 },
/* 0x82 */ { 2029, 2, 3, 5, 1, 0 },
/* 0x83 */ { 2030, 5, 13, 7, 1, -12 },
/* 0x84 */ { 2039, 5, 3, 7, 1, 0 },
/* 0x85 */ { 2041, 10, 1, 12, 1, 0 },
/* 0x86 */ { 2043, 8, 16, 10, 1, -12 },
/* 0x87 */ { 2059, 8, 16, 10, 1, -12 },
/* 0x88 */ { 2075, 10, 13, 12, 1, -12 },
/* 0x89 */ { 2092, 18, 13, 18, 0, -12 },
/* 0x8A */ { 2122, 17, 13, 18, 1, -12 },
/* 0x8B */ { 2150, 2, 4, 4, 1, -6 },
/* 0x8C */ { 2151, 17, 13, 18, 1, -12 },
/* 0x8D */ { 2179, 10, 15, 11, 1, -14 },
/* 0x8E */ { 2198, 12, 13, 14, 1, -12 },
/* 0x8F */ { 2218, 11, 15, 13, 1, -12 },
/* 0x90 */ { 2239, 9, 16, 10, 1, -12 },
/* 0x91 */ { 2257, 2, 4, 4, 2, -12 },
/* 0x92 */ { 2258, 2, 4, 4, 1, -12 },
/* 0x93 */ { 2259, 5, 4, 7, 2, -12 },
/* 0x94 */ { 2262, 5, 4, 7, 1, -12 },
/* 0x95 */ { 2265, 4, 5, 7, 1, -8 },
/* 0x96 */ { 2268, 7, 1, 9, 1, -4 },
/* 0x97 */ { 2269, 16, 1, 18, 1, -4 },
/* 0x98 */ { 2271, 0, 0, 0, 0, 0 },
/* 0x99 */ { 2271, 18, 10, 18, 1, -13 },
/* 0x9A */ { 2294, 13, 10, 14, 1, -9 },
/* 0x9B */ { 2311, 2, 4, 5, 2, -6 },
/* 0x9C */ { 2312, 14, 10, 15, 1, -9 },
/* 0x9D */ { 2330, 7, 13, 9, 1, -12 },
/* 0x9E */ { 2342, 9, 13, 10, 1, -12 },
/* 0x9F */ { 2357, 8, 12, 10, 1, -9 },
/* 0xA0 */ { 2369, 0, 0, 5, 0, 0 },
/* 0xA1 */ { 2369, 10, 15, 11, 1, -14 },
/* 0xA2 */ { 2388, 8, 16, 9, 0, -11 },
/* 0xA3 */ { 2404, 7, 13, 10, 1, -12 },
/* 0xA4 */ { 2416, 7, 6, 10, 2, -8 },
/* 0xA5 */ { 2422, 10, 14, 11, 1, -13 },
/* 0xA6 */ { 2440, 2, 17, 5, 2, -12 },
/* 0xA7 */ { 2445, 9, 17, 10, 1, -12 },
/* 0xA8 */ { 2465, 9, 15, 12, 1, -14 },
/* 0xA9 */ { 2482, 14, 13, 14, 1, -12 },
/* 0xAA */ { 2505, 11, 13, 13, 1, -12 },
/* 0xAB */ { 2523, 7, 6, 9, 1, -7 },
/* 0xAC */ { 2529, 9, 5, 11, 2, -5 },
/* 0xAD */ { 2535, 0, 0, 0, 0, 0 },
/* 0xAE */ { 2535, 14, 13, 14, 1, -12 },
/* 0xAF */ { 2558, 6, 15, 5, 0, -14 },
/* 0xB0 */ { 2570, 5, 5, 11, 3, -11 },
/* 0xB1 */ { 2574, 9, 11, 11, 1, -10 },
/* 0xB2 */ { 2587, 2, 13, 4, 1, -12 },
/* 0xB3 */ { 2591, 2, 13, 4, 1, -12 },
/* 0xB4 */ { 2595, 6, 12, 7, 1, -11 },
/* 0xB5 */ { 2604, 9, 13, 10, 1, -9 },
/* 0xB6 */ { 2619, 8, 16, 10, 2, -12 },
/* 0xB7 */ { 2635, 3, 1, 5, 1, -4 },
/* 0xB8 */ { 2636, 8, 12, 10, 1, -11 },
/* 0xB9 */ { 2648, 15, 13, 17, 1, -12 },
/* 0xBA */ { 2673, 8, 10, 9, 1, -9 },
/* 0xBB */ { 2683, 7, 6, 9, 1, -7 },
/* 0xBC */ { 2689, 4, 17, 4, 0, -12 },
/* 0xBD */ { 2698, 10, 13, 12, 1, -12 },
/* 0xBE */ { 2715, 8, 10, 9, 1, -9 },
/* 0xBF */ { 2725, 6, 12, 5, -1, -11 },
/* 0xC0 */ { 2734, 12, 13, 12, 0, -12 },
/* 0xC1 */ { 2754, 11, 13, 12, 1, -12 },
/* 0xC2 */ { 2772, 11, 13, 12, 1, -12 },
/* 0xC3 */ { 2790, 8, 13, 8, 1, -12 },
/* 0xC4 */ { 2803, 14, 16, 15, 1, -12 },
/* 0xC5 */ { 2831, 9, 13, 12, 1, -12 },
/* 0xC6 */ { 2846, 16, 13, 16, 0, -12 },
/* 0xC7 */ { 2872, 10, 13, 12, 1, -12 },
/* 0xC8 */ { 2889, 11, 13, 13, 1, -12 },
/* 0xC9 */ { 2907, 11, 16, 13, 1, -15 },
/* 0xCA */ { 2929, 10, 13, 11, 1, -12 },
/* 0xCB */ { 2946, 10, 13, 12, 1, -12 },
/* 0xCC */ { 2963, 13, 13, 15, 1, -12 },
/* 0xCD */ { 2985, 11, 13, 13, 1, -12 },
/* 0xCE */ { 3003, 13, 13, 14, 1, -12 },
/* 0xCF */ { 3025, 11, 13, 13, 1, -12 },
/* 0xD0 */ { 3043, 10, 13, 12, 1, -12 },
/* 0xD1 */ { 3060, 11, 13, 13, 1, -12 },
/* 0xD2 */ { 3078, 9, 13, 11, 1, -12 },
/* 0xD3 */ { 3093, 10, 13, 11, 1, -12 },
/* 0xD4 */ { 3110, 14, 13, 15, 1, -12 },
/* 0xD5 */ { 3133, 10, 13, 12, 1, -12 },
/* 0xD6 */ { 3150, 13, 15, 13, 1, -12 },
/* 0xD7 */ { 3175, 9, 13, 11, 1, -12 },
/* 0xD8 */ { 3190, 13, 13, 15, 1, -12 },
/* 0xD9 */ { 3212, 15, 15, 15, 1, -12 },
/* 0xDA */ { 3241, 13, 13, 15, 2, -12 },
/* 0xDB */ { 3263, 14, 13, 16, 1, -12 },
/* 0xDC */ { 3286, 11, 13, 12, 1, -12 },
/* 0xDD */ { 3304, 11, 13, 13, 1, -12 },
/* 0xDE */ { 3322, 17, 13, 18, 1, -12 },
/* 0xDF */ { 3350, 10, 13, 12, 1, -12 },
/* 0xE0 */ { 3367, 9, 10, 10, 1, -9 },
/* 0xE1 */ { 3379, 8, 14, 10, 1, -13 },
/* 0xE2 */ { 3393, 7, 10, 9, 1, -9 },
/* 0xE3 */ { 3402, 5, 10, 7, 1, -9 },
/* 0xE4 */ { 3409, 11, 12, 10, 0, -9 },
/* 0xE5 */ { 3426, 8, 10, 10, 1, -9 },
/* 0xE6 */ { 3436, 12, 10, 14, 1, -9 },
/* 0xE7 */ { 3451, 7, 10, 9, 1, -9 },
/* 0xE8 */ { 3460, 8, 10, 10, 1, -9 },
/* 0xE9 */ { 3470, 8, 12, 10, 1, -11 },
/* 0xEA */ { 3482, 7, 10, 9, 1, -9 },
/* 0xEB */ { 3491, 7, 10, 8, 0, -9 },
/* 0xEC */ { 3500, 9, 10, 11, 1, -9 },
/* 0xED */ { 3512, 8, 10, 10, 1, -9 },
/* 0xEE */ { 3522, 8, 10, 10, 1, -9 },
/* 0xEF */ { 3532, 8, 10, 10, 1, -9 },
/* 0xF0 */ { 3542, 9, 13, 10, 1, -9 },
/* 0xF1 */ { 3557, 8, 10, 9, 1, -9 },
/* 0xF2 */ { 3567, 6, 10, 7, 1, -9 },
/* 0xF3 */ { 3575, 8, 14, 9, 0, -9 },
/* 0xF4 */ { 3589, 14, 15, 15, 1, -11 },
/* 0xF5 */ { 3616, 7, 10, 9, 1, -9 },
/* 0xF6 */ { 3625, 10, 12, 10, 1, -9 },
/* 0xF7 */ { 3640, 7, 10, 9, 1, -9 },
/* 0xF8 */ { 3649, 10, 10, 12, 1, -9 },
/* 0xF9 */ { 3662, 12, 12, 13, 1, -9 },
/* 0xFA */ { 3680, 9, 10, 12, 2, -9 },
/* 0xFB */ { 3692, 10, 10, 12, 1, -9 },
/* 0xFC */ { 3705, 8, 10, 9, 1, -9 },
/* 0xFD */ { 3715, 8, 10, 9, 1, -9 },
/* 0xFE */ { 3725, 12, 10, 13, 1, -9 },
/* 0xFF */ { 3740, 8, 10, 10, 1, -9 },
};
const GFXfont FreeSans9pt_Win1251 PROGMEM = {
(uint8_t*)FreeSans9pt_Win1251Bitmaps,
(GFXglyph*)FreeSans9pt_Win1251Glyphs,
0x01, 0xFF, 21
};
@@ -0,0 +1,527 @@
// trunk-ignore-all(clang-format)
#pragma once
/* PROPERTIES
FONT_NAME FreeSans9pt_Win1252
*/
const uint8_t FreeSans9pt_Win1252Bitmaps[] PROGMEM = {
/* 0x01 */ 0x07, 0x00, 0x0A, 0x00, 0x24, 0x00, 0x48, 0x01, 0x10, 0x04, 0x40, 0x10, 0xFF, 0x20, 0x02, 0x81, 0xFD, 0x00, 0x06, 0x07, 0xF4, 0x08, 0x24, 0x0F, 0x88, 0x11, 0x0F, 0xDC, 0x00,
/* 0x02 */ 0x3F, 0x70, 0x81, 0x11, 0x03, 0xE4, 0x08, 0x28, 0x1F, 0xD0, 0x00, 0x60, 0x7F, 0x20, 0x02, 0x43, 0xFC, 0x44, 0x00, 0x44, 0x00, 0x48, 0x00, 0x90, 0x00, 0xA0, 0x01, 0xC0, 0x00,
/* 0x03 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x00, 0x31, 0x8C, 0x63, 0x18, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x20, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x04 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x82, 0x30, 0x88, 0x62, 0x08, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x3F, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x05 */ 0x0B, 0x10, 0x14, 0xA8, 0x12, 0x50, 0x29, 0x42, 0x24, 0xA5, 0x32, 0x95, 0x5A, 0x09, 0x48, 0x09, 0x24, 0x01, 0x10, 0x01, 0x48, 0x02, 0xA4, 0x02, 0x42, 0x04, 0x01, 0x98, 0x00, 0x60,
/* 0x06 */ 0x00, 0x80, 0x22, 0x80, 0x65, 0x00, 0xBE, 0xE1, 0x82, 0x4E, 0x03, 0x24, 0x04, 0x28, 0x06, 0x30, 0x12, 0x20, 0x3C, 0xA0, 0xC3, 0xFE, 0x80, 0x4D, 0x00, 0xA6, 0x01, 0x80, 0x00,
/* 0x07 */
/* 0x08 */ 0x00, 0xF8, 0x00, 0x82, 0x00, 0x80, 0x83, 0xE0, 0x41, 0x10, 0x21, 0x04, 0x1B, 0x00, 0x03, 0x00, 0x01, 0x80, 0x00, 0xE0, 0x00, 0x4F, 0xE1, 0xC0, 0x0F, 0x02, 0x00, 0x03, 0x01, 0x00, 0x09, 0x88, 0x0C, 0x0C,
/* 0x09 */ 0x00, 0xF8, 0x00, 0x82, 0x00, 0x80, 0x83, 0xE0, 0x41, 0x10, 0x21, 0x04, 0x1B, 0x00, 0x03, 0x00, 0x01, 0x80, 0x00, 0xE0, 0x00, 0x4F, 0xE1, 0xC0, 0x0F, 0x00,
/* 0x0A */
/* 0x0B */ 0x1C, 0x1C, 0x31, 0xB1, 0x90, 0x50, 0x50, 0x10, 0x18, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x02, 0x80, 0x02, 0x40, 0x01, 0x10, 0x01, 0x04, 0x01, 0x01, 0x01, 0x00, 0x41, 0x00, 0x11, 0x00, 0x07, 0x00, 0x01, 0x00,
/* 0x0C */ 0x06, 0x00, 0x0A, 0x00, 0x12, 0x00, 0x32, 0x01, 0x84, 0x04, 0x10, 0x08, 0x98, 0x1C, 0x18, 0x40, 0x48, 0x82, 0x11, 0xF0, 0x74, 0x02, 0x18, 0x70, 0x2F, 0x9F, 0x80,
/* 0x0D */
/* 0x0E */ 0x01, 0x00, 0x05, 0x00, 0x0A, 0x00, 0x3E, 0x00, 0x82, 0x02, 0x82, 0x06, 0x04, 0x10, 0x04, 0x20, 0x08, 0x40, 0x10, 0xFF, 0x22, 0x00, 0x29, 0xFF, 0x3F, 0x8F, 0xDF, 0x9F, 0x01, 0xC0,
/* 0x0F */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x82, 0x36, 0x03, 0x60, 0x00, 0xCC, 0x19, 0xA4, 0x4B, 0x00, 0x06, 0x8E, 0x2B, 0x22, 0x66, 0x7C, 0xCC, 0x71, 0x98, 0x03, 0x00,
/* 0x10 */ 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x1E, 0x00, 0x54, 0x00, 0xA8, 0x01, 0x50, 0x02, 0xA0, 0x05, 0x20, 0x32, 0x61, 0xC4, 0x74, 0x49, 0x10, 0x6C, 0x00, 0xD8, 0x01, 0x10, 0x00,
/* 0x11 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x40, 0x29, 0x00, 0x31, 0x84, 0x63, 0x18, 0xC0, 0x00, 0x80, 0x15, 0x03, 0x7E, 0x02, 0xFA, 0x04, 0xE4, 0x18, 0x84, 0x00, 0x06, 0x0C, 0x03, 0xE0,
/* 0x12 */ 0x02, 0x08, 0x01, 0x08, 0x40, 0x10, 0xC0, 0x08, 0xC0, 0x60, 0x80, 0x28, 0x04, 0x12, 0x4C, 0x10, 0x80, 0x08, 0x23, 0x0E, 0x08, 0xC4, 0x82, 0x04, 0x20, 0x83, 0x09, 0x82, 0x47, 0x01, 0x1C, 0x01, 0x30, 0x00, 0xE0, 0x00, 0x00,
/* 0x13 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x00, 0x31, 0x08, 0x65, 0x28, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x3F, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x14 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x22, 0x29, 0x83, 0x30, 0x00, 0x65, 0x14, 0xD3, 0x4D, 0xBA, 0xEB, 0x38, 0xE6, 0x00, 0x0A, 0x00, 0x24, 0x38, 0x44, 0x01, 0x07, 0x1C, 0x01, 0xC0,
/* 0x15 */ 0x07, 0xC0, 0x30, 0x18, 0x80, 0x32, 0x00, 0xF8, 0x01, 0xF1, 0x09, 0xA5, 0x28, 0x40, 0x01, 0x80, 0x03, 0x00, 0x06, 0x3F, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x16 */ 0x0C, 0x00, 0xC0, 0x1C, 0x03, 0x80, 0xF8, 0xBB, 0x36, 0xC7, 0x99, 0xF3, 0xFE, 0x3F, 0xC3, 0xF0, 0x7E, 0x0E, 0xC1, 0x8E, 0xE0, 0x20,
/* 0x17 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x00, 0x10, 0x01, 0x20, 0x1D, 0x44, 0x42, 0x84, 0x85, 0x00, 0x86, 0x00, 0xC4, 0x00, 0x44, 0x7C, 0x44, 0x00, 0x06, 0x0C, 0x03, 0xE0,
/* 0x18 */ 0x01, 0xE0, 0x00, 0x84, 0x00, 0x40, 0x80, 0x20, 0x10, 0x08, 0x24, 0x02, 0x41, 0x00, 0x86, 0x03, 0x12, 0x03, 0xB4, 0x03, 0x52, 0x81, 0x23, 0x80, 0x70, 0xA0, 0x14, 0x28, 0x05, 0x0A, 0x01, 0x42, 0x80, 0x50,
/* 0x19 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x00, 0x33, 0x18, 0x60, 0x00, 0xDC, 0xE1, 0xB9, 0xC3, 0x7B, 0xC6, 0x63, 0x0A, 0x00, 0x24, 0xF0, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x1A */ 0xFF, 0xFC, 0x00, 0x63, 0xE3, 0x31, 0x99, 0x04, 0xC8, 0x66, 0x06, 0x30, 0x61, 0x82, 0x0C, 0x10, 0x60, 0x03, 0x04, 0x18, 0x00, 0xFF, 0xFC,
/* 0x1B */ 0x07, 0xF0, 0x06, 0x0C, 0x04, 0x01, 0x04, 0x00, 0x44, 0x22, 0x12, 0x2A, 0x89, 0x00, 0x04, 0x80, 0x02, 0x44, 0x11, 0x01, 0xF0, 0x04, 0x01, 0x0D, 0x01, 0x6A, 0x41, 0x2C, 0x00, 0x05, 0xC0, 0x0E, 0x18, 0x18,
/* 0x1C */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0xC0, 0x2A, 0x00, 0x33, 0x00, 0x66, 0x00, 0xCC, 0x39, 0x80, 0x83, 0x00, 0x06, 0x00, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x1D */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x70, 0x28, 0x00, 0x31, 0x80, 0x63, 0x18, 0xC0, 0x31, 0x80, 0x03, 0x00, 0x06, 0x60, 0x0D, 0x33, 0x12, 0x10, 0x48, 0x21, 0x23, 0x8C, 0x00,
/* 0x1E */ 0x03, 0x00, 0x07, 0x9E, 0x07, 0x00, 0x86, 0x00, 0x27, 0xC0, 0x0F, 0xC0, 0x07, 0x8C, 0x62, 0x06, 0x31, 0x20, 0x00, 0x90, 0x00, 0x48, 0x00, 0x24, 0x3E, 0x11, 0x00, 0x10, 0x40, 0x10, 0x18, 0x30, 0x03, 0xE0,
/* 0x1F */ 0x18, 0x02, 0x80, 0x4C, 0x16, 0x41, 0x24, 0x3C, 0x88, 0x6E, 0x65, 0xF2, 0x78, 0x46, 0x88, 0xCF, 0x18, 0x02, 0x80, 0x8C, 0x60, 0x70,
/* ' ' 0x20 */
/* '!' 0x21 */ 0xFF, 0xFF, 0xF0, 0xC0,
/* '"' 0x22 */ 0xDE, 0xF7, 0x20,
/* '#' 0x23 */ 0x09, 0x86, 0x41, 0x91, 0xFF, 0x13, 0x04, 0xC3, 0x20, 0xC8, 0xFF, 0x89, 0x82, 0x61, 0x90,
/* '$' 0x24 */ 0x10, 0x1F, 0x14, 0xDA, 0x3D, 0x1E, 0x83, 0x40, 0x78, 0x17, 0x08, 0xF4, 0x7A, 0x35, 0x33, 0xF0, 0x40, 0x20,
/* '%' 0x25 */ 0x38, 0x10, 0xEC, 0x20, 0xC6, 0x20, 0xC6, 0x40, 0xC6, 0x40, 0x6C, 0x80, 0x39, 0x00, 0x01, 0x3C, 0x02, 0x77, 0x02, 0x63, 0x04, 0x63, 0x04, 0x77, 0x08, 0x3C,
/* '&' 0x26 */ 0x0E, 0x0C, 0xC3, 0x30, 0xCC, 0x1E, 0x03, 0x03, 0xC1, 0x9B, 0xC2, 0xF0, 0xEC, 0x19, 0x8F, 0x3C, 0x40,
/* ''' 0x27 */ 0xFE,
/* '(' 0x28 */ 0x13, 0x26, 0x6C, 0xCC, 0xCC, 0xC4, 0x66, 0x23, 0x10,
/* ')' 0x29 */ 0x8C, 0x46, 0x63, 0x33, 0x33, 0x32, 0x66, 0x4C, 0x80,
/* '*' 0x2A */ 0x25, 0x7E, 0xA5, 0x00,
/* '+' 0x2B */ 0x30, 0xC3, 0x3F, 0x30, 0xC3, 0x0C,
/* ',' 0x2C */ 0xD6,
/* '-' 0x2D */ 0xF0,
/* '.' 0x2E */ 0xC0,
/* '/' 0x2F */ 0x08, 0x44, 0x21, 0x10, 0x84, 0x42, 0x11, 0x08, 0x00,
/* '0' 0x30 */ 0x3C, 0x66, 0x42, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x42, 0x66, 0x3C,
/* '1' 0x31 */ 0x11, 0x3F, 0x33, 0x33, 0x33, 0x33, 0x30,
/* '2' 0x32 */ 0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x1C, 0x1C, 0x1C, 0x18, 0x18, 0x10, 0x08, 0x07, 0xF8,
/* '3' 0x33 */ 0x3C, 0x66, 0xC3, 0xC3, 0x03, 0x06, 0x1C, 0x07, 0x03, 0xC3, 0xC3, 0x66, 0x3C,
/* '4' 0x34 */ 0x0C, 0x18, 0x71, 0x62, 0xC9, 0xA3, 0x46, 0xFE, 0x18, 0x30, 0x60, 0xC0,
/* '5' 0x35 */ 0x7F, 0x20, 0x10, 0x08, 0x08, 0x07, 0xF3, 0x8C, 0x03, 0x01, 0x80, 0xF0, 0x6C, 0x63, 0xE0,
/* '6' 0x36 */ 0x1E, 0x31, 0x98, 0x78, 0x0C, 0x06, 0xF3, 0x8D, 0x83, 0xC1, 0xE0, 0xD0, 0x6C, 0x63, 0xE0,
/* '7' 0x37 */ 0xFF, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x18, 0x18, 0x18, 0x10, 0x30, 0x30,
/* '8' 0x38 */ 0x3E, 0x31, 0xB0, 0x78, 0x3C, 0x1B, 0x18, 0xF8, 0xC6, 0xC1, 0xE0, 0xF0, 0x6C, 0x63, 0xE0,
/* '9' 0x39 */ 0x3C, 0x66, 0xC2, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0xC2, 0x66, 0x3C,
/* ':' 0x3A */ 0xC0, 0x00, 0x30,
/* ';' 0x3B */ 0xC0, 0x00, 0x00, 0x64, 0xA0,
/* '<' 0x3C */ 0x00, 0x81, 0xC7, 0x8E, 0x0C, 0x07, 0x80, 0x70, 0x0E, 0x01, 0x80,
/* '=' 0x3D */ 0xFF, 0x80, 0x00, 0x1F, 0xF0,
/* '>' 0x3E */ 0xE0, 0x1C, 0x03, 0x80, 0x30, 0x70, 0xE3, 0x81, 0x00,
/* '?' 0x3F */ 0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x18, 0x38, 0x18, 0x18, 0x0C, 0x00, 0x00, 0x01, 0x80,
/* '@' 0x40 */ 0x03, 0xF0, 0x06, 0x0E, 0x06, 0x01, 0x86, 0x00, 0x66, 0x1D, 0xBB, 0x31, 0xCF, 0x18, 0xC7, 0x98, 0x63, 0xCC, 0x31, 0xE6, 0x11, 0xB3, 0x99, 0xCC, 0xF7, 0x86, 0x00, 0x01, 0x80, 0x00, 0x70, 0x40, 0x0F, 0xE0,
/* 'A' 0x41 */ 0x06, 0x00, 0xF0, 0x0F, 0x00, 0x90, 0x19, 0x81, 0x98, 0x10, 0x83, 0x0C, 0x3F, 0xC2, 0x04, 0x60, 0x66, 0x06, 0xC0, 0x30,
/* 'B' 0x42 */ 0xFF, 0x18, 0x33, 0x03, 0x60, 0x6C, 0x0D, 0x83, 0x3F, 0xC6, 0x06, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x6F, 0xF8,
/* 'C' 0x43 */ 0x1F, 0x86, 0x19, 0x81, 0xA0, 0x3C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0x61, 0xF0,
/* 'D' 0x44 */ 0xFF, 0x18, 0x33, 0x03, 0x60, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x03, 0x60, 0xCF, 0xF0,
/* 'E' 0x45 */ 0xFF, 0xE0, 0x30, 0x18, 0x0C, 0x06, 0x03, 0xFD, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0F, 0xF8,
/* 'F' 0x46 */ 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
/* 'G' 0x47 */ 0x0F, 0x83, 0x0E, 0x60, 0x66, 0x03, 0xC0, 0x0C, 0x00, 0xC1, 0xFC, 0x03, 0xC0, 0x36, 0x03, 0x60, 0x73, 0x0F, 0x0F, 0x10,
/* 'H' 0x48 */ 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xFF, 0xFE, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x06,
/* 'I' 0x49 */ 0xFF, 0xFF, 0xFF, 0xC0,
/* 'J' 0x4A */ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x07, 0x8F, 0x1E, 0x27, 0x80,
/* 'K' 0x4B */ 0xC0, 0xF0, 0x6C, 0x33, 0x18, 0xCC, 0x37, 0x0F, 0xC3, 0x98, 0xC3, 0x30, 0xCC, 0x1B, 0x03, 0xC0, 0xC0,
/* 'L' 0x4C */ 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF,
/* 'M' 0x4D */ 0xE0, 0x3F, 0x01, 0xFC, 0x1F, 0xE0, 0xFD, 0x05, 0xEC, 0x6F, 0x63, 0x79, 0x13, 0xCD, 0x9E, 0x6C, 0xF1, 0x47, 0x8E, 0x3C, 0x71, 0x80,
/* 'N' 0x4E */ 0xE0, 0x7C, 0x0F, 0xC1, 0xE8, 0x3D, 0x87, 0x98, 0xF1, 0x1E, 0x33, 0xC3, 0x78, 0x6F, 0x07, 0xE0, 0x7C, 0x0E,
/* 'O' 0x4F */ 0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x0C, 0x60, 0xC0, 0xF8, 0x00,
/* 'P' 0x50 */ 0xFF, 0x30, 0x6C, 0x0F, 0x03, 0xC0, 0xF0, 0x6F, 0xF3, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x00,
/* 'Q' 0x51 */ 0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x6C, 0x60, 0xC0, 0xFB, 0x00, 0x08,
/* 'R' 0x52 */ 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x0C, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x70,
/* 'S' 0x53 */ 0x3F, 0x18, 0x6C, 0x0F, 0x03, 0xC0, 0x1E, 0x01, 0xF0, 0x0E, 0x00, 0xF0, 0x3C, 0x0D, 0x86, 0x3F, 0x00,
/* 'T' 0x54 */ 0xFF, 0x86, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0,
/* 'U' 0x55 */ 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xB0, 0x61, 0xF0,
/* 'V' 0x56 */ 0xC0, 0x6C, 0x0D, 0x81, 0x10, 0x63, 0x0C, 0x61, 0x04, 0x60, 0xCC, 0x19, 0x01, 0x60, 0x3C, 0x07, 0x00, 0x60,
/* 'W' 0x57 */ 0xC1, 0x81, 0x61, 0xC3, 0x61, 0xC3, 0x61, 0x43, 0x62, 0x62, 0x22, 0x66, 0x32, 0x26, 0x36, 0x26, 0x14, 0x34, 0x14, 0x34, 0x1C, 0x1C, 0x18, 0x1C, 0x08, 0x18,
/* 'X' 0x58 */ 0xC0, 0xD8, 0x66, 0x18, 0xCC, 0x1E, 0x07, 0x00, 0xC0, 0x78, 0x32, 0x0C, 0xC6, 0x1B, 0x07, 0xC0, 0xC0,
/* 'Y' 0x59 */ 0xC0, 0x36, 0x06, 0x30, 0xC3, 0x0C, 0x19, 0x81, 0xD8, 0x0F, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00,
/* 'Z' 0x5A */ 0xFF, 0xC0, 0x60, 0x30, 0x0C, 0x06, 0x03, 0x01, 0xC0, 0x60, 0x30, 0x18, 0x06, 0x03, 0x00, 0xFF, 0xC0,
/* '[' 0x5B */ 0xFB, 0x6D, 0xB6, 0xDB, 0x6D, 0xB6, 0xE0,
/* '\' 0x5C */ 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x80,
/* ']' 0x5D */ 0xED, 0xB6, 0xDB, 0x6D, 0xB6, 0xDB, 0xE0,
/* '^' 0x5E */ 0x30, 0x60, 0xA2, 0x44, 0xD8, 0xA1, 0x80,
/* '_' 0x5F */ 0xFF, 0xC0,
/* '`' 0x60 */ 0xC6, 0x30,
/* 'a' 0x61 */ 0x7E, 0x71, 0xB0, 0xC0, 0x60, 0xF3, 0xDB, 0x0D, 0x86, 0xC7, 0x3D, 0xC0,
/* 'b' 0x62 */ 0xC0, 0x60, 0x30, 0x1B, 0xCE, 0x36, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x7C, 0x6D, 0xE0,
/* 'c' 0x63 */ 0x3C, 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 'd' 0x64 */ 0x03, 0x03, 0x03, 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B,
/* 'e' 0x65 */ 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 'f' 0x66 */ 0x36, 0x6F, 0x66, 0x66, 0x66, 0x66, 0x60,
/* 'g' 0x67 */ 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0xC6, 0x7C,
/* 'h' 0x68 */ 0xC0, 0xC0, 0xC0, 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
/* 'i' 0x69 */ 0xC3, 0xFF, 0xFF, 0xC0,
/* 'j' 0x6A */ 0x30, 0x03, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xE0,
/* 'k' 0x6B */ 0xC0, 0xC0, 0xC0, 0xC2, 0xC4, 0xCC, 0xD8, 0xF8, 0xEC, 0xC4, 0xC6, 0xC3, 0xC3,
/* 'l' 0x6C */ 0xFF, 0xFF, 0xFF, 0xC0,
/* 'm' 0x6D */ 0xDE, 0xF7, 0x1C, 0xF0, 0xC7, 0x86, 0x3C, 0x31, 0xE1, 0x8F, 0x0C, 0x78, 0x63, 0xC3, 0x1E, 0x18, 0xC0,
/* 'n' 0x6E */ 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
/* 'o' 0x6F */ 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C,
/* 'p' 0x70 */ 0xDE, 0x71, 0xB0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xE3, 0x6F, 0x30, 0x18, 0x0C, 0x00,
/* 'q' 0x71 */ 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0x03,
/* 'r' 0x72 */ 0xDF, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x00,
/* 's' 0x73 */ 0x3E, 0xE3, 0xC0, 0xC0, 0xE0, 0x3C, 0x07, 0xC3, 0xE3, 0x7E,
/* 't' 0x74 */ 0x66, 0xF6, 0x66, 0x66, 0x66, 0x67,
/* 'u' 0x75 */ 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B,
/* 'v' 0x76 */ 0xC1, 0xA0, 0x98, 0xCC, 0x42, 0x21, 0xB0, 0xD0, 0x28, 0x1C, 0x0C, 0x00,
/* 'w' 0x77 */ 0xC6, 0x1E, 0x38, 0x91, 0xC4, 0xCA, 0x66, 0xD3, 0x16, 0xD0, 0xA6, 0x87, 0x1C, 0x38, 0xC0, 0xC6, 0x00,
/* 'x' 0x78 */ 0x87, 0x89, 0xB1, 0xC3, 0x07, 0x1E, 0x26, 0xC5, 0x0C,
/* 'y' 0x79 */ 0xC1, 0x43, 0x63, 0x62, 0x26, 0x36, 0x34, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x60,
/* 'z' 0x7A */ 0xFE, 0x0C, 0x30, 0xC1, 0x86, 0x18, 0x20, 0xC1, 0xFC,
/* '{' 0x7B */ 0x36, 0x66, 0x66, 0x6E, 0xCE, 0x66, 0x66, 0x66, 0x30,
/* '|' 0x7C */ 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
/* '}' 0x7D */ 0xC6, 0x66, 0x66, 0x67, 0x37, 0x66, 0x66, 0x66, 0xC0,
/* '~' 0x7E */ 0x61, 0x24, 0x38,
/* 0x7F */
/* 0x80 */ 0x07, 0xC6, 0x13, 0x00, 0xC0, 0x60, 0x3F, 0xE6, 0x03, 0xFC, 0x60, 0x0C, 0x03, 0x00, 0x61, 0x07, 0xC0,
/* 0x81 */
/* 0x82 */ 0xDC,
/* 0x83 */ 0x19, 0x8C, 0xF3, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0xE0,
/* 0x84 */ 0xDA, 0x76,
/* 0x85 */ 0xCC, 0xC0,
/* 0x86 */ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
/* 0x87 */ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18,
/* 0x88 */ 0x72, 0xA2,
/* 0x89 */ 0x70, 0x80, 0x22, 0x20, 0x08, 0x90, 0x02, 0x24, 0x00, 0x72, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x10, 0x00, 0x09, 0xC7, 0x84, 0x8B, 0x31, 0x22, 0x84, 0x88, 0xB3, 0x21, 0xC7, 0x80,
/* 0x8A */ 0x1B, 0x03, 0x80, 0x00, 0xFC, 0x61, 0xB0, 0x3C, 0x0F, 0x00, 0x78, 0x07, 0xC0, 0x38, 0x03, 0xC0, 0xF0, 0x36, 0x18, 0xFC,
/* 0x8B */ 0x69,
/* 0x8C */ 0x1E, 0xFE, 0x43, 0x81, 0x83, 0x06, 0x06, 0x0C, 0x0C, 0x18, 0x18, 0x30, 0x3F, 0xE0, 0x60, 0xC0, 0xC1, 0x81, 0x81, 0x83, 0x01, 0x8E, 0x01, 0xEF, 0xE0,
/* 0x8D */
/* 0x8E */ 0x1B, 0x03, 0x80, 0x03, 0xFF, 0x01, 0x80, 0xC0, 0x30, 0x18, 0x0C, 0x07, 0x01, 0x80, 0xC0, 0x60, 0x18, 0x0C, 0x03, 0xFF,
/* 0x8F */
/* 0x90 */
/* 0x91 */ 0x6B,
/* 0x92 */ 0xD6,
/* 0x93 */ 0x4C, 0xA5, 0xB0,
/* 0x94 */ 0xDA, 0x53, 0x20,
/* 0x95 */ 0x6F, 0xFF, 0x60,
/* 0x96 */ 0xFE,
/* 0x97 */ 0xFF, 0xFF,
/* 0x98 */ 0x4D, 0xC0,
/* 0x99 */ 0xFC, 0xE1, 0xCC, 0x38, 0x73, 0x0E, 0x1C, 0xC3, 0x8F, 0x30, 0xD2, 0xCC, 0x34, 0xB3, 0x0D, 0x6C, 0xC3, 0x53, 0x30, 0xCC, 0xCC, 0x33, 0x30,
/* 0x9A */ 0x24, 0x3C, 0x18, 0x7E, 0xE3, 0xC0, 0xC0, 0x60, 0x3C, 0x07, 0xC3, 0xE3, 0x7E,
/* 0x9B */ 0x96,
/* 0x9C */ 0x3C, 0xF8, 0xCF, 0x1B, 0x0C, 0x1E, 0x18, 0x3C, 0x3F, 0xF8, 0x60, 0x30, 0xC0, 0x61, 0x83, 0x67, 0x8C, 0x79, 0xF0,
/* 0x9D */
/* 0x9E */ 0x48, 0xF0, 0xC7, 0xF0, 0x61, 0x86, 0x0C, 0x30, 0xC1, 0x06, 0x0F, 0xE0,
/* 0x9F */ 0x19, 0x80, 0x00, 0xC0, 0x36, 0x06, 0x30, 0xC3, 0x0C, 0x19, 0x81, 0xD8, 0x0F, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60,
/* 0xA0 */
/* 0xA1 */ 0xCF, 0xFF, 0xFF, 0xC0,
/* 0xA2 */ 0x08, 0x04, 0x0F, 0x8D, 0x6C, 0x9E, 0x43, 0x21, 0x90, 0xC8, 0x64, 0xDA, 0xC7, 0xC0, 0x80, 0x40,
/* 0xA3 */ 0x1F, 0x0C, 0x66, 0x0D, 0x83, 0x60, 0x0C, 0x0F, 0xC0, 0x60, 0x18, 0x06, 0x03, 0x01, 0xF1, 0x43, 0xC0,
/* 0xA4 */ 0xFF, 0xDF, 0x1E, 0x3E, 0xFF, 0xC0,
/* 0xA5 */ 0xC3, 0x42, 0x42, 0x24, 0x24, 0x3C, 0x18, 0x7E, 0x18, 0x7E, 0x18, 0x18, 0x18,
/* 0xA6 */ 0xFF, 0xFC, 0x0F, 0xFF, 0xC0,
/* 0xA7 */ 0x0C, 0x09, 0x0C, 0xC6, 0x63, 0x81, 0xE3, 0x19, 0x87, 0xE1, 0xB8, 0xC6, 0x41, 0xC0, 0x73, 0x19, 0x8C, 0x66, 0x1E, 0x00,
/* 0xA8 */ 0xCC,
/* 0xA9 */ 0x0F, 0xC0, 0x61, 0x87, 0x03, 0x9B, 0xC6, 0xD9, 0x8F, 0x60, 0x3D, 0x00, 0xF4, 0x03, 0xD8, 0x0D, 0xE6, 0x67, 0xF3, 0x86, 0x18, 0x0F, 0xC0,
/* 0xAA */ 0x74, 0x8D, 0xA9, 0x7C, 0x1F,
/* 0xAB */ 0x22, 0xCF, 0x26, 0x46, 0x64, 0x40,
/* 0xAC */ 0xFF, 0x80, 0xC0, 0x60, 0x30, 0x18,
/* 0xAD */
/* 0xAE */ 0x0F, 0xC0, 0x61, 0x87, 0x03, 0x9F, 0xE6, 0xD0, 0x8F, 0x42, 0x3D, 0xF0, 0xF4, 0x23, 0xD0, 0x8D, 0xC2, 0x67, 0x0B, 0x86, 0x18, 0x0F, 0xC0,
/* 0xAF */ 0xF8,
/* 0xB0 */ 0x74, 0x63, 0x17, 0x00,
/* 0xB1 */ 0x0C, 0x06, 0x03, 0x07, 0xE0, 0xC0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x3F, 0xE0,
/* 0xB2 */ 0x7B, 0x30, 0xC3, 0x11, 0x84, 0x3F,
/* 0xB3 */ 0x7D, 0x8C, 0x18, 0xC0, 0x60, 0xF1, 0xBE,
/* 0xB4 */ 0x36, 0xC0,
/* 0xB5 */ 0xC3, 0x61, 0xB0, 0xD8, 0x6C, 0x36, 0x1B, 0x0D, 0x86, 0xE7, 0x7D, 0xF0, 0x18, 0x0C, 0x00,
/* 0xB6 */ 0x3F, 0x7E, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0x72, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
/* 0xB7 */ 0xE0,
/* 0xB8 */ 0x21, 0xC7, 0xE0,
/* 0xB9 */ 0x3D, 0xB6, 0xD8,
/* 0xBA */ 0x74, 0x63, 0x18, 0xB8, 0x1F,
/* 0xBB */ 0x89, 0x98, 0x99, 0x3C, 0xD1, 0x00,
/* 0xBC */ 0x20, 0x43, 0x81, 0x06, 0x08, 0x18, 0x20, 0x61, 0x01, 0x84, 0x06, 0x21, 0x80, 0x86, 0x04, 0x78, 0x32, 0x60, 0x87, 0xC4, 0x06, 0x10, 0x18,
/* 0xBD */ 0x20, 0x43, 0x81, 0x06, 0x08, 0x18, 0x20, 0x61, 0x01, 0x8D, 0xE6, 0x2C, 0xC1, 0x03, 0x0C, 0x0C, 0x20, 0x41, 0x86, 0x0C, 0x30, 0x20, 0xFC,
/* 0xBE */ 0x78, 0x11, 0x98, 0x40, 0x31, 0x00, 0x82, 0x00, 0xC8, 0x01, 0x90, 0x33, 0x43, 0x3D, 0x06, 0x02, 0x3C, 0x08, 0x98, 0x10, 0xF8, 0x40, 0x61, 0x00, 0xC0,
/* 0xBF */ 0x0C, 0x00, 0x00, 0x01, 0x80, 0xC0, 0xC0, 0xE0, 0xC0, 0xC0, 0x60, 0xF0, 0x6C, 0x63, 0xE0,
/* 0xC0 */ 0x18, 0x03, 0x00, 0x00, 0x30, 0x1E, 0x07, 0x81, 0x20, 0xCC, 0x33, 0x0F, 0xC6, 0x19, 0x86, 0x40, 0xB0, 0x30,
/* 0xC1 */ 0x06, 0x03, 0x00, 0x00, 0x30, 0x1E, 0x07, 0x81, 0x20, 0xCC, 0x33, 0x0F, 0xC6, 0x19, 0x86, 0x40, 0xB0, 0x30,
/* 0xC2 */ 0x0C, 0x04, 0x80, 0x00, 0x30, 0x1E, 0x07, 0x81, 0x20, 0xCC, 0x33, 0x0F, 0xC6, 0x19, 0x86, 0x40, 0xB0, 0x30,
/* 0xC3 */ 0x19, 0x09, 0x80, 0x00, 0x30, 0x1E, 0x07, 0x81, 0x20, 0xCC, 0x33, 0x0F, 0xC6, 0x19, 0x86, 0x40, 0xB0, 0x30,
/* 0xC4 */ 0x33, 0x00, 0x00, 0xC0, 0x78, 0x1E, 0x04, 0x83, 0x30, 0xCC, 0x33, 0x1F, 0xE6, 0x19, 0x02, 0xC0, 0xF0, 0x30,
/* 0xC5 */ 0x0C, 0x04, 0x81, 0x20, 0x30, 0x1E, 0x07, 0x81, 0x20, 0xCC, 0x33, 0x0F, 0xC6, 0x19, 0x86, 0x40, 0xB0, 0x30,
/* 0xC6 */ 0x07, 0xFF, 0x04, 0xC0, 0x0C, 0xC0, 0x08, 0xC0, 0x18, 0xC0, 0x18, 0xC0, 0x30, 0xFF, 0x30, 0xC0, 0x3F, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF,
/* 0xC7 */ 0x1F, 0x06, 0x19, 0x83, 0xA0, 0x3C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0xE1, 0xF0, 0x08, 0x01, 0xC0, 0x18, 0x0E, 0x00,
/* 0xC8 */ 0x18, 0x06, 0x00, 0x1F, 0xFC, 0x06, 0x03, 0x01, 0x80, 0xFF, 0x60, 0x30, 0x18, 0x0C, 0x07, 0xFC,
/* 0xC9 */ 0x0C, 0x0C, 0x00, 0x1F, 0xFC, 0x06, 0x03, 0x01, 0x80, 0xFF, 0x60, 0x30, 0x18, 0x0C, 0x07, 0xFC,
/* 0xCA */ 0x1C, 0x1B, 0x00, 0x1F, 0xFC, 0x06, 0x03, 0x01, 0x80, 0xFF, 0x60, 0x30, 0x18, 0x0C, 0x07, 0xFC,
/* 0xCB */ 0x33, 0x00, 0x3F, 0xF8, 0x0C, 0x06, 0x03, 0x01, 0xFE, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x07, 0xFC,
/* 0xCC */ 0xCC, 0x36, 0xDB, 0x6D, 0xB6, 0xD8,
/* 0xCD */ 0x78, 0x36, 0xDB, 0x6D, 0xB6, 0xC0,
/* 0xCE */ 0x76, 0xC0, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18,
/* 0xCF */ 0xCC, 0x03, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC0,
/* 0xD0 */ 0x7F, 0x0C, 0x31, 0x83, 0x30, 0x36, 0x06, 0xC0, 0xFE, 0x1B, 0x03, 0x60, 0x6C, 0x0D, 0x83, 0x30, 0xE7, 0xF0,
/* 0xD1 */ 0x19, 0x02, 0xC3, 0x81, 0xF0, 0x3F, 0x07, 0xA0, 0xF6, 0x1E, 0x63, 0xC4, 0x78, 0xCF, 0x0D, 0xE1, 0xBC, 0x1F, 0x81, 0xC0,
/* 0xD2 */ 0x0C, 0x00, 0x60, 0x00, 0x00, 0xF0, 0x39, 0xC6, 0x06, 0x60, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x60, 0x63, 0x9C, 0x0F, 0x00,
/* 0xD3 */ 0x03, 0x00, 0x60, 0x00, 0x00, 0xF0, 0x39, 0xC6, 0x06, 0x60, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x60, 0x63, 0x9C, 0x0F, 0x00,
/* 0xD4 */ 0x0F, 0x01, 0x98, 0x00, 0x00, 0xF0, 0x39, 0xC6, 0x06, 0x60, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x60, 0x63, 0x9C, 0x0F, 0x00,
/* 0xD5 */ 0x1C, 0x81, 0x38, 0x00, 0x00, 0xF0, 0x39, 0xC6, 0x06, 0x60, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x60, 0x63, 0x9C, 0x0F, 0x00,
/* 0xD6 */ 0x19, 0x81, 0x98, 0x00, 0x00, 0xF0, 0x39, 0xC6, 0x06, 0x60, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x60, 0x63, 0x9C, 0x0F, 0x00,
/* 0xD7 */ 0x83, 0x89, 0xA1, 0x83, 0x89, 0xA1, 0x80,
/* 0xD8 */ 0x0F, 0xD9, 0x83, 0x18, 0x1C, 0xC1, 0xEC, 0x19, 0xE0, 0x8F, 0x08, 0x78, 0x83, 0xC8, 0x1B, 0x81, 0x98, 0x0C, 0xE0, 0xC8, 0xF8, 0x00,
/* 0xD9 */ 0x0C, 0x00, 0xC3, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x36, 0x0C, 0x3E, 0x00,
/* 0xDA */ 0x06, 0x01, 0x83, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x36, 0x0C, 0x3E, 0x00,
/* 0xDB */ 0x0E, 0x03, 0x63, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x36, 0x0C, 0x3E, 0x00,
/* 0xDC */ 0x1B, 0x00, 0x03, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x36, 0x0C, 0x3E, 0x00,
/* 0xDD */ 0x03, 0x0C, 0x63, 0x60, 0x63, 0x0C, 0x30, 0xC1, 0x98, 0x1D, 0x80, 0xF0, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60,
/* 0xDE */ 0xC0, 0x30, 0x0F, 0xF3, 0x06, 0xC0, 0xF0, 0x3C, 0x0F, 0x06, 0xFF, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x00,
/* 0xDF */ 0x3C, 0x33, 0x30, 0xD8, 0x6C, 0x36, 0x33, 0x39, 0x86, 0xC1, 0xE0, 0xF0, 0x78, 0x6D, 0xE0,
/* 0xE0 */ 0x60, 0x18, 0x06, 0x0F, 0xCE, 0x36, 0x18, 0x0C, 0x1E, 0x7B, 0x61, 0xB0, 0xD8, 0xE7, 0xB8,
/* 0xE1 */ 0x0C, 0x04, 0x04, 0x0F, 0xCE, 0x36, 0x18, 0x0C, 0x1E, 0x7B, 0x61, 0xB0, 0xD8, 0xE7, 0xB8,
/* 0xE2 */ 0x10, 0x14, 0x1B, 0x0F, 0xCE, 0x36, 0x18, 0x0C, 0x1E, 0x7B, 0x61, 0xB0, 0xD8, 0xE7, 0xB8,
/* 0xE3 */ 0x24, 0x2E, 0x00, 0x0F, 0xCE, 0x36, 0x18, 0x0C, 0x1E, 0x7B, 0x61, 0xB0, 0xD8, 0xE7, 0xB8,
/* 0xE4 */ 0x66, 0x00, 0x1F, 0x9C, 0x6C, 0x30, 0x18, 0x3C, 0xF6, 0xC3, 0x61, 0xB1, 0xCF, 0x70,
/* 0xE5 */ 0x1C, 0x1B, 0x0D, 0x83, 0x87, 0xE7, 0x1B, 0x0C, 0x06, 0x0F, 0x3D, 0xB0, 0xD8, 0x6C, 0x73, 0xDC,
/* 0xE6 */ 0x7E, 0xF9, 0xC7, 0x1B, 0x0C, 0x18, 0x18, 0x33, 0xFF, 0xFC, 0x60, 0x30, 0xC0, 0x61, 0x83, 0xC7, 0x8C, 0xF1, 0xF0,
/* 0xE7 */ 0x3C, 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, 0x10, 0x1C, 0x0C, 0x38,
/* 0xE8 */ 0x60, 0x30, 0x18, 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 0xE9 */ 0x0C, 0x08, 0x18, 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 0xEA */ 0x10, 0x28, 0x6C, 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 0xEB */ 0x66, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 0xEC */ 0xCC, 0xB6, 0xDB, 0x6D, 0xB6,
/* 0xED */ 0x7A, 0x6D, 0xB6, 0xDB, 0x6C,
/* 0xEE */ 0x6E, 0x96, 0x66, 0x66, 0x66, 0x66, 0x60,
/* 0xEF */ 0xCC, 0x03, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C,
/* 0xF0 */ 0x34, 0x0C, 0x16, 0x03, 0x3F, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C,
/* 0xF1 */ 0x24, 0x5C, 0x00, 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
/* 0xF2 */ 0x30, 0x18, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C,
/* 0xF3 */ 0x0C, 0x18, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C,
/* 0xF4 */ 0x18, 0x24, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C,
/* 0xF5 */ 0x34, 0x2C, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C,
/* 0xF6 */ 0x66, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C,
/* 0xF7 */ 0x18, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x00, 0x30,
/* 0xF8 */ 0x3D, 0x66, 0xC7, 0xCB, 0xCB, 0xD3, 0xD3, 0xE3, 0x66, 0xBC,
/* 0xF9 */ 0x60, 0x30, 0x18, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B,
/* 0xFA */ 0x06, 0x0C, 0x18, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B,
/* 0xFB */ 0x3C, 0x66, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B,
/* 0xFC */ 0x66, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B,
/* 0xFD */ 0x06, 0x04, 0x08, 0xC1, 0x43, 0x63, 0x62, 0x26, 0x36, 0x34, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x60,
/* 0xFE */ 0xC0, 0x60, 0x30, 0x1B, 0xCE, 0x36, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x7C, 0x6D, 0xE6, 0x03, 0x01, 0x80,
/* 0xFF */ 0x33, 0x00, 0xC1, 0x43, 0x63, 0x62, 0x26, 0x36, 0x34, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x60,
};
const GFXglyph FreeSans9pt_Win1252Glyphs[] PROGMEM = {
/* 0x01 */ { 0, 15, 15, 17, 1, -13 },
/* 0x02 */ { 29, 15, 15, 17, 1, -13 },
/* 0x03 */ { 58, 15, 16, 17, 1, -14 },
/* 0x04 */ { 88, 15, 16, 17, 1, -14 },
/* 0x05 */ { 118, 16, 15, 18, 1, -13 },
/* 0x06 */ { 148, 15, 15, 17, 1, -13 },
/* 0x07 */ { 177, 0, 0, 8, 0, 0 },
/* 0x08 */ { 177, 17, 16, 19, 1, -14 },
/* 0x09 */ { 211, 17, 12, 19, 1, -12 },
/* 0x0A */ { 237, 0, 0, 8, 0, 0 },
/* 0x0B */ { 237, 17, 16, 19, 1, -14 },
/* 0x0C */ { 271, 15, 14, 17, 1, -12 },
/* 0x0D */ { 298, 0, 0, 8, 0, 0 },
/* 0x0E */ { 298, 15, 16, 17, 1, -14 },
/* 0x0F */ { 328, 15, 15, 17, 1, -13 },
/* 0x10 */ { 357, 15, 15, 17, 1, -13 },
/* 0x11 */ { 386, 15, 16, 17, 1, -14 },
/* 0x12 */ { 416, 17, 17, 19, 1, -15 },
/* 0x13 */ { 453, 15, 16, 17, 1, -14 },
/* 0x14 */ { 483, 15, 16, 17, 1, -14 },
/* 0x15 */ { 513, 15, 16, 17, 1, -14 },
/* 0x16 */ { 543, 11, 16, 13, 1, -14 },
/* 0x17 */ { 565, 15, 16, 17, 1, -14 },
/* 0x18 */ { 595, 18, 15, 20, 1, -13 },
/* 0x19 */ { 629, 15, 16, 17, 1, -14 },
/* 0x1A */ { 659, 13, 14, 15, 1, -12 },
/* 0x1B */ { 682, 17, 16, 19, 1, -14 },
/* 0x1C */ { 716, 15, 16, 17, 1, -14 },
/* 0x1D */ { 746, 15, 15, 17, 1, -13 },
/* 0x1E */ { 775, 17, 16, 19, 1, -14 },
/* 0x1F */ { 809, 11, 16, 13, 1, -14 },
/* ' ' 0x20 */ { 831, 0, 0, 5, 0, 0 },
/* '!' 0x21 */ { 831, 2, 13, 6, 2, -12 },
/* '"' 0x22 */ { 835, 5, 4, 6, 1, -12 },
/* '#' 0x23 */ { 838, 10, 12, 10, 0, -11 },
/* '$' 0x24 */ { 853, 9, 16, 10, 1, -13 },
/* '%' 0x25 */ { 871, 16, 13, 16, 1, -12 },
/* '&' 0x26 */ { 897, 10, 13, 12, 1, -12 },
/* ''' 0x27 */ { 914, 2, 4, 4, 1, -12 },
/* '(' 0x28 */ { 915, 4, 17, 6, 1, -12 },
/* ')' 0x29 */ { 924, 4, 17, 6, 1, -12 },
/* '*' 0x2A */ { 933, 5, 5, 7, 1, -12 },
/* '+' 0x2B */ { 937, 6, 8, 11, 3, -7 },
/* ',' 0x2C */ { 943, 2, 4, 5, 2, 0 },
/* '-' 0x2D */ { 944, 4, 1, 6, 1, -4 },
/* '.' 0x2E */ { 945, 2, 1, 5, 1, 0 },
/* '/' 0x2F */ { 946, 5, 13, 5, 0, -12 },
/* '0' 0x30 */ { 955, 8, 13, 10, 1, -12 },
/* '1' 0x31 */ { 968, 4, 13, 10, 3, -12 },
/* '2' 0x32 */ { 975, 9, 13, 10, 1, -12 },
/* '3' 0x33 */ { 990, 8, 13, 10, 1, -12 },
/* '4' 0x34 */ { 1003, 7, 13, 10, 2, -12 },
/* '5' 0x35 */ { 1015, 9, 13, 10, 1, -12 },
/* '6' 0x36 */ { 1030, 9, 13, 10, 1, -12 },
/* '7' 0x37 */ { 1045, 8, 13, 10, 0, -12 },
/* '8' 0x38 */ { 1058, 9, 13, 10, 1, -12 },
/* '9' 0x39 */ { 1073, 8, 13, 10, 1, -12 },
/* ':' 0x3A */ { 1086, 2, 10, 5, 1, -9 },
/* ';' 0x3B */ { 1089, 3, 12, 5, 1, -8 },
/* '<' 0x3C */ { 1094, 9, 9, 11, 1, -8 },
/* '=' 0x3D */ { 1105, 9, 4, 11, 1, -5 },
/* '>' 0x3E */ { 1110, 9, 8, 11, 1, -7 },
/* '?' 0x3F */ { 1119, 9, 13, 10, 1, -12 },
/* '@' 0x40 */ { 1134, 17, 16, 18, 1, -12 },
/* 'A' 0x41 */ { 1168, 12, 13, 12, 0, -12 },
/* 'B' 0x42 */ { 1188, 11, 13, 12, 1, -12 },
/* 'C' 0x43 */ { 1206, 11, 13, 13, 1, -12 },
/* 'D' 0x44 */ { 1224, 11, 13, 13, 1, -12 },
/* 'E' 0x45 */ { 1242, 9, 13, 11, 1, -12 },
/* 'F' 0x46 */ { 1257, 8, 13, 11, 1, -12 },
/* 'G' 0x47 */ { 1270, 12, 13, 14, 1, -12 },
/* 'H' 0x48 */ { 1290, 11, 13, 13, 1, -12 },
/* 'I' 0x49 */ { 1308, 2, 13, 5, 2, -12 },
/* 'J' 0x4A */ { 1312, 7, 13, 10, 1, -12 },
/* 'K' 0x4B */ { 1324, 10, 13, 12, 1, -12 },
/* 'L' 0x4C */ { 1341, 8, 13, 10, 1, -12 },
/* 'M' 0x4D */ { 1354, 13, 13, 15, 1, -12 },
/* 'N' 0x4E */ { 1376, 11, 13, 13, 1, -12 },
/* 'O' 0x4F */ { 1394, 13, 13, 14, 1, -12 },
/* 'P' 0x50 */ { 1416, 10, 13, 12, 1, -12 },
/* 'Q' 0x51 */ { 1433, 13, 14, 14, 1, -12 },
/* 'R' 0x52 */ { 1456, 12, 13, 13, 1, -12 },
/* 'S' 0x53 */ { 1476, 10, 13, 12, 1, -12 },
/* 'T' 0x54 */ { 1493, 9, 13, 11, 1, -12 },
/* 'U' 0x55 */ { 1508, 11, 13, 13, 1, -12 },
/* 'V' 0x56 */ { 1526, 11, 13, 11, 0, -12 },
/* 'W' 0x57 */ { 1544, 16, 13, 17, 0, -12 },
/* 'X' 0x58 */ { 1570, 10, 13, 12, 1, -12 },
/* 'Y' 0x59 */ { 1587, 12, 13, 12, 0, -12 },
/* 'Z' 0x5A */ { 1607, 10, 13, 11, 1, -12 },
/* '[' 0x5B */ { 1624, 3, 17, 5, 1, -12 },
/* '\' 0x5C */ { 1631, 5, 13, 5, 0, -12 },
/* ']' 0x5D */ { 1640, 3, 17, 5, 0, -12 },
/* '^' 0x5E */ { 1647, 7, 7, 8, 1, -12 },
/* '_' 0x5F */ { 1654, 10, 1, 10, 0, 3 },
/* '`' 0x60 */ { 1656, 4, 3, 5, 0, -12 },
/* 'a' 0x61 */ { 1658, 9, 10, 10, 1, -9 },
/* 'b' 0x62 */ { 1670, 9, 13, 10, 1, -12 },
/* 'c' 0x63 */ { 1685, 8, 10, 9, 1, -9 },
/* 'd' 0x64 */ { 1695, 8, 13, 10, 1, -12 },
/* 'e' 0x65 */ { 1708, 8, 10, 10, 1, -9 },
/* 'f' 0x66 */ { 1718, 4, 13, 5, 1, -12 },
/* 'g' 0x67 */ { 1725, 8, 14, 10, 1, -9 },
/* 'h' 0x68 */ { 1739, 8, 13, 10, 1, -12 },
/* 'i' 0x69 */ { 1752, 2, 13, 4, 1, -12 },
/* 'j' 0x6A */ { 1756, 4, 17, 4, 0, -12 },
/* 'k' 0x6B */ { 1765, 8, 13, 9, 1, -12 },
/* 'l' 0x6C */ { 1778, 2, 13, 4, 1, -12 },
/* 'm' 0x6D */ { 1782, 13, 10, 15, 1, -9 },
/* 'n' 0x6E */ { 1799, 8, 10, 10, 1, -9 },
/* 'o' 0x6F */ { 1809, 8, 10, 10, 1, -9 },
/* 'p' 0x70 */ { 1819, 9, 13, 10, 1, -9 },
/* 'q' 0x71 */ { 1834, 8, 13, 10, 1, -9 },
/* 'r' 0x72 */ { 1847, 5, 10, 6, 1, -9 },
/* 's' 0x73 */ { 1854, 8, 10, 9, 1, -9 },
/* 't' 0x74 */ { 1864, 4, 12, 5, 1, -11 },
/* 'u' 0x75 */ { 1870, 8, 10, 10, 1, -9 },
/* 'v' 0x76 */ { 1880, 9, 10, 9, 0, -9 },
/* 'w' 0x77 */ { 1892, 13, 10, 13, 0, -9 },
/* 'x' 0x78 */ { 1909, 7, 10, 9, 1, -9 },
/* 'y' 0x79 */ { 1918, 8, 14, 9, 0, -9 },
/* 'z' 0x7A */ { 1932, 7, 10, 9, 1, -9 },
/* '{' 0x7B */ { 1941, 4, 17, 6, 1, -12 },
/* '|' 0x7C */ { 1950, 2, 17, 4, 2, -12 },
/* '}' 0x7D */ { 1955, 4, 17, 6, 1, -12 },
/* '~' 0x7E */ { 1964, 7, 3, 9, 1, -7 },
/* 0x7F */ { 1967, 0, 0, 0, 0, 0 },
/* 0x80 */ { 1967, 10, 13, 12, 1, -12 },
/* 0x81 */ { 1984, 0, 0, 8, 0, 0 },
/* 0x82 */ { 1984, 2, 3, 5, 1, 0 },
/* 0x83 */ { 1985, 5, 17, 5, 0, -12 },
/* 0x84 */ { 1996, 5, 3, 7, 1, 0 },
/* 0x85 */ { 1998, 10, 1, 12, 1, 0 },
/* 0x86 */ { 2000, 8, 16, 10, 1, -12 },
/* 0x87 */ { 2016, 8, 16, 10, 1, -12 },
/* 0x88 */ { 2032, 5, 3, 6, 0, -12 },
/* 0x89 */ { 2034, 18, 13, 18, 0, -12 },
/* 0x8A */ { 2064, 10, 16, 12, 1, -15 },
/* 0x8B */ { 2084, 2, 4, 4, 1, -6 },
/* 0x8C */ { 2085, 15, 13, 18, 1, -12 },
/* 0x8D */ { 2110, 0, 0, 8, 0, 0 },
/* 0x8E */ { 2110, 10, 16, 11, 1, -15 },
/* 0x8F */ { 2130, 0, 0, 8, 0, 0 },
/* 0x90 */ { 2130, 0, 0, 8, 0, 0 },
/* 0x91 */ { 2130, 2, 4, 4, 2, -12 },
/* 0x92 */ { 2131, 2, 4, 4, 1, -12 },
/* 0x93 */ { 2132, 5, 4, 7, 2, -12 },
/* 0x94 */ { 2135, 5, 4, 7, 1, -12 },
/* 0x95 */ { 2138, 4, 5, 7, 1, -8 },
/* 0x96 */ { 2141, 7, 1, 9, 1, -4 },
/* 0x97 */ { 2142, 16, 1, 18, 1, -4 },
/* 0x98 */ { 2144, 5, 2, 6, 0, -12 },
/* 0x99 */ { 2146, 18, 10, 18, 1, -13 },
/* 0x9A */ { 2169, 8, 13, 9, 1, -12 },
/* 0x9B */ { 2182, 2, 4, 5, 2, -6 },
/* 0x9C */ { 2183, 15, 10, 17, 1, -9 },
/* 0x9D */ { 2202, 0, 0, 8, 0, 0 },
/* 0x9E */ { 2202, 7, 13, 9, 1, -12 },
/* 0x9F */ { 2214, 12, 14, 12, 0, -13 },
/* 0xA0 */ { 2235, 0, 0, 5, 0, 0 },
/* 0xA1 */ { 2235, 2, 13, 6, 2, -8 },
/* 0xA2 */ { 2239, 9, 14, 10, 1, -11 },
/* 0xA3 */ { 2255, 10, 13, 10, 0, -12 },
/* 0xA4 */ { 2272, 7, 6, 10, 2, -8 },
/* 0xA5 */ { 2278, 8, 13, 10, 1, -12 },
/* 0xA6 */ { 2291, 2, 17, 5, 2, -12 },
/* 0xA7 */ { 2296, 9, 17, 10, 1, -12 },
/* 0xA8 */ { 2316, 6, 1, 6, 0, -11 },
/* 0xA9 */ { 2317, 14, 13, 14, 1, -12 },
/* 0xAA */ { 2340, 5, 8, 7, 1, -12 },
/* 0xAB */ { 2345, 7, 6, 9, 1, -7 },
/* 0xAC */ { 2351, 9, 5, 11, 2, -5 },
/* 0xAD */ { 2357, 0, 0, 0, 0, 0 },
/* 0xAE */ { 2357, 14, 13, 14, 1, -12 },
/* 0xAF */ { 2380, 5, 1, 6, 0, -12 },
/* 0xB0 */ { 2381, 5, 5, 11, 3, -11 },
/* 0xB1 */ { 2385, 9, 11, 11, 1, -10 },
/* 0xB2 */ { 2398, 6, 8, 6, 1, -13 },
/* 0xB3 */ { 2404, 7, 8, 6, 0, -13 },
/* 0xB4 */ { 2411, 4, 3, 6, 2, -12 },
/* 0xB5 */ { 2413, 9, 13, 10, 1, -9 },
/* 0xB6 */ { 2428, 8, 16, 10, 2, -12 },
/* 0xB7 */ { 2444, 3, 1, 5, 1, -4 },
/* 0xB8 */ { 2445, 5, 4, 6, 1, 1 },
/* 0xB9 */ { 2448, 3, 7, 6, 2, -13 },
/* 0xBA */ { 2451, 5, 8, 7, 1, -12 },
/* 0xBB */ { 2456, 7, 6, 9, 1, -7 },
/* 0xBC */ { 2462, 14, 13, 16, 2, -12 },
/* 0xBD */ { 2485, 14, 13, 16, 2, -12 },
/* 0xBE */ { 2508, 15, 13, 16, 1, -12 },
/* 0xBF */ { 2533, 9, 13, 10, 1, -8 },
/* 0xC0 */ { 2548, 10, 14, 12, 1, -13 },
/* 0xC1 */ { 2566, 10, 14, 12, 1, -13 },
/* 0xC2 */ { 2584, 10, 14, 12, 1, -13 },
/* 0xC3 */ { 2602, 10, 14, 12, 1, -13 },
/* 0xC4 */ { 2620, 10, 14, 12, 1, -13 },
/* 0xC5 */ { 2638, 10, 14, 12, 1, -13 },
/* 0xC6 */ { 2656, 16, 13, 18, 1, -12 },
/* 0xC7 */ { 2682, 11, 17, 13, 1, -12 },
/* 0xC8 */ { 2706, 9, 14, 11, 1, -13 },
/* 0xC9 */ { 2722, 9, 14, 11, 1, -13 },
/* 0xCA */ { 2738, 9, 14, 11, 1, -13 },
/* 0xCB */ { 2754, 9, 14, 11, 1, -13 },
/* 0xCC */ { 2770, 3, 15, 5, 1, -13 },
/* 0xCD */ { 2776, 3, 14, 5, 1, -13 },
/* 0xCE */ { 2782, 5, 14, 5, 0, -13 },
/* 0xCF */ { 2791, 6, 14, 5, 0, -13 },
/* 0xD0 */ { 2802, 11, 13, 13, 1, -12 },
/* 0xD1 */ { 2820, 11, 14, 13, 1, -13 },
/* 0xD2 */ { 2840, 12, 15, 13, 1, -14 },
/* 0xD3 */ { 2863, 12, 15, 13, 1, -14 },
/* 0xD4 */ { 2886, 12, 15, 13, 1, -14 },
/* 0xD5 */ { 2909, 12, 15, 13, 1, -14 },
/* 0xD6 */ { 2932, 12, 15, 13, 1, -14 },
/* 0xD7 */ { 2955, 7, 7, 11, 2, -7 },
/* 0xD8 */ { 2962, 13, 13, 14, 1, -12 },
/* 0xD9 */ { 2984, 11, 14, 13, 1, -13 },
/* 0xDA */ { 3004, 11, 14, 13, 1, -13 },
/* 0xDB */ { 3024, 11, 14, 13, 1, -13 },
/* 0xDC */ { 3044, 11, 14, 13, 1, -13 },
/* 0xDD */ { 3064, 12, 14, 12, 0, -13 },
/* 0xDE */ { 3085, 10, 13, 12, 1, -12 },
/* 0xDF */ { 3102, 9, 13, 11, 1, -12 },
/* 0xE0 */ { 3117, 9, 13, 10, 1, -12 },
/* 0xE1 */ { 3132, 9, 13, 10, 1, -12 },
/* 0xE2 */ { 3147, 9, 13, 10, 1, -12 },
/* 0xE3 */ { 3162, 9, 13, 10, 1, -12 },
/* 0xE4 */ { 3177, 9, 12, 10, 1, -11 },
/* 0xE5 */ { 3191, 9, 14, 10, 1, -13 },
/* 0xE6 */ { 3207, 15, 10, 16, 1, -9 },
/* 0xE7 */ { 3226, 8, 14, 9, 1, -9 },
/* 0xE8 */ { 3240, 8, 13, 10, 1, -12 },
/* 0xE9 */ { 3253, 8, 13, 10, 1, -12 },
/* 0xEA */ { 3266, 8, 13, 10, 1, -12 },
/* 0xEB */ { 3279, 8, 12, 10, 1, -11 },
/* 0xEC */ { 3291, 3, 13, 4, 0, -12 },
/* 0xED */ { 3296, 3, 13, 4, 1, -12 },
/* 0xEE */ { 3301, 4, 13, 5, 0, -12 },
/* 0xEF */ { 3308, 6, 12, 5, -1, -11 },
/* 0xF0 */ { 3317, 8, 13, 10, 1, -12 },
/* 0xF1 */ { 3330, 8, 13, 10, 1, -12 },
/* 0xF2 */ { 3343, 8, 13, 10, 1, -12 },
/* 0xF3 */ { 3356, 8, 13, 10, 1, -12 },
/* 0xF4 */ { 3369, 8, 13, 10, 1, -12 },
/* 0xF5 */ { 3382, 8, 13, 10, 1, -12 },
/* 0xF6 */ { 3395, 8, 12, 10, 1, -11 },
/* 0xF7 */ { 3407, 9, 8, 11, 1, -7 },
/* 0xF8 */ { 3416, 8, 10, 10, 1, -9 },
/* 0xF9 */ { 3426, 8, 13, 10, 1, -12 },
/* 0xFA */ { 3439, 8, 13, 10, 1, -12 },
/* 0xFB */ { 3452, 8, 13, 10, 1, -12 },
/* 0xFC */ { 3465, 8, 12, 10, 1, -11 },
/* 0xFD */ { 3477, 8, 17, 9, 0, -12 },
/* 0xFE */ { 3494, 9, 16, 10, 1, -12 },
/* 0xFF */ { 3512, 8, 16, 9, 0, -11 },
};
const GFXfont FreeSans9pt_Win1252 PROGMEM = {
(uint8_t*)FreeSans9pt_Win1252Bitmaps,
(GFXglyph*)FreeSans9pt_Win1252Glyphs,
0x01, 0xFF, 16
};
@@ -0,0 +1,527 @@
// trunk-ignore-all(clang-format)
#pragma once
/* PROPERTIES
FONT_NAME FreeSans9pt_Win1253
*/
const uint8_t FreeSans9pt_Win1253Bitmaps[] PROGMEM = {
/* 0x01 */ 0x07, 0x00, 0x0A, 0x00, 0x24, 0x00, 0x48, 0x01, 0x10, 0x04, 0x40, 0x10, 0xFF, 0x20, 0x02, 0x81, 0xFD, 0x00, 0x06, 0x07, 0xF4, 0x08, 0x24, 0x0F, 0x88, 0x11, 0x0F, 0xDC, 0x00,
/* 0x02 */ 0x3F, 0x70, 0x81, 0x11, 0x03, 0xE4, 0x08, 0x28, 0x1F, 0xD0, 0x00, 0x60, 0x7F, 0x20, 0x02, 0x43, 0xFC, 0x44, 0x00, 0x44, 0x00, 0x48, 0x00, 0x90, 0x00, 0xA0, 0x01, 0xC0, 0x00,
/* 0x03 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x00, 0x31, 0x8C, 0x63, 0x18, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x20, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x04 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x82, 0x30, 0x88, 0x62, 0x08, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x3F, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x05 */ 0x0B, 0x10, 0x14, 0xA8, 0x12, 0x50, 0x29, 0x42, 0x24, 0xA5, 0x32, 0x95, 0x5A, 0x09, 0x48, 0x09, 0x24, 0x01, 0x10, 0x01, 0x48, 0x02, 0xA4, 0x02, 0x42, 0x04, 0x01, 0x98, 0x00, 0x60,
/* 0x06 */ 0x00, 0x80, 0x22, 0x80, 0x65, 0x00, 0xBE, 0xE1, 0x82, 0x4E, 0x03, 0x24, 0x04, 0x28, 0x06, 0x30, 0x12, 0x20, 0x3C, 0xA0, 0xC3, 0xFE, 0x80, 0x4D, 0x00, 0xA6, 0x01, 0x80, 0x00,
/* 0x07 */
/* 0x08 */ 0x00, 0xF8, 0x00, 0x82, 0x00, 0x80, 0x83, 0xE0, 0x41, 0x10, 0x21, 0x04, 0x1B, 0x00, 0x03, 0x00, 0x01, 0x80, 0x00, 0xE0, 0x00, 0x4F, 0xE1, 0xC0, 0x0F, 0x02, 0x00, 0x03, 0x01, 0x00, 0x09, 0x88, 0x0C, 0x0C,
/* 0x09 */ 0x00, 0xF8, 0x00, 0x82, 0x00, 0x80, 0x83, 0xE0, 0x41, 0x10, 0x21, 0x04, 0x1B, 0x00, 0x03, 0x00, 0x01, 0x80, 0x00, 0xE0, 0x00, 0x4F, 0xE1, 0xC0, 0x0F, 0x00,
/* 0x0A */
/* 0x0B */ 0x1C, 0x1C, 0x31, 0xB1, 0x90, 0x50, 0x50, 0x10, 0x18, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x02, 0x80, 0x02, 0x40, 0x01, 0x10, 0x01, 0x04, 0x01, 0x01, 0x01, 0x00, 0x41, 0x00, 0x11, 0x00, 0x07, 0x00, 0x01, 0x00,
/* 0x0C */ 0x06, 0x00, 0x0A, 0x00, 0x12, 0x00, 0x32, 0x01, 0x84, 0x04, 0x10, 0x08, 0x98, 0x1C, 0x18, 0x40, 0x48, 0x82, 0x11, 0xF0, 0x74, 0x02, 0x18, 0x70, 0x2F, 0x9F, 0x80,
/* 0x0D */
/* 0x0E */ 0x01, 0x00, 0x05, 0x00, 0x0A, 0x00, 0x3E, 0x00, 0x82, 0x02, 0x82, 0x06, 0x04, 0x10, 0x04, 0x20, 0x08, 0x40, 0x10, 0xFF, 0x22, 0x00, 0x29, 0xFF, 0x3F, 0x8F, 0xDF, 0x9F, 0x01, 0xC0,
/* 0x0F */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x82, 0x36, 0x03, 0x60, 0x00, 0xCC, 0x19, 0xA4, 0x4B, 0x00, 0x06, 0x8E, 0x2B, 0x22, 0x66, 0x7C, 0xCC, 0x71, 0x98, 0x03, 0x00,
/* 0x10 */ 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x1E, 0x00, 0x54, 0x00, 0xA8, 0x01, 0x50, 0x02, 0xA0, 0x05, 0x20, 0x32, 0x61, 0xC4, 0x74, 0x49, 0x10, 0x6C, 0x00, 0xD8, 0x01, 0x10, 0x00,
/* 0x11 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x40, 0x29, 0x00, 0x31, 0x84, 0x63, 0x18, 0xC0, 0x00, 0x80, 0x15, 0x03, 0x7E, 0x02, 0xFA, 0x04, 0xE4, 0x18, 0x84, 0x00, 0x06, 0x0C, 0x03, 0xE0,
/* 0x12 */ 0x02, 0x08, 0x01, 0x08, 0x40, 0x10, 0xC0, 0x08, 0xC0, 0x60, 0x80, 0x28, 0x04, 0x12, 0x4C, 0x10, 0x80, 0x08, 0x23, 0x0E, 0x08, 0xC4, 0x82, 0x04, 0x20, 0x83, 0x09, 0x82, 0x47, 0x01, 0x1C, 0x01, 0x30, 0x00, 0xE0, 0x00, 0x00,
/* 0x13 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x00, 0x31, 0x08, 0x65, 0x28, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x3F, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x14 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x22, 0x29, 0x83, 0x30, 0x00, 0x65, 0x14, 0xD3, 0x4D, 0xBA, 0xEB, 0x38, 0xE6, 0x00, 0x0A, 0x00, 0x24, 0x38, 0x44, 0x01, 0x07, 0x1C, 0x01, 0xC0,
/* 0x15 */ 0x07, 0xC0, 0x30, 0x18, 0x80, 0x32, 0x00, 0xF8, 0x01, 0xF1, 0x09, 0xA5, 0x28, 0x40, 0x01, 0x80, 0x03, 0x00, 0x06, 0x3F, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x16 */ 0x0C, 0x00, 0xC0, 0x1C, 0x03, 0x80, 0xF8, 0xBB, 0x36, 0xC7, 0x99, 0xF3, 0xFE, 0x3F, 0xC3, 0xF0, 0x7E, 0x0E, 0xC1, 0x8E, 0xE0, 0x20,
/* 0x17 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x00, 0x10, 0x01, 0x20, 0x1D, 0x44, 0x42, 0x84, 0x85, 0x00, 0x86, 0x00, 0xC4, 0x00, 0x44, 0x7C, 0x44, 0x00, 0x06, 0x0C, 0x03, 0xE0,
/* 0x18 */ 0x01, 0xE0, 0x00, 0x84, 0x00, 0x40, 0x80, 0x20, 0x10, 0x08, 0x24, 0x02, 0x41, 0x00, 0x86, 0x03, 0x12, 0x03, 0xB4, 0x03, 0x52, 0x81, 0x23, 0x80, 0x70, 0xA0, 0x14, 0x28, 0x05, 0x0A, 0x01, 0x42, 0x80, 0x50,
/* 0x19 */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x00, 0x28, 0x00, 0x33, 0x18, 0x60, 0x00, 0xDC, 0xE1, 0xB9, 0xC3, 0x7B, 0xC6, 0x63, 0x0A, 0x00, 0x24, 0xF0, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x1A */ 0xFF, 0xFC, 0x00, 0x63, 0xE3, 0x31, 0x99, 0x04, 0xC8, 0x66, 0x06, 0x30, 0x61, 0x82, 0x0C, 0x10, 0x60, 0x03, 0x04, 0x18, 0x00, 0xFF, 0xFC,
/* 0x1B */ 0x07, 0xF0, 0x06, 0x0C, 0x04, 0x01, 0x04, 0x00, 0x44, 0x22, 0x12, 0x2A, 0x89, 0x00, 0x04, 0x80, 0x02, 0x44, 0x11, 0x01, 0xF0, 0x04, 0x01, 0x0D, 0x01, 0x6A, 0x41, 0x2C, 0x00, 0x05, 0xC0, 0x0E, 0x18, 0x18,
/* 0x1C */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0xC0, 0x2A, 0x00, 0x33, 0x00, 0x66, 0x00, 0xCC, 0x39, 0x80, 0x83, 0x00, 0x06, 0x00, 0x8C, 0x3E, 0x14, 0x00, 0x44, 0x01, 0x06, 0x0C, 0x03, 0xE0,
/* 0x1D */ 0x07, 0xC0, 0x30, 0x60, 0x80, 0x22, 0x70, 0x28, 0x00, 0x31, 0x80, 0x63, 0x18, 0xC0, 0x31, 0x80, 0x03, 0x00, 0x06, 0x60, 0x0D, 0x33, 0x12, 0x10, 0x48, 0x21, 0x23, 0x8C, 0x00,
/* 0x1E */ 0x03, 0x00, 0x07, 0x9E, 0x07, 0x00, 0x86, 0x00, 0x27, 0xC0, 0x0F, 0xC0, 0x07, 0x8C, 0x62, 0x06, 0x31, 0x20, 0x00, 0x90, 0x00, 0x48, 0x00, 0x24, 0x3E, 0x11, 0x00, 0x10, 0x40, 0x10, 0x18, 0x30, 0x03, 0xE0,
/* 0x1F */ 0x18, 0x02, 0x80, 0x4C, 0x16, 0x41, 0x24, 0x3C, 0x88, 0x6E, 0x65, 0xF2, 0x78, 0x46, 0x88, 0xCF, 0x18, 0x02, 0x80, 0x8C, 0x60, 0x70,
/* ' ' 0x20 */
/* '!' 0x21 */ 0xFF, 0xFF, 0xF0, 0xC0,
/* '"' 0x22 */ 0xDE, 0xF7, 0x20,
/* '#' 0x23 */ 0x09, 0x86, 0x41, 0x91, 0xFF, 0x13, 0x04, 0xC3, 0x20, 0xC8, 0xFF, 0x89, 0x82, 0x61, 0x90,
/* '$' 0x24 */ 0x10, 0x1F, 0x14, 0xDA, 0x3D, 0x1E, 0x83, 0x40, 0x78, 0x17, 0x08, 0xF4, 0x7A, 0x35, 0x33, 0xF0, 0x40, 0x20,
/* '%' 0x25 */ 0x38, 0x10, 0xEC, 0x20, 0xC6, 0x20, 0xC6, 0x40, 0xC6, 0x40, 0x6C, 0x80, 0x39, 0x00, 0x01, 0x3C, 0x02, 0x77, 0x02, 0x63, 0x04, 0x63, 0x04, 0x77, 0x08, 0x3C,
/* '&' 0x26 */ 0x0E, 0x0C, 0xC3, 0x30, 0xCC, 0x1E, 0x03, 0x03, 0xC1, 0x9B, 0xC2, 0xF0, 0xEC, 0x19, 0x8F, 0x3C, 0x40,
/* ''' 0x27 */ 0xFE,
/* '(' 0x28 */ 0x13, 0x26, 0x6C, 0xCC, 0xCC, 0xC4, 0x66, 0x23, 0x10,
/* ')' 0x29 */ 0x8C, 0x46, 0x63, 0x33, 0x33, 0x32, 0x66, 0x4C, 0x80,
/* '*' 0x2A */ 0x25, 0x7E, 0xA5, 0x00,
/* '+' 0x2B */ 0x30, 0xC3, 0x3F, 0x30, 0xC3, 0x0C,
/* ',' 0x2C */ 0xD6,
/* '-' 0x2D */ 0xF0,
/* '.' 0x2E */ 0xC0,
/* '/' 0x2F */ 0x08, 0x44, 0x21, 0x10, 0x84, 0x42, 0x11, 0x08, 0x00,
/* '0' 0x30 */ 0x3C, 0x66, 0x42, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x42, 0x66, 0x3C,
/* '1' 0x31 */ 0x11, 0x3F, 0x33, 0x33, 0x33, 0x33, 0x30,
/* '2' 0x32 */ 0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x1C, 0x1C, 0x1C, 0x18, 0x18, 0x10, 0x08, 0x07, 0xF8,
/* '3' 0x33 */ 0x3C, 0x66, 0xC3, 0xC3, 0x03, 0x06, 0x1C, 0x07, 0x03, 0xC3, 0xC3, 0x66, 0x3C,
/* '4' 0x34 */ 0x0C, 0x18, 0x71, 0x62, 0xC9, 0xA3, 0x46, 0xFE, 0x18, 0x30, 0x60, 0xC0,
/* '5' 0x35 */ 0x7F, 0x20, 0x10, 0x08, 0x08, 0x07, 0xF3, 0x8C, 0x03, 0x01, 0x80, 0xF0, 0x6C, 0x63, 0xE0,
/* '6' 0x36 */ 0x1E, 0x31, 0x98, 0x78, 0x0C, 0x06, 0xF3, 0x8D, 0x83, 0xC1, 0xE0, 0xD0, 0x6C, 0x63, 0xE0,
/* '7' 0x37 */ 0xFF, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x18, 0x18, 0x18, 0x10, 0x30, 0x30,
/* '8' 0x38 */ 0x3E, 0x31, 0xB0, 0x78, 0x3C, 0x1B, 0x18, 0xF8, 0xC6, 0xC1, 0xE0, 0xF0, 0x6C, 0x63, 0xE0,
/* '9' 0x39 */ 0x3C, 0x66, 0xC2, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0xC2, 0x66, 0x3C,
/* ':' 0x3A */ 0xC0, 0x00, 0x30,
/* ';' 0x3B */ 0xC0, 0x00, 0x00, 0x64, 0xA0,
/* '<' 0x3C */ 0x00, 0x81, 0xC7, 0x8E, 0x0C, 0x07, 0x80, 0x70, 0x0E, 0x01, 0x80,
/* '=' 0x3D */ 0xFF, 0x80, 0x00, 0x1F, 0xF0,
/* '>' 0x3E */ 0xE0, 0x1C, 0x03, 0x80, 0x30, 0x70, 0xE3, 0x81, 0x00,
/* '?' 0x3F */ 0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x18, 0x38, 0x18, 0x18, 0x0C, 0x00, 0x00, 0x01, 0x80,
/* '@' 0x40 */ 0x03, 0xF0, 0x06, 0x0E, 0x06, 0x01, 0x86, 0x00, 0x66, 0x1D, 0xBB, 0x31, 0xCF, 0x18, 0xC7, 0x98, 0x63, 0xCC, 0x31, 0xE6, 0x11, 0xB3, 0x99, 0xCC, 0xF7, 0x86, 0x00, 0x01, 0x80, 0x00, 0x70, 0x40, 0x0F, 0xE0,
/* 'A' 0x41 */ 0x06, 0x00, 0xF0, 0x0F, 0x00, 0x90, 0x19, 0x81, 0x98, 0x10, 0x83, 0x0C, 0x3F, 0xC2, 0x04, 0x60, 0x66, 0x06, 0xC0, 0x30,
/* 'B' 0x42 */ 0xFF, 0x18, 0x33, 0x03, 0x60, 0x6C, 0x0D, 0x83, 0x3F, 0xC6, 0x06, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x6F, 0xF8,
/* 'C' 0x43 */ 0x1F, 0x86, 0x19, 0x81, 0xA0, 0x3C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0x61, 0xF0,
/* 'D' 0x44 */ 0xFF, 0x18, 0x33, 0x03, 0x60, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x03, 0x60, 0xCF, 0xF0,
/* 'E' 0x45 */ 0xFF, 0xE0, 0x30, 0x18, 0x0C, 0x06, 0x03, 0xFD, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0F, 0xF8,
/* 'F' 0x46 */ 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
/* 'G' 0x47 */ 0x0F, 0x83, 0x0E, 0x60, 0x66, 0x03, 0xC0, 0x0C, 0x00, 0xC1, 0xFC, 0x03, 0xC0, 0x36, 0x03, 0x60, 0x73, 0x0F, 0x0F, 0x10,
/* 'H' 0x48 */ 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xFF, 0xFE, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x06,
/* 'I' 0x49 */ 0xFF, 0xFF, 0xFF, 0xC0,
/* 'J' 0x4A */ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x07, 0x8F, 0x1E, 0x27, 0x80,
/* 'K' 0x4B */ 0xC0, 0xF0, 0x6C, 0x33, 0x18, 0xCC, 0x37, 0x0F, 0xC3, 0x98, 0xC3, 0x30, 0xCC, 0x1B, 0x03, 0xC0, 0xC0,
/* 'L' 0x4C */ 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF,
/* 'M' 0x4D */ 0xE0, 0x3F, 0x01, 0xFC, 0x1F, 0xE0, 0xFD, 0x05, 0xEC, 0x6F, 0x63, 0x79, 0x13, 0xCD, 0x9E, 0x6C, 0xF1, 0x47, 0x8E, 0x3C, 0x71, 0x80,
/* 'N' 0x4E */ 0xE0, 0x7C, 0x0F, 0xC1, 0xE8, 0x3D, 0x87, 0x98, 0xF1, 0x1E, 0x33, 0xC3, 0x78, 0x6F, 0x07, 0xE0, 0x7C, 0x0E,
/* 'O' 0x4F */ 0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x0C, 0x60, 0xC0, 0xF8, 0x00,
/* 'P' 0x50 */ 0xFF, 0x30, 0x6C, 0x0F, 0x03, 0xC0, 0xF0, 0x6F, 0xF3, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x00,
/* 'Q' 0x51 */ 0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x6C, 0x60, 0xC0, 0xFB, 0x00, 0x08,
/* 'R' 0x52 */ 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x0C, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0, 0x70,
/* 'S' 0x53 */ 0x3F, 0x18, 0x6C, 0x0F, 0x03, 0xC0, 0x1E, 0x01, 0xF0, 0x0E, 0x00, 0xF0, 0x3C, 0x0D, 0x86, 0x3F, 0x00,
/* 'T' 0x54 */ 0xFF, 0x86, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0,
/* 'U' 0x55 */ 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xB0, 0x61, 0xF0,
/* 'V' 0x56 */ 0xC0, 0x6C, 0x0D, 0x81, 0x10, 0x63, 0x0C, 0x61, 0x04, 0x60, 0xCC, 0x19, 0x01, 0x60, 0x3C, 0x07, 0x00, 0x60,
/* 'W' 0x57 */ 0xC1, 0x81, 0x61, 0xC3, 0x61, 0xC3, 0x61, 0x43, 0x62, 0x62, 0x22, 0x66, 0x32, 0x26, 0x36, 0x26, 0x14, 0x34, 0x14, 0x34, 0x1C, 0x1C, 0x18, 0x1C, 0x08, 0x18,
/* 'X' 0x58 */ 0xC0, 0xD8, 0x66, 0x18, 0xCC, 0x1E, 0x07, 0x00, 0xC0, 0x78, 0x32, 0x0C, 0xC6, 0x1B, 0x07, 0xC0, 0xC0,
/* 'Y' 0x59 */ 0xC0, 0x36, 0x06, 0x30, 0xC3, 0x0C, 0x19, 0x81, 0xD8, 0x0F, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00,
/* 'Z' 0x5A */ 0xFF, 0xC0, 0x60, 0x30, 0x0C, 0x06, 0x03, 0x01, 0xC0, 0x60, 0x30, 0x18, 0x06, 0x03, 0x00, 0xFF, 0xC0,
/* '[' 0x5B */ 0xFB, 0x6D, 0xB6, 0xDB, 0x6D, 0xB6, 0xE0,
/* '\' 0x5C */ 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x80,
/* ']' 0x5D */ 0xED, 0xB6, 0xDB, 0x6D, 0xB6, 0xDB, 0xE0,
/* '^' 0x5E */ 0x30, 0x60, 0xA2, 0x44, 0xD8, 0xA1, 0x80,
/* '_' 0x5F */ 0xFF, 0xC0,
/* '`' 0x60 */ 0xC6, 0x30,
/* 'a' 0x61 */ 0x7E, 0x71, 0xB0, 0xC0, 0x60, 0xF3, 0xDB, 0x0D, 0x86, 0xC7, 0x3D, 0xC0,
/* 'b' 0x62 */ 0xC0, 0x60, 0x30, 0x1B, 0xCE, 0x36, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x7C, 0x6D, 0xE0,
/* 'c' 0x63 */ 0x3C, 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 'd' 0x64 */ 0x03, 0x03, 0x03, 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B,
/* 'e' 0x65 */ 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C,
/* 'f' 0x66 */ 0x36, 0x6F, 0x66, 0x66, 0x66, 0x66, 0x60,
/* 'g' 0x67 */ 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0xC6, 0x7C,
/* 'h' 0x68 */ 0xC0, 0xC0, 0xC0, 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
/* 'i' 0x69 */ 0xC3, 0xFF, 0xFF, 0xC0,
/* 'j' 0x6A */ 0x30, 0x03, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xE0,
/* 'k' 0x6B */ 0xC0, 0xC0, 0xC0, 0xC2, 0xC4, 0xCC, 0xD8, 0xF8, 0xEC, 0xC4, 0xC6, 0xC3, 0xC3,
/* 'l' 0x6C */ 0xFF, 0xFF, 0xFF, 0xC0,
/* 'm' 0x6D */ 0xDE, 0xF7, 0x1C, 0xF0, 0xC7, 0x86, 0x3C, 0x31, 0xE1, 0x8F, 0x0C, 0x78, 0x63, 0xC3, 0x1E, 0x18, 0xC0,
/* 'n' 0x6E */ 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
/* 'o' 0x6F */ 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C,
/* 'p' 0x70 */ 0xDE, 0x71, 0xB0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xE3, 0x6F, 0x30, 0x18, 0x0C, 0x00,
/* 'q' 0x71 */ 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0x03,
/* 'r' 0x72 */ 0xDF, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x00,
/* 's' 0x73 */ 0x3E, 0xE3, 0xC0, 0xC0, 0xE0, 0x3C, 0x07, 0xC3, 0xE3, 0x7E,
/* 't' 0x74 */ 0x66, 0xF6, 0x66, 0x66, 0x66, 0x67,
/* 'u' 0x75 */ 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B,
/* 'v' 0x76 */ 0xC1, 0xA0, 0x98, 0xCC, 0x42, 0x21, 0xB0, 0xD0, 0x28, 0x1C, 0x0C, 0x00,
/* 'w' 0x77 */ 0xC6, 0x1E, 0x38, 0x91, 0xC4, 0xCA, 0x66, 0xD3, 0x16, 0xD0, 0xA6, 0x87, 0x1C, 0x38, 0xC0, 0xC6, 0x00,
/* 'x' 0x78 */ 0x87, 0x89, 0xB1, 0xC3, 0x07, 0x1E, 0x26, 0xC5, 0x0C,
/* 'y' 0x79 */ 0xC1, 0x43, 0x63, 0x62, 0x26, 0x36, 0x34, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x60,
/* 'z' 0x7A */ 0xFE, 0x0C, 0x30, 0xC1, 0x86, 0x18, 0x20, 0xC1, 0xFC,
/* '{' 0x7B */ 0x36, 0x66, 0x66, 0x6E, 0xCE, 0x66, 0x66, 0x66, 0x30,
/* '|' 0x7C */ 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
/* '}' 0x7D */ 0xC6, 0x66, 0x66, 0x67, 0x37, 0x66, 0x66, 0x66, 0xC0,
/* '~' 0x7E */ 0x61, 0x24, 0x38,
/* 0x7F */
/* 0x80 */ 0x07, 0xC6, 0x13, 0x00, 0xC0, 0x60, 0x3F, 0xE6, 0x03, 0xFC, 0x60, 0x0C, 0x03, 0x00, 0x61, 0x07, 0xC0,
/* 0x81 */
/* 0x82 */ 0xDC,
/* 0x83 */ 0x19, 0x8C, 0xF3, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0xE0,
/* 0x84 */ 0xDA, 0x76,
/* 0x85 */ 0xCC, 0xC0,
/* 0x86 */ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
/* 0x87 */ 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18,
/* 0x88 */ 0x72, 0xA2,
/* 0x89 */ 0x70, 0x80, 0x22, 0x20, 0x08, 0x90, 0x02, 0x24, 0x00, 0x72, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x10, 0x00, 0x09, 0xC7, 0x84, 0x8B, 0x31, 0x22, 0x84, 0x88, 0xB3, 0x21, 0xC7, 0x80,
/* 0x8A */ 0x1B, 0x03, 0x80, 0x00, 0xFC, 0x61, 0xB0, 0x3C, 0x0F, 0x00, 0x78, 0x07, 0xC0, 0x38, 0x03, 0xC0, 0xF0, 0x36, 0x18, 0xFC,
/* 0x8B */ 0x69,
/* 0x8C */ 0x1E, 0xFE, 0x43, 0x81, 0x83, 0x06, 0x06, 0x0C, 0x0C, 0x18, 0x18, 0x30, 0x3F, 0xE0, 0x60, 0xC0, 0xC1, 0x81, 0x81, 0x83, 0x01, 0x8E, 0x01, 0xEF, 0xE0,
/* 0x8D */
/* 0x8E */ 0x1B, 0x03, 0x80, 0x03, 0xFF, 0x01, 0x80, 0xC0, 0x30, 0x18, 0x0C, 0x07, 0x01, 0x80, 0xC0, 0x60, 0x18, 0x0C, 0x03, 0xFF,
/* 0x8F */
/* 0x90 */
/* 0x91 */ 0x6B,
/* 0x92 */ 0xD6,
/* 0x93 */ 0x4C, 0xA5, 0xB0,
/* 0x94 */ 0xDA, 0x53, 0x20,
/* 0x95 */ 0x6F, 0xFF, 0x60,
/* 0x96 */ 0xFE,
/* 0x97 */ 0xFF, 0xFF,
/* 0x98 */ 0x4D, 0xC0,
/* 0x99 */ 0xFC, 0xE1, 0xCC, 0x38, 0x73, 0x0E, 0x1C, 0xC3, 0x8F, 0x30, 0xD2, 0xCC, 0x34, 0xB3, 0x0D, 0x6C, 0xC3, 0x53, 0x30, 0xCC, 0xCC, 0x33, 0x30,
/* 0x9A */ 0x24, 0x3C, 0x18, 0x7E, 0xE3, 0xC0, 0xC0, 0x60, 0x3C, 0x07, 0xC3, 0xE3, 0x7E,
/* 0x9B */ 0x96,
/* 0x9C */ 0x3C, 0xF8, 0xCF, 0x1B, 0x0C, 0x1E, 0x18, 0x3C, 0x3F, 0xF8, 0x60, 0x30, 0xC0, 0x61, 0x83, 0x67, 0x8C, 0x79, 0xF0,
/* 0x9D */
/* 0x9E */ 0x48, 0xF0, 0xC7, 0xF0, 0x61, 0x86, 0x0C, 0x30, 0xC1, 0x06, 0x0F, 0xE0,
/* 0x9F */ 0x19, 0x80, 0x00, 0xC0, 0x36, 0x06, 0x30, 0xC3, 0x0C, 0x19, 0x81, 0xD8, 0x0F, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60,
/* 0xA0 */
/* 0xA1 */ 0xCF, 0xFF, 0xFF, 0xC0,
/* 0xA2 */ 0x08, 0x04, 0x0F, 0x8D, 0x6C, 0x9E, 0x43, 0x21, 0x90, 0xC8, 0x64, 0xDA, 0xC7, 0xC0, 0x80, 0x40,
/* 0xA3 */ 0x1F, 0x0C, 0x66, 0x0D, 0x83, 0x60, 0x0C, 0x0F, 0xC0, 0x60, 0x18, 0x06, 0x03, 0x01, 0xF1, 0x43, 0xC0,
/* 0xA4 */ 0xFF, 0xDF, 0x1E, 0x3E, 0xFF, 0xC0,
/* 0xA5 */ 0xC3, 0x42, 0x42, 0x24, 0x24, 0x3C, 0x18, 0x7E, 0x18, 0x7E, 0x18, 0x18, 0x18,
/* 0xA6 */ 0xFF, 0xFC, 0x0F, 0xFF, 0xC0,
/* 0xA7 */ 0x0C, 0x09, 0x0C, 0xC6, 0x63, 0x81, 0xE3, 0x19, 0x87, 0xE1, 0xB8, 0xC6, 0x41, 0xC0, 0x73, 0x19, 0x8C, 0x66, 0x1E, 0x00,
/* 0xA8 */ 0xCC,
/* 0xA9 */ 0x0F, 0xC0, 0x61, 0x87, 0x03, 0x9B, 0xC6, 0xD9, 0x8F, 0x60, 0x3D, 0x00, 0xF4, 0x03, 0xD8, 0x0D, 0xE6, 0x67, 0xF3, 0x86, 0x18, 0x0F, 0xC0,
/* 0xAA */ 0x74, 0x8D, 0xA9, 0x7C, 0x1F,
/* 0xAB */ 0x22, 0xCF, 0x26, 0x46, 0x64, 0x40,
/* 0xAC */ 0xFF, 0x80, 0xC0, 0x60, 0x30, 0x18,
/* 0xAD */
/* 0xAE */ 0x0F, 0xC0, 0x61, 0x87, 0x03, 0x9F, 0xE6, 0xD0, 0x8F, 0x42, 0x3D, 0xF0, 0xF4, 0x23, 0xD0, 0x8D, 0xC2, 0x67, 0x0B, 0x86, 0x18, 0x0F, 0xC0,
/* 0xAF */ 0xF8,
/* 0xB0 */ 0x74, 0x63, 0x17, 0x00,
/* 0xB1 */ 0x0C, 0x06, 0x03, 0x07, 0xE0, 0xC0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x3F, 0xE0,
/* 0xB2 */ 0x7B, 0x30, 0xC3, 0x11, 0x84, 0x3F,
/* 0xB3 */ 0x7D, 0x8C, 0x18, 0xC0, 0x60, 0xF1, 0xBE,
/* 0xB4 */ 0x36, 0xC0,
/* 0xB5 */ 0xC3, 0x61, 0xB0, 0xD8, 0x6C, 0x36, 0x1B, 0x0D, 0x86, 0xE7, 0x7D, 0xF0, 0x18, 0x0C, 0x00,
/* 0xB6 */ 0x3F, 0x7E, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0x72, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
/* 0xB7 */ 0xE0,
/* 0xB8 */ 0x21, 0xC7, 0xE0,
/* 0xB9 */ 0x3D, 0xB6, 0xD8,
/* 0xBA */ 0x74, 0x63, 0x18, 0xB8, 0x1F,
/* 0xBB */ 0x89, 0x98, 0x99, 0x3C, 0xD1, 0x00,
/* 0xBC */ 0x20, 0x43, 0x81, 0x06, 0x08, 0x18, 0x20, 0x61, 0x01, 0x84, 0x06, 0x21, 0x80, 0x86, 0x04, 0x78, 0x32, 0x60, 0x87, 0xC4, 0x06, 0x10, 0x18,
/* 0xBD */ 0x20, 0x43, 0x81, 0x06, 0x08, 0x18, 0x20, 0x61, 0x01, 0x8D, 0xE6, 0x2C, 0xC1, 0x03, 0x0C, 0x0C, 0x20, 0x41, 0x86, 0x0C, 0x30, 0x20, 0xFC,
/* 0xBE */ 0x78, 0x11, 0x98, 0x40, 0x31, 0x00, 0x82, 0x00, 0xC8, 0x01, 0x90, 0x33, 0x43, 0x3D, 0x06, 0x02, 0x3C, 0x08, 0x98, 0x10, 0xF8, 0x40, 0x61, 0x00, 0xC0,
/* 0xBF */ 0x0C, 0x00, 0x00, 0x01, 0x80, 0xC0, 0xC0, 0xE0, 0xC0, 0xC0, 0x60, 0xF0, 0x6C, 0x63, 0xE0,
/* 0xC0 */ 0x0C, 0xDB, 0xD3, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
/* 0xC1 */ 0x0E, 0x01, 0xC0, 0x6C, 0x0D, 0x81, 0xB0, 0x63, 0x0C, 0x61, 0xFC, 0x7F, 0xCC, 0x19, 0x83, 0x60, 0x3C, 0x06,
/* 0xC2 */ 0xFF, 0x3F, 0xEC, 0x0F, 0x03, 0xC0, 0xFF, 0xEF, 0xFB, 0x03, 0xC0, 0xF0, 0x3C, 0x1F, 0xFE, 0xFF, 0x00,
/* 0xC3 */ 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
/* 0xC4 */ 0x07, 0x00, 0x38, 0x01, 0xC0, 0x1B, 0x00, 0xD8, 0x0C, 0x60, 0x63, 0x03, 0x18, 0x30, 0x61, 0x83, 0x18, 0x0C, 0xFF, 0xE7, 0xFF, 0x00,
/* 0xC5 */ 0xFF, 0xFF, 0xFC, 0x03, 0x00, 0xC0, 0x3F, 0xEF, 0xFB, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0xFF, 0xFF, 0xC0,
/* 0xC6 */ 0x7F, 0xDF, 0xF0, 0x18, 0x0C, 0x07, 0x01, 0x80, 0xC0, 0x60, 0x38, 0x0C, 0x06, 0x03, 0xFF, 0xFF, 0xC0,
/* 0xC7 */ 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0xFF, 0xFF, 0xFE, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x06,
/* 0xC8 */ 0x0F, 0x03, 0xFC, 0x70, 0xE6, 0x06, 0xC0, 0x3C, 0xF3, 0xCF, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x70, 0xE3, 0xFC, 0x1F, 0x80,
/* 0xC9 */ 0xFF, 0xFF, 0xFF, 0xC0,
/* 0xCA */ 0xC1, 0xD8, 0x73, 0x1C, 0x67, 0x0D, 0xC1, 0xF0, 0x3F, 0x07, 0x70, 0xC7, 0x18, 0x63, 0x0E, 0x60, 0xEC, 0x0E,
/* 0xCB */ 0x07, 0x00, 0x38, 0x01, 0xC0, 0x1B, 0x00, 0xD8, 0x0C, 0x60, 0x63, 0x03, 0x18, 0x30, 0x61, 0x83, 0x1C, 0x1C, 0xC0, 0x66, 0x03, 0x00,
/* 0xCC */ 0xE0, 0x3F, 0x83, 0xFC, 0x1F, 0xE0, 0xFD, 0x8D, 0xEC, 0x6F, 0x63, 0x79, 0x13, 0xCD, 0x9E, 0x6C, 0xF3, 0x67, 0x8E, 0x3C, 0x71, 0x80,
/* 0xCD */ 0xC0, 0x7C, 0x0F, 0xC1, 0xF8, 0x3D, 0x87, 0x98, 0xF3, 0x9E, 0x33, 0xC3, 0x78, 0x3F, 0x07, 0xE0, 0x7C, 0x06,
/* 0xCE */ 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x1F, 0xE7, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0,
/* 0xCF */ 0x0F, 0x83, 0xFC, 0x70, 0xE6, 0x06, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x70, 0xE3, 0xFC, 0x0F, 0x00,
/* 0xD0 */ 0xFF, 0xFF, 0xFF, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x06,
/* 0xD1 */ 0xFF, 0x3F, 0xEC, 0x1F, 0x03, 0xC0, 0xF0, 0x7F, 0xFB, 0xFC, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x00,
/* 0xD2 */
/* 0xD3 */ 0xFF, 0xFF, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xFF, 0xFF,
/* 0xD4 */ 0xFF, 0xFF, 0xF0, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x00,
/* 0xD5 */ 0xE0, 0x76, 0x06, 0x30, 0xC3, 0x9C, 0x19, 0x80, 0xF0, 0x0F, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00,
/* 0xD6 */ 0x06, 0x00, 0x60, 0x1F, 0x87, 0xFE, 0xE6, 0x7C, 0x63, 0xC6, 0x3C, 0x63, 0xE6, 0x77, 0xFE, 0x1F, 0x80, 0x60, 0x06, 0x00,
/* 0xD7 */ 0x71, 0xC6, 0x30, 0x6C, 0x0D, 0x80, 0xE0, 0x1C, 0x03, 0x80, 0xD8, 0x1B, 0x07, 0x70, 0xC6, 0x30, 0x6E, 0x0E,
/* 0xD8 */ 0xC6, 0x3C, 0x63, 0xC6, 0x3C, 0x63, 0xC6, 0x3C, 0x63, 0x46, 0x66, 0x66, 0x3F, 0xC0, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00,
/* 0xD9 */ 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0x40, 0x4C, 0x18, 0xEE, 0x7D, 0xFF, 0xBE,
/* 0xDA */ 0xCF, 0x30, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C,
/* 0xDB */ 0x19, 0x81, 0x98, 0x00, 0x0E, 0x07, 0x60, 0x63, 0x0C, 0x39, 0xC1, 0x98, 0x0F, 0x00, 0xF0, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60,
/* 0xDC */ 0x06, 0x0C, 0x00, 0x3B, 0x7B, 0xEE, 0xC6, 0xC6, 0xC6, 0xC6, 0xEE, 0x7B, 0x3B,
/* 0xDD */ 0x18, 0x20, 0x03, 0xCF, 0xF8, 0xB0, 0x38, 0x71, 0x83, 0x17, 0xF7, 0x80,
/* 0xDE */ 0x0C, 0x18, 0x00, 0xDE, 0xFF, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x03, 0x03, 0x03, 0x03,
/* 0xDF */ 0x78, 0x6D, 0xB6, 0xDB, 0x6C,
/* 0xE0 */ 0x0C, 0xDB, 0xD3, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7E, 0x3C,
/* 0xE1 */ 0x3B, 0x7B, 0xEE, 0xC6, 0xC6, 0xC6, 0xC6, 0xEE, 0x7B, 0x3B,
/* 0xE2 */ 0x3C, 0x7E, 0xC6, 0xC6, 0xC4, 0xD8, 0xDE, 0xC7, 0xC3, 0xC3, 0xE7, 0xFE, 0xDC, 0xC0, 0xC0, 0xC0, 0xC0,
/* 0xE3 */ 0x61, 0x98, 0x66, 0x18, 0xCC, 0x33, 0x0C, 0xC1, 0xE0, 0x78, 0x1E, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00,
/* 0xE4 */ 0x7E, 0x7E, 0x30, 0x3C, 0x7E, 0xE7, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7E, 0x3C,
/* 0xE5 */ 0x79, 0xFF, 0x16, 0x07, 0x0E, 0x30, 0x62, 0xFE, 0xF0,
/* 0xE6 */ 0x7E, 0xFC, 0x30, 0xC3, 0x0C, 0x18, 0x60, 0xC1, 0x83, 0x07, 0xE7, 0xE0, 0xC1, 0x83, 0x0C,
/* 0xE7 */ 0xDE, 0xFF, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x03, 0x03, 0x03, 0x03,
/* 0xE8 */ 0x3C, 0x7E, 0x66, 0xC3, 0xC3, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 0x66, 0x7E, 0x3C,
/* 0xE9 */ 0xFF, 0xFF, 0xF0,
/* 0xEA */ 0xC3, 0x63, 0x33, 0x1B, 0x0F, 0x06, 0xC3, 0x31, 0x8C, 0xC6, 0x61, 0x80,
/* 0xEB */ 0x30, 0x0C, 0x06, 0x03, 0x01, 0xC1, 0xE0, 0xD0, 0x6C, 0x36, 0x33, 0x18, 0xCC, 0x66, 0x30,
/* 0xEC */ 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0xFF, 0xDB, 0xC0, 0xC0, 0xC0, 0xC0,
/* 0xED */ 0xC1, 0xE0, 0xD8, 0xCC, 0x66, 0x31, 0xB0, 0xD8, 0x38, 0x1C, 0x04, 0x00,
/* 0xEE */ 0x7D, 0xFB, 0x06, 0x07, 0xC7, 0x9C, 0x70, 0xC1, 0x83, 0x83, 0xE3, 0xE0, 0xC1, 0x8E, 0x18,
/* 0xEF */ 0x3C, 0x7E, 0xE7, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7E, 0x3C,
/* 0xF0 */ 0xFF, 0xFF, 0xFF, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C,
/* 0xF1 */ 0x3C, 0x7E, 0xE7, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0xFE, 0xDC, 0xC0, 0xC0, 0xC0, 0xC0,
/* 0xF2 */ 0x1E, 0xFD, 0x86, 0x0C, 0x18, 0x30, 0x70, 0x7C, 0x7C, 0x18, 0x33, 0xE7, 0x00,
/* 0xF3 */ 0x3F, 0xDF, 0xFE, 0x63, 0x0C, 0xC3, 0x30, 0xCC, 0x33, 0x9C, 0x7E, 0x0F, 0x00,
/* 0xF4 */ 0xFF, 0xF3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC0,
/* 0xF5 */ 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7E, 0x3C,
/* 0xF6 */ 0x2F, 0x1B, 0xEC, 0xDF, 0x33, 0xCC, 0xF3, 0x3C, 0xCD, 0xB6, 0x7F, 0x8F, 0x80, 0xC0, 0x30, 0x0C, 0x03, 0x00,
/* 0xF7 */ 0x63, 0x31, 0x8D, 0x86, 0xC3, 0x60, 0xE0, 0x70, 0x38, 0x1C, 0x1B, 0x0D, 0x86, 0xC6, 0x33, 0x18,
/* 0xF8 */ 0xCC, 0xF3, 0x3C, 0xCF, 0x33, 0xCC, 0xF3, 0x3C, 0xCF, 0x33, 0x6D, 0x8F, 0xC0, 0xC0, 0x30, 0x0C, 0x03, 0x00,
/* 0xF9 */ 0x30, 0xC6, 0x06, 0x66, 0x6C, 0x63, 0xC6, 0x3C, 0x63, 0xC6, 0x3E, 0xF7, 0x79, 0xE3, 0x9C,
/* 0xFA */ 0xCF, 0x30, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30,
/* 0xFB */ 0x66, 0x66, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7E, 0x3C,
/* 0xFC */ 0x0C, 0x18, 0x00, 0x3C, 0x7E, 0xE7, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7E, 0x3C,
/* 0xFD */ 0x08, 0x10, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7E, 0x3C,
/* 0xFE */ 0x03, 0x00, 0x60, 0x00, 0x03, 0x0C, 0x60, 0x66, 0x66, 0xC6, 0x3C, 0x63, 0xC6, 0x3C, 0x63, 0xEF, 0x77, 0x9E, 0x39, 0xC0,
/* 0xFF */
};
const GFXglyph FreeSans9pt_Win1253Glyphs[] PROGMEM = {
/* 0x01 */ { 0, 15, 15, 17, 1, -13 },
/* 0x02 */ { 29, 15, 15, 17, 1, -13 },
/* 0x03 */ { 58, 15, 16, 17, 1, -14 },
/* 0x04 */ { 88, 15, 16, 17, 1, -14 },
/* 0x05 */ { 118, 16, 15, 18, 1, -13 },
/* 0x06 */ { 148, 15, 15, 17, 1, -13 },
/* 0x07 */ { 177, 0, 0, 8, 0, 0 },
/* 0x08 */ { 177, 17, 16, 19, 1, -14 },
/* 0x09 */ { 211, 17, 12, 19, 1, -12 },
/* 0x0A */ { 237, 0, 0, 8, 0, 0 },
/* 0x0B */ { 237, 17, 16, 19, 1, -14 },
/* 0x0C */ { 271, 15, 14, 17, 1, -12 },
/* 0x0D */ { 298, 0, 0, 8, 0, 0 },
/* 0x0E */ { 298, 15, 16, 17, 1, -14 },
/* 0x0F */ { 328, 15, 15, 17, 1, -13 },
/* 0x10 */ { 357, 15, 15, 17, 1, -13 },
/* 0x11 */ { 386, 15, 16, 17, 1, -14 },
/* 0x12 */ { 416, 17, 17, 19, 1, -15 },
/* 0x13 */ { 453, 15, 16, 17, 1, -14 },
/* 0x14 */ { 483, 15, 16, 17, 1, -14 },
/* 0x15 */ { 513, 15, 16, 17, 1, -14 },
/* 0x16 */ { 543, 11, 16, 13, 1, -14 },
/* 0x17 */ { 565, 15, 16, 17, 1, -14 },
/* 0x18 */ { 595, 18, 15, 20, 1, -13 },
/* 0x19 */ { 629, 15, 16, 17, 1, -14 },
/* 0x1A */ { 659, 13, 14, 15, 1, -12 },
/* 0x1B */ { 682, 17, 16, 19, 1, -14 },
/* 0x1C */ { 716, 15, 16, 17, 1, -14 },
/* 0x1D */ { 746, 15, 15, 17, 1, -13 },
/* 0x1E */ { 775, 17, 16, 19, 1, -14 },
/* 0x1F */ { 809, 11, 16, 13, 1, -14 },
/* ' ' 0x20 */ { 831, 0, 0, 5, 0, 0 },
/* '!' 0x21 */ { 831, 2, 13, 6, 2, -12 },
/* '"' 0x22 */ { 835, 5, 4, 6, 1, -12 },
/* '#' 0x23 */ { 838, 10, 12, 10, 0, -11 },
/* '$' 0x24 */ { 853, 9, 16, 10, 1, -13 },
/* '%' 0x25 */ { 871, 16, 13, 16, 1, -12 },
/* '&' 0x26 */ { 897, 10, 13, 12, 1, -12 },
/* ''' 0x27 */ { 914, 2, 4, 4, 1, -12 },
/* '(' 0x28 */ { 915, 4, 17, 6, 1, -12 },
/* ')' 0x29 */ { 924, 4, 17, 6, 1, -12 },
/* '*' 0x2A */ { 933, 5, 5, 7, 1, -12 },
/* '+' 0x2B */ { 937, 6, 8, 11, 3, -7 },
/* ',' 0x2C */ { 943, 2, 4, 5, 2, 0 },
/* '-' 0x2D */ { 944, 4, 1, 6, 1, -4 },
/* '.' 0x2E */ { 945, 2, 1, 5, 1, 0 },
/* '/' 0x2F */ { 946, 5, 13, 5, 0, -12 },
/* '0' 0x30 */ { 955, 8, 13, 10, 1, -12 },
/* '1' 0x31 */ { 968, 4, 13, 10, 3, -12 },
/* '2' 0x32 */ { 975, 9, 13, 10, 1, -12 },
/* '3' 0x33 */ { 990, 8, 13, 10, 1, -12 },
/* '4' 0x34 */ { 1003, 7, 13, 10, 2, -12 },
/* '5' 0x35 */ { 1015, 9, 13, 10, 1, -12 },
/* '6' 0x36 */ { 1030, 9, 13, 10, 1, -12 },
/* '7' 0x37 */ { 1045, 8, 13, 10, 0, -12 },
/* '8' 0x38 */ { 1058, 9, 13, 10, 1, -12 },
/* '9' 0x39 */ { 1073, 8, 13, 10, 1, -12 },
/* ':' 0x3A */ { 1086, 2, 10, 5, 1, -9 },
/* ';' 0x3B */ { 1089, 3, 12, 5, 1, -8 },
/* '<' 0x3C */ { 1094, 9, 9, 11, 1, -8 },
/* '=' 0x3D */ { 1105, 9, 4, 11, 1, -5 },
/* '>' 0x3E */ { 1110, 9, 8, 11, 1, -7 },
/* '?' 0x3F */ { 1119, 9, 13, 10, 1, -12 },
/* '@' 0x40 */ { 1134, 17, 16, 18, 1, -12 },
/* 'A' 0x41 */ { 1168, 12, 13, 12, 0, -12 },
/* 'B' 0x42 */ { 1188, 11, 13, 12, 1, -12 },
/* 'C' 0x43 */ { 1206, 11, 13, 13, 1, -12 },
/* 'D' 0x44 */ { 1224, 11, 13, 13, 1, -12 },
/* 'E' 0x45 */ { 1242, 9, 13, 11, 1, -12 },
/* 'F' 0x46 */ { 1257, 8, 13, 11, 1, -12 },
/* 'G' 0x47 */ { 1270, 12, 13, 14, 1, -12 },
/* 'H' 0x48 */ { 1290, 11, 13, 13, 1, -12 },
/* 'I' 0x49 */ { 1308, 2, 13, 5, 2, -12 },
/* 'J' 0x4A */ { 1312, 7, 13, 10, 1, -12 },
/* 'K' 0x4B */ { 1324, 10, 13, 12, 1, -12 },
/* 'L' 0x4C */ { 1341, 8, 13, 10, 1, -12 },
/* 'M' 0x4D */ { 1354, 13, 13, 15, 1, -12 },
/* 'N' 0x4E */ { 1376, 11, 13, 13, 1, -12 },
/* 'O' 0x4F */ { 1394, 13, 13, 14, 1, -12 },
/* 'P' 0x50 */ { 1416, 10, 13, 12, 1, -12 },
/* 'Q' 0x51 */ { 1433, 13, 14, 14, 1, -12 },
/* 'R' 0x52 */ { 1456, 12, 13, 13, 1, -12 },
/* 'S' 0x53 */ { 1476, 10, 13, 12, 1, -12 },
/* 'T' 0x54 */ { 1493, 9, 13, 11, 1, -12 },
/* 'U' 0x55 */ { 1508, 11, 13, 13, 1, -12 },
/* 'V' 0x56 */ { 1526, 11, 13, 11, 0, -12 },
/* 'W' 0x57 */ { 1544, 16, 13, 17, 0, -12 },
/* 'X' 0x58 */ { 1570, 10, 13, 12, 1, -12 },
/* 'Y' 0x59 */ { 1587, 12, 13, 12, 0, -12 },
/* 'Z' 0x5A */ { 1607, 10, 13, 11, 1, -12 },
/* '[' 0x5B */ { 1624, 3, 17, 5, 1, -12 },
/* '\' 0x5C */ { 1631, 5, 13, 5, 0, -12 },
/* ']' 0x5D */ { 1640, 3, 17, 5, 0, -12 },
/* '^' 0x5E */ { 1647, 7, 7, 8, 1, -12 },
/* '_' 0x5F */ { 1654, 10, 1, 10, 0, 3 },
/* '`' 0x60 */ { 1656, 4, 3, 5, 0, -12 },
/* 'a' 0x61 */ { 1658, 9, 10, 10, 1, -9 },
/* 'b' 0x62 */ { 1670, 9, 13, 10, 1, -12 },
/* 'c' 0x63 */ { 1685, 8, 10, 9, 1, -9 },
/* 'd' 0x64 */ { 1695, 8, 13, 10, 1, -12 },
/* 'e' 0x65 */ { 1708, 8, 10, 10, 1, -9 },
/* 'f' 0x66 */ { 1718, 4, 13, 5, 1, -12 },
/* 'g' 0x67 */ { 1725, 8, 14, 10, 1, -9 },
/* 'h' 0x68 */ { 1739, 8, 13, 10, 1, -12 },
/* 'i' 0x69 */ { 1752, 2, 13, 4, 1, -12 },
/* 'j' 0x6A */ { 1756, 4, 17, 4, 0, -12 },
/* 'k' 0x6B */ { 1765, 8, 13, 9, 1, -12 },
/* 'l' 0x6C */ { 1778, 2, 13, 4, 1, -12 },
/* 'm' 0x6D */ { 1782, 13, 10, 15, 1, -9 },
/* 'n' 0x6E */ { 1799, 8, 10, 10, 1, -9 },
/* 'o' 0x6F */ { 1809, 8, 10, 10, 1, -9 },
/* 'p' 0x70 */ { 1819, 9, 13, 10, 1, -9 },
/* 'q' 0x71 */ { 1834, 8, 13, 10, 1, -9 },
/* 'r' 0x72 */ { 1847, 5, 10, 6, 1, -9 },
/* 's' 0x73 */ { 1854, 8, 10, 9, 1, -9 },
/* 't' 0x74 */ { 1864, 4, 12, 5, 1, -11 },
/* 'u' 0x75 */ { 1870, 8, 10, 10, 1, -9 },
/* 'v' 0x76 */ { 1880, 9, 10, 9, 0, -9 },
/* 'w' 0x77 */ { 1892, 13, 10, 13, 0, -9 },
/* 'x' 0x78 */ { 1909, 7, 10, 9, 1, -9 },
/* 'y' 0x79 */ { 1918, 8, 14, 9, 0, -9 },
/* 'z' 0x7A */ { 1932, 7, 10, 9, 1, -9 },
/* '{' 0x7B */ { 1941, 4, 17, 6, 1, -12 },
/* '|' 0x7C */ { 1950, 2, 17, 4, 2, -12 },
/* '}' 0x7D */ { 1955, 4, 17, 6, 1, -12 },
/* '~' 0x7E */ { 1964, 7, 3, 9, 1, -7 },
/* 0x7F */ { 1967, 0, 0, 0, 0, 0 },
/* 0x80 */ { 1967, 10, 13, 12, 1, -12 },
/* 0x81 */ { 1984, 0, 0, 8, 0, 0 },
/* 0x82 */ { 1984, 2, 3, 5, 1, 0 },
/* 0x83 */ { 1985, 5, 17, 5, 0, -12 },
/* 0x84 */ { 1996, 5, 3, 7, 1, 0 },
/* 0x85 */ { 1998, 10, 1, 12, 1, 0 },
/* 0x86 */ { 2000, 8, 16, 10, 1, -12 },
/* 0x87 */ { 2016, 8, 16, 10, 1, -12 },
/* 0x88 */ { 2032, 5, 3, 6, 0, -12 },
/* 0x89 */ { 2034, 18, 13, 18, 0, -12 },
/* 0x8A */ { 2064, 10, 16, 12, 1, -15 },
/* 0x8B */ { 2084, 2, 4, 4, 1, -6 },
/* 0x8C */ { 2085, 15, 13, 18, 1, -12 },
/* 0x8D */ { 2110, 0, 0, 8, 0, 0 },
/* 0x8E */ { 2110, 10, 16, 11, 1, -15 },
/* 0x8F */ { 2130, 0, 0, 8, 0, 0 },
/* 0x90 */ { 2130, 0, 0, 8, 0, 0 },
/* 0x91 */ { 2130, 2, 4, 4, 2, -12 },
/* 0x92 */ { 2131, 2, 4, 4, 1, -12 },
/* 0x93 */ { 2132, 5, 4, 7, 2, -12 },
/* 0x94 */ { 2135, 5, 4, 7, 1, -12 },
/* 0x95 */ { 2138, 4, 5, 7, 1, -8 },
/* 0x96 */ { 2141, 7, 1, 9, 1, -4 },
/* 0x97 */ { 2142, 16, 1, 18, 1, -4 },
/* 0x98 */ { 2144, 5, 2, 6, 0, -12 },
/* 0x99 */ { 2146, 18, 10, 18, 1, -13 },
/* 0x9A */ { 2169, 8, 13, 9, 1, -12 },
/* 0x9B */ { 2182, 2, 4, 5, 2, -6 },
/* 0x9C */ { 2183, 15, 10, 17, 1, -9 },
/* 0x9D */ { 2202, 0, 0, 8, 0, 0 },
/* 0x9E */ { 2202, 7, 13, 9, 1, -12 },
/* 0x9F */ { 2214, 12, 14, 12, 0, -13 },
/* 0xA0 */ { 2235, 0, 0, 5, 0, 0 },
/* 0xA1 */ { 2235, 2, 13, 6, 2, -8 },
/* 0xA2 */ { 2239, 9, 14, 10, 1, -11 },
/* 0xA3 */ { 2255, 10, 13, 10, 0, -12 },
/* 0xA4 */ { 2272, 7, 6, 10, 2, -8 },
/* 0xA5 */ { 2278, 8, 13, 10, 1, -12 },
/* 0xA6 */ { 2291, 2, 17, 5, 2, -12 },
/* 0xA7 */ { 2296, 9, 17, 10, 1, -12 },
/* 0xA8 */ { 2316, 6, 1, 6, 0, -11 },
/* 0xA9 */ { 2317, 14, 13, 14, 1, -12 },
/* 0xAA */ { 2340, 5, 8, 7, 1, -12 },
/* 0xAB */ { 2345, 7, 6, 9, 1, -7 },
/* 0xAC */ { 2351, 9, 5, 11, 2, -5 },
/* 0xAD */ { 2357, 0, 0, 0, 0, 0 },
/* 0xAE */ { 2357, 14, 13, 14, 1, -12 },
/* 0xAF */ { 2380, 5, 1, 6, 0, -12 },
/* 0xB0 */ { 2381, 5, 5, 11, 3, -11 },
/* 0xB1 */ { 2385, 9, 11, 11, 1, -10 },
/* 0xB2 */ { 2398, 6, 8, 6, 1, -13 },
/* 0xB3 */ { 2404, 7, 8, 6, 0, -13 },
/* 0xB4 */ { 2411, 4, 3, 6, 2, -12 },
/* 0xB5 */ { 2413, 9, 13, 10, 1, -9 },
/* 0xB6 */ { 2428, 8, 16, 10, 2, -12 },
/* 0xB7 */ { 2444, 3, 1, 5, 1, -4 },
/* 0xB8 */ { 2445, 5, 4, 6, 1, 1 },
/* 0xB9 */ { 2448, 3, 7, 6, 2, -13 },
/* 0xBA */ { 2451, 5, 8, 7, 1, -12 },
/* 0xBB */ { 2456, 7, 6, 9, 1, -7 },
/* 0xBC */ { 2462, 14, 13, 16, 2, -12 },
/* 0xBD */ { 2485, 14, 13, 16, 2, -12 },
/* 0xBE */ { 2508, 15, 13, 16, 1, -12 },
/* 0xBF */ { 2533, 9, 13, 10, 1, -8 },
/* 0xC0 */ { 2548, 8, 15, 4, -2, -15 },
/* 0xC1 */ { 2563, 11, 13, 11, 0, -13 },
/* 0xC2 */ { 2581, 10, 13, 12, 1, -13 },
/* 0xC3 */ { 2598, 8, 13, 10, 2, -13 },
/* 0xC4 */ { 2611, 13, 13, 12, -1, -13 },
/* 0xC5 */ { 2633, 10, 13, 12, 1, -13 },
/* 0xC6 */ { 2650, 10, 13, 11, 0, -13 },
/* 0xC7 */ { 2667, 11, 13, 13, 1, -13 },
/* 0xC8 */ { 2685, 12, 13, 14, 1, -13 },
/* 0xC9 */ { 2705, 2, 13, 4, 1, -13 },
/* 0xCA */ { 2709, 11, 13, 12, 1, -13 },
/* 0xCB */ { 2727, 13, 13, 12, -1, -13 },
/* 0xCC */ { 2749, 13, 13, 15, 1, -13 },
/* 0xCD */ { 2771, 11, 13, 13, 1, -13 },
/* 0xCE */ { 2789, 10, 13, 12, 1, -13 },
/* 0xCF */ { 2806, 12, 13, 14, 1, -13 },
/* 0xD0 */ { 2826, 11, 13, 13, 1, -13 },
/* 0xD1 */ { 2844, 10, 13, 12, 1, -13 },
/* 0xD2 */ { 2861, 0, 0, 5, 0, 0 },
/* 0xD3 */ { 2861, 8, 13, 11, 2, -13 },
/* 0xD4 */ { 2874, 10, 13, 12, 1, -13 },
/* 0xD5 */ { 2891, 12, 13, 12, 0, -13 },
/* 0xD6 */ { 2911, 12, 13, 14, 1, -13 },
/* 0xD7 */ { 2931, 11, 13, 11, 0, -13 },
/* 0xD8 */ { 2949, 12, 13, 14, 1, -13 },
/* 0xD9 */ { 2969, 11, 13, 13, 1, -13 },
/* 0xDA */ { 2987, 6, 16, 4, -1, -16 },
/* 0xDB */ { 2999, 12, 16, 12, 0, -16 },
/* 0xDC */ { 3023, 8, 13, 10, 1, -13 },
/* 0xDD */ { 3036, 7, 13, 8, 1, -13 },
/* 0xDE */ { 3048, 8, 17, 10, 1, -13 },
/* 0xDF */ { 3065, 3, 13, 4, 1, -13 },
/* 0xE0 */ { 3070, 8, 14, 10, 1, -14 },
/* 0xE1 */ { 3084, 8, 10, 10, 1, -10 },
/* 0xE2 */ { 3094, 8, 17, 10, 1, -13 },
/* 0xE3 */ { 3111, 10, 14, 8, -1, -10 },
/* 0xE4 */ { 3129, 8, 13, 10, 1, -13 },
/* 0xE5 */ { 3142, 7, 10, 8, 1, -10 },
/* 0xE6 */ { 3151, 7, 17, 8, 1, -13 },
/* 0xE7 */ { 3166, 8, 14, 10, 1, -10 },
/* 0xE8 */ { 3180, 8, 13, 10, 1, -13 },
/* 0xE9 */ { 3193, 2, 10, 4, 1, -10 },
/* 0xEA */ { 3196, 9, 10, 9, 1, -10 },
/* 0xEB */ { 3208, 9, 13, 9, 0, -13 },
/* 0xEC */ { 3223, 8, 14, 10, 1, -10 },
/* 0xED */ { 3237, 9, 10, 9, 0, -10 },
/* 0xEE */ { 3249, 7, 17, 8, 1, -13 },
/* 0xEF */ { 3264, 8, 10, 10, 1, -10 },
/* 0xF0 */ { 3274, 12, 10, 12, 0, -10 },
/* 0xF1 */ { 3289, 8, 14, 10, 1, -10 },
/* 0xF2 */ { 3303, 7, 14, 9, 1, -10 },
/* 0xF3 */ { 3316, 10, 10, 11, 1, -10 },
/* 0xF4 */ { 3329, 6, 10, 8, 1, -10 },
/* 0xF5 */ { 3337, 8, 10, 10, 1, -10 },
/* 0xF6 */ { 3347, 10, 14, 12, 1, -10 },
/* 0xF7 */ { 3365, 9, 14, 9, 0, -10 },
/* 0xF8 */ { 3381, 10, 14, 12, 1, -10 },
/* 0xF9 */ { 3399, 12, 10, 14, 1, -10 },
/* 0xFA */ { 3414, 6, 13, 4, -1, -13 },
/* 0xFB */ { 3424, 8, 13, 10, 1, -13 },
/* 0xFC */ { 3437, 8, 13, 10, 1, -13 },
/* 0xFD */ { 3450, 8, 13, 10, 1, -13 },
/* 0xFE */ { 3463, 12, 13, 14, 1, -13 },
/* 0xFF */ { 3483, 0, 0, 5, 0, 0 },
};
const GFXfont FreeSans9pt_Win1253 PROGMEM = {
(uint8_t*)FreeSans9pt_Win1253Bitmaps,
(GFXglyph*)FreeSans9pt_Win1253Glyphs,
0x01, 0xFF, 16
};
@@ -0,0 +1,4 @@
# NicheGraphics - Fonts
A common area to store fonts which might be reused by different Niche Graphics UIs
In future, we may want to separate these by library (AdafruitGFX, u8g2, etc)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,211 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Base class for InkHUD applets
Must be overriden
An applet is one "program" which may show info on the display.
*/
#pragma once
#include "configuration.h"
#include <GFX.h> // GFXRoot drawing lib
#include "mesh/MeshTypes.h"
#include "./AppletFont.h"
#include "./Applets/System/Notification/Notification.h" // The notification object, not the applet
#include "./InkHUD.h"
#include "./Persistence.h"
#include "./Tile.h"
#include "graphics/niche/Drivers/EInk/EInk.h"
namespace NicheGraphics::InkHUD
{
using NicheGraphics::Drivers::EInk;
using std::to_string;
class Applet : public GFX
{
public:
// Which edge Applet::printAt will place on the Y parameter
enum VerticalAlignment : uint8_t {
TOP,
MIDDLE,
BOTTOM,
};
// Which edge Applet::printAt will place on the X parameter
enum HorizontalAlignment : uint8_t {
LEFT,
RIGHT,
CENTER,
};
// An easy-to-understand interpretation of SNR and RSSI
// Calculate with Applet::getSignalStrength
enum SignalStrength : int8_t {
SIGNAL_UNKNOWN = -1,
SIGNAL_NONE,
SIGNAL_BAD,
SIGNAL_FAIR,
SIGNAL_GOOD,
};
Applet();
void setTile(Tile *t); // Should only be called via Tile::setApplet
Tile *getTile(); // Tile with which this applet is linked
// Rendering
void render(bool full); // Draw the applet
bool wantsToRender(); // Check whether applet wants to render
bool wantsToAutoshow(); // Check whether applet wants to become foreground
Drivers::EInk::UpdateTypes wantsUpdateType(); // Check which display update type the applet would prefer
bool wantsFullRender(); // Check whether applet wants to render over its previous render
void updateDimensions(); // Get current size from tile
void resetDrawingSpace(); // Makes sure every render starts with same parameters
// State of the applet
void activate(); // Begin running
void deactivate(); // Stop running
void bringToForeground(); // Show
void sendToBackground(); // Hide
bool isActive();
bool isForeground();
// Event handlers
virtual void onRender(bool full) = 0; // For drawing the applet
virtual void onActivate() {}
virtual void onDeactivate() {}
virtual void onForeground() {}
virtual void onBackground() {}
virtual void onShutdown() {}
// Input Events
virtual void onButtonShortPress() {}
virtual void onButtonLongPress() {}
virtual void onExitShort() {}
virtual void onExitLong() {}
virtual void onNavUp() {}
virtual void onNavDown() {}
virtual void onNavLeft() {}
virtual void onNavRight() {}
virtual void onFreeText(char c) {}
virtual void onFreeTextDone() {}
virtual void onFreeTextCancel() {}
// List of inputs which can be subscribed to
enum InputMask { // | No Joystick | With Joystick |
BUTTON_SHORT = 1, // | Button Click | Joystick Center Click |
BUTTON_LONG = 2, // | Button Hold | Joystick Center Hold |
EXIT_SHORT = 4, // | no-op | Back Button Click |
EXIT_LONG = 8, // | no-op | Back Button Hold |
NAV_UP = 16, // | no-op | Joystick Up |
NAV_DOWN = 32, // | no-op | Joystick Down |
NAV_LEFT = 64, // | no-op | Joystick Left |
NAV_RIGHT = 128 // | no-op | Joystick Right |
};
bool isInputSubscribed(InputMask input); // Check if input should be handled by applet, this should not be overloaded.
virtual bool approveNotification(Notification &n); // Allow an applet to veto a notification
static uint16_t getHeaderHeight(); // How tall the "standard" applet header is
static AppletFont fontSmall, fontMedium, fontLarge; // The general purpose fonts, used by all applets
const char *name = nullptr; // Shown in applet selection menu. Also used as an identifier by InkHUD::getSystemApplet
protected:
void drawPixel(int16_t x, int16_t y, uint16_t color) override; // Place a single pixel. All drawing output passes through here
void requestUpdate(EInk::UpdateTypes type = EInk::UpdateTypes::UNSPECIFIED,
bool full = true); // Ask WindowManager to schedule a display update
void requestAutoshow(); // Ask for applet to be moved to foreground
uint16_t X(float f); // Map applet width, mapped from 0 to 1.0
uint16_t Y(float f); // Map applet height, mapped from 0 to 1.0
void setCrop(int16_t left, int16_t top, uint16_t width, uint16_t height); // Ignore pixels drawn outside a certain region
void resetCrop(); // Removes setCrop()
// User Input Handling
uint8_t subscribedInputs = 0b00000000; // Maybe uint16_t for futureproofing? other devices may need more inputs
void setInputsSubscribed(uint8_t input,
bool captured); // Set if an input should be handled by applet or not, this should not be
// overloaded. Can take multiple inputs at once if you OR/`|` them together
// Text
void setFont(AppletFont f);
AppletFont getFont();
uint16_t getTextWidth(const std::string &text);
uint16_t getTextWidth(const char *text);
uint32_t getWrappedTextHeight(int16_t left, uint16_t width, const std::string &text); // Result of printWrapped
void printAt(int16_t x, int16_t y, const char *text, HorizontalAlignment ha = LEFT, VerticalAlignment va = TOP);
void printAt(int16_t x, int16_t y, const std::string &text, HorizontalAlignment ha = LEFT, VerticalAlignment va = TOP);
void printThick(int16_t xCenter, int16_t yCenter, const std::string &text, uint8_t thicknessX,
uint8_t thicknessY); // Faux bold
void printWrapped(int16_t left, int16_t top, uint16_t width, const std::string &text); // Per-word line wrapping
void hatchRegion(int16_t x, int16_t y, uint16_t w, uint16_t h, uint8_t spacing, Color color); // Fill with sparse lines
void drawHeader(const std::string &text); // Draw the standard applet header
// Meshtastic Logo
static constexpr float LOGO_ASPECT_RATIO = 1.9; // Width:Height for drawing the Meshtastic logo
uint16_t getLogoWidth(uint16_t limitWidth, uint16_t limitHeight); // Size Meshtastic logo to fit within region
uint16_t getLogoHeight(uint16_t limitWidth, uint16_t limitHeight); // Size Meshtastic logo to fit within region
void drawLogo(int16_t centerX, int16_t centerY, uint16_t width, uint16_t height,
Color color = BLACK); // Draw the Meshtastic logo
std::string hexifyNodeNum(NodeNum num); // Style as !0123abdc
SignalStrength getSignalStrength(float snr, float rssi); // Interpret SNR and RSSI, as an easy to understand value
std::string getTimeString(uint32_t epochSeconds); // Human readable
std::string getTimeString(); // Current time, human readable
uint16_t getActiveNodeCount(); // Duration determined by user, in onscreen menu
std::string localizeDistance(uint32_t meters); // Human readable distance, imperial or metric
std::string parse(const std::string &text); // Handle text which might contain special chars
std::string parseShortName(meshtastic_NodeInfoLite *node); // Get the shortname, or a substitute if has unprintable chars
bool isPrintable(const std::string &text); // Check for characters which the font can't print
// Convenient references
InkHUD *inkhud = nullptr;
Persistence::Settings *settings = nullptr;
Persistence::LatestMessage *latestMessage = nullptr;
private:
Tile *assignedTile = nullptr; // Rendered pixels are fed into a Tile object, which translates them, then passes to WM
bool active = false; // Has the user enabled this applet (at run-time)?
bool foreground = false; // Is the applet currently drawn on a tile?
bool wantRender = false; // In some situations, checked by WindowManager when updating, to skip unneeded redrawing.
bool wantAutoshow = false; // Does the applet have new data it would like to display in foreground?
NicheGraphics::Drivers::EInk::UpdateTypes wantUpdateType =
NicheGraphics::Drivers::EInk::UpdateTypes::UNSPECIFIED; // Which update method we'd prefer when redrawing the display
bool wantFullRender = true; // Render with a fresh canvas
using GFX::setFont; // Make sure derived classes use AppletFont instead of AdafruitGFX fonts directly
using GFX::setRotation; // Block setRotation calls. Rotation is handled globally by WindowManager.
AppletFont currentFont; // As passed to setFont
// As set by setCrop
int16_t cropLeft = 0;
int16_t cropTop = 0;
uint16_t cropWidth = 0;
uint16_t cropHeight = 0;
};
}; // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,830 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./AppletFont.h"
#include <assert.h>
using namespace NicheGraphics;
InkHUD::AppletFont::AppletFont()
{
// Default constructor uses the in-built AdafruitGFX font (not recommended)
}
InkHUD::AppletFont::AppletFont(const GFXfont &adafruitGFXFont, Encoding encoding, int8_t paddingTop, int8_t paddingBottom)
: gfxFont(&adafruitGFXFont), encoding(encoding)
{
// AdafruitGFX fonts are drawn relative to a "cursor line";
// they print as if the glyphs are resting on the line of piece of ruled paper.
// The glyphs also each have a different height.
// To simplify drawing, we will scan the entire font now, and determine an appropriate height for a line of text
// We also need to know where that "cursor line" sits inside this "line height";
// we need this additional info in order to align text by top-left, bottom-right, etc
// AdafruitGFX fonts do declare a line-height, but this seems to include a certain amount of padding,
// which we'd rather not deal with. If we want padding, we'll add it manually.
this->ascenderHeight = 0;
this->descenderHeight = 0;
this->height = 0;
// Scan each glyph in the AdafruitGFX font
for (uint16_t i = 0; i <= (gfxFont->last - gfxFont->first); i++) {
uint8_t glyphHeight = gfxFont->glyph[i].height; // Height of glyph
this->height = max(this->height, glyphHeight); // Store if it's a new max
// Calculate how far the glyph rises the cursor line
// Store if new max value
// Caution: signed and unsigned types
int8_t glyphAscender = 0 - gfxFont->glyph[i].yOffset;
if (glyphAscender > 0)
this->ascenderHeight = max(this->ascenderHeight, static_cast<uint8_t>(glyphAscender));
int8_t glyphDescender = gfxFont->glyph[i].height + gfxFont->glyph[i].yOffset;
if (glyphDescender > 0)
this->descenderHeight = max(this->descenderHeight, static_cast<uint8_t>(glyphDescender));
}
// Apply any manual padding to grow or shrink the line size
// Helpful if a font has one or two exceptionally large characters, which would make the lines ridiculously tall
ascenderHeight += paddingTop;
descenderHeight += paddingBottom;
// Find how far the cursor advances when we "print" a space character
spaceCharWidth = gfxFont->glyph[static_cast<uint8_t>(' ') - gfxFont->first].xAdvance;
}
/*
▲ ##### # ▲
│ # # │
lineHeight │ ### # │
│ # # # # │ heightAboveCursor
│ # # # # │
│ # # #### │
│ -----------------#----
│ # │ heightBelowCursor
▼ ### ▼
*/
uint8_t InkHUD::AppletFont::lineHeight()
{
return this->height;
}
// AdafruitGFX fonts print characters so that they nicely on an imaginary line (think: ruled paper).
// This value is the height of the font, above that imaginary line.
// Used to calculate the true height of the font
uint8_t InkHUD::AppletFont::heightAboveCursor()
{
return this->ascenderHeight;
}
// AdafruitGFX fonts print characters so that they nicely on an imaginary line (think: ruled paper).
// This value is the height of the font, below that imaginary line.
// Used to calculate the true height of the font
uint8_t InkHUD::AppletFont::heightBelowCursor()
{
return this->descenderHeight;
}
// Width of the space character
// Used with Applet::printWrapped
uint8_t InkHUD::AppletFont::widthBetweenWords()
{
return this->spaceCharWidth;
}
// Convert a unicode char from set of UTF-8 bytes to UTF-32
// Used by AppletFont::applyEncoding, which remaps unicode chars for extended ASCII fonts, based on their UTF-32 value
uint32_t InkHUD::AppletFont::toUtf32(const std::string &utf8)
{
uint32_t utf32 = 0;
switch (utf8.length()) {
case 2:
// 5 bits + 6 bits
utf32 |= (utf8.at(0) & 0b00011111) << 6;
utf32 |= (utf8.at(1) & 0b00111111);
break;
case 3:
// 4 bits + 6 bits + 6 bits
utf32 |= (utf8.at(0) & 0b00001111) << (6 + 6);
utf32 |= (utf8.at(1) & 0b00111111) << 6;
utf32 |= (utf8.at(2) & 0b00111111);
break;
case 4:
// 3 bits + 6 bits + 6 bits + 6 bits
utf32 |= (utf8.at(0) & 0b00000111) << (6 + 6 + 6);
utf32 |= (utf8.at(1) & 0b00111111) << (6 + 6);
utf32 |= (utf8.at(2) & 0b00111111) << 6;
utf32 |= (utf8.at(3) & 0b00111111);
break;
default:
return 0;
}
return utf32;
}
// Process a string, collating UTF-8 bytes, and sending them off for re-encoding to extended ASCII
// Not all InkHUD text is passed through here, only text which could potentially contain non-ASCII chars
std::string InkHUD::AppletFont::decodeUTF8(const std::string &encoded)
{
// Final processed output
std::string decoded;
// Holds bytes for one UTF-8 char during parsing
std::string utf8Char;
uint8_t utf8CharSize = 0;
for (const char &c : encoded) {
// If first byte
if (utf8Char.empty()) {
// If MSB is unset, byte is an ASCII char
// If MSB is set, byte is part of a UTF-8 char. Counting number of higher-order bits tells how many bytes in char
if ((c & 0x80)) {
char c1 = c;
while (c1 & 0x80) {
c1 <<= 1;
utf8CharSize++;
}
}
}
// Append the byte to the UTF-8 char we're building
utf8Char += c;
// More bytes left to collect. Iterate.
if (utf8Char.length() < utf8CharSize)
continue;
// Now collected all bytes for this char
// Remap the value to match the encoding of our 8-bit AppletFont
decoded += applyEncoding(utf8Char);
// Reset, ready to build next UTF-8 char from the encoded bytes
utf8Char.clear();
utf8CharSize = 0;
} // For each char
// All chars processed, return result
return decoded;
}
// Re-encode a single UTF-8 character to extended ASCII
// Target encoding depends on the font
char InkHUD::AppletFont::applyEncoding(const std::string &utf8)
{
// ##################################################### Syntactic Sugar #####################################################
#define REMAP(in, out) \
case in: \
return out;
// ###########################################################################################################################
// Latin - Central Europe
// https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1250.TXT
if (encoding == WINDOWS_1250) {
// 1-Byte chars: no remapping
if (utf8.length() == 1)
return utf8.at(0);
// Multi-byte chars:
switch (toUtf32(utf8)) {
REMAP(0x20AC, 0x80); // EURO SIGN
REMAP(0x201A, 0x82); // SINGLE LOW-9 QUOTATION MARK
REMAP(0x201E, 0x84); // DOUBLE LOW-9 QUOTATION MARK
REMAP(0x2026, 0x85); // HORIZONTAL ELLIPSIS
REMAP(0x2020, 0x86); // DAGGER
REMAP(0x2021, 0x87); // DOUBLE DAGGER
REMAP(0x2030, 0x89); // PER MILLE SIGN
REMAP(0x0160, 0x8A); // LATIN CAPITAL LETTER S WITH CARON
REMAP(0x2039, 0x8B); // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
REMAP(0x015A, 0x8C); // LATIN CAPITAL LETTER S WITH ACUTE
REMAP(0x0164, 0x8D); // LATIN CAPITAL LETTER T WITH CARON
REMAP(0x017D, 0x8E); // LATIN CAPITAL LETTER Z WITH CARON
REMAP(0x0179, 0x8F); // LATIN CAPITAL LETTER Z WITH ACUTE
REMAP(0x2018, 0x91); // LEFT SINGLE QUOTATION MARK
REMAP(0x2019, 0x92); // RIGHT SINGLE QUOTATION MARK
REMAP(0x201C, 0x93); // LEFT DOUBLE QUOTATION MARK
REMAP(0x201D, 0x94); // RIGHT DOUBLE QUOTATION MARK
REMAP(0x2022, 0x95); // BULLET
REMAP(0x2013, 0x96); // EN DASH
REMAP(0x2014, 0x97); // EM DASH
REMAP(0x2122, 0x99); // TRADE MARK SIGN
REMAP(0x0161, 0x9A); // LATIN SMALL LETTER S WITH CARON
REMAP(0x203A, 0x9B); // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
REMAP(0x015B, 0x9C); // LATIN SMALL LETTER S WITH ACUTE
REMAP(0x0165, 0x9D); // LATIN SMALL LETTER T WITH CARON
REMAP(0x017E, 0x9E); // LATIN SMALL LETTER Z WITH CARON
REMAP(0x017A, 0x9F); // LATIN SMALL LETTER Z WITH ACUTE
REMAP(0x00A0, 0xA0); // NO-BREAK SPACE
REMAP(0x02C7, 0xA1); // CARON
REMAP(0x02D8, 0xA2); // BREVE
REMAP(0x0141, 0xA3); // LATIN CAPITAL LETTER L WITH STROKE
REMAP(0x00A4, 0xA4); // CURRENCY SIGN
REMAP(0x0104, 0xA5); // LATIN CAPITAL LETTER A WITH OGONEK
REMAP(0x00A6, 0xA6); // BROKEN BAR
REMAP(0x00A7, 0xA7); // SECTION SIGN
REMAP(0x00A8, 0xA8); // DIAERESIS
REMAP(0x00A9, 0xA9); // COPYRIGHT SIGN
REMAP(0x015E, 0xAA); // LATIN CAPITAL LETTER S WITH CEDILLA
REMAP(0x00AB, 0xAB); // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
REMAP(0x00AC, 0xAC); // NOT SIGN
REMAP(0x00AD, 0xAD); // SOFT HYPHEN
REMAP(0x00AE, 0xAE); // REGISTERED SIGN
REMAP(0x017B, 0xAF); // LATIN CAPITAL LETTER Z WITH DOT ABOVE
REMAP(0x00B0, 0xB0); // DEGREE SIGN
REMAP(0x00B1, 0xB1); // PLUS-MINUS SIGN
REMAP(0x02DB, 0xB2); // OGONEK
REMAP(0x0142, 0xB3); // LATIN SMALL LETTER L WITH STROKE
REMAP(0x00B4, 0xB4); // ACUTE ACCENT
REMAP(0x00B5, 0xB5); // MICRO SIGN
REMAP(0x00B6, 0xB6); // PILCROW SIGN
REMAP(0x00B7, 0xB7); // MIDDLE DOT
REMAP(0x00B8, 0xB8); // CEDILLA
REMAP(0x0105, 0xB9); // LATIN SMALL LETTER A WITH OGONEK
REMAP(0x015F, 0xBA); // LATIN SMALL LETTER S WITH CEDILLA
REMAP(0x00BB, 0xBB); // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
REMAP(0x013D, 0xBC); // LATIN CAPITAL LETTER L WITH CARON
REMAP(0x02DD, 0xBD); // DOUBLE ACUTE ACCENT
REMAP(0x013E, 0xBE); // LATIN SMALL LETTER L WITH CARON
REMAP(0x017C, 0xBF); // LATIN SMALL LETTER Z WITH DOT ABOVE
REMAP(0x0154, 0xC0); // LATIN CAPITAL LETTER R WITH ACUTE
REMAP(0x00C1, 0xC1); // LATIN CAPITAL LETTER A WITH ACUTE
REMAP(0x00C2, 0xC2); // LATIN CAPITAL LETTER A WITH CIRCUMFLEX
REMAP(0x0102, 0xC3); // LATIN CAPITAL LETTER A WITH BREVE
REMAP(0x00C4, 0xC4); // LATIN CAPITAL LETTER A WITH DIAERESIS
REMAP(0x0139, 0xC5); // LATIN CAPITAL LETTER L WITH ACUTE
REMAP(0x0106, 0xC6); // LATIN CAPITAL LETTER C WITH ACUTE
REMAP(0x00C7, 0xC7); // LATIN CAPITAL LETTER C WITH CEDILLA
REMAP(0x010C, 0xC8); // LATIN CAPITAL LETTER C WITH CARON
REMAP(0x00C9, 0xC9); // LATIN CAPITAL LETTER E WITH ACUTE
REMAP(0x0118, 0xCA); // LATIN CAPITAL LETTER E WITH OGONEK
REMAP(0x00CB, 0xCB); // LATIN CAPITAL LETTER E WITH DIAERESIS
REMAP(0x011A, 0xCC); // LATIN CAPITAL LETTER E WITH CARON
REMAP(0x00CD, 0xCD); // LATIN CAPITAL LETTER I WITH ACUTE
REMAP(0x00CE, 0xCE); // LATIN CAPITAL LETTER I WITH CIRCUMFLEX
REMAP(0x010E, 0xCF); // LATIN CAPITAL LETTER D WITH CARON
REMAP(0x0110, 0xD0); // LATIN CAPITAL LETTER D WITH STROKE
REMAP(0x0143, 0xD1); // LATIN CAPITAL LETTER N WITH ACUTE
REMAP(0x0147, 0xD2); // LATIN CAPITAL LETTER N WITH CARON
REMAP(0x00D3, 0xD3); // LATIN CAPITAL LETTER O WITH ACUTE
REMAP(0x00D4, 0xD4); // LATIN CAPITAL LETTER O WITH CIRCUMFLEX
REMAP(0x0150, 0xD5); // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
REMAP(0x00D6, 0xD6); // LATIN CAPITAL LETTER O WITH DIAERESIS
REMAP(0x00D7, 0xD7); // MULTIPLICATION SIGN
REMAP(0x0158, 0xD8); // LATIN CAPITAL LETTER R WITH CARON
REMAP(0x016E, 0xD9); // LATIN CAPITAL LETTER U WITH RING ABOVE
REMAP(0x00DA, 0xDA); // LATIN CAPITAL LETTER U WITH ACUTE
REMAP(0x0170, 0xDB); // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
REMAP(0x00DC, 0xDC); // LATIN CAPITAL LETTER U WITH DIAERESIS
REMAP(0x00DD, 0xDD); // LATIN CAPITAL LETTER Y WITH ACUTE
REMAP(0x0162, 0xDE); // LATIN CAPITAL LETTER T WITH CEDILLA
REMAP(0x00DF, 0xDF); // LATIN SMALL LETTER SHARP S
REMAP(0x0155, 0xE0); // LATIN SMALL LETTER R WITH ACUTE
REMAP(0x00E1, 0xE1); // LATIN SMALL LETTER A WITH ACUTE
REMAP(0x00E2, 0xE2); // LATIN SMALL LETTER A WITH CIRCUMFLEX
REMAP(0x0103, 0xE3); // LATIN SMALL LETTER A WITH BREVE
REMAP(0x00E4, 0xE4); // LATIN SMALL LETTER A WITH DIAERESIS
REMAP(0x013A, 0xE5); // LATIN SMALL LETTER L WITH ACUTE
REMAP(0x0107, 0xE6); // LATIN SMALL LETTER C WITH ACUTE
REMAP(0x00E7, 0xE7); // LATIN SMALL LETTER C WITH CEDILLA
REMAP(0x010D, 0xE8); // LATIN SMALL LETTER C WITH CARON
REMAP(0x00E9, 0xE9); // LATIN SMALL LETTER E WITH ACUTE
REMAP(0x0119, 0xEA); // LATIN SMALL LETTER E WITH OGONEK
REMAP(0x00EB, 0xEB); // LATIN SMALL LETTER E WITH DIAERESIS
REMAP(0x011B, 0xEC); // LATIN SMALL LETTER E WITH CARON
REMAP(0x00ED, 0xED); // LATIN SMALL LETTER I WITH ACUTE
REMAP(0x00EE, 0xEE); // LATIN SMALL LETTER I WITH CIRCUMFLEX
REMAP(0x010F, 0xEF); // LATIN SMALL LETTER D WITH CARON
REMAP(0x0111, 0xF0); // LATIN SMALL LETTER D WITH STROKE
REMAP(0x0144, 0xF1); // LATIN SMALL LETTER N WITH ACUTE
REMAP(0x0148, 0xF2); // LATIN SMALL LETTER N WITH CARON
REMAP(0x00F3, 0xF3); // LATIN SMALL LETTER O WITH ACUTE
REMAP(0x00F4, 0xF4); // LATIN SMALL LETTER O WITH CIRCUMFLEX
REMAP(0x0151, 0xF5); // LATIN SMALL LETTER O WITH DOUBLE ACUTE
REMAP(0x00F6, 0xF6); // LATIN SMALL LETTER O WITH DIAERESIS
REMAP(0x00F7, 0xF7); // DIVISION SIGN
REMAP(0x0159, 0xF8); // LATIN SMALL LETTER R WITH CARON
REMAP(0x016F, 0xF9); // LATIN SMALL LETTER U WITH RING ABOVE
REMAP(0x00FA, 0xFA); // LATIN SMALL LETTER U WITH ACUTE
REMAP(0x0171, 0xFB); // LATIN SMALL LETTER U WITH DOUBLE ACUTE
REMAP(0x00FC, 0xFC); // LATIN SMALL LETTER U WITH DIAERESIS
REMAP(0x00FD, 0xFD); // LATIN SMALL LETTER Y WITH ACUTE
REMAP(0x0163, 0xFE); // LATIN SMALL LETTER T WITH CEDILLA
REMAP(0x02D9, 0xFF); // DOT ABOVE
}
}
// Latin - Cyrillic
// https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT
else if (encoding == WINDOWS_1251) {
// 1-Byte chars: no remapping
if (utf8.length() == 1)
return utf8.at(0);
// Multi-byte chars:
switch (toUtf32(utf8)) {
REMAP(0x0402, 0x80); // CYRILLIC CAPITAL LETTER DJE
REMAP(0x0403, 0x81); // CYRILLIC CAPITAL LETTER GJE
REMAP(0x201A, 0x82); // SINGLE LOW-9 QUOTATION MARK
REMAP(0x0453, 0x83); // CYRILLIC SMALL LETTER GJE
REMAP(0x201E, 0x84); // DOUBLE LOW-9 QUOTATION MARK
REMAP(0x2026, 0x85); // HORIZONTAL ELLIPSIS
REMAP(0x2020, 0x86); // DAGGER
REMAP(0x2021, 0x87); // DOUBLE DAGGER
REMAP(0x20AC, 0x88); // EURO SIGN
REMAP(0x2030, 0x89); // PER MILLE SIGN
REMAP(0x0409, 0x8A); // CYRILLIC CAPITAL LETTER LJE
REMAP(0x2039, 0x8B); // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
REMAP(0x040A, 0x8C); // CYRILLIC CAPITAL LETTER NJE
REMAP(0x040C, 0x8D); // CYRILLIC CAPITAL LETTER KJE
REMAP(0x040B, 0x8E); // CYRILLIC CAPITAL LETTER TSHE
REMAP(0x040F, 0x8F); // CYRILLIC CAPITAL LETTER DZHE
REMAP(0x0452, 0x90); // CYRILLIC SMALL LETTER DJE
REMAP(0x2018, 0x91); // LEFT SINGLE QUOTATION MARK
REMAP(0x2019, 0x92); // RIGHT SINGLE QUOTATION MARK
REMAP(0x201C, 0x93); // LEFT DOUBLE QUOTATION MARK
REMAP(0x201D, 0x94); // RIGHT DOUBLE QUOTATION MARK
REMAP(0x2022, 0x95); // BULLET
REMAP(0x2013, 0x96); // EN DASH
REMAP(0x2014, 0x97); // EM DASH
REMAP(0x2122, 0x99); // TRADE MARK SIGN
REMAP(0x0459, 0x9A); // CYRILLIC SMALL LETTER LJE
REMAP(0x203A, 0x9B); // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
REMAP(0x045A, 0x9C); // CYRILLIC SMALL LETTER NJE
REMAP(0x045C, 0x9D); // CYRILLIC SMALL LETTER KJE
REMAP(0x045B, 0x9E); // CYRILLIC SMALL LETTER TSHE
REMAP(0x045F, 0x9F); // CYRILLIC SMALL LETTER DZHE
REMAP(0x00A0, 0xA0); // NO-BREAK SPACE
REMAP(0x040E, 0xA1); // CYRILLIC CAPITAL LETTER SHORT U
REMAP(0x045E, 0xA2); // CYRILLIC SMALL LETTER SHORT U
REMAP(0x0408, 0xA3); // CYRILLIC CAPITAL LETTER JE
REMAP(0x00A4, 0xA4); // CURRENCY SIGN
REMAP(0x0490, 0xA5); // CYRILLIC CAPITAL LETTER GHE WITH UPTURN
REMAP(0x00A6, 0xA6); // BROKEN BAR
REMAP(0x00A7, 0xA7); // SECTION SIGN
REMAP(0x0401, 0xA8); // CYRILLIC CAPITAL LETTER IO
REMAP(0x00A9, 0xA9); // COPYRIGHT SIGN
REMAP(0x0404, 0xAA); // CYRILLIC CAPITAL LETTER UKRAINIAN IE
REMAP(0x00AB, 0xAB); // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
REMAP(0x00AC, 0xAC); // NOT SIGN
REMAP(0x00AD, 0xAD); // SOFT HYPHEN
REMAP(0x00AE, 0xAE); // REGISTERED SIGN
REMAP(0x0407, 0xAF); // CYRILLIC CAPITAL LETTER YI
REMAP(0x00B0, 0xB0); // DEGREE SIGN
REMAP(0x00B1, 0xB1); // PLUS-MINUS SIGN
REMAP(0x0406, 0xB2); // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
REMAP(0x0456, 0xB3); // CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
REMAP(0x0491, 0xB4); // CYRILLIC SMALL LETTER GHE WITH UPTURN
REMAP(0x00B5, 0xB5); // MICRO SIGN
REMAP(0x00B6, 0xB6); // PILCROW SIGN
REMAP(0x00B7, 0xB7); // MIDDLE DOT
REMAP(0x0451, 0xB8); // CYRILLIC SMALL LETTER IO
REMAP(0x2116, 0xB9); // NUMERO SIGN
REMAP(0x0454, 0xBA); // CYRILLIC SMALL LETTER UKRAINIAN IE
REMAP(0x00BB, 0xBB); // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
REMAP(0x0458, 0xBC); // CYRILLIC SMALL LETTER JE
REMAP(0x0405, 0xBD); // CYRILLIC CAPITAL LETTER DZE
REMAP(0x0455, 0xBE); // CYRILLIC SMALL LETTER DZE
REMAP(0x0457, 0xBF); // CYRILLIC SMALL LETTER YI
REMAP(0x0410, 0xC0); // CYRILLIC CAPITAL LETTER A
REMAP(0x0411, 0xC1); // CYRILLIC CAPITAL LETTER BE
REMAP(0x0412, 0xC2); // CYRILLIC CAPITAL LETTER VE
REMAP(0x0413, 0xC3); // CYRILLIC CAPITAL LETTER GHE
REMAP(0x0414, 0xC4); // CYRILLIC CAPITAL LETTER DE
REMAP(0x0415, 0xC5); // CYRILLIC CAPITAL LETTER IE
REMAP(0x0416, 0xC6); // CYRILLIC CAPITAL LETTER ZHE
REMAP(0x0417, 0xC7); // CYRILLIC CAPITAL LETTER ZE
REMAP(0x0418, 0xC8); // CYRILLIC CAPITAL LETTER I
REMAP(0x0419, 0xC9); // CYRILLIC CAPITAL LETTER SHORT I
REMAP(0x041A, 0xCA); // CYRILLIC CAPITAL LETTER KA
REMAP(0x041B, 0xCB); // CYRILLIC CAPITAL LETTER EL
REMAP(0x041C, 0xCC); // CYRILLIC CAPITAL LETTER EM
REMAP(0x041D, 0xCD); // CYRILLIC CAPITAL LETTER EN
REMAP(0x041E, 0xCE); // CYRILLIC CAPITAL LETTER O
REMAP(0x041F, 0xCF); // CYRILLIC CAPITAL LETTER PE
REMAP(0x0420, 0xD0); // CYRILLIC CAPITAL LETTER ER
REMAP(0x0421, 0xD1); // CYRILLIC CAPITAL LETTER ES
REMAP(0x0422, 0xD2); // CYRILLIC CAPITAL LETTER TE
REMAP(0x0423, 0xD3); // CYRILLIC CAPITAL LETTER U
REMAP(0x0424, 0xD4); // CYRILLIC CAPITAL LETTER EF
REMAP(0x0425, 0xD5); // CYRILLIC CAPITAL LETTER HA
REMAP(0x0426, 0xD6); // CYRILLIC CAPITAL LETTER TSE
REMAP(0x0427, 0xD7); // CYRILLIC CAPITAL LETTER CHE
REMAP(0x0428, 0xD8); // CYRILLIC CAPITAL LETTER SHA
REMAP(0x0429, 0xD9); // CYRILLIC CAPITAL LETTER SHCHA
REMAP(0x042A, 0xDA); // CYRILLIC CAPITAL LETTER HARD SIGN
REMAP(0x042B, 0xDB); // CYRILLIC CAPITAL LETTER YERU
REMAP(0x042C, 0xDC); // CYRILLIC CAPITAL LETTER SOFT SIGN
REMAP(0x042D, 0xDD); // CYRILLIC CAPITAL LETTER E
REMAP(0x042E, 0xDE); // CYRILLIC CAPITAL LETTER YU
REMAP(0x042F, 0xDF); // CYRILLIC CAPITAL LETTER YA
REMAP(0x0430, 0xE0); // CYRILLIC SMALL LETTER A
REMAP(0x0431, 0xE1); // CYRILLIC SMALL LETTER BE
REMAP(0x0432, 0xE2); // CYRILLIC SMALL LETTER VE
REMAP(0x0433, 0xE3); // CYRILLIC SMALL LETTER GHE
REMAP(0x0434, 0xE4); // CYRILLIC SMALL LETTER DE
REMAP(0x0435, 0xE5); // CYRILLIC SMALL LETTER IE
REMAP(0x0436, 0xE6); // CYRILLIC SMALL LETTER ZHE
REMAP(0x0437, 0xE7); // CYRILLIC SMALL LETTER ZE
REMAP(0x0438, 0xE8); // CYRILLIC SMALL LETTER I
REMAP(0x0439, 0xE9); // CYRILLIC SMALL LETTER SHORT I
REMAP(0x043A, 0xEA); // CYRILLIC SMALL LETTER KA
REMAP(0x043B, 0xEB); // CYRILLIC SMALL LETTER EL
REMAP(0x043C, 0xEC); // CYRILLIC SMALL LETTER EM
REMAP(0x043D, 0xED); // CYRILLIC SMALL LETTER EN
REMAP(0x043E, 0xEE); // CYRILLIC SMALL LETTER O
REMAP(0x043F, 0xEF); // CYRILLIC SMALL LETTER PE
REMAP(0x0440, 0xF0); // CYRILLIC SMALL LETTER ER
REMAP(0x0441, 0xF1); // CYRILLIC SMALL LETTER ES
REMAP(0x0442, 0xF2); // CYRILLIC SMALL LETTER TE
REMAP(0x0443, 0xF3); // CYRILLIC SMALL LETTER U
REMAP(0x0444, 0xF4); // CYRILLIC SMALL LETTER EF
REMAP(0x0445, 0xF5); // CYRILLIC SMALL LETTER HA
REMAP(0x0446, 0xF6); // CYRILLIC SMALL LETTER TSE
REMAP(0x0447, 0xF7); // CYRILLIC SMALL LETTER CHE
REMAP(0x0448, 0xF8); // CYRILLIC SMALL LETTER SHA
REMAP(0x0449, 0xF9); // CYRILLIC SMALL LETTER SHCHA
REMAP(0x044A, 0xFA); // CYRILLIC SMALL LETTER HARD SIGN
REMAP(0x044B, 0xFB); // CYRILLIC SMALL LETTER YERU
REMAP(0x044C, 0xFC); // CYRILLIC SMALL LETTER SOFT SIGN
REMAP(0x044D, 0xFD); // CYRILLIC SMALL LETTER E
REMAP(0x044E, 0xFE); // CYRILLIC SMALL LETTER YU
REMAP(0x044F, 0xFF); // CYRILLIC SMALL LETTER YA
}
}
// Latin - Western Europe
// https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT
else if (encoding == WINDOWS_1252) {
// 1-Byte chars: no remapping
if (utf8.length() == 1)
return utf8.at(0);
// Multi-byte chars:
switch (toUtf32(utf8)) {
REMAP(0x20AC, 0x80) // EURO SIGN
REMAP(0x201A, 0x82) // SINGLE LOW-9 QUOTATION MARK
REMAP(0x0192, 0x83) // LATIN SMALL LETTER F WITH HOOK
REMAP(0x201E, 0x84) // DOUBLE LOW-9 QUOTATION MARK
REMAP(0x2026, 0x85) // HORIZONTAL ELLIPSIS
REMAP(0x2020, 0x86) // DAGGER
REMAP(0x2021, 0x87) // DOUBLE DAGGER
REMAP(0x02C6, 0x88) // MODIFIER LETTER CIRCUMFLEX ACCENT
REMAP(0x2030, 0x89) // PER MILLE SIGN
REMAP(0x0160, 0x8A) // LATIN CAPITAL LETTER S WITH CARON
REMAP(0x2039, 0x8B) // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
REMAP(0x0152, 0x8C) // LATIN CAPITAL LIGATURE OE
REMAP(0x017D, 0x8E) // LATIN CAPITAL LETTER Z WITH CARON
REMAP(0x2018, 0x91) // LEFT SINGLE QUOTATION MARK
REMAP(0x2019, 0x92) // RIGHT SINGLE QUOTATION MARK
REMAP(0x201C, 0x93) // LEFT DOUBLE QUOTATION MARK
REMAP(0x201D, 0x94) // RIGHT DOUBLE QUOTATION MARK
REMAP(0x2022, 0x95) // BULLET
REMAP(0x2013, 0x96) // EN DASH
REMAP(0x2014, 0x97) // EM DASH
REMAP(0x02DC, 0x98) // SMALL TILDE
REMAP(0x2122, 0x99) // TRADE MARK SIGN
REMAP(0x0161, 0x9A) // LATIN SMALL LETTER S WITH CARON
REMAP(0x203A, 0x9B) // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
REMAP(0x0153, 0x9C) // LATIN SMALL LIGATURE OE
REMAP(0x017E, 0x9E) // LATIN SMALL LETTER Z WITH CARON
REMAP(0x0178, 0x9F) // LATIN CAPITAL LETTER Y WITH DIAERESIS
REMAP(0x00A0, 0xA0) // NO-BREAK SPACE
REMAP(0x00A1, 0xA1) // INVERTED EXCLAMATION MARK
REMAP(0x00A2, 0xA2) // CENT SIGN
REMAP(0x00A3, 0xA3) // POUND SIGN
REMAP(0x00A4, 0xA4) // CURRENCY SIGN
REMAP(0x00A5, 0xA5) // YEN SIGN
REMAP(0x00A6, 0xA6) // BROKEN BAR
REMAP(0x00A7, 0xA7) // SECTION SIGN
REMAP(0x00A8, 0xA8) // DIAERESIS
REMAP(0x00A9, 0xA9) // COPYRIGHT SIGN
REMAP(0x00AA, 0xAA) // FEMININE ORDINAL INDICATOR
REMAP(0x00AB, 0xAB) // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
REMAP(0x00AC, 0xAC) // NOT SIGN
REMAP(0x00AD, 0xAD) // SOFT HYPHEN
REMAP(0x00AE, 0xAE) // REGISTERED SIGN
REMAP(0x00AF, 0xAF) // MACRON
REMAP(0x00B0, 0xB0) // DEGREE SIGN
REMAP(0x00B1, 0xB1) // PLUS-MINUS SIGN
REMAP(0x00B2, 0xB2) // SUPERSCRIPT TWO
REMAP(0x00B3, 0xB3) // SUPERSCRIPT THREE
REMAP(0x00B4, 0xB4) // ACUTE ACCENT
REMAP(0x00B5, 0xB5) // MICRO SIGN
REMAP(0x00B6, 0xB6) // PILCROW SIGN
REMAP(0x00B7, 0xB7) // MIDDLE DOT
REMAP(0x00B8, 0xB8) // CEDILLA
REMAP(0x00B9, 0xB9) // SUPERSCRIPT ONE
REMAP(0x00BA, 0xBA) // MASCULINE ORDINAL INDICATOR
REMAP(0x00BB, 0xBB) // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
REMAP(0x00BC, 0xBC) // VULGAR FRACTION ONE QUARTER
REMAP(0x00BD, 0xBD) // VULGAR FRACTION ONE HALF
REMAP(0x00BE, 0xBE) // VULGAR FRACTION THREE QUARTERS
REMAP(0x00BF, 0xBF) // INVERTED QUESTION MARK
REMAP(0x00C0, 0xC0) // LATIN CAPITAL LETTER A WITH GRAVE
REMAP(0x00C1, 0xC1) // LATIN CAPITAL LETTER A WITH ACUTE
REMAP(0x00C2, 0xC2) // LATIN CAPITAL LETTER A WITH CIRCUMFLEX
REMAP(0x00C3, 0xC3) // LATIN CAPITAL LETTER A WITH TILDE
REMAP(0x00C4, 0xC4) // LATIN CAPITAL LETTER A WITH DIAERESIS
REMAP(0x00C5, 0xC5) // LATIN CAPITAL LETTER A WITH RING ABOVE
REMAP(0x00C6, 0xC6) // LATIN CAPITAL LETTER AE
REMAP(0x00C7, 0xC7) // LATIN CAPITAL LETTER C WITH CEDILLA
REMAP(0x00C8, 0xC8) // LATIN CAPITAL LETTER E WITH GRAVE
REMAP(0x00C9, 0xC9) // LATIN CAPITAL LETTER E WITH ACUTE
REMAP(0x00CA, 0xCA) // LATIN CAPITAL LETTER E WITH CIRCUMFLEX
REMAP(0x00CB, 0xCB) // LATIN CAPITAL LETTER E WITH DIAERESIS
REMAP(0x00CC, 0xCC) // LATIN CAPITAL LETTER I WITH GRAVE
REMAP(0x00CD, 0xCD) // LATIN CAPITAL LETTER I WITH ACUTE
REMAP(0x00CE, 0xCE) // LATIN CAPITAL LETTER I WITH CIRCUMFLEX
REMAP(0x00CF, 0xCF) // LATIN CAPITAL LETTER I WITH DIAERESIS
REMAP(0x00D0, 0xD0) // LATIN CAPITAL LETTER ETH
REMAP(0x00D1, 0xD1) // LATIN CAPITAL LETTER N WITH TILDE
REMAP(0x00D2, 0xD2) // LATIN CAPITAL LETTER O WITH GRAVE
REMAP(0x00D3, 0xD3) // LATIN CAPITAL LETTER O WITH ACUTE
REMAP(0x00D4, 0xD4) // LATIN CAPITAL LETTER O WITH CIRCUMFLEX
REMAP(0x00D5, 0xD5) // LATIN CAPITAL LETTER O WITH TILDE
REMAP(0x00D6, 0xD6) // LATIN CAPITAL LETTER O WITH DIAERESIS
REMAP(0x00D7, 0xD7) // MULTIPLICATION SIGN
REMAP(0x00D8, 0xD8) // LATIN CAPITAL LETTER O WITH STROKE
REMAP(0x00D9, 0xD9) // LATIN CAPITAL LETTER U WITH GRAVE
REMAP(0x00DA, 0xDA) // LATIN CAPITAL LETTER U WITH ACUTE
REMAP(0x00DB, 0xDB) // LATIN CAPITAL LETTER U WITH CIRCUMFLEX
REMAP(0x00DC, 0xDC) // LATIN CAPITAL LETTER U WITH DIAERESIS
REMAP(0x00DD, 0xDD) // LATIN CAPITAL LETTER Y WITH ACUTE
REMAP(0x00DE, 0xDE) // LATIN CAPITAL LETTER THORN
REMAP(0x00DF, 0xDF) // LATIN SMALL LETTER SHARP S
REMAP(0x00E0, 0xE0) // LATIN SMALL LETTER A WITH GRAVE
REMAP(0x00E1, 0xE1) // LATIN SMALL LETTER A WITH ACUTE
REMAP(0x00E2, 0xE2) // LATIN SMALL LETTER A WITH CIRCUMFLEX
REMAP(0x00E3, 0xE3) // LATIN SMALL LETTER A WITH TILDE
REMAP(0x00E4, 0xE4) // LATIN SMALL LETTER A WITH DIAERESIS
REMAP(0x00E5, 0xE5) // LATIN SMALL LETTER A WITH RING ABOVE
REMAP(0x00E6, 0xE6) // LATIN SMALL LETTER AE
REMAP(0x00E7, 0xE7) // LATIN SMALL LETTER C WITH CEDILLA
REMAP(0x00E8, 0xE8) // LATIN SMALL LETTER E WITH GRAVE
REMAP(0x00E9, 0xE9) // LATIN SMALL LETTER E WITH ACUTE
REMAP(0x00EA, 0xEA) // LATIN SMALL LETTER E WITH CIRCUMFLEX
REMAP(0x00EB, 0xEB) // LATIN SMALL LETTER E WITH DIAERESIS
REMAP(0x00EC, 0xEC) // LATIN SMALL LETTER I WITH GRAVE
REMAP(0x00ED, 0xED) // LATIN SMALL LETTER I WITH ACUTE
REMAP(0x00EE, 0xEE) // LATIN SMALL LETTER I WITH CIRCUMFLEX
REMAP(0x00EF, 0xEF) // LATIN SMALL LETTER I WITH DIAERESIS
REMAP(0x00F0, 0xF0) // LATIN SMALL LETTER ETH
REMAP(0x00F1, 0xF1) // LATIN SMALL LETTER N WITH TILDE
REMAP(0x00F2, 0xF2) // LATIN SMALL LETTER O WITH GRAVE
REMAP(0x00F3, 0xF3) // LATIN SMALL LETTER O WITH ACUTE
REMAP(0x00F4, 0xF4) // LATIN SMALL LETTER O WITH CIRCUMFLEX
REMAP(0x00F5, 0xF5) // LATIN SMALL LETTER O WITH TILDE
REMAP(0x00F6, 0xF6) // LATIN SMALL LETTER O WITH DIAERESIS
REMAP(0x00F7, 0xF7) // DIVISION SIGN
REMAP(0x00F8, 0xF8) // LATIN SMALL LETTER O WITH STROKE
REMAP(0x00F9, 0xF9) // LATIN SMALL LETTER U WITH GRAVE
REMAP(0x00FA, 0xFA) // LATIN SMALL LETTER U WITH ACUTE
REMAP(0x00FB, 0xFB) // LATIN SMALL LETTER U WITH CIRCUMFLEX
REMAP(0x00FC, 0xFC) // LATIN SMALL LETTER U WITH DIAERESIS
REMAP(0x00FD, 0xFD) // LATIN SMALL LETTER Y WITH ACUTE
REMAP(0x00FE, 0xFE) // LATIN SMALL LETTER THORN
REMAP(0x00FF, 0xFF) // LATIN SMALL LETTER Y WITH DIAERESIS
}
}
else if (encoding == WINDOWS_1253) {
// Greek
// 1-Byte chars: no remapping
if (utf8.length() == 1)
return utf8.at(0);
// Multi-byte chars:
switch (toUtf32(utf8)) {
// Windows-1253 special characters (0x80-0xBF range)
REMAP(0x20AC, 0x80) // EURO SIGN
REMAP(0x2018, 0x91) // LEFT SINGLE QUOTATION MARK
REMAP(0x2019, 0x92) // RIGHT SINGLE QUOTATION MARK
REMAP(0x201C, 0x93) // LEFT DOUBLE QUOTATION MARK
REMAP(0x201D, 0x94) // RIGHT DOUBLE QUOTATION MARK
REMAP(0x2022, 0x95) // BULLET
REMAP(0x2013, 0x96) // EN DASH
REMAP(0x2014, 0x97) // EM DASH
// Greek accented capitals
REMAP(0x0386, 0xA2) // GREEK CAPITAL LETTER ALPHA WITH TONOS
REMAP(0x0388, 0xB8) // GREEK CAPITAL LETTER EPSILON WITH TONOS
REMAP(0x0389, 0xB9) // GREEK CAPITAL LETTER ETA WITH TONOS
REMAP(0x038A, 0xBA) // GREEK CAPITAL LETTER IOTA WITH TONOS
REMAP(0x038C, 0xBC) // GREEK CAPITAL LETTER OMICRON WITH TONOS
REMAP(0x038E, 0xBE) // GREEK CAPITAL LETTER UPSILON WITH TONOS
REMAP(0x038F, 0xBF) // GREEK CAPITAL LETTER OMEGA WITH TONOS
// Greek capital letters (U+0391-U+03A9 -> 0xC1-0xD1, with gaps)
REMAP(0x0391, 0xC1) // GREEK CAPITAL LETTER ALPHA
REMAP(0x0392, 0xC2) // GREEK CAPITAL LETTER BETA
REMAP(0x0393, 0xC3) // GREEK CAPITAL LETTER GAMMA
REMAP(0x0394, 0xC4) // GREEK CAPITAL LETTER DELTA
REMAP(0x0395, 0xC5) // GREEK CAPITAL LETTER EPSILON
REMAP(0x0396, 0xC6) // GREEK CAPITAL LETTER ZETA
REMAP(0x0397, 0xC7) // GREEK CAPITAL LETTER ETA
REMAP(0x0398, 0xC8) // GREEK CAPITAL LETTER THETA
REMAP(0x0399, 0xC9) // GREEK CAPITAL LETTER IOTA
REMAP(0x039A, 0xCA) // GREEK CAPITAL LETTER KAPPA
REMAP(0x039B, 0xCB) // GREEK CAPITAL LETTER LAMDA
REMAP(0x039C, 0xCC) // GREEK CAPITAL LETTER MU
REMAP(0x039D, 0xCD) // GREEK CAPITAL LETTER NU
REMAP(0x039E, 0xCE) // GREEK CAPITAL LETTER XI
REMAP(0x039F, 0xCF) // GREEK CAPITAL LETTER OMICRON
REMAP(0x03A0, 0xD0) // GREEK CAPITAL LETTER PI
REMAP(0x03A1, 0xD1) // GREEK CAPITAL LETTER RHO
REMAP(0x03A3, 0xD3) // GREEK CAPITAL LETTER SIGMA
REMAP(0x03A4, 0xD4) // GREEK CAPITAL LETTER TAU
REMAP(0x03A5, 0xD5) // GREEK CAPITAL LETTER UPSILON
REMAP(0x03A6, 0xD6) // GREEK CAPITAL LETTER PHI
REMAP(0x03A7, 0xD7) // GREEK CAPITAL LETTER CHI
REMAP(0x03A8, 0xD8) // GREEK CAPITAL LETTER PSI
REMAP(0x03A9, 0xD9) // GREEK CAPITAL LETTER OMEGA
// Greek small letters with tonos (accented)
REMAP(0x03AC, 0xDC) // GREEK SMALL LETTER ALPHA WITH TONOS
REMAP(0x03AD, 0xDD) // GREEK SMALL LETTER EPSILON WITH TONOS
REMAP(0x03AE, 0xDE) // GREEK SMALL LETTER ETA WITH TONOS
REMAP(0x03AF, 0xDF) // GREEK SMALL LETTER IOTA WITH TONOS
// Greek small letters (U+03B1-U+03C9 -> 0xE1-0xF9)
REMAP(0x03B1, 0xE1) // GREEK SMALL LETTER ALPHA
REMAP(0x03B2, 0xE2) // GREEK SMALL LETTER BETA
REMAP(0x03B3, 0xE3) // GREEK SMALL LETTER GAMMA
REMAP(0x03B4, 0xE4) // GREEK SMALL LETTER DELTA
REMAP(0x03B5, 0xE5) // GREEK SMALL LETTER EPSILON
REMAP(0x03B6, 0xE6) // GREEK SMALL LETTER ZETA
REMAP(0x03B7, 0xE7) // GREEK SMALL LETTER ETA
REMAP(0x03B8, 0xE8) // GREEK SMALL LETTER THETA
REMAP(0x03B9, 0xE9) // GREEK SMALL LETTER IOTA
REMAP(0x03BA, 0xEA) // GREEK SMALL LETTER KAPPA
REMAP(0x03BB, 0xEB) // GREEK SMALL LETTER LAMDA
REMAP(0x03BC, 0xEC) // GREEK SMALL LETTER MU
REMAP(0x03BD, 0xED) // GREEK SMALL LETTER NU
REMAP(0x03BE, 0xEE) // GREEK SMALL LETTER XI
REMAP(0x03BF, 0xEF) // GREEK SMALL LETTER OMICRON
REMAP(0x03C0, 0xF0) // GREEK SMALL LETTER PI
REMAP(0x03C1, 0xF1) // GREEK SMALL LETTER RHO
REMAP(0x03C2, 0xF2) // GREEK SMALL LETTER FINAL SIGMA
REMAP(0x03C3, 0xF3) // GREEK SMALL LETTER SIGMA
REMAP(0x03C4, 0xF4) // GREEK SMALL LETTER TAU
REMAP(0x03C5, 0xF5) // GREEK SMALL LETTER UPSILON
REMAP(0x03C6, 0xF6) // GREEK SMALL LETTER PHI
REMAP(0x03C7, 0xF7) // GREEK SMALL LETTER CHI
REMAP(0x03C8, 0xF8) // GREEK SMALL LETTER PSI
REMAP(0x03C9, 0xF9) // GREEK SMALL LETTER OMEGA
// More accented small letters
REMAP(0x03CA, 0xFA) // GREEK SMALL LETTER IOTA WITH DIALYTIKA
REMAP(0x03CB, 0xFB) // GREEK SMALL LETTER UPSILON WITH DIALYTIKA
REMAP(0x03CC, 0xFC) // GREEK SMALL LETTER OMICRON WITH TONOS
REMAP(0x03CD, 0xFD) // GREEK SMALL LETTER UPSILON WITH TONOS
REMAP(0x03CE, 0xFE) // GREEK SMALL LETTER OMEGA WITH TONOS
}
}
else /*ASCII or Unhandled*/ {
if (utf8.length() == 1)
return utf8.at(0);
}
// All single-byte (ASCII) characters should have been handled by now
// Only unhandled multi-byte UTF8 characters should remain
assert(utf8.length() > 1);
// Parse emoji
// Strip emoji modifiers
switch (toUtf32(utf8)) {
REMAP(0x1F44D, 0x01) // 👍 Thumbs Up
REMAP(0x1F44E, 0x02) // 👎 Thumbs Down
REMAP(0x1F60A, 0x03) // 😊 Smiling Face with Smiling Eyes
REMAP(0x1F642, 0x03) // 🙂 Slightly Smiling Face
REMAP(0x1F601, 0x03) // 😁 Grinning Face with Smiling Eye
REMAP(0x1F602, 0x04) // 😂 Face with Tears of Joy
REMAP(0x1F923, 0x04) // 🤣 Rolling on the Floor Laughing
REMAP(0x1F606, 0x04) // 😆 Smiling with Open Mouth and Closed Eyes
REMAP(0x1F44B, 0x05) // 👋 Waving Hand
REMAP(0x02600, 0x06) // ☀ Sun
REMAP(0x1F31E, 0x06) // 🌞 Sun with Face
// 0x07 - Bell character (unused)
REMAP(0x1F327, 0x08) // 🌧️ Cloud with Rain
REMAP(0x02601, 0x09) // ☁️ Cloud
REMAP(0x1F32B, 0x09) // Fog
REMAP(0x1F9E1, 0x0B) // 🧡 Orange Heart
REMAP(0x02763, 0x0B) // ❣ Heart Exclamation
REMAP(0x02764, 0x0B) // ❤ Heart
REMAP(0x1F495, 0x0B) // 💕 Two Hearts
REMAP(0x1F496, 0x0B) // 💖 Sparkling Heart
REMAP(0x1F497, 0x0B) // 💗 Growing Heart
REMAP(0x1F498, 0x0B) // 💘 Heart with Arrow
REMAP(0x1F4A9, 0x0C) // 💩 Pile of Poo
// 0x0D - Carriage return (unused)
REMAP(0x1F514, 0x0E) // 🔔 Bell
REMAP(0x1F62D, 0x0F) // 😭 Loudly Crying Face
REMAP(0x1F622, 0x0F) // 😢 Crying Face
REMAP(0x1F64F, 0x10) // 🙏 Person with Folded Hands
REMAP(0x1F618, 0x11) // 😘 Face Throwing a Kiss
REMAP(0x1F389, 0x12) // 🎉 Party Popper
REMAP(0x1F600, 0x13) // 😀 Grinning Face
REMAP(0x1F603, 0x13) // 😃 Smiling Face with Open Mouth
REMAP(0x1F604, 0x13) // 😄 Smiling Face with Open Mouth and Smiling Eyes
REMAP(0x1F97A, 0x14) // 🥺 Face with Pleading Eyes
REMAP(0x1F605, 0x15) // 😅 Smiling with Sweat
REMAP(0x1F525, 0x16) // 🔥 Fire
REMAP(0x1F926, 0x17) // 🤦 Face Palm
REMAP(0x1F937, 0x18) // 🤷 Shrug
REMAP(0x1F644, 0x19) // 🙄 Face with Rolling Eyes
// 0x1A Substitution (unused)
REMAP(0x1F917, 0x1B) // 🤗 Hugging Face
REMAP(0x1F609, 0x1C) // 😉 Winking Face
REMAP(0x1F61C, 0x1C) // 😜 Face with Stuck-Out Tongue and Winking Eye
REMAP(0x1F60F, 0x1C) // 😏 Smirking Face
REMAP(0x1F914, 0x1D) // 🤔 Thinking Face
REMAP(0x1FAE1, 0x1E) // 🫡 Saluting Face
REMAP(0x1F44C, 0x1F) // 👌 OK Hand Sign
REMAP(0x02755, '!') // ❕
REMAP(0x02757, '!') // ❗
REMAP(0x0203C, '!') // ‼
REMAP(0x02753, '?') // ❓
REMAP(0x02754, '?') // ❔
REMAP(0x02049, '?') // ⁉
// Modifiers (deleted)
REMAP(0x02640, 0x7F) // Gender
REMAP(0x02642, 0x7F)
REMAP(0x1F3FB, 0x7F) // Skin Tones
REMAP(0x1F3FC, 0x7F)
REMAP(0x1F3FD, 0x7F)
REMAP(0x1F3FE, 0x7F)
REMAP(0x1F3FF, 0x7F)
REMAP(0x0FE00, 0x7F) // Variation Selectors
REMAP(0x0FE01, 0x7F)
REMAP(0x0FE02, 0x7F)
REMAP(0x0FE03, 0x7F)
REMAP(0x0FE04, 0x7F)
REMAP(0x0FE05, 0x7F)
REMAP(0x0FE06, 0x7F)
REMAP(0x0FE07, 0x7F)
REMAP(0x0FE08, 0x7F)
REMAP(0x0FE09, 0x7F)
REMAP(0x0FE0A, 0x7F)
REMAP(0x0FE0B, 0x7F)
REMAP(0x0FE0C, 0x7F)
REMAP(0x0FE0D, 0x7F)
REMAP(0x0FE0E, 0x7F)
REMAP(0x0FE0F, 0x7F)
REMAP(0x0200D, 0x7F) // Zero Width Joiner
}
// If not handled, return SUB
return '\x1A';
// Sweep up the syntactic sugar
// Don't want ants in the house
#undef REMAP
}
#endif
@@ -0,0 +1,97 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Wrapper class for an AdafruitGFX font
Pre-calculates some font dimension info which InkHUD uses repeatedly
Re-encodes UTF-8 characters to suit extended ASCII AdafruitGFX fonts
*/
#pragma once
#include "configuration.h"
#include <GFX.h> // GFXRoot drawing lib
namespace NicheGraphics::InkHUD
{
// An AdafruitGFX font, bundled with precalculated dimensions which are used frequently by InkHUD
class AppletFont
{
public:
enum Encoding {
ASCII,
WINDOWS_1250,
WINDOWS_1251,
WINDOWS_1252,
WINDOWS_1253,
};
AppletFont();
explicit AppletFont(const GFXfont &adafruitGFXFont, Encoding encoding = ASCII, int8_t paddingTop = 0,
int8_t paddingBottom = 0);
uint8_t lineHeight();
uint8_t heightAboveCursor();
uint8_t heightBelowCursor();
uint8_t widthBetweenWords(); // Width of the space character
std::string decodeUTF8(const std::string &encoded);
const GFXfont *gfxFont = nullptr; // Default value: in-built AdafruitGFX font
private:
uint32_t toUtf32(const std::string &utf8);
char applyEncoding(const std::string &utf8);
uint8_t height = 8; // Default value: in-built AdafruitGFX font
uint8_t ascenderHeight = 0; // Default value: in-built AdafruitGFX font
uint8_t descenderHeight = 8; // Default value: in-built AdafruitGFX font
uint8_t spaceCharWidth = 8; // Default value: in-built AdafruitGFX font
Encoding encoding = ASCII;
};
} // namespace NicheGraphics::InkHUD
// Macros for InkHUD's standard fonts
// --------------------------------------
// Use these once only, passing them to InkHUD::Applet::fontLarge and InkHUD::Applet:fontSmall
// Line padding has been adjusted manually, to compensate for a few *extra tall* diacritics
// Central European
#include "graphics/niche/Fonts/FreeSans12pt_Win1250.h"
#include "graphics/niche/Fonts/FreeSans6pt_Win1250.h"
#include "graphics/niche/Fonts/FreeSans9pt_Win1250.h"
#define FREESANS_12PT_WIN1250 InkHUD::AppletFont(FreeSans12pt_Win1250, InkHUD::AppletFont::WINDOWS_1250, -3, 1)
#define FREESANS_9PT_WIN1250 InkHUD::AppletFont(FreeSans9pt_Win1250, InkHUD::AppletFont::WINDOWS_1250, -1, -1)
#define FREESANS_6PT_WIN1250 InkHUD::AppletFont(FreeSans6pt_Win1250, InkHUD::AppletFont::WINDOWS_1250, -1, -2)
// Cyrillic
#include "graphics/niche/Fonts/FreeSans12pt_Win1251.h"
#include "graphics/niche/Fonts/FreeSans6pt_Win1251.h"
#include "graphics/niche/Fonts/FreeSans9pt_Win1251.h"
#define FREESANS_12PT_WIN1251 InkHUD::AppletFont(FreeSans12pt_Win1251, InkHUD::AppletFont::WINDOWS_1251, -3, 1)
#define FREESANS_9PT_WIN1251 InkHUD::AppletFont(FreeSans9pt_Win1251, InkHUD::AppletFont::WINDOWS_1251, -2, -1)
#define FREESANS_6PT_WIN1251 InkHUD::AppletFont(FreeSans6pt_Win1251, InkHUD::AppletFont::WINDOWS_1251, -1, -2)
// Western European
#include "graphics/niche/Fonts/FreeSans12pt_Win1252.h"
#include "graphics/niche/Fonts/FreeSans6pt_Win1252.h"
#include "graphics/niche/Fonts/FreeSans9pt_Win1252.h"
#define FREESANS_12PT_WIN1252 InkHUD::AppletFont(FreeSans12pt_Win1252, InkHUD::AppletFont::WINDOWS_1252, -3, 1)
#define FREESANS_9PT_WIN1252 InkHUD::AppletFont(FreeSans9pt_Win1252, InkHUD::AppletFont::WINDOWS_1252, -2, -1)
#define FREESANS_6PT_WIN1252 InkHUD::AppletFont(FreeSans6pt_Win1252, InkHUD::AppletFont::WINDOWS_1252, -1, -2)
// Greek
#include "graphics/niche/Fonts/FreeSans12pt_Win1253.h"
#include "graphics/niche/Fonts/FreeSans6pt_Win1253.h"
#include "graphics/niche/Fonts/FreeSans9pt_Win1253.h"
#define FREESANS_12PT_WIN1253 InkHUD::AppletFont(FreeSans12pt_Win1253, InkHUD::AppletFont::WINDOWS_1253, -3, 1)
#define FREESANS_9PT_WIN1253 InkHUD::AppletFont(FreeSans9pt_Win1253, InkHUD::AppletFont::WINDOWS_1253, -2, -1)
#define FREESANS_6PT_WIN1253 InkHUD::AppletFont(FreeSans6pt_Win1253, InkHUD::AppletFont::WINDOWS_1253, -1, -2)
#endif
@@ -0,0 +1,558 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./MapApplet.h"
using namespace NicheGraphics;
void InkHUD::MapApplet::onRender(bool full)
{
// Abort if no markers to render
if (!enoughMarkers()) {
printAt(X(0.5), Y(0.5) - (getFont().lineHeight() / 2), "Node positions", CENTER, MIDDLE);
printAt(X(0.5), Y(0.5) + (getFont().lineHeight() / 2), "will appear here", CENTER, MIDDLE);
return;
}
// Helper: draw rounded rectangle centered at x,y
auto fillRoundedRect = [&](int16_t cx, int16_t cy, int16_t w, int16_t h, int16_t r, uint16_t color) {
int16_t x = cx - (w / 2);
int16_t y = cy - (h / 2);
// center rects
fillRect(x + r, y, w - 2 * r, h, color);
fillRect(x, y + r, r, h - 2 * r, color);
fillRect(x + w - r, y + r, r, h - 2 * r, color);
// corners
fillCircle(x + r, y + r, r, color);
fillCircle(x + w - r - 1, y + r, r, color);
fillCircle(x + r, y + h - r - 1, r, color);
fillCircle(x + w - r - 1, y + h - r - 1, r, color);
};
// Find center of map
getMapCenter(&latCenter, &lngCenter);
calculateAllMarkers();
getMapSize(&widthMeters, &heightMeters);
calculateMapScale();
// Draw all markers first
for (Marker m : markers) {
int16_t x = X(0.5) + (m.eastMeters * metersToPx);
int16_t y = Y(0.5) - (m.northMeters * metersToPx);
// Add white halo outline first
constexpr int outlinePad = 1;
int boxSize = 11;
int radius = 2; // rounded corner radius
// White halo background
fillRoundedRect(x, y, boxSize + (outlinePad * 2), boxSize + (outlinePad * 2), radius + 1, WHITE);
// Draw inner box
fillRoundedRect(x, y, boxSize, boxSize, radius, BLACK);
// Text inside
setFont(fontSmall);
setTextColor(WHITE);
// Draw actual marker on top
if (m.hasHopsAway && m.hopsAway > config.lora.hop_limit) {
printAt(x + 1, y + 1, "X", CENTER, MIDDLE);
} else if (!m.hasHopsAway) {
printAt(x + 1, y + 1, "?", CENTER, MIDDLE);
} else {
char hopStr[4];
snprintf(hopStr, sizeof(hopStr), "%d", m.hopsAway);
printAt(x, y + 1, hopStr, CENTER, MIDDLE);
}
// Restore default font and color
setFont(fontSmall);
setTextColor(BLACK);
}
// Dual map scale bars
int16_t horizPx = width() * 0.25f;
int16_t vertPx = height() * 0.25f;
float horizMeters = horizPx / metersToPx;
float vertMeters = vertPx / metersToPx;
auto formatDistance = [&](float meters, char *out, size_t len) {
if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) {
float feet = meters * 3.28084f;
if (feet < 528)
snprintf(out, len, "%.0f ft", feet);
else {
float miles = feet / 5280.0f;
snprintf(out, len, miles < 10 ? "%.1f mi" : "%.0f mi", miles);
}
} else {
if (meters >= 1000)
snprintf(out, len, "%.1f km", meters / 1000.0f);
else
snprintf(out, len, "%.0f m", meters);
}
};
// Horizontal scale bar
int16_t horizBarY = height() - 2;
int16_t horizBarX = 1;
drawLine(horizBarX, horizBarY, horizBarX + horizPx, horizBarY, BLACK);
drawLine(horizBarX, horizBarY - 3, horizBarX, horizBarY + 3, BLACK);
drawLine(horizBarX + horizPx, horizBarY - 3, horizBarX + horizPx, horizBarY + 3, BLACK);
char horizLabel[32];
formatDistance(horizMeters, horizLabel, sizeof(horizLabel));
int16_t horizLabelW = getTextWidth(horizLabel);
int16_t horizLabelH = getFont().lineHeight();
int16_t horizLabelX = horizBarX + horizPx + 4;
int16_t horizLabelY = horizBarY - horizLabelH + 1;
fillRect(horizLabelX - 2, horizLabelY - 1, horizLabelW + 4, horizLabelH + 2, WHITE);
printAt(horizLabelX, horizBarY, horizLabel, LEFT, BOTTOM);
// Vertical scale bar
int16_t vertBarX = 1;
int16_t vertBarBottom = horizBarY;
int16_t vertBarTop = vertBarBottom - vertPx;
drawLine(vertBarX, vertBarBottom, vertBarX, vertBarTop, BLACK);
drawLine(vertBarX - 3, vertBarBottom, vertBarX + 3, vertBarBottom, BLACK);
drawLine(vertBarX - 3, vertBarTop, vertBarX + 3, vertBarTop, BLACK);
char vertTopLabel[32];
formatDistance(vertMeters, vertTopLabel, sizeof(vertTopLabel));
int16_t topLabelY = vertBarTop - getFont().lineHeight() - 2;
int16_t topLabelW = getTextWidth(vertTopLabel);
int16_t topLabelH = getFont().lineHeight();
fillRect(vertBarX - 2, topLabelY - 1, topLabelW + 6, topLabelH + 2, WHITE);
printAt(vertBarX + (topLabelW / 2) + 1, topLabelY + (topLabelH / 2), vertTopLabel, CENTER, MIDDLE);
char vertBottomLabel[32];
formatDistance(vertMeters, vertBottomLabel, sizeof(vertBottomLabel));
int16_t bottomLabelY = vertBarBottom + 4;
int16_t bottomLabelW = getTextWidth(vertBottomLabel);
int16_t bottomLabelH = getFont().lineHeight();
fillRect(vertBarX - 2, bottomLabelY - 1, bottomLabelW + 6, bottomLabelH + 2, WHITE);
printAt(vertBarX + (bottomLabelW / 2) + 1, bottomLabelY + (bottomLabelH / 2), vertBottomLabel, CENTER, MIDDLE);
// Draw our node LAST with full white fill + outline
meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
if (ourNode && nodeDB->hasValidPosition(ourNode)) {
Marker self = calculateMarker(ourNode->position.latitude_i * 1e-7, ourNode->position.longitude_i * 1e-7, false, 0);
int16_t centerX = X(0.5) + (self.eastMeters * metersToPx);
int16_t centerY = Y(0.5) - (self.northMeters * metersToPx);
// White fill background + halo
fillCircle(centerX, centerY, 8, WHITE); // big white base
drawCircle(centerX, centerY, 8, WHITE); // crisp edge
// Black bullseye on top
drawCircle(centerX, centerY, 6, BLACK);
fillCircle(centerX, centerY, 2, BLACK);
// Crosshairs
drawLine(centerX - 8, centerY, centerX + 8, centerY, BLACK);
drawLine(centerX, centerY - 8, centerX, centerY + 8, BLACK);
}
}
// Find the center point, in the middle of all node positions
// Calculated values are written to the *lat and *long pointer args
// - Finds the "mean lat long"
// - Calculates furthest nodes from "mean lat long"
// - Place map center directly between these furthest nodes
void InkHUD::MapApplet::getMapCenter(float *lat, float *lng)
{
// If we have a valid position for our own node, use that as the anchor
meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
if (ourNode && nodeDB->hasValidPosition(ourNode)) {
*lat = ourNode->position.latitude_i * 1e-7;
*lng = ourNode->position.longitude_i * 1e-7;
} else {
// Find mean lat long coords
// ============================
// - assigning X, Y and Z values to position on Earth's surface in 3D space, relative to center of planet
// - averages the x, y and z coords
// - uses tan to find angles for lat / long degrees
// - longitude: triangle formed by x and y (on plane of the equator)
// - latitude: triangle formed by z (north south),
// and the line along plane of equator which stretches from earth's axis to where point xyz intersects planet's
// surface
// Working totals, averaged after nodeDB processed
uint32_t positionCount = 0;
float xAvg = 0;
float yAvg = 0;
float zAvg = 0;
// For each node in db
for (uint32_t i = 0; i < nodeDB->getNumMeshNodes(); i++) {
meshtastic_NodeInfoLite *node = nodeDB->getMeshNodeByIndex(i);
// Skip if no position
if (!nodeDB->hasValidPosition(node))
continue;
// Skip if derived applet doesn't want to show this node on the map
if (!shouldDrawNode(node))
continue;
// Latitude and Longitude of node, in radians
float latRad = node->position.latitude_i * (1e-7) * DEG_TO_RAD;
float lngRad = node->position.longitude_i * (1e-7) * DEG_TO_RAD;
// Convert to cartesian points, with center of earth at 0, 0, 0
// Exact distance from center is irrelevant, as we're only interested in the vector
float x = cos(latRad) * cos(lngRad);
float y = cos(latRad) * sin(lngRad);
float z = sin(latRad);
// To find mean values shortly
xAvg += x;
yAvg += y;
zAvg += z;
positionCount++;
}
// All NodeDB processed, find mean values
xAvg /= positionCount;
yAvg /= positionCount;
zAvg /= positionCount;
// Longitude from cartesian coords
// (Angle from 3D coords describing a point of globe's surface)
/*
UK
/-------\
(Top View) /- -\
/- (You) -\
/- . -\
/- . X -\
Asia - ... - USA
\- Y -/
\- -/
\- -/
\- -/
\- -----/
Pacific
*/
*lng = atan2(yAvg, xAvg) * RAD_TO_DEG;
// Latitude from cartesian coords
// (Angle from 3D coords describing a point on the globe's surface)
// As latitude increases, distance from the Earth's north-south axis out to our surface point decreases.
// Means we need to first find the hypotenuse which becomes base of our triangle in the second step
/*
UK North
/-------\ (Front View) /-------\
(Top View) /- -\ /- -\
/- (You) -\ /-(You) -\
/- /. -\ /- . -\
/- √X²+Y²/ . X -\ /- Z . -\
Asia - /... - USA - ..... -
\- Y -/ \- √X²+Y² -/
\- -/ \- -/
\- -/ \- -/
\- -/ \- -/
\- -----/ \- -----/
Pacific South
*/
float hypotenuse = sqrt((xAvg * xAvg) + (yAvg * yAvg)); // Distance from globe's north-south axis to surface intersect
*lat = atan2(zAvg, hypotenuse) * RAD_TO_DEG;
}
// Use either our node position, or the mean fallback as the center
latCenter = *lat;
lngCenter = *lng;
// ----------------------------------------------
// This has given us either:
// - our actual position (preferred), or
// - a mean position (fallback if we had no fix)
//
// What we actually want is to place our center so that our outermost nodes
// end up on the border of our map. The only real use of our "center" is to give
// us a reference frame: which direction is east, and which is west.
//------------------------------------------------
// Find furthest nodes from our center
// ========================================
float northernmost = latCenter;
float southernmost = latCenter;
float easternmost = lngCenter;
float westernmost = lngCenter;
for (size_t i = 0; i < nodeDB->getNumMeshNodes(); i++) {
meshtastic_NodeInfoLite *node = nodeDB->getMeshNodeByIndex(i);
// Skip if no position
if (!nodeDB->hasValidPosition(node))
continue;
// Skip if derived applet doesn't want to show this node on the map
if (!shouldDrawNode(node))
continue;
// Check for a new top or bottom latitude
float latNode = node->position.latitude_i * 1e-7;
northernmost = max(northernmost, latNode);
southernmost = min(southernmost, latNode);
// Longitude is trickier
float lngNode = node->position.longitude_i * 1e-7;
float degEastward = fmod(((lngNode - lngCenter) + 360), 360); // Degrees traveled east from lngCenter to reach node
float degWestward = abs(fmod(((lngNode - lngCenter) - 360), 360)); // Degrees traveled west from lngCenter to reach node
if (degEastward < degWestward)
easternmost = max(easternmost, lngCenter + degEastward);
else
westernmost = min(westernmost, lngCenter - degWestward);
}
// Todo: check for issues with map spans >180 deg. MQTT only..
latCenter = (northernmost + southernmost) / 2;
lngCenter = (westernmost + easternmost) / 2;
// In case our new center is west of -180, or east of +180, for some reason
lngCenter = fmod(lngCenter, 180);
}
// Size of map in meters
// Grown to fit the nodes furthest from map center
// Overridable if derived applet wants a custom map size (fixed size?)
void InkHUD::MapApplet::getMapSize(uint32_t *widthMeters, uint32_t *heightMeters)
{
// Reset the value
*widthMeters = 0;
*heightMeters = 0;
// Find the greatest distance horizontally and vertically from map center
for (Marker m : markers) {
*widthMeters = max(*widthMeters, (uint32_t)abs(m.eastMeters) * 2);
*heightMeters = max(*heightMeters, (uint32_t)abs(m.northMeters) * 2);
}
// Add padding
*widthMeters *= 1.1;
*heightMeters *= 1.1;
}
// Convert and store info we need for drawing a marker
// Lat / long to "meters relative to map center", for position on screen
// Info about hopsAway, for marker size
InkHUD::MapApplet::Marker InkHUD::MapApplet::calculateMarker(float lat, float lng, bool hasHopsAway, uint8_t hopsAway)
{
assert(lat != 0 || lng != 0); // Not null island. Applets should check this before calling.
// Bearing and distance from map center to node
float distanceFromCenter = GeoCoord::latLongToMeter(latCenter, lngCenter, lat, lng);
float bearingFromCenter = GeoCoord::bearing(latCenter, lngCenter, lat, lng); // in radians
// Split into meters north and meters east components (signed)
// - signedness of cos / sin automatically sets negative if south or west
float northMeters = cos(bearingFromCenter) * distanceFromCenter;
float eastMeters = sin(bearingFromCenter) * distanceFromCenter;
// Store this as a new marker
Marker m;
m.eastMeters = eastMeters;
m.northMeters = northMeters;
m.hasHopsAway = hasHopsAway;
m.hopsAway = hopsAway;
return m;
}
// Draw a marker on the map for a node, with a shortname label, and backing box
void InkHUD::MapApplet::drawLabeledMarker(meshtastic_NodeInfoLite *node)
{
// Find x and y position based on node's position in nodeDB
assert(nodeDB->hasValidPosition(node));
Marker m = calculateMarker(node->position.latitude_i * 1e-7, // Lat, converted from Meshtastic's internal int32 style
node->position.longitude_i * 1e-7, // Long, converted from Meshtastic's internal int32 style
node->has_hops_away, // Is the hopsAway number valid
node->hops_away // Hops away
);
// Convert to pixel coords
int16_t markerX = X(0.5) + (m.eastMeters * metersToPx);
int16_t markerY = Y(0.5) - (m.northMeters * metersToPx);
constexpr uint16_t paddingH = 2;
constexpr uint16_t paddingW = 4;
uint16_t paddingInnerW = 2; // Zero'd out if no text
constexpr uint16_t markerSizeMax = 12; // Size of cross (if marker uses a cross)
constexpr uint16_t markerSizeMin = 5;
int16_t textX;
int16_t textY;
uint16_t textW;
uint16_t textH;
int16_t labelX;
int16_t labelY;
uint16_t labelW;
uint16_t labelH;
uint8_t markerSize;
bool tooManyHops = node->hops_away > config.lora.hop_limit;
bool isOurNode = node->num == nodeDB->getNodeNum();
bool unknownHops = !node->has_hops_away && !isOurNode;
// Parse any non-ascii chars in the short name,
// and use last 4 instead if unknown / can't render
std::string shortName = parseShortName(node);
// We will draw a left or right hand variant, to place text towards screen center
// Hopefully avoid text spilling off screen
// Most values are the same, regardless of left-right handedness
// Pick emblem style
if (tooManyHops)
markerSize = getTextWidth("!");
else if (unknownHops)
markerSize = markerSizeMin;
else
markerSize = map(node->hops_away, 0, config.lora.hop_limit, markerSizeMax, markerSizeMin);
// Common dimensions (left or right variant)
textW = getTextWidth(shortName);
if (textW == 0)
paddingInnerW = 0; // If no text, no padding for text
textH = fontSmall.lineHeight();
labelH = paddingH + max((int16_t)(textH), (int16_t)markerSize) + paddingH;
labelY = markerY - (labelH / 2);
textY = markerY;
labelW = paddingW + markerSize + paddingInnerW + textW + paddingW; // Width is same whether right or left hand variant
// Left-side variant
if (markerX < width() / 2) {
labelX = markerX - (markerSize / 2) - paddingW;
textX = labelX + paddingW + markerSize + paddingInnerW;
}
// Right-side variant
else {
labelX = markerX - (markerSize / 2) - paddingInnerW - textW - paddingW;
textX = labelX + paddingW;
}
// Prevent overlap with scale bars and their labels
// Define a "safe zone" in the bottom-left where the scale bars and text are drawn
constexpr int16_t safeZoneHeight = 28; // adjust based on your label font height
constexpr int16_t safeZoneWidth = 60; // adjust based on horizontal label width zone
bool overlapsScale = (labelY + labelH > height() - safeZoneHeight) && (labelX < safeZoneWidth);
// If it overlaps, shift label upward slightly above the safe zone
if (overlapsScale) {
labelY = height() - safeZoneHeight - labelH - 2;
textY = labelY + (labelH / 2);
}
// Backing box
fillRect(labelX, labelY, labelW, labelH, WHITE);
drawRect(labelX, labelY, labelW, labelH, BLACK);
// Short name
printAt(textX, textY, shortName, LEFT, MIDDLE);
// If the label is for our own node,
// fade it by overdrawing partially with white
if (node == nodeDB->getMeshNode(nodeDB->getNodeNum()))
hatchRegion(labelX, labelY, labelW, labelH, 2, WHITE);
// Draw the marker emblem
// - after the fading, because hatching (own node) can align with cross and make it look weird
if (tooManyHops)
printAt(markerX, markerY, "!", CENTER, MIDDLE);
else
drawCross(markerX, markerY, markerSize); // The fewer the hops, the larger the marker. Also handles unknownHops
}
// Check if we actually have enough nodes which would be shown on the map
// Need at least two, to draw a sensible map
bool InkHUD::MapApplet::enoughMarkers()
{
size_t count = 0;
for (size_t i = 0; i < nodeDB->getNumMeshNodes(); i++) {
meshtastic_NodeInfoLite *node = nodeDB->getMeshNodeByIndex(i);
// Count nodes
if (nodeDB->hasValidPosition(node) && shouldDrawNode(node))
count++;
// We need to find two
if (count == 2)
return true; // Two nodes is enough for a sensible map
}
return false; // No nodes would be drawn (or just the one, uselessly at 0,0)
}
// Calculate how far north and east of map center each node is
// Derived applets can control which nodes to calculate (and later, draw) by overriding MapApplet::shouldDrawNode
void InkHUD::MapApplet::calculateAllMarkers()
{
// Clear old markers
markers.clear();
// For each node in db
for (uint32_t i = 0; i < nodeDB->getNumMeshNodes(); i++) {
meshtastic_NodeInfoLite *node = nodeDB->getMeshNodeByIndex(i);
// Skip if no position
if (!nodeDB->hasValidPosition(node))
continue;
// Skip if derived applet doesn't want to show this node on the map
if (!shouldDrawNode(node))
continue;
// Skip if our own node
// - special handling in render()
if (node->num == nodeDB->getNodeNum())
continue;
// Calculate marker and store it
markers.push_back(
calculateMarker(node->position.latitude_i * 1e-7, // Lat, converted from Meshtastic's internal int32 style
node->position.longitude_i * 1e-7, // Long, converted from Meshtastic's internal int32 style
node->has_hops_away, // Is the hopsAway number valid
node->hops_away // Hops away
));
}
}
// Determine the conversion factor between metres, and pixels on screen
// May be overriden by derived applet, if custom scale required (fixed map size?)
void InkHUD::MapApplet::calculateMapScale()
{
// Aspect ratio of map and screen
// - larger = wide, smaller = tall
// - used to set scale, so that widest map dimension fits in applet
float mapAspectRatio = (float)widthMeters / heightMeters;
float appletAspectRatio = (float)width() / height();
// "Shrink to fit"
// Scale the map so that the largest dimension is fully displayed
// Because aspect ratio will be maintained, the other dimension will appear "padded"
if (mapAspectRatio > appletAspectRatio)
metersToPx = (float)width() / widthMeters; // Too wide for applet. Constrain to fit width.
else
metersToPx = (float)height() / heightMeters; // Too tall for applet. Constrain to fit height.
}
// Draw an x, centered on a specific point
// Most markers will draw with this method
void InkHUD::MapApplet::drawCross(int16_t x, int16_t y, uint8_t size)
{
int16_t x0 = x - (size / 2);
int16_t y0 = y - (size / 2);
int16_t x1 = x0 + size - 1;
int16_t y1 = y0 + size - 1;
drawLine(x0, y0, x1, y1, BLACK);
drawLine(x0, y1, x1, y0, BLACK);
}
#endif
@@ -0,0 +1,65 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Base class for Applets which show nodes on a map
Plots position of for a selection of nodes, with north facing up.
Size of cross represents hops away.
Our own node is identified with a faded label.
The base applet doesn't handle any events; this is left to the derived applets.
*/
#pragma once
#include "configuration.h"
#include "graphics/niche/InkHUD/Applet.h"
#include "MeshModule.h"
#include "gps/GeoCoord.h"
namespace NicheGraphics::InkHUD
{
class MapApplet : public Applet
{
public:
void onRender(bool full) override;
protected:
virtual bool shouldDrawNode(meshtastic_NodeInfoLite *node) { return true; } // Allow derived applets to filter the nodes
virtual void getMapCenter(float *lat, float *lng);
virtual void getMapSize(uint32_t *widthMeters, uint32_t *heightMeters);
bool enoughMarkers(); // Anything to draw?
void drawLabeledMarker(meshtastic_NodeInfoLite *node); // Highlight a specific marker
private:
// Position and size of a marker to be drawn
struct Marker {
float eastMeters = 0; // Meters east of map center. Negative if west.
float northMeters = 0; // Meters north of map center. Negative if south.
bool hasHopsAway = false;
uint8_t hopsAway = 0; // Determines marker size
};
Marker calculateMarker(float lat, float lng, bool hasHopsAway, uint8_t hopsAway);
void calculateAllMarkers();
void calculateMapScale(); // Conversion factor for meters to pixels
void drawCross(int16_t x, int16_t y, uint8_t size); // Draw the X used for most markers
float metersToPx = 0; // Conversion factor for meters to pixels
float latCenter = 0; // Map center: latitude
float lngCenter = 0; // Map center: longitude
std::list<Marker> markers;
uint32_t widthMeters = 0; // Map width: meters
uint32_t heightMeters = 0; // Map height: meters
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,291 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "RTC.h"
#include "GeoCoord.h"
#include "NodeDB.h"
#include "./NodeListApplet.h"
using namespace NicheGraphics;
InkHUD::NodeListApplet::NodeListApplet(const char *name) : MeshModule(name)
{
// We only need to be promiscuous in order to hear NodeInfo, apparently. See NodeInfoModule
// For all other packets, we manually act as if isPromiscuous=false, in wantPacket
MeshModule::isPromiscuous = true;
}
// Do we want to process this packet with handleReceived()?
bool InkHUD::NodeListApplet::wantPacket(const meshtastic_MeshPacket *p)
{
// Only interested if:
return isActive() // Applet is active
&& !isFromUs(p) // Packet is incoming (not outgoing)
&& (isToUs(p) || isBroadcast(p->to) || // Either: intended for us,
p->decoded.portnum == meshtastic_PortNum_NODEINFO_APP); // or nodeinfo
// To match the behavior seen in the client apps:
// - NodeInfoModule's ProtoBufModule base is "promiscuous"
// - All other activity is *not* promiscuous
// To achieve this, our MeshModule *is* promiscuous, and we're manually reimplementing non-promiscuous behavior here,
// to match the code in MeshModule::callModules
}
// MeshModule packets arrive here
// Extract the info and pass it to the derived applet
// Derived applet will store the CardInfo, and perform any required sorting of the CardInfo collection
// Derived applet might also need to keep other tallies (active nodes count?)
ProcessMessage InkHUD::NodeListApplet::handleReceived(const meshtastic_MeshPacket &mp)
{
// Abort if applet fully deactivated
// Already handled by wantPacket in this case, but good practice for all applets, as some *do* require this early return
if (!isActive())
return ProcessMessage::CONTINUE;
// Assemble info: from this event
CardInfo c;
c.nodeNum = mp.from;
c.signal = getSignalStrength(mp.rx_snr, mp.rx_rssi);
// Assemble info: from nodeDB (needed to detect changes)
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(c.nodeNum);
meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
if (node) {
if (node->has_hops_away)
c.hopsAway = node->hops_away;
if (nodeDB->hasValidPosition(node) && nodeDB->hasValidPosition(ourNode)) {
// Get lat and long as float
// Meshtastic stores these as integers internally
float ourLat = ourNode->position.latitude_i * 1e-7;
float ourLong = ourNode->position.longitude_i * 1e-7;
float theirLat = node->position.latitude_i * 1e-7;
float theirLong = node->position.longitude_i * 1e-7;
c.distanceMeters = (int32_t)GeoCoord::latLongToMeter(theirLat, theirLong, ourLat, ourLong);
}
}
// Pass to the derived applet
// Derived applet is responsible for requesting update, if justified
// That request will eventually trigger our class' onRender method
handleParsed(c);
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
}
// Calculate maximum number of cards we may ever need to render, in our tallest layout config
// Number might be slightly in excess of the true value: applet header text not accounted for
uint8_t InkHUD::NodeListApplet::maxCards()
{
// Cache result. Shouldn't change during execution
static uint8_t maxCardCount = 0;
if (!maxCardCount) {
const uint16_t height = Tile::maxDisplayDimension();
// Use a loop instead of arithmetic, because it's easier for my brain to follow
// Add cards one by one, until the latest card extends below screen
uint16_t y = cardH; // First card: no margin above
maxCardCount = 1;
while (y < height) {
y += cardMarginH;
y += cardH;
maxCardCount++;
}
}
return maxCardCount;
}
// Draw, using info which derived applet placed into NodeListApplet::cards for us
void InkHUD::NodeListApplet::onRender(bool full)
{
// ================================
// Draw the standard applet header
// ================================
drawHeader(getHeaderText()); // Ask derived applet for the title
// Dimensions of the header
int16_t headerDivY = getHeaderHeight() - 1;
constexpr uint16_t padDivH = 2;
// ========================
// Draw the main node list
// ========================
// Imaginary vertical line dividing left-side and right-side info
// Long-name will crop here
const uint16_t dividerX = (width() - 1) - getTextWidth("X Hops");
// Y value (top) of the current card. Increases as we draw.
uint16_t cardTopY = headerDivY + padDivH;
// Clean up deleted nodes before drawing
cards.erase(
std::remove_if(cards.begin(), cards.end(), [](const CardInfo &c) { return nodeDB->getMeshNode(c.nodeNum) == nullptr; }),
cards.end());
// -- Each node in list --
for (auto card = cards.begin(); card != cards.end(); ++card) {
// Gather info
// ========================================
const NodeNum &nodeNum = card->nodeNum;
SignalStrength &signal = card->signal;
std::string longName; // handled below
std::string shortName; // handled below
std::string distance; // handled below;
const uint8_t &hopsAway = card->hopsAway;
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeNum);
// Skip deleted nodes
if (!node) {
continue;
}
// -- Shortname --
// Parse special chars in the short name
// Use "?" if unknown
if (node)
shortName = parseShortName(node);
else
shortName = "?";
// -- Longname --
// Parse special chars in long name
// Use node id if unknown
if (node && node->has_user)
longName = parse(node->user.long_name); // Found in nodeDB
else {
// Not found in nodeDB, show a hex nodeid instead
longName = hexifyNodeNum(nodeNum);
}
// -- Distance --
if (card->distanceMeters != CardInfo::DISTANCE_UNKNOWN)
distance = localizeDistance(card->distanceMeters);
// Draw the info
// ====================================
// Define two lines of text for the card
// We will center our text on these lines
uint16_t lineAY = cardTopY + (fontMedium.lineHeight() / 2);
uint16_t lineBY = cardTopY + fontMedium.lineHeight() + (fontSmall.lineHeight() / 2);
// Print the short name
setFont(fontMedium);
printAt(0, lineAY, shortName, LEFT, MIDDLE);
// Print the distance
setFont(fontSmall);
printAt(width() - 1, lineBY, distance, RIGHT, MIDDLE);
// If we have a direct connection to the node, draw the signal indicator
if (hopsAway == 0 && signal != SIGNAL_UNKNOWN) {
uint16_t signalW = getTextWidth("Xkm"); // Indicator should be similar width to distance label
uint16_t signalH = fontMedium.lineHeight() * 0.75;
int16_t signalY = lineAY + (fontMedium.lineHeight() / 2) - (fontMedium.lineHeight() * 0.75);
int16_t signalX = width() - signalW;
drawSignalIndicator(signalX, signalY, signalW, signalH, signal);
}
// Otherwise, print "hops away" info, if available
else if (hopsAway != CardInfo::HOPS_UNKNOWN && node) {
std::string hopString = to_string(node->hops_away);
hopString += " Hop";
if (node->hops_away != 1)
hopString += "s"; // Append s for "Hops", rather than "Hop"
printAt(width() - 1, lineAY, hopString, RIGHT, MIDDLE);
}
// Print the long name, cropping to prevent overflow onto the right-side info
setCrop(0, 0, dividerX - 1, height());
printAt(0, lineBY, longName, LEFT, MIDDLE);
// GFX effect: "hatch" the right edge of longName area
// If a longName has been cropped, it will appear to fade out,
// creating a soft barrier with the right-side info
const int16_t hatchLeft = dividerX - 1 - (fontSmall.lineHeight());
const int16_t hatchWidth = fontSmall.lineHeight();
hatchRegion(hatchLeft, cardTopY, hatchWidth, cardH, 2, WHITE);
// Prepare to draw the next card
resetCrop();
cardTopY += cardH;
// Once we've run out of screen, stop drawing cards
// Depending on tiles / rotation, this may be before we hit maxCards
if (cardTopY > height())
break;
}
}
// Draw element: a "mobile phone" style signal indicator
// We will calculate values as floats, then "rasterize" at the last moment, relative to x and w, etc
// This prevents issues with premature rounding when rendering tiny elements
void InkHUD::NodeListApplet::drawSignalIndicator(int16_t x, int16_t y, uint16_t w, uint16_t h, SignalStrength strength)
{
/*
+-------------------------------------------+
| |
| |
| barHeightRelative=1.0
| +--+ ^ |
| gutterW +--+ | | | |
| <--> +--+ | | | | | |
| +--+ | | | | | | | |
| | | | | | | | | | |
| <-> +--+ +--+ +--+ +--+ v |
| paddingW ^ |
| paddingH | |
| v |
+-------------------------------------------+
*/
constexpr float paddingW = 0.1; // Either side
constexpr float paddingH = 0.1; // Above and below
constexpr float gutterW = 0.1; // Between bars
constexpr float barHRel[] = {0.3, 0.5, 0.7, 1.0}; // Heights of the signal bars, relative to the tallest
constexpr uint8_t barCount = 4; // How many bars we draw. Reference only: changing value won't change the count.
// Dynamically calculate the width of the bars, and height of the rightmost, relative to other dimensions
float barW = (1.0 - (paddingW + ((barCount - 1) * gutterW) + paddingW)) / barCount;
float barHMax = 1.0 - (paddingH + paddingH);
// Draw signal bar rectangles, then placeholder lines once strength reached
for (uint8_t i = 0; i < barCount; i++) {
// Coords for this specific bar
float barH = barHMax * barHRel[i];
float barX = paddingW + (i * (gutterW + barW));
float barY = paddingH + (barHMax - barH);
// Rasterize to px coords at the last moment
int16_t rX = (x + (w * barX)) + 0.5;
int16_t rY = (y + (h * barY)) + 0.5;
uint16_t rW = (w * barW) + 0.5;
uint16_t rH = (h * barH) + 0.5;
// Draw signal bars, until we are displaying the correct "signal strength", then just draw placeholder lines
if (i <= strength)
drawRect(rX, rY, rW, rH, BLACK);
else {
// Just draw a placeholder line
float lineY = barY + barH;
uint16_t rLineY = (y + (h * lineY)) + 0.5; // Rasterize
drawLine(rX, rLineY, rX + rW - 1, rLineY, BLACK);
}
}
}
#endif
@@ -0,0 +1,74 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Base class for Applets which display a list of nodes
Used by the "Recents" and "Heard" applets. Possibly more in future?
+-------------------------------+
| | |
| SHRT . | | |
| Long name 50km |
| |
| ABCD 2 Hops |
| abcdedfghijk 30km |
| |
+-------------------------------+
*/
#pragma once
#include "configuration.h"
#include "graphics/niche/InkHUD/Applet.h"
#include "main.h"
namespace NicheGraphics::InkHUD
{
class NodeListApplet : public Applet, public MeshModule
{
protected:
// Info needed to draw a node card to the list
// - generated each time we hear a node
struct CardInfo {
static constexpr uint8_t HOPS_UNKNOWN = -1;
static constexpr uint32_t DISTANCE_UNKNOWN = -1;
NodeNum nodeNum = 0;
SignalStrength signal = SignalStrength::SIGNAL_UNKNOWN;
uint32_t distanceMeters = DISTANCE_UNKNOWN;
uint8_t hopsAway = HOPS_UNKNOWN;
};
public:
NodeListApplet(const char *name);
void onRender(bool full) override;
bool wantPacket(const meshtastic_MeshPacket *p) override;
ProcessMessage handleReceived(const meshtastic_MeshPacket &mp) override;
protected:
virtual void handleParsed(CardInfo c) = 0; // Tell derived applet that we heard a node
virtual std::string getHeaderText() = 0; // Ask derived class what the applet's title should be
uint8_t maxCards(); // Max number of cards which could ever fit on screen
std::deque<CardInfo> cards; // Cards to be rendered. Derived applet fills this.
private:
void drawSignalIndicator(int16_t x, int16_t y, uint16_t w, uint16_t h,
SignalStrength signal); // Draw a "mobile phone" style signal indicator
// Card Dimensions
// - for rendering and for maxCards calc
uint8_t cardMarginH = fontSmall.lineHeight() / 2; // Gap between cards
uint16_t cardH = fontMedium.lineHeight() + fontSmall.lineHeight() + cardMarginH; // Height of card
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,20 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./BasicExampleApplet.h"
using namespace NicheGraphics;
// All drawing happens here
// Our basic example doesn't do anything useful. It just passively prints some text.
void InkHUD::BasicExampleApplet::onRender(bool full)
{
printAt(0, 0, "Hello, World!");
// If text might contain "special characters", is needs parsing first
// This applies to data such as text-messages and and node names
// std::string greeting = parse("Grüezi mitenand!");
// printAt(0, 0, greeting);
}
#endif
@@ -0,0 +1,36 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
A bare-minimum example of an InkHUD applet.
Only prints Hello World.
In variants/<your device>/nicheGraphics.h:
- include this .h file
- add the following line of code:
windowManager->addApplet("Basic", new InkHUD::BasicExampleApplet);
*/
#pragma once
#include "configuration.h"
#include "graphics/niche/InkHUD/Applet.h"
namespace NicheGraphics::InkHUD
{
class BasicExampleApplet : public Applet
{
public:
// You must have an onRender() method
// All drawing happens here
void onRender(bool full) override;
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,53 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./NewMsgExampleApplet.h"
using namespace NicheGraphics;
// We configured the Module API to call this method when we receive a new text message
ProcessMessage InkHUD::NewMsgExampleApplet::handleReceived(const meshtastic_MeshPacket &mp)
{
// Abort if applet fully deactivated
// Don't waste time: we wouldn't be rendered anyway
if (!isActive())
return ProcessMessage::CONTINUE;
// Check that this is an incoming message
// Outgoing messages (sent by us) will also call handleReceived
if (!isFromUs(&mp)) {
// Store the sender's nodenum
// We need to keep this information, so we can re-use it anytime render() is called
haveMessage = true;
fromWho = mp.from;
// Tell InkHUD that we have something new to show on the screen
requestUpdate();
}
// Tell Module API to continue informing other firmware components about this message
// We're not the only component which is interested in new text messages
return ProcessMessage::CONTINUE;
}
// All drawing happens here
// We can trigger a render by calling requestUpdate()
// Render might be called by some external source
// We should always be ready to draw
void InkHUD::NewMsgExampleApplet::onRender(bool full)
{
printAt(0, 0, "Example: NewMsg", LEFT, TOP); // Print top-left corner of text at (0,0)
int16_t centerX = X(0.5); // Same as width() / 2
int16_t centerY = Y(0.5); // Same as height() / 2
if (haveMessage) {
printAt(centerX, centerY, "New Message", CENTER, BOTTOM);
printAt(centerX, centerY, "From: " + hexifyNodeNum(fromWho), CENTER, TOP);
} else {
printAt(centerX, centerY, "No Message", CENTER, MIDDLE); // Place center of string at (centerX, centerY)
}
}
#endif
@@ -0,0 +1,61 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
An example of an InkHUD applet.
Tells us when a new text message arrives.
This applet makes use of the Module API to detect new messages,
which is a general part of the Meshtastic firmware, and not part of InkHUD.
In variants/<your device>/nicheGraphics.h:
- include this .h file
- add the following line of code:
windowManager->addApplet("New Msg", new InkHUD::NewMsgExampleApplet);
*/
#pragma once
#include "configuration.h"
#include "graphics/niche/InkHUD/Applet.h"
#include "mesh/SinglePortModule.h"
namespace NicheGraphics::InkHUD
{
class NewMsgExampleApplet : public Applet, public SinglePortModule
{
public:
// The MeshModule API requires us to have a constructor, to specify that we're interested in Text Messages.
NewMsgExampleApplet() : SinglePortModule("NewMsgExampleApplet", meshtastic_PortNum_TEXT_MESSAGE_APP) {}
// All drawing happens here
void onRender(bool full) override;
// Your applet might also want to use some of these
// Useful for setting up or tidying up
/*
void onActivate(); // When started
void onDeactivate(); // When stopped
void onForeground(); // When shown by short-press
void onBackground(); // When hidden by short-press
*/
private:
// Called when we receive new text messages
// Part of the MeshModule API
ProcessMessage handleReceived(const meshtastic_MeshPacket &mp) override;
// Store info from handleReceived
bool haveMessage = false;
NodeNum fromWho = 0;
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,79 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./UserAppletInputExample.h"
using namespace NicheGraphics;
void InkHUD::UserAppletInputExampleApplet::onActivate()
{
setGrabbed(false);
}
void InkHUD::UserAppletInputExampleApplet::onRender(bool full)
{
drawHeader("Input Example");
uint16_t headerHeight = getHeaderHeight();
std::string buttonName;
if (settings->joystick.enabled)
buttonName = "joystick center button";
else
buttonName = "user button";
std::string additional = " | Control is grabbed, long press " + buttonName + " to release controls";
if (!isGrabbed)
additional = " | Control is released, long press " + buttonName + " to grab controls";
printWrapped(0, headerHeight, width(), "Last button: " + lastInput + additional);
}
void InkHUD::UserAppletInputExampleApplet::setGrabbed(bool grabbed)
{
isGrabbed = grabbed;
setInputsSubscribed(BUTTON_SHORT | EXIT_SHORT | EXIT_LONG | NAV_UP | NAV_DOWN | NAV_LEFT | NAV_RIGHT,
grabbed); // Enables/disables grabbing all inputs
setInputsSubscribed(BUTTON_LONG, true); // Always grab this input
}
void InkHUD::UserAppletInputExampleApplet::onButtonShortPress()
{
lastInput = "BUTTON_SHORT";
requestUpdate();
}
void InkHUD::UserAppletInputExampleApplet::onButtonLongPress()
{
lastInput = "BUTTON_LONG";
setGrabbed(!isGrabbed);
requestUpdate();
}
void InkHUD::UserAppletInputExampleApplet::onExitShort()
{
lastInput = "EXIT_SHORT";
requestUpdate();
}
void InkHUD::UserAppletInputExampleApplet::onExitLong()
{
lastInput = "EXIT_LONG";
requestUpdate();
}
void InkHUD::UserAppletInputExampleApplet::onNavUp()
{
lastInput = "NAV_UP";
requestUpdate();
}
void InkHUD::UserAppletInputExampleApplet::onNavDown()
{
lastInput = "NAV_DOWN";
requestUpdate();
}
void InkHUD::UserAppletInputExampleApplet::onNavLeft()
{
lastInput = "NAV_LEFT";
requestUpdate();
}
void InkHUD::UserAppletInputExampleApplet::onNavRight()
{
lastInput = "NAV_RIGHT";
requestUpdate();
}
#endif
@@ -0,0 +1,36 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#pragma once
#include "configuration.h"
#include "graphics/niche/InkHUD/Applet.h"
namespace NicheGraphics::InkHUD
{
class UserAppletInputExampleApplet : public Applet
{
public:
void onActivate() override;
void onRender(bool full) override;
void onButtonShortPress() override;
void onButtonLongPress() override;
void onExitShort() override;
void onExitLong() override;
void onNavUp() override;
void onNavDown() override;
void onNavLeft() override;
void onNavRight() override;
private:
std::string lastInput = "None";
bool isGrabbed = false;
void setGrabbed(bool grabbed);
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,199 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./AlignStickApplet.h"
using namespace NicheGraphics;
InkHUD::AlignStickApplet::AlignStickApplet()
{
if (!settings->joystick.aligned)
bringToForeground();
}
void InkHUD::AlignStickApplet::onRender(bool full)
{
setFont(fontMedium);
printAt(0, 0, "Align Joystick:");
setFont(fontSmall);
std::string instructions = "Move joystick in the direction indicated";
printWrapped(0, fontMedium.lineHeight() * 1.5, width(), instructions);
// Size of the region in which the joystick graphic should fit
uint16_t joyXLimit = X(0.8);
uint16_t contentH = fontMedium.lineHeight() * 1.5 + fontSmall.lineHeight() * 1;
if (getTextWidth(instructions) > width())
contentH += fontSmall.lineHeight();
uint16_t freeY = height() - contentH - fontSmall.lineHeight() * 1.2;
uint16_t joyYLimit = freeY * 0.8;
// Use the shorter of the two
uint16_t joyWidth = joyXLimit < joyYLimit ? joyXLimit : joyYLimit;
// Center the joystick graphic
uint16_t centerX = X(0.5);
uint16_t centerY = contentH + freeY * 0.5;
// Draw joystick graphic
drawStick(centerX, centerY, joyWidth);
setFont(fontSmall);
printAt(X(0.5), Y(1.0) - fontSmall.lineHeight() * 0.2, "Long press to skip", CENTER, BOTTOM);
}
// Draw a scalable joystick graphic
void InkHUD::AlignStickApplet::drawStick(uint16_t centerX, uint16_t centerY, uint16_t width)
{
if (width < 9) // too small to draw
return;
else if (width < 40) { // only draw up arrow
uint16_t chamfer = width < 20 ? 1 : 2;
// Draw filled up arrow
drawDirection(centerX, centerY - width / 4, Direction::UP, width, chamfer, BLACK);
} else { // large enough to draw the full thing
uint16_t chamfer = width < 80 ? 1 : 2;
uint16_t stroke = 3; // pixels
uint16_t arrowW = width * 0.22;
uint16_t hollowW = arrowW - stroke * 2;
// Draw center circle
fillCircle((int16_t)centerX, (int16_t)centerY, (int16_t)(width * 0.2), BLACK);
fillCircle((int16_t)centerX, (int16_t)centerY, (int16_t)(width * 0.2) - stroke, WHITE);
// Draw filled up arrow
drawDirection(centerX, centerY - width / 2, Direction::UP, arrowW, chamfer, BLACK);
// Draw down arrow
drawDirection(centerX, centerY + width / 2, Direction::DOWN, arrowW, chamfer, BLACK);
drawDirection(centerX, centerY + width / 2 - stroke, Direction::DOWN, hollowW, 0, WHITE);
// Draw left arrow
drawDirection(centerX - width / 2, centerY, Direction::LEFT, arrowW, chamfer, BLACK);
drawDirection(centerX - width / 2 + stroke, centerY, Direction::LEFT, hollowW, 0, WHITE);
// Draw right arrow
drawDirection(centerX + width / 2, centerY, Direction::RIGHT, arrowW, chamfer, BLACK);
drawDirection(centerX + width / 2 - stroke, centerY, Direction::RIGHT, hollowW, 0, WHITE);
}
}
// Draw a scalable joystick direction arrow
// a right-triangle with blunted tips
/*
_ <--point
^ / \
| / \
size / \
| / \
v |_________|
*/
void InkHUD::AlignStickApplet::drawDirection(uint16_t pointX, uint16_t pointY, Direction direction, uint16_t size,
uint16_t chamfer, Color color)
{
uint16_t chamferW = chamfer * 2 + 1;
uint16_t triangleW = size - chamferW;
// Draw arrow
switch (direction) {
case Direction::UP:
fillRect(pointX - chamfer, pointY, chamferW, triangleW, color);
fillRect(pointX - chamfer - triangleW, pointY + triangleW, chamferW + triangleW * 2, chamferW, color);
fillTriangle(pointX - chamfer, pointY, pointX - chamfer - triangleW, pointY + triangleW, pointX - chamfer,
pointY + triangleW, color);
fillTriangle(pointX + chamfer, pointY, pointX + chamfer + triangleW, pointY + triangleW, pointX + chamfer,
pointY + triangleW, color);
break;
case Direction::DOWN:
fillRect(pointX - chamfer, pointY - triangleW + 1, chamferW, triangleW, color);
fillRect(pointX - chamfer - triangleW, pointY - size + 1, chamferW + triangleW * 2, chamferW, color);
fillTriangle(pointX - chamfer, pointY, pointX - chamfer - triangleW, pointY - triangleW, pointX - chamfer,
pointY - triangleW, color);
fillTriangle(pointX + chamfer, pointY, pointX + chamfer + triangleW, pointY - triangleW, pointX + chamfer,
pointY - triangleW, color);
break;
case Direction::LEFT:
fillRect(pointX, pointY - chamfer, triangleW, chamferW, color);
fillRect(pointX + triangleW, pointY - chamfer - triangleW, chamferW, chamferW + triangleW * 2, color);
fillTriangle(pointX, pointY - chamfer, pointX + triangleW, pointY - chamfer - triangleW, pointX + triangleW,
pointY - chamfer, color);
fillTriangle(pointX, pointY + chamfer, pointX + triangleW, pointY + chamfer + triangleW, pointX + triangleW,
pointY + chamfer, color);
break;
case Direction::RIGHT:
fillRect(pointX - triangleW + 1, pointY - chamfer, triangleW, chamferW, color);
fillRect(pointX - size + 1, pointY - chamfer - triangleW, chamferW, chamferW + triangleW * 2, color);
fillTriangle(pointX, pointY - chamfer, pointX - triangleW, pointY - chamfer - triangleW, pointX - triangleW,
pointY - chamfer, color);
fillTriangle(pointX, pointY + chamfer, pointX - triangleW, pointY + chamfer + triangleW, pointX - triangleW,
pointY + chamfer, color);
break;
}
}
void InkHUD::AlignStickApplet::onForeground()
{
// Prevent most other applets from requesting update, and skip their rendering entirely
// Another system applet with a higher precedence can potentially ignore this
SystemApplet::lockRendering = true;
SystemApplet::lockRequests = true;
handleInput = true; // Intercept the button input for our applet
}
void InkHUD::AlignStickApplet::onBackground()
{
// Allow normal update behavior to resume
SystemApplet::lockRendering = false;
SystemApplet::lockRequests = false;
SystemApplet::handleInput = false;
// Need to force an update, as a polite request wouldn't be honored, seeing how we are now in the background
// Usually, onBackground is followed by another applet's onForeground (which requests update), but not in this case
inkhud->forceUpdate(EInk::UpdateTypes::FULL, true);
}
void InkHUD::AlignStickApplet::onButtonLongPress()
{
sendToBackground();
}
void InkHUD::AlignStickApplet::onExitLong()
{
sendToBackground();
}
void InkHUD::AlignStickApplet::onNavUp()
{
settings->joystick.aligned = true;
sendToBackground();
}
void InkHUD::AlignStickApplet::onNavDown()
{
inkhud->rotateJoystick(2); // 180 deg
settings->joystick.aligned = true;
sendToBackground();
}
void InkHUD::AlignStickApplet::onNavLeft()
{
inkhud->rotateJoystick(3); // 270 deg
settings->joystick.aligned = true;
sendToBackground();
}
void InkHUD::AlignStickApplet::onNavRight()
{
inkhud->rotateJoystick(1); // 90 deg
settings->joystick.aligned = true;
sendToBackground();
}
#endif
@@ -0,0 +1,50 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
System Applet for manually aligning the joystick with the screen
should be run at startup if the joystick is enabled
and not aligned to the screen
*/
#pragma once
#include "configuration.h"
#include "graphics/niche/InkHUD/SystemApplet.h"
namespace NicheGraphics::InkHUD
{
class AlignStickApplet : public SystemApplet
{
public:
AlignStickApplet();
void onRender(bool full) override;
void onForeground() override;
void onBackground() override;
void onButtonLongPress() override;
void onExitLong() override;
void onNavUp() override;
void onNavDown() override;
void onNavLeft() override;
void onNavRight() override;
protected:
enum Direction {
UP,
DOWN,
LEFT,
RIGHT,
};
void drawStick(uint16_t centerX, uint16_t centerY, uint16_t width);
void drawDirection(uint16_t pointX, uint16_t pointY, Direction direction, uint16_t size, uint16_t chamfer, Color color);
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,94 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./BatteryIconApplet.h"
using namespace NicheGraphics;
InkHUD::BatteryIconApplet::BatteryIconApplet()
{
alwaysRender = true; // render everytime the screen is updated
// Show at boot, if user has previously enabled the feature
if (settings->optionalFeatures.batteryIcon)
bringToForeground();
// Register to our have BatteryIconApplet::onPowerStatusUpdate method called when new power info is available
// This happens whether or not the battery icon feature is enabled
powerStatusObserver.observe(&powerStatus->onNewStatus);
}
// We handle power status' even when the feature is disabled,
// so that we have up to date data ready if the feature is enabled later.
// Otherwise could be 30s before new status update, with weird battery value displayed
int InkHUD::BatteryIconApplet::onPowerStatusUpdate(const meshtastic::Status *status)
{
// System applets are always active
assert(isActive());
// This method should only receive power statuses
// If we get a different type of status, something has gone weird elsewhere
assert(status->getStatusType() == STATUS_TYPE_POWER);
const meshtastic::PowerStatus *pwrStatus = (const meshtastic::PowerStatus *)status;
// Get the new state of charge %, and round to the nearest 10%
uint8_t newSocRounded = ((pwrStatus->getBatteryChargePercent() + 5) / 10) * 10;
// If rounded value has changed, trigger a display update
// It's okay to requestUpdate before we store the new value, as the update won't run until next loop()
// Don't trigger an update if the feature is disabled
if (this->socRounded != newSocRounded && settings->optionalFeatures.batteryIcon)
requestUpdate();
// Store the new value
this->socRounded = newSocRounded;
return 0; // Tell Observable to continue informing other observers
}
void InkHUD::BatteryIconApplet::onRender(bool full)
{
// Clear the region beneath the tile, including the border
// Most applets are drawing onto an empty frame buffer and don't need to do this
// We do need to do this with the battery though, as it is an "overlay"
fillRect(0, 0, width(), height(), WHITE);
// =====================
// Draw battery outline
// =====================
// Positive terminal "bump"
constexpr uint16_t bumpW = 2;
const int16_t &bumpL = 1;
const uint16_t bumpH = (height() - 2) / 2;
const int16_t bumpT = (1 + ((height() - 2) / 2)) - (bumpH / 2);
fillRect(bumpL, bumpT, bumpW, bumpH, BLACK);
// Main body of battery
const int16_t bodyL = 1 + bumpW;
const int16_t &bodyT = 1;
const int16_t &bodyH = height() - 2; // Handle top/bottom padding
const int16_t bodyW = (width() - 1) - bumpW; // Handle 1px left pad
drawRect(bodyL, bodyT, bodyW, bodyH, BLACK);
// Erase join between bump and body
drawLine(bodyL, bumpT, bodyL, bumpT + bumpH - 1, WHITE);
// ===================
// Draw battery level
// ===================
constexpr int16_t slicePad = 2;
int16_t sliceL = bodyL + slicePad;
const int16_t sliceT = bodyT + slicePad;
const uint16_t sliceH = bodyH - (slicePad * 2);
uint16_t sliceW = bodyW - (slicePad * 2);
sliceW = (sliceW * socRounded) / 100; // Apply percentage
sliceL += ((bodyW - (slicePad * 2)) - sliceW); // Shift slice to the battery's negative terminal, correcting drain direction
hatchRegion(sliceL, sliceT, sliceW, sliceH, 2, BLACK);
drawRect(sliceL, sliceT, sliceW, sliceH, BLACK);
}
#endif
@@ -0,0 +1,39 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
This applet floats top-left, giving a graphical representation of battery remaining
It should be optional, enabled by the on-screen menu
*/
#pragma once
#include "configuration.h"
#include "graphics/niche/InkHUD/SystemApplet.h"
#include "PowerStatus.h"
namespace NicheGraphics::InkHUD
{
class BatteryIconApplet : public SystemApplet
{
public:
BatteryIconApplet();
void onRender(bool full) override;
int onPowerStatusUpdate(const meshtastic::Status *status); // Called when new info about battery is available
private:
// Get informed when new information about the battery is available (via onPowerStatusUpdate method)
CallbackObserver<BatteryIconApplet, const meshtastic::Status *> powerStatusObserver =
CallbackObserver<BatteryIconApplet, const meshtastic::Status *>(this, &BatteryIconApplet::onPowerStatusUpdate);
uint8_t socRounded = 0; // Battery state of charge, rounded to nearest 10%
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,257 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./KeyboardApplet.h"
using namespace NicheGraphics;
InkHUD::KeyboardApplet::KeyboardApplet()
{
// Calculate row widths
for (uint8_t row = 0; row < KBD_ROWS; row++) {
rowWidths[row] = 0;
for (uint8_t col = 0; col < KBD_COLS; col++)
rowWidths[row] += keyWidths[row * KBD_COLS + col];
}
}
void InkHUD::KeyboardApplet::onRender(bool full)
{
uint16_t em = fontSmall.lineHeight(); // 16 pt
uint16_t keyH = Y(1.0) / KBD_ROWS;
int16_t keyTopPadding = (keyH - fontSmall.lineHeight()) / 2;
if (full) { // Draw full keyboard
for (uint8_t row = 0; row < KBD_ROWS; row++) {
// Calculate the remaining space to be used as padding
int16_t keyXPadding = X(1.0) - ((rowWidths[row] * em) >> 4);
// Draw keys
uint16_t xPos = 0;
for (uint8_t col = 0; col < KBD_COLS; col++) {
Color fgcolor = BLACK;
uint8_t index = row * KBD_COLS + col;
uint16_t keyX = ((xPos * em) >> 4) + ((col * keyXPadding) / (KBD_COLS - 1));
uint16_t keyY = row * keyH;
uint16_t keyW = (keyWidths[index] * em) >> 4;
if (index == selectedKey) {
fgcolor = WHITE;
fillRect(keyX, keyY, keyW, keyH, BLACK);
}
drawKeyLabel(keyX, keyY + keyTopPadding, keyW, keys[index], fgcolor);
xPos += keyWidths[index];
}
}
} else { // Only draw the difference
if (selectedKey != prevSelectedKey) {
// Draw previously selected key
uint8_t row = prevSelectedKey / KBD_COLS;
int16_t keyXPadding = X(1.0) - ((rowWidths[row] * em) >> 4);
uint16_t xPos = 0;
for (uint8_t i = prevSelectedKey - (prevSelectedKey % KBD_COLS); i < prevSelectedKey; i++)
xPos += keyWidths[i];
uint16_t keyX = ((xPos * em) >> 4) + (((prevSelectedKey % KBD_COLS) * keyXPadding) / (KBD_COLS - 1));
uint16_t keyY = row * keyH;
uint16_t keyW = (keyWidths[prevSelectedKey] * em) >> 4;
fillRect(keyX, keyY, keyW, keyH, WHITE);
drawKeyLabel(keyX, keyY + keyTopPadding, keyW, keys[prevSelectedKey], BLACK);
// Draw newly selected key
row = selectedKey / KBD_COLS;
keyXPadding = X(1.0) - ((rowWidths[row] * em) >> 4);
xPos = 0;
for (uint8_t i = selectedKey - (selectedKey % KBD_COLS); i < selectedKey; i++)
xPos += keyWidths[i];
keyX = ((xPos * em) >> 4) + (((selectedKey % KBD_COLS) * keyXPadding) / (KBD_COLS - 1));
keyY = row * keyH;
keyW = (keyWidths[selectedKey] * em) >> 4;
fillRect(keyX, keyY, keyW, keyH, BLACK);
drawKeyLabel(keyX, keyY + keyTopPadding, keyW, keys[selectedKey], WHITE);
}
}
prevSelectedKey = selectedKey;
}
// Draw the key label corresponding to the char
// for most keys it draws the character itself
// for ['\b', '\n', ' ', '\x1b'] it draws special glyphs
void InkHUD::KeyboardApplet::drawKeyLabel(uint16_t left, uint16_t top, uint16_t width, char key, Color color)
{
if (key == '\b') {
// Draw backspace glyph: 13 x 9 px
/**
* [][][][][][][][][]
* [][] []
* [][] [] [] []
* [][] [] [] []
* [][] [] []
* [][] [] [] []
* [][] [] [] []
* [][] []
* [][][][][][][][][]
*/
const uint8_t bsBitmap[] = {0x0f, 0xf8, 0x18, 0x08, 0x32, 0x28, 0x61, 0x48, 0xc0,
0x88, 0x61, 0x48, 0x32, 0x28, 0x18, 0x08, 0x0f, 0xf8};
uint16_t leftPadding = (width - 13) >> 1;
drawBitmap(left + leftPadding, top + 1, bsBitmap, 13, 9, color);
} else if (key == '\n') {
// Draw done glyph: 12 x 9 px
/**
* [][]
* [][]
* [][]
* [][]
* [][]
* [][] [][]
* [][] [][]
* [][][]
* []
*/
const uint8_t doneBitmap[] = {0x00, 0x30, 0x00, 0x60, 0x00, 0xc0, 0x01, 0x80, 0x03,
0x00, 0xc6, 0x00, 0x6c, 0x00, 0x38, 0x00, 0x10, 0x00};
uint16_t leftPadding = (width - 12) >> 1;
drawBitmap(left + leftPadding, top + 1, doneBitmap, 12, 9, color);
} else if (key == ' ') {
// Draw space glyph: 13 x 9 px
/**
*
*
*
*
* [] []
* [] []
* [][][][][][][][][][][][][]
*
*
*/
const uint8_t spaceBitmap[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x08, 0x80, 0x08, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00};
uint16_t leftPadding = (width - 13) >> 1;
drawBitmap(left + leftPadding, top + 1, spaceBitmap, 13, 9, color);
} else if (key == '\x1b') {
setTextColor(color);
std::string keyText = "ESC";
uint16_t leftPadding = (width - getTextWidth(keyText)) >> 1;
printAt(left + leftPadding, top, keyText);
} else {
setTextColor(color);
if (key >= 0x61)
key -= 32; // capitalize
std::string keyText = std::string(1, key);
uint16_t leftPadding = (width - getTextWidth(keyText)) >> 1;
printAt(left + leftPadding, top, keyText);
}
}
void InkHUD::KeyboardApplet::onForeground()
{
handleInput = true; // Intercept the button input for our applet
// Select the first key
selectedKey = 0;
prevSelectedKey = 0;
}
void InkHUD::KeyboardApplet::onBackground()
{
handleInput = false;
}
void InkHUD::KeyboardApplet::onButtonShortPress()
{
char key = keys[selectedKey];
if (key == '\n') {
inkhud->freeTextDone();
inkhud->closeKeyboard();
} else if (key == '\x1b') {
inkhud->freeTextCancel();
inkhud->closeKeyboard();
} else {
inkhud->freeText(key);
}
}
void InkHUD::KeyboardApplet::onButtonLongPress()
{
char key = keys[selectedKey];
if (key == '\n') {
inkhud->freeTextDone();
inkhud->closeKeyboard();
} else if (key == '\x1b') {
inkhud->freeTextCancel();
inkhud->closeKeyboard();
} else {
if (key >= 0x61)
key -= 32; // capitalize
inkhud->freeText(key);
}
}
void InkHUD::KeyboardApplet::onExitShort()
{
inkhud->freeTextCancel();
inkhud->closeKeyboard();
}
void InkHUD::KeyboardApplet::onExitLong()
{
inkhud->freeTextCancel();
inkhud->closeKeyboard();
}
void InkHUD::KeyboardApplet::onNavUp()
{
if (selectedKey < KBD_COLS) // wrap
selectedKey += KBD_COLS * (KBD_ROWS - 1);
else // move 1 row back
selectedKey -= KBD_COLS;
// Request rendering over the previously drawn render
requestUpdate(EInk::UpdateTypes::FAST, false);
// Force an update to bypass lockRequests
inkhud->forceUpdate(EInk::UpdateTypes::FAST);
}
void InkHUD::KeyboardApplet::onNavDown()
{
selectedKey += KBD_COLS;
selectedKey %= (KBD_COLS * KBD_ROWS);
// Request rendering over the previously drawn render
requestUpdate(EInk::UpdateTypes::FAST, false);
// Force an update to bypass lockRequests
inkhud->forceUpdate(EInk::UpdateTypes::FAST);
}
void InkHUD::KeyboardApplet::onNavLeft()
{
if (selectedKey % KBD_COLS == 0) // wrap
selectedKey += KBD_COLS - 1;
else // move 1 column back
selectedKey--;
// Request rendering over the previously drawn render
requestUpdate(EInk::UpdateTypes::FAST, false);
// Force an update to bypass lockRequests
inkhud->forceUpdate(EInk::UpdateTypes::FAST);
}
void InkHUD::KeyboardApplet::onNavRight()
{
if (selectedKey % KBD_COLS == KBD_COLS - 1) // wrap
selectedKey -= KBD_COLS - 1;
else // move 1 column forward
selectedKey++;
// Request rendering over the previously drawn render
requestUpdate(EInk::UpdateTypes::FAST, false);
// Force an update to bypass lockRequests
inkhud->forceUpdate(EInk::UpdateTypes::FAST);
}
uint16_t InkHUD::KeyboardApplet::getKeyboardHeight()
{
const uint16_t keyH = fontSmall.lineHeight() * 1.2;
return keyH * KBD_ROWS;
}
#endif
@@ -0,0 +1,66 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
System Applet to render an on-screeen keyboard
*/
#pragma once
#include "configuration.h"
#include "graphics/niche/InkHUD/InkHUD.h"
#include "graphics/niche/InkHUD/SystemApplet.h"
#include <string>
namespace NicheGraphics::InkHUD
{
class KeyboardApplet : public SystemApplet
{
public:
KeyboardApplet();
void onRender(bool full) override;
void onForeground() override;
void onBackground() override;
void onButtonShortPress() override;
void onButtonLongPress() override;
void onExitShort() override;
void onExitLong() override;
void onNavUp() override;
void onNavDown() override;
void onNavLeft() override;
void onNavRight() override;
static uint16_t getKeyboardHeight(); // used to set the keyboard tile height
private:
void drawKeyLabel(uint16_t left, uint16_t top, uint16_t width, char key, Color color);
static const uint8_t KBD_COLS = 11;
static const uint8_t KBD_ROWS = 4;
const char keys[KBD_COLS * KBD_ROWS] = {
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '\b', // row 0
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '\n', // row 1
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '!', ' ', // row 2
'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '?', '\x1b' // row 3
};
// This array represents the widths of each key in points
// 16 pt = line height of the text
const uint16_t keyWidths[KBD_COLS * KBD_ROWS] = {
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 24, // row 0
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 24, // row 1
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 24, // row 2
16, 16, 16, 16, 16, 16, 16, 10, 10, 12, 40 // row 3
};
uint16_t rowWidths[KBD_ROWS];
uint8_t selectedKey = 0; // selected key index
uint8_t prevSelectedKey = 0;
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,189 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./LogoApplet.h"
#include "mesh/NodeDB.h"
using namespace NicheGraphics;
InkHUD::LogoApplet::LogoApplet() : concurrency::OSThread("LogoApplet")
{
OSThread::setIntervalFromNow(8 * 1000UL);
OSThread::enabled = true;
// During onboarding, show the default short name as well as the version string
// This behavior assists manufacturers during mass production, and should not be modified without good reason
if (!settings->tips.safeShutdownSeen) {
meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
fontTitle = fontMedium;
textLeft = xstr(APP_VERSION_SHORT);
textRight = parseShortName(ourNode);
textTitle = "Meshtastic";
} else {
fontTitle = fontSmall;
textLeft = "";
textRight = "";
textTitle = xstr(APP_VERSION_SHORT);
}
bringToForeground();
// This is then drawn with a FULL refresh by Renderer::begin
}
void InkHUD::LogoApplet::onRender(bool full)
{
// Size of the region which the logo should "scale to fit"
uint16_t logoWLimit = X(0.8);
uint16_t logoHLimit = Y(0.5);
// Get the max width and height we can manage within the region, while still maintaining aspect ratio
uint16_t logoW = getLogoWidth(logoWLimit, logoHLimit);
uint16_t logoH = getLogoHeight(logoWLimit, logoHLimit);
// Where to place the center of the logo
int16_t logoCX = X(0.5);
int16_t logoCY = Y(0.5 - 0.05);
// Invert colors if black-on-white
// Used during shutdown, to resport display health
// Todo: handle this in InkHUD::Renderer instead
if (inverted) {
fillScreen(BLACK);
setTextColor(WHITE);
}
#ifdef USERPREFS_OEM_IMAGE_DATA // Custom boot screen, if defined in userPrefs.jsonc
// Only show the custom screen at startup
// This allows us to draw the usual Meshtastic logo at shutdown
// The effect is similar to the two-stage userPrefs boot screen used by BaseUI
if (millis() < 10 * 1000UL) {
// Draw the custom logo
const uint8_t logo[] = USERPREFS_OEM_IMAGE_DATA;
drawXBitmap(logoCX - (USERPREFS_OEM_IMAGE_WIDTH / 2), // Left
logoCY - (USERPREFS_OEM_IMAGE_HEIGHT / 2), // Top
logo, // XBM data
USERPREFS_OEM_IMAGE_WIDTH, // Width
USERPREFS_OEM_IMAGE_HEIGHT, // Height
inverted ? WHITE : BLACK // Color
);
// Select the largest font which will still comfortably fit the custom text
setFont(fontLarge);
if (getTextWidth(USERPREFS_OEM_TEXT) > 0.8 * width())
setFont(fontMedium);
if (getTextWidth(USERPREFS_OEM_TEXT) > 0.8 * width())
setFont(fontSmall);
// Draw custom text below logo
int16_t logoB = logoCY + (USERPREFS_OEM_IMAGE_HEIGHT / 2); // Bottom of the logo
printAt(X(0.5), logoB + Y(0.1), USERPREFS_OEM_TEXT, CENTER, TOP);
// Don't draw the normal boot screen, we've already drawn our custom version
return;
}
#endif
drawLogo(logoCX, logoCY, logoW, logoH, inverted ? WHITE : BLACK);
if (!textLeft.empty()) {
setFont(fontSmall);
printAt(0, 0, textLeft, LEFT, TOP);
}
if (!textRight.empty()) {
setFont(fontSmall);
printAt(X(1), 0, textRight, RIGHT, TOP);
}
if (!textTitle.empty()) {
int16_t logoB = logoCY + (logoH / 2); // Bottom of the logo
setFont(fontTitle);
printAt(X(0.5), logoB + Y(0.1), textTitle, CENTER, TOP);
}
}
void InkHUD::LogoApplet::onForeground()
{
SystemApplet::lockRendering = true;
SystemApplet::lockRequests = true;
SystemApplet::handleInput = true; // We don't actually use this input. Just blocking other applets from using it.
}
void InkHUD::LogoApplet::onBackground()
{
SystemApplet::lockRendering = false;
SystemApplet::lockRequests = false;
SystemApplet::handleInput = false;
// Need to force an update, as a polite request wouldn't be honored, seeing how we are now in the background
// Usually, onBackground is followed by another applet's onForeground (which requests update), but not in this case
inkhud->forceUpdate(EInk::UpdateTypes::FULL, true);
}
// Begin displaying the screen which is shown at shutdown
void InkHUD::LogoApplet::onShutdown()
{
bringToForeground();
textLeft = "";
textRight = "";
textTitle = "Shutting Down...";
fontTitle = fontSmall;
// Draw a shutting down screen, twice.
// Once white on black, once black on white.
// Intention is to restore display health.
inverted = true;
inkhud->forceUpdate(Drivers::EInk::FULL, true, false);
delay(1000); // Cooldown. Back to back updates aren't great for health.
inverted = false;
inkhud->forceUpdate(Drivers::EInk::FULL, true, false);
delay(1000); // Cooldown
// Prepare for the powered-off screen now
// We can change these values because the initial "shutting down" screen has already rendered at this point
meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
textLeft = "";
textRight = "";
textTitle = parseShortName(ourNode);
fontTitle = fontMedium;
// This is then drawn by InkHUD::Events::onShutdown, with a blocking FULL update, after InkHUD's flash write is complete
}
void InkHUD::LogoApplet::onApplyingChanges()
{
bringToForeground();
textLeft = "";
textRight = "";
textTitle = "Applying changes";
fontTitle = fontSmall;
inkhud->forceUpdate(Drivers::EInk::FAST, false);
}
void InkHUD::LogoApplet::onReboot()
{
bringToForeground();
textLeft = "";
textRight = "";
textTitle = "Rebooting...";
fontTitle = fontSmall;
inkhud->forceUpdate(Drivers::EInk::FULL, true, false);
// Perform the update right now, waiting here until complete
}
int32_t InkHUD::LogoApplet::runOnce()
{
sendToBackground();
return OSThread::disable();
}
#endif
@@ -0,0 +1,43 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Shows the Meshtastic logo fullscreen, with accompanying text
Used for boot and shutdown
*/
#pragma once
#include "configuration.h"
#include "concurrency/OSThread.h"
#include "graphics/niche/InkHUD/SystemApplet.h"
namespace NicheGraphics::InkHUD
{
class LogoApplet : public SystemApplet, public concurrency::OSThread
{
public:
LogoApplet();
void onRender(bool full) override;
void onForeground() override;
void onBackground() override;
void onShutdown() override;
void onReboot() override;
void onApplyingChanges();
protected:
int32_t runOnce() override;
std::string textLeft;
std::string textRight;
std::string textTitle;
AppletFont fontTitle;
bool inverted = false; // Invert colors. Used during shutdown, to restore display health.
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,122 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Set of end-point actions for the Menu Applet
Added as menu entries in MenuApplet::showPage
Behaviors assigned in MenuApplet::execute
*/
#pragma once
#include "configuration.h"
namespace NicheGraphics::InkHUD
{
enum MenuAction {
NO_ACTION,
SEND_PING,
FREE_TEXT,
STORE_CANNEDMESSAGE_SELECTION,
SEND_CANNEDMESSAGE,
SHUTDOWN,
NEXT_TILE,
TOGGLE_BACKLIGHT,
TOGGLE_GPS,
ENABLE_BLUETOOTH,
TOGGLE_APPLET,
TOGGLE_AUTOSHOW_APPLET,
SET_RECENTS,
ROTATE,
ALIGN_JOYSTICK,
LAYOUT,
TOGGLE_BATTERY_ICON,
TOGGLE_NOTIFICATIONS,
TOGGLE_INVERT_COLOR,
TOGGLE_12H_CLOCK,
// Regions
SET_REGION_US,
SET_REGION_EU_868,
SET_REGION_EU_433,
SET_REGION_CN,
SET_REGION_JP,
SET_REGION_ANZ,
SET_REGION_KR,
SET_REGION_TW,
SET_REGION_RU,
SET_REGION_IN,
SET_REGION_NZ_865,
SET_REGION_TH,
SET_REGION_LORA_24,
SET_REGION_UA_433,
SET_REGION_UA_868,
SET_REGION_MY_433,
SET_REGION_MY_919,
SET_REGION_SG_923,
SET_REGION_PH_433,
SET_REGION_PH_868,
SET_REGION_PH_915,
SET_REGION_ANZ_433,
SET_REGION_KZ_433,
SET_REGION_KZ_863,
SET_REGION_NP_865,
SET_REGION_BR_902,
// Device Roles
SET_ROLE_CLIENT,
SET_ROLE_CLIENT_MUTE,
SET_ROLE_ROUTER,
SET_ROLE_REPEATER,
// Presets
SET_PRESET_LONG_SLOW,
SET_PRESET_LONG_MODERATE,
SET_PRESET_LONG_FAST,
SET_PRESET_MEDIUM_SLOW,
SET_PRESET_MEDIUM_FAST,
SET_PRESET_SHORT_SLOW,
SET_PRESET_SHORT_FAST,
SET_PRESET_SHORT_TURBO,
// Timezones
SET_TZ_US_HAWAII,
SET_TZ_US_ALASKA,
SET_TZ_US_PACIFIC,
SET_TZ_US_ARIZONA,
SET_TZ_US_MOUNTAIN,
SET_TZ_US_CENTRAL,
SET_TZ_US_EASTERN,
SET_TZ_BR_BRAZILIA,
SET_TZ_UTC,
SET_TZ_EU_WESTERN,
SET_TZ_EU_CENTRAL,
SET_TZ_EU_EASTERN,
SET_TZ_ASIA_KOLKATA,
SET_TZ_ASIA_HONG_KONG,
SET_TZ_AU_AWST,
SET_TZ_AU_ACST,
SET_TZ_AU_AEST,
SET_TZ_PACIFIC_NZ,
// Power
TOGGLE_POWER_SAVE,
CALIBRATE_ADC,
// Bluetooth
TOGGLE_BLUETOOTH,
TOGGLE_BLUETOOTH_PAIR_MODE,
// Channel
TOGGLE_CHANNEL_UPLINK,
TOGGLE_CHANNEL_DOWNLINK,
TOGGLE_CHANNEL_POSITION,
SET_CHANNEL_PRECISION,
// Display
TOGGLE_DISPLAY_UNITS,
// Network
TOGGLE_WIFI,
// Administration
RESET_NODEDB_ALL,
RESET_NODEDB_KEEP_FAVORITES,
};
} // namespace NicheGraphics::InkHUD
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,124 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "configuration.h"
#include "graphics/niche/Drivers/Backlight/LatchingBacklight.h"
#include "graphics/niche/InkHUD/InkHUD.h"
#include "graphics/niche/InkHUD/Persistence.h"
#include "graphics/niche/InkHUD/SystemApplet.h"
#include "graphics/niche/Utils/CannedMessageStore.h"
#include "./MenuItem.h"
#include "./MenuPage.h"
#include "Channels.h"
#include "concurrency/OSThread.h"
namespace NicheGraphics::InkHUD
{
class Applet;
class MenuApplet : public SystemApplet, public concurrency::OSThread
{
public:
MenuApplet();
void onForeground() override;
void onBackground() override;
void onButtonShortPress() override;
void onButtonLongPress() override;
void onExitShort() override;
void onNavUp() override;
void onNavDown() override;
void onNavLeft() override;
void onNavRight() override;
void onFreeText(char c) override;
void onFreeTextDone() override;
void onFreeTextCancel() override;
void onRender(bool full) override;
void show(Tile *t); // Open the menu, onto a user tile
void setStartPage(MenuPage page);
protected:
Drivers::LatchingBacklight *backlight = nullptr; // Convenient access to the backlight singleton
int32_t runOnce() override;
void execute(MenuItem item); // Perform the MenuAction associated with a MenuItem, if any
void showPage(MenuPage page); // Load and display a MenuPage
void populateSendPage(); // Dynamically create MenuItems including canned messages
void populateRecipientPage(); // Dynamically create a page of possible destinations for a canned message
void populateAppletPage(); // Dynamically create MenuItems for toggling loaded applets
void populateAutoshowPage(); // Dynamically create MenuItems for selecting which applets can autoshow
void populateRecentsPage(); // Create menu items: a choice of values for settings.recentlyActiveSeconds
void drawInputField(uint16_t left, uint16_t top, uint16_t width, uint16_t height,
const std::string &text); // Draw input field for free text
uint16_t getSystemInfoPanelHeight();
void drawSystemInfoPanel(int16_t left, int16_t top, uint16_t width,
uint16_t *height = nullptr); // Info panel at top of root menu
void sendText(NodeNum dest, ChannelIndex channel, const char *message); // Send a text message to mesh
void freeCannedMessageResources(); // Clear MenuApplet's canned message processing data
MenuPage startPageOverride = MenuPage::ROOT;
MenuPage currentPage = MenuPage::ROOT;
MenuPage previousPage = MenuPage::EXIT;
uint8_t cursor = 0; // Which menu item is currently highlighted
bool cursorShown = false; // Is *any* item highlighted? (Root menu: no initial selection)
bool freeTextMode = false;
uint16_t systemInfoPanelHeight = 0; // Need to know before we render
uint16_t menuTextLimit = 200;
std::vector<MenuItem> items; // MenuItems for the current page. Filled by ShowPage
std::vector<std::string> nodeConfigLabels; // Persistent labels for Node Config pages
uint8_t selectedChannelIndex = 0; // Currently selected LoRa channel (Node Config → Radio → Channel)
bool channelPositionEnabled = false;
bool gpsEnabled = false;
// Recents menu checkbox state (derived from settings.recentlyActiveSeconds)
static constexpr uint8_t RECENTS_COUNT = 6;
bool recentsSelected[RECENTS_COUNT] = {};
// Data for selecting and sending canned messages via the menu
// Placed into a sub-class for organization only
class CannedMessages
{
public:
// Share NicheGraphics component
// Handles loading, getting, setting
CannedMessageStore *store;
// One canned message
// Links the menu item to the true message text
struct MessageItem {
std::string label; // Shown in menu. Prefixed, and UTF-8 chars parsed
std::string rawText; // The message which will be sent, if this item is selected
} *selectedMessageItem;
// One possible destination for a canned message
// Links the menu item to the intended recipient
// May represent either broadcast or DM
struct RecipientItem {
std::string label; // Shown in menu
NodeNum dest = NODENUM_BROADCAST;
uint8_t channelIndex = 0;
} *selectedRecipientItem;
// These lists are generated when the menu page is populated
// Cleared onBackground (when MenuApplet closes)
std::vector<MessageItem> messageItems;
std::vector<RecipientItem> recipientItems;
MessageItem freeTextItem;
} cm;
Applet *borrowedTileOwner = nullptr; // Which applet we have temporarily replaced while displaying menu
bool invertedColors = false; // Helper to display current state of config.display.displaymode in InkHUD options
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,54 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
One item of a MenuPage, in InkHUD::MenuApplet
Added to MenuPages in InkHUD::showPage
- May open a submenu or exit
- May perform an action
- May toggle a bool value, shown by a checkbox
*/
#pragma once
#include "configuration.h"
#include "./MenuAction.h"
#include "./MenuPage.h"
namespace NicheGraphics::InkHUD
{
// One item of a MenuPage
class MenuItem
{
public:
std::string label;
MenuAction action = NO_ACTION;
MenuPage nextPage = EXIT;
bool *checkState = nullptr;
bool isHeader = false; // Non-selectable section label
// Various constructors, depending on the intended function of the item
MenuItem(const char *label, MenuPage nextPage) : label(label), nextPage(nextPage) {}
MenuItem(const char *label, MenuAction action) : label(label), action(action) {}
MenuItem(const char *label, MenuAction action, MenuPage nextPage) : label(label), action(action), nextPage(nextPage) {}
MenuItem(const char *label, MenuAction action, MenuPage nextPage, bool *checkState)
: label(label), action(action), nextPage(nextPage), checkState(checkState)
{
}
static MenuItem Header(const char *label)
{
MenuItem item(label, NO_ACTION, EXIT);
item.isHeader = true;
return item;
}
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,48 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Sub-menu for InkHUD::MenuApplet
Structure of the menu is defined in InkHUD::showPage
*/
#pragma once
#include "configuration.h"
namespace NicheGraphics::InkHUD
{
// Sub-menu for MenuApplet
enum MenuPage : uint8_t {
ROOT, // Initial menu page
SEND,
CANNEDMESSAGE_RECIPIENT, // Select destination for a canned message
OPTIONS,
NODE_CONFIG,
NODE_CONFIG_LORA,
NODE_CONFIG_CHANNELS, // List of channels
NODE_CONFIG_CHANNEL_DETAIL, // Per-channel options
NODE_CONFIG_CHANNEL_PRECISION,
NODE_CONFIG_PRESET,
NODE_CONFIG_DEVICE,
NODE_CONFIG_DEVICE_ROLE,
NODE_CONFIG_POWER,
NODE_CONFIG_POWER_ADC_CAL,
NODE_CONFIG_NETWORK,
NODE_CONFIG_DISPLAY,
NODE_CONFIG_BLUETOOTH,
NODE_CONFIG_POSITION,
NODE_CONFIG_ADMIN_RESET,
TIMEZONE,
APPLETS,
AUTOSHOW,
RECENTS, // Select length of "recentlyActiveSeconds"
REGION,
EXIT, // Dismiss the menu applet
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,40 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
A notification which might be displayed by the NotificationApplet
An instance of this class is offered to Applets via Applet::approveNotification, in case they want to veto the notification.
An Applet should veto a notification if it is already displaying the same info which the notification would convey.
*/
#pragma once
#include "configuration.h"
namespace NicheGraphics::InkHUD
{
class Notification
{
public:
enum Type : uint8_t { NOTIFICATION_MESSAGE_BROADCAST, NOTIFICATION_MESSAGE_DIRECT, NOTIFICATION_BATTERY } type;
uint32_t timestamp;
uint8_t getChannel() { return channel; }
uint32_t getSender() { return sender; }
uint8_t getBatteryPercentage() { return batteryPercentage; }
friend class NotificationApplet;
protected:
uint8_t channel;
uint32_t sender;
uint8_t batteryPercentage;
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,272 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./NotificationApplet.h"
#include "./Notification.h"
#include "graphics/niche/InkHUD/Persistence.h"
#include "meshUtils.h"
#include "modules/TextMessageModule.h"
#include "RTC.h"
using namespace NicheGraphics;
InkHUD::NotificationApplet::NotificationApplet()
{
textMessageObserver.observe(textMessageModule);
}
// Collect meta-info about the text message, and ask for approval for the notification
// No need to save the message itself; we can use the cached InkHUD::latestMessage data during render()
int InkHUD::NotificationApplet::onReceiveTextMessage(const meshtastic_MeshPacket *p)
{
// System applets are always active
assert(isActive());
// Abort if feature disabled
// This is a bit clumsy, but avoids complicated handling when the feature is enabled / disabled
if (!settings->optionalFeatures.notifications)
return 0;
// Abort if this is an outgoing message
if (getFrom(p) == nodeDB->getNodeNum())
return 0;
Notification n;
n.timestamp = getValidTime(RTCQuality::RTCQualityDevice, true); // Current RTC time
// Gather info: in-channel message
if (isBroadcast(p->to)) {
n.type = Notification::Type::NOTIFICATION_MESSAGE_BROADCAST;
n.channel = p->channel;
}
// Gather info: DM
else {
n.type = Notification::Type::NOTIFICATION_MESSAGE_DIRECT;
n.sender = p->from;
}
// Close an old notification, if shown
dismiss();
// Check if we should display the notification
// A foreground applet might already be displaying this info
hasNotification = true;
currentNotification = n;
if (isApproved()) {
bringToForeground();
inkhud->forceUpdate();
} else
hasNotification = false; // Clear the pending notification: it was rejected
// Return zero: no issues here, carry on notifying other observers!
return 0;
}
void InkHUD::NotificationApplet::onRender(bool full)
{
// Clear the region beneath the tile
// Most applets are drawing onto an empty frame buffer and don't need to do this
// We do need to do this with the battery though, as it is an "overlay"
fillRect(0, 0, width(), height(), WHITE);
// Padding (horizontal)
const uint16_t padW = 4;
// Main border
drawRect(0, 0, width(), height(), BLACK);
// drawRect(1, 1, width() - 2, height() - 2, BLACK);
// Timestamp (potentially)
// ====================
std::string ts = getTimeString(currentNotification.timestamp);
uint16_t tsW = 0;
int16_t divX = 0;
// Timestamp available
if (ts.length() > 0) {
tsW = getTextWidth(ts);
divX = padW + tsW + padW;
hatchRegion(0, 0, divX, height(), 2, BLACK); // Fill with a dark background
drawLine(divX, 0, divX, height() - 1, BLACK); // Draw divider between timestamp and main text
setCrop(1, 1, divX - 1, height() - 2);
// Drop shadow
setTextColor(WHITE);
printThick(padW + (tsW / 2), height() / 2, ts, 4, 4);
// Bold text
setTextColor(BLACK);
printThick(padW + (tsW / 2), height() / 2, ts, 2, 1);
}
// Main text
// =====================
// Background fill
// - medium dark (1/3)
hatchRegion(divX, 0, width() - divX - 1, height(), 3, BLACK);
uint16_t availableWidth = width() - divX - padW;
std::string text = getNotificationText(availableWidth);
int16_t textM = divX + padW + (getTextWidth(text) / 2);
// Restrict area for printing
// - don't overlap border, or divider
setCrop(divX + 1, 1, (width() - (divX + 1) - 1), height() - 2);
// Drop shadow
// - thick white text
setTextColor(WHITE);
printThick(textM, height() / 2, text, 4, 4);
// Main text
// - faux bold: double width
setTextColor(BLACK);
printThick(textM, height() / 2, text, 2, 1);
}
void InkHUD::NotificationApplet::onForeground()
{
handleInput = true; // Intercept the button input for our applet, so we can dismiss the notification
}
void InkHUD::NotificationApplet::onBackground()
{
handleInput = false;
inkhud->forceUpdate(EInk::UpdateTypes::FULL, true);
}
void InkHUD::NotificationApplet::onButtonShortPress()
{
dismiss();
}
void InkHUD::NotificationApplet::onButtonLongPress()
{
dismiss();
}
void InkHUD::NotificationApplet::onExitShort()
{
dismiss();
}
void InkHUD::NotificationApplet::onExitLong()
{
dismiss();
}
void InkHUD::NotificationApplet::onNavUp()
{
dismiss();
}
void InkHUD::NotificationApplet::onNavDown()
{
dismiss();
}
void InkHUD::NotificationApplet::onNavLeft()
{
dismiss();
}
void InkHUD::NotificationApplet::onNavRight()
{
dismiss();
}
// Ask the WindowManager to check whether any displayed applets are already displaying the info from this notification
// Called internally when we first get a "notifiable event", and then again before render,
// in case autoshow swapped which applet was displayed
bool InkHUD::NotificationApplet::isApproved()
{
// Instead of an assert
if (!hasNotification) {
LOG_WARN("No notif to approve");
return false;
}
// Ask all visible user applets for approval
for (Applet *ua : inkhud->userApplets) {
if (ua->isForeground() && !ua->approveNotification(currentNotification))
return false;
}
return true;
}
// Mark that the notification should no-longer be rendered
// In addition to calling thing method, code needs to request a re-render of all applets
void InkHUD::NotificationApplet::dismiss()
{
sendToBackground();
hasNotification = false;
// Not requesting update directly from this method,
// as it is used to dismiss notifications which have been made redundant by autoshow settings, before they are ever drawn
}
// Get a string for the main body text of a notification
// Formatted to suit screen width
// Takes info from InkHUD::currentNotification
std::string InkHUD::NotificationApplet::getNotificationText(uint16_t widthAvailable)
{
assert(hasNotification);
std::string text;
// Text message
// ==============
if (IS_ONE_OF(currentNotification.type, Notification::Type::NOTIFICATION_MESSAGE_DIRECT,
Notification::Type::NOTIFICATION_MESSAGE_BROADCAST)) {
// Although we are handling DM and broadcast notifications together, we do need to treat them slightly differently
bool msgIsBroadcast = currentNotification.type == Notification::Type::NOTIFICATION_MESSAGE_BROADCAST;
// Pick source of message
const MessageStore::Message *message =
msgIsBroadcast ? &inkhud->persistence->latestMessage.broadcast : &inkhud->persistence->latestMessage.dm;
// Find info about the sender
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(message->sender);
// Leading tag (channel vs. DM)
text += msgIsBroadcast ? "From:" : "DM: ";
// Sender id
if (node && node->has_user)
text += parseShortName(node);
else
text += hexifyNodeNum(message->sender);
// Check if text fits
// - use a longer string, if we have the space
if (getTextWidth(text) < widthAvailable * 0.5) {
text.clear();
// Leading tag (channel vs. DM)
text += msgIsBroadcast ? "Msg from " : "DM from ";
// Sender id
if (node && node->has_user)
text += parseShortName(node);
else
text += hexifyNodeNum(message->sender);
text += ": ";
text += message->text;
}
}
// Parse any non-ascii characters and return
return parse(text);
}
#endif
@@ -0,0 +1,59 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Pop-up notification bar, on screen top edge
Displays information we feel is important, but which is not shown on currently focused applet(s)
E.g.: messages, while viewing map, etc
Feature should be optional; enable disable via on-screen menu
*/
#pragma once
#include "configuration.h"
#include "concurrency/OSThread.h"
#include "graphics/niche/InkHUD/SystemApplet.h"
namespace NicheGraphics::InkHUD
{
class NotificationApplet : public SystemApplet
{
public:
NotificationApplet();
void onRender(bool full) override;
void onForeground() override;
void onBackground() override;
void onButtonShortPress() override;
void onButtonLongPress() override;
void onExitShort() override;
void onExitLong() override;
void onNavUp() override;
void onNavDown() override;
void onNavLeft() override;
void onNavRight() override;
int onReceiveTextMessage(const meshtastic_MeshPacket *p);
bool isApproved(); // Does a foreground applet make notification redundant?
void dismiss(); // Close the Notification Popup
protected:
// Get notified when a new text message arrives
CallbackObserver<NotificationApplet, const meshtastic_MeshPacket *> textMessageObserver =
CallbackObserver<NotificationApplet, const meshtastic_MeshPacket *>(this, &NotificationApplet::onReceiveTextMessage);
std::string getNotificationText(uint16_t widthAvailable); // Get text for notification, to suit screen width
bool hasNotification = false; // Only used for assert. Todo: remove?
Notification currentNotification = Notification(); // Set when something notification-worthy happens. Used by render()
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,77 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./PairingApplet.h"
using namespace NicheGraphics;
InkHUD::PairingApplet::PairingApplet()
{
bluetoothStatusObserver.observe(&bluetoothStatus->onNewStatus);
}
void InkHUD::PairingApplet::onRender(bool full)
{
// Header
setFont(fontMedium);
printAt(X(0.5), Y(0.25), "Bluetooth", CENTER, BOTTOM);
setFont(fontSmall);
printAt(X(0.5), Y(0.25), "Enter this code", CENTER, TOP);
// Passkey
setFont(fontMedium);
printThick(X(0.5), Y(0.5), passkey.substr(0, 3) + " " + passkey.substr(3), 3, 2);
// Device's bluetooth name, if it will fit
setFont(fontSmall);
std::string name = "Name: " + parse(getDeviceName());
if (getTextWidth(name) > width()) // Too wide, try without the leading "Name: "
name = parse(getDeviceName());
if (getTextWidth(name) < width()) // Does it fit?
printAt(X(0.5), Y(0.75), name, CENTER, MIDDLE);
}
void InkHUD::PairingApplet::onForeground()
{
// Prevent most other applets from requesting update, and skip their rendering entirely
// Another system applet with a higher precedence can potentially ignore this
SystemApplet::lockRendering = true;
SystemApplet::lockRequests = true;
}
void InkHUD::PairingApplet::onBackground()
{
// Allow normal update behavior to resume
SystemApplet::lockRendering = false;
SystemApplet::lockRequests = false;
// Need to force an update, as a polite request wouldn't be honored, seeing how we are now in the background
// Usually, onBackground is followed by another applet's onForeground (which requests update), but not in this case
inkhud->forceUpdate(EInk::UpdateTypes::FULL, true);
}
int InkHUD::PairingApplet::onBluetoothStatusUpdate(const meshtastic::Status *status)
{
// The standard Meshtastic convention is to pass these "generic" Status objects,
// check their type, and then cast them.
// We'll mimic that behavior, just to keep in line with the other Statuses,
// even though I'm not sure what the original reason for jumping through these extra hoops was.
assert(status->getStatusType() == STATUS_TYPE_BLUETOOTH);
const auto *btStatus = static_cast<const meshtastic::BluetoothStatus *>(status);
// When pairing begins
if (btStatus->getConnectionState() == meshtastic::BluetoothStatus::ConnectionState::PAIRING) {
// Store the passkey for rendering
passkey = btStatus->getPasskey();
// Show pairing screen
bringToForeground();
}
// When pairing ends
// or rather, when something changes, and we shouldn't be showing the pairing screen
else if (isForeground())
sendToBackground();
return 0; // No special result to report back to Observable
}
#endif
@@ -0,0 +1,41 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Shows the Bluetooth passkey during pairing
*/
#pragma once
#include "configuration.h"
#include "graphics/niche/InkHUD/SystemApplet.h"
#include "main.h"
namespace NicheGraphics::InkHUD
{
class PairingApplet : public SystemApplet
{
public:
PairingApplet();
void onRender(bool full) override;
void onForeground() override;
void onBackground() override;
int onBluetoothStatusUpdate(const meshtastic::Status *status);
protected:
// Get notified when status of the Bluetooth connection changes
CallbackObserver<PairingApplet, const meshtastic::Status *> bluetoothStatusObserver =
CallbackObserver<PairingApplet, const meshtastic::Status *>(this, &PairingApplet::onBluetoothStatusUpdate);
std::string passkey = ""; // Passkey. Six digits, possibly with leading zeros
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,13 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./PlaceholderApplet.h"
using namespace NicheGraphics;
void InkHUD::PlaceholderApplet::onRender(bool full)
{
// This placeholder applet fills its area with sparse diagonal lines
hatchRegion(0, 0, width(), height(), 8, BLACK);
}
#endif
@@ -0,0 +1,29 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Shown when a tile doesn't have any other valid Applets
Fills the area with diagonal lines
*/
#include "configuration.h"
#include "graphics/niche/InkHUD/SystemApplet.h"
namespace NicheGraphics::InkHUD
{
class PlaceholderApplet : public SystemApplet
{
public:
void onRender(bool full) override;
// Note: onForeground, onBackground, and wantsToRender are not meaningful for this applet.
// The window manager decides when and where it should be rendered
// It may be drawn to several different tiles during an Renderer::render call
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,308 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./TipsApplet.h"
#include "graphics/niche/InkHUD/Persistence.h"
#include "main.h"
using namespace NicheGraphics;
InkHUD::TipsApplet::TipsApplet()
{
bool needsRegion = (config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET);
bool showTutorialTips = (settings->tips.firstBoot || needsRegion);
// Welcome screen
if (showTutorialTips)
tipQueue.push_back(Tip::WELCOME);
// Finish setup
if (needsRegion)
tipQueue.push_back(Tip::FINISH_SETUP);
// Using the UI
if (showTutorialTips) {
tipQueue.push_back(Tip::CUSTOMIZATION);
tipQueue.push_back(Tip::BUTTONS);
}
// Shutdown info
// Shown until user performs one valid shutdown
if (!settings->tips.safeShutdownSeen)
tipQueue.push_back(Tip::SAFE_SHUTDOWN);
// Catch an incorrect attempt at rotating display
if (config.display.flip_screen)
tipQueue.push_back(Tip::ROTATION);
// Region picker
if (needsRegion)
tipQueue.push_back(Tip::PICK_REGION);
if (!tipQueue.empty())
bringToForeground();
}
void InkHUD::TipsApplet::onRender(bool full)
{
switch (tipQueue.front()) {
case Tip::WELCOME:
renderWelcome();
break;
case Tip::FINISH_SETUP: {
setFont(fontMedium);
const char *title = "Tip: Finish Setup";
uint16_t h = getWrappedTextHeight(0, width(), title);
printWrapped(0, 0, width(), title);
setFont(fontSmall);
int16_t cursorY = h + fontSmall.lineHeight();
auto drawBullet = [&](const char *text) {
uint16_t bh = getWrappedTextHeight(0, width(), text);
printWrapped(0, cursorY, width(), text);
cursorY += bh + (fontSmall.lineHeight() / 3);
};
drawBullet("- connect antenna");
drawBullet("- connect a client app");
if (config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET)
drawBullet("- set region");
if (!(*config.device.tzdef && config.device.tzdef[0] != 0))
drawBullet("- set timezone");
cursorY += fontSmall.lineHeight() / 2;
drawBullet("More info at meshtastic.org");
printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM);
} break;
case Tip::PICK_REGION: {
setFont(fontMedium);
printAt(0, 0, "Set Region");
setFont(fontSmall);
printWrapped(0, fontMedium.lineHeight() * 1.5, width(), "Please select your LoRa region to complete setup.");
printAt(0, Y(1.0), "Press button to choose", LEFT, BOTTOM);
} break;
case Tip::SAFE_SHUTDOWN: {
setFont(fontMedium);
const char *title = "Tip: Shutdown";
uint16_t h = getWrappedTextHeight(0, width(), title);
printWrapped(0, 0, width(), title);
setFont(fontSmall);
int16_t cursorY = h + fontSmall.lineHeight();
const char *body = "Before removing power, please shut down from InkHUD menu, or a client app.\n\n"
"This ensures data is saved.";
uint16_t bodyH = getWrappedTextHeight(0, width(), body);
printWrapped(0, cursorY, width(), body);
cursorY += bodyH + (fontSmall.lineHeight() / 2);
printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM);
} break;
case Tip::CUSTOMIZATION: {
setFont(fontMedium);
const char *title = "Tip: Customization";
uint16_t h = getWrappedTextHeight(0, width(), title);
printWrapped(0, 0, width(), title);
setFont(fontSmall);
int16_t cursorY = h + fontSmall.lineHeight();
const char *body = "Configure & control display with the InkHUD menu. "
"Optional features, layout, rotation, and more.";
uint16_t bodyH = getWrappedTextHeight(0, width(), body);
printWrapped(0, cursorY, width(), body);
cursorY += bodyH + (fontSmall.lineHeight() / 2);
printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM);
} break;
case Tip::BUTTONS: {
setFont(fontMedium);
const char *title = "Tip: Buttons";
uint16_t h = getWrappedTextHeight(0, width(), title);
printWrapped(0, 0, width(), title);
setFont(fontSmall);
int16_t cursorY = h + fontSmall.lineHeight();
auto drawBullet = [&](const char *text) {
uint16_t bh = getWrappedTextHeight(0, width(), text);
printWrapped(0, cursorY, width(), text);
cursorY += bh + (fontSmall.lineHeight() / 3);
};
if (!settings->joystick.enabled) {
drawBullet("User Button");
drawBullet("- short press: next");
drawBullet("- long press: select or open menu");
} else {
drawBullet("Joystick");
drawBullet("- press: open menu or select");
drawBullet("Exit Button");
drawBullet("- press: switch tile or close menu");
}
printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM);
} break;
case Tip::ROTATION: {
setFont(fontMedium);
const char *title = "Tip: Rotation";
uint16_t h = getWrappedTextHeight(0, width(), title);
printWrapped(0, 0, width(), title);
setFont(fontSmall);
if (!settings->joystick.enabled) {
int16_t cursorY = h + fontSmall.lineHeight();
const char *body = "To rotate the display, use the InkHUD menu. "
"Long-press the user button > Options > Rotate.";
uint16_t bh = getWrappedTextHeight(0, width(), body);
printWrapped(0, cursorY, width(), body);
cursorY += bh + (fontSmall.lineHeight() / 2);
} else {
printWrapped(0, fontMedium.lineHeight() * 1.5, width(),
"To rotate the display, use the InkHUD menu. Press the user button > Options > Rotate.");
}
printAt(0, Y(1.0), "Press button to continue", LEFT, BOTTOM);
// Revert the "flip screen" setting, preventing this message showing again
config.display.flip_screen = false;
nodeDB->saveToDisk(SEGMENT_DEVICESTATE);
} break;
}
}
// This tip has its own render method, only because it's a big block of code
// Didn't want to clutter up the switch in onRender too much
void InkHUD::TipsApplet::renderWelcome()
{
uint16_t padW = X(0.05);
// Detect portrait orientation
bool portrait = height() > width();
// Block 1 - logo & title
// ========================
// Logo size
uint16_t logoWLimit = portrait ? X(0.5) : X(0.3);
uint16_t logoHLimit = portrait ? Y(0.25) : Y(0.3);
uint16_t logoW = getLogoWidth(logoWLimit, logoHLimit);
uint16_t logoH = getLogoHeight(logoWLimit, logoHLimit);
// Title size
setFont(fontMedium);
std::string title;
if (width() >= 200) // Future proofing: hide if *tiny* display
title = "meshtastic.org";
uint16_t titleW = getTextWidth(title);
// Center the block
// Desired effect: equal margin from display edge for logo left and title right
int16_t block1Y = portrait ? Y(0.2) : Y(0.3);
int16_t block1CX = X(0.5) + (logoW / 2) - (titleW / 2);
int16_t logoCX = block1CX - (logoW / 2) - (padW / 2);
int16_t titleCX = block1CX + (titleW / 2) + (padW / 2);
// Draw block
drawLogo(logoCX, block1Y, logoW, logoH);
printAt(titleCX, block1Y, title, CENTER, MIDDLE);
// Block 2 - subtitle
// =======================
setFont(fontSmall);
std::string subtitle = "InkHUD";
if (width() >= 200)
subtitle += " - A Heads-Up Display"; // Future proofing: narrower for tiny display
printAt(X(0.5), portrait ? Y(0.45) : Y(0.6), subtitle, CENTER, MIDDLE);
// Block 3 - press to continue
// ============================
printAt(X(0.5), Y(1), "Press button to continue", CENTER, BOTTOM);
}
void InkHUD::TipsApplet::onForeground()
{
// Prevent most other applets from requesting update, and skip their rendering entirely
// Another system applet with a higher precedence can potentially ignore this
SystemApplet::lockRendering = true;
SystemApplet::lockRequests = true;
SystemApplet::handleInput = true; // Our applet should handle button input (unless another system applet grabs it first)
}
void InkHUD::TipsApplet::onBackground()
{
// Allow normal update behavior to resume
SystemApplet::lockRendering = false;
SystemApplet::lockRequests = false;
SystemApplet::handleInput = false;
// Need to force an update, as a polite request wouldn't be honored, seeing how we are now in the background
// Usually, onBackground is followed by another applet's onForeground (which requests update), but not in this case
inkhud->forceUpdate(EInk::UpdateTypes::FULL, true);
}
// While our SystemApplet::handleInput flag is true
void InkHUD::TipsApplet::onButtonShortPress()
{
bool needsRegion = (config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET);
// If we're prompting the user to pick a region, hand off to the menu
if (!tipQueue.empty() && tipQueue.front() == Tip::PICK_REGION) {
tipQueue.pop_front();
// Signal InkHUD to open the menu on Region page
inkhud->forceRegionMenu = true;
// Close tips and open menu
sendToBackground();
inkhud->openMenu();
return;
}
// Consume current tip
tipQueue.pop_front();
// All tips done
if (tipQueue.empty()) {
// Record that user has now seen the "tutorial" set of tips
// Don't show them on subsequent boots
if (settings->tips.firstBoot && !needsRegion) {
settings->tips.firstBoot = false;
inkhud->persistence->saveSettings();
}
// Close applet
sendToBackground();
} else {
requestUpdate();
}
}
// Functions the same as the user button in this instance
void InkHUD::TipsApplet::onExitShort()
{
onButtonShortPress();
}
#endif
@@ -0,0 +1,52 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Shows info on how to use InkHUD
- tutorial at first boot
- additional tips in certain situation (e.g. bad shutdown, region unset)
*/
#pragma once
#include "configuration.h"
#include "graphics/niche/InkHUD/SystemApplet.h"
namespace NicheGraphics::InkHUD
{
class TipsApplet : public SystemApplet
{
protected:
enum class Tip {
WELCOME,
FINISH_SETUP,
PICK_REGION,
SAFE_SHUTDOWN,
CUSTOMIZATION,
BUTTONS,
ROTATION,
};
public:
TipsApplet();
void onRender(bool full) override;
void onForeground() override;
void onBackground() override;
void onButtonShortPress() override;
void onExitShort() override;
protected:
void renderWelcome(); // Very first screen of tutorial
std::deque<Tip> tipQueue; // List of tips to show, one after another
WindowManager *windowManager = nullptr; // For convenience. Set in constructor.
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,139 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./AllMessageApplet.h"
using namespace NicheGraphics;
void InkHUD::AllMessageApplet::onActivate()
{
textMessageObserver.observe(textMessageModule);
}
void InkHUD::AllMessageApplet::onDeactivate()
{
textMessageObserver.unobserve(textMessageModule);
}
// We're not consuming the data passed to this method;
// we're just just using it to trigger a render
int InkHUD::AllMessageApplet::onReceiveTextMessage(const meshtastic_MeshPacket *p)
{
// Abort if applet fully deactivated
// Already handled by onActivate and onDeactivate, but good practice for all applets
if (!isActive())
return 0;
// Abort if this is an outgoing message
if (getFrom(p) == nodeDB->getNodeNum())
return 0;
requestAutoshow(); // Want to become foreground, if permitted
requestUpdate(); // Want to update display, if applet is foreground
// Return zero: no issues here, carry on notifying other observers!
return 0;
}
void InkHUD::AllMessageApplet::onRender(bool full)
{
// Find newest message, regardless of whether DM or broadcast
MessageStore::Message *message;
if (latestMessage->wasBroadcast)
message = &latestMessage->broadcast;
else
message = &latestMessage->dm;
// Short circuit: no text message
if (!message->sender) {
printAt(X(0.5), Y(0.5), "No Message", CENTER, MIDDLE);
return;
}
// ===========================
// Header (sender, timestamp)
// ===========================
// Y position for divider
// - between header text and messages
std::string header;
// RX Time
// - if valid
std::string timeString = getTimeString(message->timestamp);
if (timeString.length() > 0) {
header += timeString;
header += ": ";
}
// Sender's id
// - short name and long name, if available, or
// - node id
meshtastic_NodeInfoLite *sender = nodeDB->getMeshNode(message->sender);
if (sender && sender->has_user) {
header += parseShortName(sender); // May be last-four of node if unprintable (emoji, etc)
header += " (";
header += parse(sender->user.long_name);
header += ")";
} else
header += hexifyNodeNum(message->sender);
// Draw a "standard" applet header
drawHeader(header);
// Fade the right edge of the header, if text spills over edge
uint8_t wF = getFont().lineHeight() / 2; // Width of fade effect
uint8_t hF = getHeaderHeight(); // Height of fade effect
if (getCursorX() > width())
hatchRegion(width() - wF - 1, 1, wF, hF, 2, WHITE);
// Dimensions of the header
constexpr int16_t padDivH = 2;
const int16_t headerDivY = Applet::getHeaderHeight() - 1;
// ===================
// Print message text
// ===================
// Parse any non-ascii chars in the message
std::string text = parse(message->text);
// Extra gap below the header
int16_t textTop = headerDivY + padDivH;
// Attempt to print with fontLarge
uint32_t textHeight;
setFont(fontLarge);
textHeight = getWrappedTextHeight(0, width(), text);
if (textHeight <= (uint32_t)height()) {
printWrapped(0, textTop, width(), text);
return;
}
// Fallback (too large): attempt to print with fontMedium
setFont(fontMedium);
textHeight = getWrappedTextHeight(0, width(), text);
if (textHeight <= (uint32_t)height()) {
printWrapped(0, textTop, width(), text);
return;
}
// Fallback (too large): print with fontSmall
setFont(fontSmall);
printWrapped(0, textTop, width(), text);
}
// Don't show notifications for text messages when our applet is displayed
bool InkHUD::AllMessageApplet::approveNotification(Notification &n)
{
if (n.type == Notification::Type::NOTIFICATION_MESSAGE_BROADCAST)
return false;
else if (n.type == Notification::Type::NOTIFICATION_MESSAGE_DIRECT)
return false;
else
return true;
}
#endif
@@ -0,0 +1,49 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Shows the latest incoming text message, as well as sender.
Both broadcast and direct messages will be shown here, from all channels.
This module doesn't doesn't use the devicestate.rx_text_message,' as this is overwritten to contain outgoing messages
This module doesn't collect its own text message. Instead, the WindowManager stores the most recent incoming text message.
This is available to any interested modules (SingeMessageApplet, NotificationApplet etc.) via InkHUD::latestMessage
We do still receive notifications from the text message module though,
to know when a new message has arrived, and trigger the update.
*/
#pragma once
#include "configuration.h"
#include "graphics/niche/InkHUD/Applet.h"
#include "modules/TextMessageModule.h"
namespace NicheGraphics::InkHUD
{
class Applet;
class AllMessageApplet : public Applet
{
public:
void onRender(bool full) override;
void onActivate() override;
void onDeactivate() override;
int onReceiveTextMessage(const meshtastic_MeshPacket *p);
bool approveNotification(Notification &n) override; // Which notifications to suppress
protected:
// Used to register our text message callback
CallbackObserver<AllMessageApplet, const meshtastic_MeshPacket *> textMessageObserver =
CallbackObserver<AllMessageApplet, const meshtastic_MeshPacket *>(this, &AllMessageApplet::onReceiveTextMessage);
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,132 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./DMApplet.h"
using namespace NicheGraphics;
void InkHUD::DMApplet::onActivate()
{
textMessageObserver.observe(textMessageModule);
}
void InkHUD::DMApplet::onDeactivate()
{
textMessageObserver.unobserve(textMessageModule);
}
// We're not consuming the data passed to this method;
// we're just just using it to trigger a render
int InkHUD::DMApplet::onReceiveTextMessage(const meshtastic_MeshPacket *p)
{
// Abort if applet fully deactivated
// Already handled by onActivate and onDeactivate, but good practice for all applets
if (!isActive())
return 0;
// If DM (not broadcast)
if (!isBroadcast(p->to)) {
// Want to update display, if applet is foreground
requestUpdate();
// If this was an incoming message, suggest that our applet becomes foreground, if permitted
if (getFrom(p) != nodeDB->getNodeNum())
requestAutoshow();
}
// Return zero: no issues here, carry on notifying other observers!
return 0;
}
void InkHUD::DMApplet::onRender(bool full)
{
// Abort if no text message
if (!latestMessage->dm.sender) {
printAt(X(0.5), Y(0.5), "No DMs", CENTER, MIDDLE);
return;
}
// ===========================
// Header (sender, timestamp)
// ===========================
// Y position for divider
// - between header text and messages
std::string header;
// RX Time
// - if valid
std::string timeString = getTimeString(latestMessage->dm.timestamp);
if (timeString.length() > 0) {
header += timeString;
header += ": ";
}
// Sender's id
// - shortname and long name, if available, or
// - node id
meshtastic_NodeInfoLite *sender = nodeDB->getMeshNode(latestMessage->dm.sender);
if (sender && sender->has_user) {
header += parseShortName(sender); // May be last-four of node if unprintable (emoji, etc)
header += " (";
header += parse(sender->user.long_name);
header += ")";
} else
header += hexifyNodeNum(latestMessage->dm.sender);
// Draw a "standard" applet header
drawHeader(header);
// Fade the right edge of the header, if text spills over edge
uint8_t wF = getFont().lineHeight() / 2; // Width of fade effect
uint8_t hF = getHeaderHeight(); // Height of fade effect
if (getCursorX() > width())
hatchRegion(width() - wF - 1, 1, wF, hF, 2, WHITE);
// Dimensions of the header
constexpr int16_t padDivH = 2;
const int16_t headerDivY = Applet::getHeaderHeight() - 1;
// ===================
// Print message text
// ===================
// Parse any non-ascii chars in the message
std::string text = parse(latestMessage->dm.text);
// Extra gap below the header
int16_t textTop = headerDivY + padDivH;
// Attempt to print with fontLarge
uint32_t textHeight;
setFont(fontLarge);
textHeight = getWrappedTextHeight(0, width(), text);
if (textHeight <= (uint32_t)height()) {
printWrapped(0, textTop, width(), text);
return;
}
// Fallback (too large): attempt to print with fontMedium
setFont(fontMedium);
textHeight = getWrappedTextHeight(0, width(), text);
if (textHeight <= (uint32_t)height()) {
printWrapped(0, textTop, width(), text);
return;
}
// Fallback (too large): print with fontSmall
setFont(fontSmall);
printWrapped(0, textTop, width(), text);
}
// Don't show notifications for direct messages when our applet is displayed
bool InkHUD::DMApplet::approveNotification(Notification &n)
{
if (n.type == Notification::Type::NOTIFICATION_MESSAGE_DIRECT)
return false;
else
return true;
}
#endif
@@ -0,0 +1,49 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Shows the latest incoming *Direct Message* (DM), as well as sender.
This compliments the threaded message applets
This module doesn't doesn't use the devicestate.rx_text_message,' as this is overwritten to contain outgoing messages
This module doesn't collect its own text message. Instead, the WindowManager stores the most recent incoming text message.
This is available to any interested modules (SingeMessageApplet, NotificationApplet etc.) via InkHUD::latestMessage
We do still receive notifications from the text message module though,
to know when a new message has arrived, and trigger the update.
*/
#pragma once
#include "configuration.h"
#include "graphics/niche/InkHUD/Applet.h"
#include "modules/TextMessageModule.h"
namespace NicheGraphics::InkHUD
{
class Applet;
class DMApplet : public Applet
{
public:
void onRender(bool full) override;
void onActivate() override;
void onDeactivate() override;
int onReceiveTextMessage(const meshtastic_MeshPacket *p);
bool approveNotification(Notification &n) override; // Which notifications to suppress
protected:
// Used to register our text message callback
CallbackObserver<DMApplet, const meshtastic_MeshPacket *> textMessageObserver =
CallbackObserver<DMApplet, const meshtastic_MeshPacket *>(this, &DMApplet::onReceiveTextMessage);
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,111 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./FavoritesMapApplet.h"
#include "NodeDB.h"
using namespace NicheGraphics;
bool InkHUD::FavoritesMapApplet::shouldDrawNode(meshtastic_NodeInfoLite *node)
{
// Keep our own node available as map anchor/center; all others must be favorited.
return node && (node->num == nodeDB->getNodeNum() || node->is_favorite);
}
void InkHUD::FavoritesMapApplet::onRender(bool full)
{
// Custom empty state text for favorites-only map.
if (!enoughMarkers()) {
printAt(X(0.5), Y(0.5) - (getFont().lineHeight() / 2), "Favorite node position", CENTER, MIDDLE);
printAt(X(0.5), Y(0.5) + (getFont().lineHeight() / 2), "will appear here", CENTER, MIDDLE);
return;
}
// Draw the usual map applet first.
MapApplet::onRender(full);
// Draw our latest "node of interest" as a special marker.
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(lastFrom);
if (node && node->is_favorite && nodeDB->hasValidPosition(node) && enoughMarkers())
drawLabeledMarker(node);
}
// Determine if we need to redraw the map, when we receive a new position packet.
ProcessMessage InkHUD::FavoritesMapApplet::handleReceived(const meshtastic_MeshPacket &mp)
{
// If applet is not active, we shouldn't be handling any data.
if (!isActive())
return ProcessMessage::CONTINUE;
// Try decode a position from the packet.
bool hasPosition = false;
float lat;
float lng;
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.decoded.portnum == meshtastic_PortNum_POSITION_APP) {
meshtastic_Position position = meshtastic_Position_init_default;
if (pb_decode_from_bytes(mp.decoded.payload.bytes, mp.decoded.payload.size, &meshtastic_Position_msg, &position)) {
if (position.has_latitude_i && position.has_longitude_i // Actually has position
&& (position.latitude_i != 0 || position.longitude_i != 0)) // Position isn't "null island"
{
hasPosition = true;
lat = position.latitude_i * 1e-7; // Convert from Meshtastic's internal int32_t format
lng = position.longitude_i * 1e-7;
}
}
}
// Skip if we didn't get a valid position.
if (!hasPosition)
return ProcessMessage::CONTINUE;
const int8_t hopsAway = getHopsAway(mp);
const bool hasHopsAway = hopsAway >= 0;
// Determine if the position packet would change anything on-screen.
bool somethingChanged = false;
// If our own position.
if (isFromUs(&mp)) {
// Ignore tiny local movement to reduce update spam.
if (GeoCoord::latLongToMeter(ourLastLat, ourLastLng, lat, lng) > 50) {
somethingChanged = true;
ourLastLat = lat;
ourLastLng = lng;
}
} else {
// For non-local packets, this applet only reacts to favorited nodes.
const meshtastic_NodeInfoLite *sender = nodeDB->getMeshNode(mp.from);
if (!sender || !sender->is_favorite)
return ProcessMessage::CONTINUE;
// Check if this position is from someone different than our previous position packet.
if (mp.from != lastFrom) {
somethingChanged = true;
lastFrom = mp.from;
lastLat = lat;
lastLng = lng;
lastHopsAway = hopsAway;
}
// Same sender: check if position changed.
else if (GeoCoord::latLongToMeter(lastLat, lastLng, lat, lng) > 10) {
somethingChanged = true;
lastLat = lat;
lastLng = lng;
}
// Same sender, same position: check if hops changed.
else if (hasHopsAway && (hopsAway != lastHopsAway)) {
somethingChanged = true;
lastHopsAway = hopsAway;
}
}
if (somethingChanged) {
requestAutoshow();
requestUpdate();
}
return ProcessMessage::CONTINUE;
}
#endif
@@ -0,0 +1,44 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Plots position of favorited nodes from DB, with North facing up.
Scaled to fit the most distant node.
Size of marker represents hops away.
The favorite node which most recently sent a position will be labeled.
*/
#pragma once
#include "configuration.h"
#include "graphics/niche/InkHUD/Applets/Bases/Map/MapApplet.h"
#include "SinglePortModule.h"
namespace NicheGraphics::InkHUD
{
class FavoritesMapApplet : public MapApplet, public SinglePortModule
{
public:
FavoritesMapApplet() : SinglePortModule("FavoritesMapApplet", meshtastic_PortNum_POSITION_APP) {}
void onRender(bool full) override;
protected:
bool shouldDrawNode(meshtastic_NodeInfoLite *node) override;
ProcessMessage handleReceived(const meshtastic_MeshPacket &mp) override;
NodeNum lastFrom = 0; // Sender of most recent favorited (non-local) position packet
float lastLat = 0.0;
float lastLng = 0.0;
float lastHopsAway = 0;
float ourLastLat = 0.0; // Info about most recent local position
float ourLastLng = 0.0;
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,125 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "RTC.h"
#include "gps/GeoCoord.h"
#include "./HeardApplet.h"
using namespace NicheGraphics;
void InkHUD::HeardApplet::onActivate()
{
// When applet begins, pre-fill with stale info from NodeDB
populateFromNodeDB();
}
void InkHUD::HeardApplet::onDeactivate()
{
// Avoid an unlikely situation where frequent activation / deactivation populates duplicate info from node DB
cards.clear();
}
// When base applet hears a new packet, it extracts the info and passes it to us as CardInfo
// We need to store it (at front to sort recent), and request display update if our list has visibly changed as a result
void InkHUD::HeardApplet::handleParsed(CardInfo c)
{
// Grab the previous entry.
// To check if the new data is different enough to justify re-render
// Need to cache now, before we manipulate the deque
CardInfo previous;
if (!cards.empty())
previous = cards.at(0);
// If we're updating an existing entry, remove the old one. Will reinsert at front
for (auto it = cards.begin(); it != cards.end(); ++it) {
if (it->nodeNum == c.nodeNum) {
cards.erase(it);
break;
}
}
cards.push_front(c); // Insert into base class' card collection
cards.resize(min(maxCards(), (uint8_t)cards.size())); // Don't keep more cards than we could *ever* fit on screen
cards.shrink_to_fit();
// Our rendered image needs to change if:
if (previous.nodeNum != c.nodeNum // Different node
|| previous.signal != c.signal // or different signal strength
|| previous.distanceMeters != c.distanceMeters // or different position
|| previous.hopsAway != c.hopsAway) // or different hops away
{
requestAutoshow();
requestUpdate();
}
}
// When applet is activated, pre-fill with stale data from NodeDB
// We're sorting using the last_heard value. Susceptible to weirdness if node's RTC changes.
// No SNR is available in node db, so we can't calculate signal either
// These initial cards from node db will be gradually pushed out by new packets which originate from out base applet instead
void InkHUD::HeardApplet::populateFromNodeDB()
{
// Fill a collection with pointers to each node in db
std::vector<meshtastic_NodeInfoLite *> ordered;
for (auto mn = nodeDB->meshNodes->begin(); mn != nodeDB->meshNodes->end(); ++mn) {
// Only copy if valid, and not our own node
if (mn->num != 0 && mn->num != nodeDB->getNodeNum())
ordered.push_back(&*mn);
}
// Sort the collection by age
std::sort(ordered.begin(), ordered.end(),
[](const meshtastic_NodeInfoLite *top, const meshtastic_NodeInfoLite *bottom) -> bool {
return (top->last_heard > bottom->last_heard);
});
// Keep the most recent entries only
// Just enough to fill the screen
if (ordered.size() > maxCards())
ordered.resize(maxCards());
// Create card info for these (stale) node observations
meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
for (meshtastic_NodeInfoLite *node : ordered) {
CardInfo c;
c.nodeNum = node->num;
if (node->has_hops_away)
c.hopsAway = node->hops_away;
if (nodeDB->hasValidPosition(node) && nodeDB->hasValidPosition(ourNode)) {
// Get lat and long as float
// Meshtastic stores these as integers internally
float ourLat = ourNode->position.latitude_i * 1e-7;
float ourLong = ourNode->position.longitude_i * 1e-7;
float theirLat = node->position.latitude_i * 1e-7;
float theirLong = node->position.longitude_i * 1e-7;
c.distanceMeters = (int32_t)GeoCoord::latLongToMeter(theirLat, theirLong, ourLat, ourLong);
}
// Insert into the card collection (member of base class)
cards.push_back(c);
}
}
// Text drawn in the usual applet header
// Handled by base class: ChronoListApplet
std::string InkHUD::HeardApplet::getHeaderText()
{
uint16_t nodeCount = nodeDB->getNumMeshNodes() - 1; // Don't count our own node
std::string text = "Heard: ";
// Print node count, if nodeDB not yet nearing full
if (nodeCount < MAX_NUM_NODES) {
text += to_string(nodeCount); // Max nodes
text += " ";
text += (nodeCount == 1) ? "node" : "nodes";
}
return text;
}
#endif
@@ -0,0 +1,35 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Shows a list of all nodes (recently heard or not), sorted by time last heard.
Most of the work is done by the InkHUD::NodeListApplet base class
*/
#pragma once
#include "configuration.h"
#include "graphics/niche/InkHUD/Applets/Bases/NodeList/NodeListApplet.h"
namespace NicheGraphics::InkHUD
{
class HeardApplet : public NodeListApplet
{
public:
HeardApplet() : NodeListApplet("HeardApplet") {}
void onActivate() override;
void onDeactivate() override;
protected:
void handleParsed(CardInfo c) override; // Store new info, and update display if needed
std::string getHeaderText() override; // Set title for this applet
void populateFromNodeDB(); // Pre-fill the CardInfo collection from NodeDB
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,111 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./PositionsApplet.h"
#include "NodeDB.h"
using namespace NicheGraphics;
void InkHUD::PositionsApplet::onRender(bool full)
{
// Draw the usual map applet first
MapApplet::onRender(full);
// Draw our latest "node of interest" as a special marker
// -------------------------------------------------------
// We might be rendering because we got a position packet from them
// We might be rendering because our own position updated
// Either way, we still highlight which node most recently sent us a position packet
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(lastFrom);
if (node && nodeDB->hasValidPosition(node) && enoughMarkers())
drawLabeledMarker(node);
}
// Determine if we need to redraw the map, when we receive a new position packet
ProcessMessage InkHUD::PositionsApplet::handleReceived(const meshtastic_MeshPacket &mp)
{
// If applet is not active, we shouldn't be handling any data
// It's good practice for all applets to implement an early return like this
// for PositionsApplet, this is **required** - it's where we're handling active vs deactive
if (!isActive())
return ProcessMessage::CONTINUE;
// Try decode a position from the packet
bool hasPosition = false;
float lat;
float lng;
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.decoded.portnum == meshtastic_PortNum_POSITION_APP) {
meshtastic_Position position = meshtastic_Position_init_default;
if (pb_decode_from_bytes(mp.decoded.payload.bytes, mp.decoded.payload.size, &meshtastic_Position_msg, &position)) {
if (position.has_latitude_i && position.has_longitude_i // Actually has position
&& (position.latitude_i != 0 || position.longitude_i != 0)) // Position isn't "null island"
{
hasPosition = true;
lat = position.latitude_i * 1e-7; // Convert from Meshtastic's internal int32_t format
lng = position.longitude_i * 1e-7;
}
}
}
// Skip if we didn't get a valid position
if (!hasPosition)
return ProcessMessage::CONTINUE;
const int8_t hopsAway = getHopsAway(mp);
const bool hasHopsAway = hopsAway >= 0;
// Determine if the position packet would change anything on-screen
// -----------------------------------------------------------------
bool somethingChanged = false;
// If our own position
if (isFromUs(&mp)) {
// We get frequent position updates from connected phone
// Only update if we're travelled some distance, for rate limiting
// Todo: smarter detection of position changes
if (GeoCoord::latLongToMeter(ourLastLat, ourLastLng, lat, lng) > 50) {
somethingChanged = true;
ourLastLat = lat;
ourLastLng = lng;
}
}
// If someone else's position
else {
// Check if this position is from someone different than our previous position packet
if (mp.from != lastFrom) {
somethingChanged = true;
lastFrom = mp.from;
lastLat = lat;
lastLng = lng;
lastHopsAway = hopsAway;
}
// Same sender: check if position changed
// Todo: smarter detection of position changes
else if (GeoCoord::latLongToMeter(lastLat, lastLng, lat, lng) > 10) {
somethingChanged = true;
lastLat = lat;
lastLng = lng;
}
// Same sender, same position: check if hops changed
// Only pay attention if the hopsAway value is valid
else if (hasHopsAway && (hopsAway != lastHopsAway)) {
somethingChanged = true;
lastHopsAway = hopsAway;
}
}
// Decision reached
// -----------------
if (somethingChanged) {
requestAutoshow(); // Todo: only request this in some situations?
requestUpdate();
}
return ProcessMessage::CONTINUE;
}
#endif
@@ -0,0 +1,43 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Plots position of all nodes from DB, with North facing up.
Scaled to fit the most distant node.
Size of cross represents hops away.
The node which has most recently sent a position will be labeled.
*/
#pragma once
#include "configuration.h"
#include "graphics/niche/InkHUD/Applets/Bases/Map/MapApplet.h"
#include "SinglePortModule.h"
namespace NicheGraphics::InkHUD
{
class PositionsApplet : public MapApplet, public SinglePortModule
{
public:
PositionsApplet() : SinglePortModule("PositionsApplet", meshtastic_PortNum_POSITION_APP) {}
void onRender(bool full) override;
protected:
ProcessMessage handleReceived(const meshtastic_MeshPacket &mp) override;
NodeNum lastFrom = 0; // Sender of most recent (non-local) position packet
float lastLat = 0.0;
float lastLng = 0.0;
float lastHopsAway = 0;
float ourLastLat = 0.0; // Info about the most recent (non-local) position packet
float ourLastLng = 0.0; // Info about most recent *local* position
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,153 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./RecentsListApplet.h"
#include "RTC.h"
using namespace NicheGraphics;
InkHUD::RecentsListApplet::RecentsListApplet() : NodeListApplet("RecentsListApplet"), concurrency::OSThread("RecentsListApplet")
{
// No scheduled tasks initially
OSThread::disable();
}
void InkHUD::RecentsListApplet::onActivate()
{
// When the applet is activated, begin scheduled purging of any nodes which are no longer "active"
OSThread::enabled = true;
OSThread::setIntervalFromNow(60 * 1000UL); // Every minute
}
void InkHUD::RecentsListApplet::onDeactivate()
{
// Halt scheduled purging
OSThread::disable();
}
int32_t InkHUD::RecentsListApplet::runOnce()
{
prune(); // Remove CardInfo and Age record for nodes which we haven't heard recently
return OSThread::interval;
}
// When base applet hears a new packet, it extracts the info and passes it to us as CardInfo
// We need to store it (at front to sort recent), and request display update if our list has visibly changed as a result
// We also need to record the current time against the nodenum, so we know when it becomes inactive
void InkHUD::RecentsListApplet::handleParsed(CardInfo c)
{
// Grab the previous entry.
// To check if the new data is different enough to justify re-render
// Need to cache now, before we manipulate the deque
CardInfo previous;
if (!cards.empty())
previous = cards.at(0);
// If we're updating an existing entry, remove the old one. Will reinsert at front
for (auto it = cards.begin(); it != cards.end(); ++it) {
if (it->nodeNum == c.nodeNum) {
cards.erase(it);
break;
}
}
cards.push_front(c); // Store this CardInfo
cards.resize(min(maxCards(), (uint8_t)cards.size())); // Don't keep more cards than we could *ever* fit on screen
cards.shrink_to_fit();
// Record the time of this observation
// Used to count active nodes, and to know when to prune inactive nodes
seenNow(c.nodeNum);
// Our rendered image needs to change if:
if (previous.nodeNum != c.nodeNum // Different node
|| previous.signal != c.signal // or different signal strength
|| previous.distanceMeters != c.distanceMeters // or different position
|| previous.hopsAway != c.hopsAway) // or different hops away
{
prune(); // Take the opportunity now to remove inactive nodes
requestAutoshow();
requestUpdate();
}
}
// Record the time (millis, right now) that we hear a node
// If we do not hear from a node for a while, its card and age info will be removed by the purge method, which runs regularly
void InkHUD::RecentsListApplet::seenNow(NodeNum nodeNum)
{
// If we're updating an existing entry, remove the old one. Will reinsert at front
for (auto it = ages.begin(); it != ages.end(); ++it) {
if (it->nodeNum == nodeNum) {
ages.erase(it);
break;
}
}
Age a;
a.nodeNum = nodeNum;
a.seenAtMs = millis();
ages.push_front(a);
}
// Remove Card and Age info for any nodes which are now inactive
// Determined by when a node was last heard, in our internal record (not from nodeDB)
void InkHUD::RecentsListApplet::prune()
{
// Iterate age records from newest to oldest
for (uint16_t i = 0; i < ages.size(); i++) {
// Found the first record which is too old
if (!isActive(ages.at(i).seenAtMs)) {
// Drop this item, and all others behind it
ages.resize(i);
ages.shrink_to_fit();
cards.resize(i);
cards.shrink_to_fit();
// Request an update, if pruning did modify our data
// Required if pruning was scheduled. Redundant if pruning was prior to rendering.
requestAutoshow();
requestUpdate();
break;
}
}
// Push next scheduled pruning back
// Pruning may be called from by handleParsed, immediately prior to rendering
// In that case, we can slightly delay our scheduled pruning
OSThread::setIntervalFromNow(60 * 1000UL);
}
// Is a timestamp old enough that it would make a node inactive, and in need of purging?
bool InkHUD::RecentsListApplet::isActive(uint32_t seenAtMs)
{
uint32_t now = millis();
uint32_t secsAgo = (now - seenAtMs) / 1000UL; // millis() overflow safe
return (secsAgo < settings->recentlyActiveSeconds);
}
// Text to be shown at top of applet
// ChronoListApplet base class allows us to set this dynamically
// Might want to adjust depending on node count, RTC status, etc
std::string InkHUD::RecentsListApplet::getHeaderText()
{
std::string text;
// Print the length of our "Recents" time-window
text += "Last ";
text += to_string(settings->recentlyActiveSeconds / 60);
text += " mins";
// Print the node count
const uint16_t nodeCount = ages.size();
text += ": ";
text += to_string(nodeCount);
text += " ";
text += (nodeCount == 1) ? "node" : "nodes";
return text;
}
#endif
@@ -0,0 +1,52 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Shows a list of nodes which have been recently active
The length of this "recently active" window is configurable using the onscreen menu
Most of the work is done by the shared InkHUD::NodeListApplet base class
*/
#pragma once
#include "configuration.h"
#include "graphics/niche/InkHUD/Applets/Bases/NodeList/NodeListApplet.h"
namespace NicheGraphics::InkHUD
{
class RecentsListApplet : public NodeListApplet, public concurrency::OSThread
{
protected:
// Used internally to count the number of active nodes
// We count for ourselves, instead of using the value provided by NodeDB,
// as the values occasionally differ, due to the timing of our Applet's purge method
struct Age {
uint32_t nodeNum;
uint32_t seenAtMs;
};
public:
RecentsListApplet();
void onActivate() override;
void onDeactivate() override;
protected:
int32_t runOnce() override;
void handleParsed(CardInfo c) override; // Store new info, update active count, update display if needed
std::string getHeaderText() override; // Set title for this applet
void seenNow(NodeNum nodeNum); // Record that we have just seen this node, for active node count
void prune(); // Remove cards for nodes which we haven't seen recently
bool isActive(uint32_t seenAtMillis); // Is a node still active, based on when we last heard it?
std::deque<Age> ages; // Information about when we last heard nodes. Independent of NodeDB
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,268 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./ThreadedMessageApplet.h"
#include "RTC.h"
#include "mesh/NodeDB.h"
using namespace NicheGraphics;
// Hard limits on how much message data to write to flash
// Avoid filling the storage if something goes wrong
// Normal usage should be well below this size
constexpr uint8_t MAX_MESSAGES_SAVED = 10;
constexpr uint32_t MAX_MESSAGE_SIZE = 250;
InkHUD::ThreadedMessageApplet::ThreadedMessageApplet(uint8_t channelIndex)
: SinglePortModule("ThreadedMessageApplet", meshtastic_PortNum_TEXT_MESSAGE_APP), channelIndex(channelIndex)
{
// Create the message store
// Will shortly attempt to load messages from RAM, if applet is active
// Label (filename in flash) is set from channel index
store = new MessageStore("ch" + to_string(channelIndex));
}
void InkHUD::ThreadedMessageApplet::onRender(bool full)
{
// =============
// Draw a header
// =============
// Header text
std::string headerText;
headerText += "Channel ";
headerText += to_string(channelIndex);
headerText += ": ";
if (channels.isDefaultChannel(channelIndex))
headerText += "Public";
else
headerText += channels.getByIndex(channelIndex).settings.name;
// Draw a "standard" applet header
drawHeader(headerText);
// Y position for divider
const int16_t dividerY = Applet::getHeaderHeight() - 1;
// ==================
// Draw each message
// ==================
// Restrict drawing area
// - don't overdraw the header
// - small gap below divider
setCrop(0, dividerY + 2, width(), height() - (dividerY + 2));
// Set padding
// - separates text from the vertical line which marks its edge
constexpr uint16_t padW = 2;
constexpr int16_t msgL = padW;
const int16_t msgR = (width() - 1) - padW;
const uint16_t msgW = (msgR - msgL) + 1;
int16_t msgB = height() - 1; // Vertical cursor for drawing. Messages are bottom-aligned to this value.
uint8_t i = 0; // Index of stored message
// Loop over messages
// - until no messages left, or
// - until no part of message fits on screen
while (msgB >= (0 - fontSmall.lineHeight()) && i < store->messages.size()) {
// Grab data for message
const MessageStore::Message &m = store->messages.at(i);
bool outgoing = (m.sender == 0) || (m.sender == myNodeInfo.my_node_num); // Own NodeNum if canned message
std::string bodyText = parse(m.text); // Parse any non-ascii chars in the message
// Cache bottom Y of message text
// - Used when drawing vertical line alongside
const int16_t dotsB = msgB;
// Get dimensions for message text
uint16_t bodyH = getWrappedTextHeight(msgL, msgW, bodyText);
int16_t bodyT = msgB - bodyH;
// Print message
// - if incoming
if (!outgoing)
printWrapped(msgL, bodyT, msgW, bodyText);
// Print message
// - if outgoing
else {
if (getTextWidth(bodyText) < width()) // If short,
printAt(msgR, bodyT, bodyText, RIGHT); // print right align
else // If long,
printWrapped(msgL, bodyT, msgW, bodyText); // need printWrapped(), which doesn't support right align
}
// Move cursor up
// - above message text
msgB -= bodyH;
msgB -= getFont().lineHeight() * 0.2; // Padding between message and header
// Compose info string
// - shortname, if possible, or "me"
// - time received, if possible
std::string info;
if (outgoing)
info += "Me";
else {
// Check if sender is node db
meshtastic_NodeInfoLite *sender = nodeDB->getMeshNode(m.sender);
if (sender)
info += parseShortName(sender); // Handle any unprintable chars in short name
else
info += hexifyNodeNum(m.sender); // No node info at all. Print the node num
}
std::string timeString = getTimeString(m.timestamp);
if (timeString.length() > 0) {
info += " - ";
info += timeString;
}
// Print the info string
// - Faux bold: printed twice, shifted horizontally by one px
printAt(outgoing ? msgR : msgL, msgB, info, outgoing ? RIGHT : LEFT, BOTTOM);
printAt(outgoing ? msgR - 1 : msgL + 1, msgB, info, outgoing ? RIGHT : LEFT, BOTTOM);
// Underline the info string
const int16_t divY = msgB;
int16_t divL;
int16_t divR;
if (!outgoing) {
// Left side - incoming
divL = msgL;
divR = getTextWidth(info) + getFont().lineHeight() / 2;
} else {
// Right side - outgoing
divR = msgR;
divL = divR - getTextWidth(info) - getFont().lineHeight() / 2;
}
for (int16_t x = divL; x <= divR; x += 2)
drawPixel(x, divY, BLACK);
// Move cursor up: above info string
msgB -= fontSmall.lineHeight();
// Vertical line alongside message
for (int16_t y = msgB; y < dotsB; y += 1)
drawPixel(outgoing ? width() - 1 : 0, y, BLACK);
// Move cursor up: padding before next message
msgB -= fontSmall.lineHeight() * 0.5;
i++;
} // End of loop: drawing each message
// Fade effect:
// Area immediately below the divider. Overdraw with sparse white lines.
// Make text appear to pass behind the header
hatchRegion(0, dividerY + 1, width(), fontSmall.lineHeight() / 3, 2, WHITE);
// If we've run out of screen to draw messages, we can drop any leftover data from the queue
// Those messages have been pushed off the screen-top by newer ones
while (i < store->messages.size())
store->messages.pop_back();
}
// Code which runs when the applet begins running
// This might happen at boot, or if user enables the applet at run-time, via the menu
void InkHUD::ThreadedMessageApplet::onActivate()
{
loadMessagesFromFlash();
loopbackOk = true; // Allow us to handle messages generated on the node (canned messages)
}
// Code which runs when the applet stop running
// This might be at shutdown, or if the user disables the applet at run-time, via the menu
void InkHUD::ThreadedMessageApplet::onDeactivate()
{
loopbackOk = false; // Slightly reduce our impact if the applet is disabled
}
// Handle new text messages
// These might be incoming, from the mesh, or outgoing from phone
// Each instance of the ThreadMessageApplet will only listen on one specific channel
ProcessMessage InkHUD::ThreadedMessageApplet::handleReceived(const meshtastic_MeshPacket &mp)
{
// Abort if applet fully deactivated
if (!isActive())
return ProcessMessage::CONTINUE;
// Abort if wrong channel
if (mp.channel != this->channelIndex)
return ProcessMessage::CONTINUE;
// Abort if message was a DM
if (mp.to != NODENUM_BROADCAST)
return ProcessMessage::CONTINUE;
// Extract info into our slimmed-down "StoredMessage" type
MessageStore::Message newMessage;
newMessage.timestamp = getValidTime(RTCQuality::RTCQualityDevice, true); // Current RTC time
newMessage.sender = mp.from;
newMessage.channelIndex = mp.channel;
newMessage.text = std::string((const char *)mp.decoded.payload.bytes, mp.decoded.payload.size);
// Store newest message at front
// These records are used when rendering, and also stored in flash at shutdown
store->messages.push_front(newMessage);
// If this was an incoming message, suggest that our applet becomes foreground, if permitted
if (getFrom(&mp) != nodeDB->getNodeNum())
requestAutoshow();
// Redraw the applet, perhaps.
requestUpdate(); // Want to update display, if applet is foreground
// Tell Module API to continue informing other firmware components about this message
// We're not the only component which is interested in new text messages
return ProcessMessage::CONTINUE;
}
// Don't show notifications for text messages broadcast to our channel, when the applet is displayed
bool InkHUD::ThreadedMessageApplet::approveNotification(Notification &n)
{
if (n.type == Notification::Type::NOTIFICATION_MESSAGE_BROADCAST && n.getChannel() == channelIndex)
return false;
// None of our business. Allow the notification.
else
return true;
}
// Save several recent messages to flash
// Stores the contents of ThreadedMessageApplet::messages
// Just enough messages to fill the display
// Messages are packed "back-to-back", to minimize blocks of flash used
void InkHUD::ThreadedMessageApplet::saveMessagesToFlash()
{
// Create a label (will become the filename in flash)
std::string label = "ch" + to_string(channelIndex);
store->saveToFlash();
}
// Load recent messages to flash
// Fills ThreadedMessageApplet::messages with previous messages
// Just enough messages have been stored to cover the display
void InkHUD::ThreadedMessageApplet::loadMessagesFromFlash()
{
// Create a label (will become the filename in flash)
std::string label = "ch" + to_string(channelIndex);
store->loadFromFlash();
}
// Code to run when device is shutting down
// This is in addition to any onDeactivate() code, which will also run
// Todo: implement before a reboot also
void InkHUD::ThreadedMessageApplet::onShutdown()
{
// Save our current set of messages to flash, provided the applet isn't disabled
if (isActive())
saveMessagesToFlash();
}
#endif
@@ -0,0 +1,58 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Displays a thread-view of incoming and outgoing message for a specific channel
The channel for this applet is set in the constructor,
when the applet is added to WindowManager in the setupNicheGraphics method.
Several messages are saved to flash at shutdown, to preseve applet between reboots.
This class has its own internal method for saving and loading to fs, which interacts directly with the FSCommon layer.
If the amount of flash usage is unacceptable, we could keep these in RAM only.
Multiple instances of this channel may be used. This must be done at buildtime.
Suggest a max of two channel, to minimize fs usage?
*/
#pragma once
#include "configuration.h"
#include "graphics/niche/InkHUD/Applet.h"
#include "graphics/niche/InkHUD/MessageStore.h"
#include "modules/TextMessageModule.h"
namespace NicheGraphics::InkHUD
{
class Applet;
class ThreadedMessageApplet : public Applet, public SinglePortModule
{
public:
explicit ThreadedMessageApplet(uint8_t channelIndex);
ThreadedMessageApplet() = delete;
void onRender(bool full) override;
void onActivate() override;
void onDeactivate() override;
void onShutdown() override;
ProcessMessage handleReceived(const meshtastic_MeshPacket &mp) override;
bool approveNotification(Notification &n) override; // Which notifications to suppress
protected:
void saveMessagesToFlash();
void loadMessagesFromFlash();
MessageStore *store; // Messages, held in RAM for use, ready to save to flash on shutdown
uint8_t channelIndex = 0;
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,176 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./DisplayHealth.h"
#include "DisplayHealth.h"
using namespace NicheGraphics;
// Timing for "maintenance"
// Paying off full-refresh debt with unprovoked updates, if the display is not very active
static constexpr uint32_t MAINTENANCE_MS_INITIAL = 60 * 1000UL;
static constexpr uint32_t MAINTENANCE_MS = 60 * 60 * 1000UL;
InkHUD::DisplayHealth::DisplayHealth() : concurrency::OSThread("Mediator")
{
// Timer disabled by default
OSThread::disable();
}
// Request which update type we would prefer, when the display image next changes
// DisplayHealth class will consider our suggestion, and weigh it against other requests
void InkHUD::DisplayHealth::requestUpdateType(Drivers::EInk::UpdateTypes type)
{
// Update our "working decision", to decide if this request is important enough to change our plan
if (!forced)
workingDecision = prioritize(workingDecision, type);
}
// Demand that a specific update type be used, when the display image next changes
// Note: multiple DisplayHealth::force calls should not be made,
// but if they are, the importance of the type will be weighed the same as if both calls were to DisplayHealth::request
void InkHUD::DisplayHealth::forceUpdateType(Drivers::EInk::UpdateTypes type)
{
if (!forced)
workingDecision = type;
else
workingDecision = prioritize(workingDecision, type);
forced = true;
}
// Find out which update type the DisplayHealth has chosen for us
// Calling this method consumes the result, and resets for the next update
Drivers::EInk::UpdateTypes InkHUD::DisplayHealth::decideUpdateType()
{
LOG_DEBUG("FULL-update debt:%f", debt);
// For convenience
typedef Drivers::EInk::UpdateTypes UpdateTypes;
// Grab our final decision for the update type, so we can reset now, for the next update
// We do this at top of the method, so we can return early
UpdateTypes finalDecision = workingDecision;
workingDecision = UpdateTypes::UNSPECIFIED;
forced = false;
// Check whether we've paid off enough debt to stop unprovoked refreshing (if in progress)
// This maintenance behavior will also have opportunity to halt itself when the timer next fires,
// but that could be an hour away, so we can stop it early here and free up resources
if (OSThread::enabled && debt == 0.0)
endMaintenance();
// Explicitly requested FULL
if (finalDecision == UpdateTypes::FULL) {
LOG_DEBUG("Explicit FULL");
debt = max(debt - 1.0, 0.0); // Record that we have paid back (some of) the FULL refresh debt
return UpdateTypes::FULL;
}
// Explicitly requested FAST
if (finalDecision == UpdateTypes::FAST) {
LOG_DEBUG("Explicit FAST");
// Add to the FULL refresh debt
if (debt < 1.0)
debt += 1.0 / fastPerFull;
else
debt += stressMultiplier * (1.0 / fastPerFull); // More debt if too many consecutive FAST refreshes
// If *significant debt*, begin occasionally refreshing *unprovoked*
// This maintenance behavior is only triggered here, by periods of user interaction
// Debt would otherwise not be able to climb above 1.0
if (debt >= 2.0)
beginMaintenance();
return UpdateTypes::FAST; // Give them what the asked for
}
// Handling UpdateTypes::UNSPECIFIED
// -----------------------------------
// In this case, the UI doesn't care which refresh we use
// Not much debt: suggest FAST
if (debt < 1.0) {
LOG_DEBUG("UNSPECIFIED: using FAST");
debt += 1.0 / fastPerFull;
return UpdateTypes::FAST;
}
// In debt: suggest FULL
else {
LOG_DEBUG("UNSPECIFIED: using FULL");
debt = max(debt - 1.0, 0.0); // Record that we have paid back (some of) the FULL refresh debt
// When maintenance begins, the first refresh happens shortly after user interaction ceases (a minute or so)
// If we *are* given an opportunity to refresh before that, we'll skip that initial maintenance refresh
// We were intending to use that initial refresh to redraw the screen as FULL, but we're doing that now, organically
if (OSThread::enabled && OSThread::interval == MAINTENANCE_MS_INITIAL)
OSThread::setInterval(MAINTENANCE_MS); // Note: not intervalFromNow
return UpdateTypes::FULL;
}
}
// Determine which of two update types is more important to honor
// Explicit FAST is more important than UNSPECIFIED - prioritize responsiveness
// Explicit FULL is more important than explicit FAST - prioritize image quality: explicit FULL is rare
// Used when multiple applets have all requested update simultaneously, each with their own preferred UpdateType
Drivers::EInk::UpdateTypes InkHUD::DisplayHealth::prioritize(Drivers::EInk::UpdateTypes type1, Drivers::EInk::UpdateTypes type2)
{
switch (type1) {
case Drivers::EInk::UpdateTypes::UNSPECIFIED:
return type2;
case Drivers::EInk::UpdateTypes::FAST:
return (type2 == Drivers::EInk::UpdateTypes::FULL) ? Drivers::EInk::UpdateTypes::FULL : Drivers::EInk::UpdateTypes::FAST;
case Drivers::EInk::UpdateTypes::FULL:
return type1;
}
return Drivers::EInk::UpdateTypes::UNSPECIFIED; // Suppress compiler warning only
}
// We're using the timer to perform "maintenance"
// If significant FULL-refresh debt has accumulated, we will occasionally run FULL refreshes unprovoked.
// This prevents gradual build-up of debt,
// in case we aren't doing enough UNSPECIFIED refreshes to pay the debt back organically.
// The first refresh takes place shortly after user finishes interacting with the device; this does the bulk of the restoration
// Subsequent refreshes take place *much* less frequently.
// Hopefully an applet will want to render before this, meaning we can cancel the maintenance.
int32_t InkHUD::DisplayHealth::runOnce()
{
if (debt > 0.0) {
LOG_DEBUG("debt=%f: performing maintenance", debt);
// Ask WindowManager to redraw everything, purely for the refresh
// Todo: optimize? Could update without re-rendering
InkHUD::getInstance()->forceUpdate(Drivers::EInk::UpdateTypes::FULL);
// Record that we have paid back (some of) the FULL refresh debt
debt = max(debt - 1.0, 0.0);
// Next maintenance refresh scheduled - long wait (an hour?)
return MAINTENANCE_MS;
}
else
return endMaintenance();
}
// Begin periodically refreshing the display, to repay FULL-refresh debt
// We do this in case user doesn't have enough activity to repay it organically, with UpdateTypes::UNSPECIFIED
// After an initial refresh, to redraw as FULL, we only perform these maintenance refreshes very infrequently
// This gives the display a chance to heal by evaluating UNSPECIFIED as FULL, which is preferable
void InkHUD::DisplayHealth::beginMaintenance()
{
OSThread::setIntervalFromNow(MAINTENANCE_MS_INITIAL);
OSThread::enabled = true;
}
// FULL-refresh debt is low enough that we no longer need to pay it back with periodic updates
int32_t InkHUD::DisplayHealth::endMaintenance()
{
return OSThread::disable();
}
#endif
@@ -0,0 +1,53 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
/*
Responsible for maintaining display health, by optimizing the ratio of FAST vs FULL refreshes
- counts number of FULL vs FAST refresh
- suggests whether to use FAST or FULL, when not explicitly specified
- periodically requests update unprovoked, if required for display health
*/
#pragma once
#include "configuration.h"
#include "InkHUD.h"
#include "graphics/niche/Drivers/EInk/EInk.h"
namespace NicheGraphics::InkHUD
{
class DisplayHealth : protected concurrency::OSThread
{
public:
DisplayHealth();
void requestUpdateType(Drivers::EInk::UpdateTypes type);
void forceUpdateType(Drivers::EInk::UpdateTypes type);
Drivers::EInk::UpdateTypes decideUpdateType();
uint8_t fastPerFull = 5; // Ideal number of fast refreshes between full refreshes
float stressMultiplier = 2.0; // How bad for the display are extra fast refreshes beyond fastPerFull?
private:
int32_t runOnce() override;
void beginMaintenance(); // Excessive debt: begin unprovoked refreshing of display, for health
int32_t endMaintenance(); // End unprovoked refreshing: debt paid
Drivers::EInk::UpdateTypes
prioritize(Drivers::EInk::UpdateTypes type1,
Drivers::EInk::UpdateTypes type2); // Determine which of two update types is more important to honor
bool forced = false;
Drivers::EInk::UpdateTypes workingDecision = Drivers::EInk::UpdateTypes::UNSPECIFIED;
float debt = 0.0; // How many full refreshes are due
};
} // namespace NicheGraphics::InkHUD
#endif
@@ -0,0 +1,490 @@
#ifdef MESHTASTIC_INCLUDE_INKHUD
#include "./Events.h"
#include "RTC.h"
#include "buzz.h"
#include "modules/ExternalNotificationModule.h"
#include "modules/TextMessageModule.h"
#include "sleep.h"
#include "./Applet.h"
#include "./SystemApplet.h"
#include "graphics/niche/Utils/FlashData.h"
using namespace NicheGraphics;
InkHUD::Events::Events()
{
// Get convenient references
inkhud = InkHUD::getInstance();
settings = &inkhud->persistence->settings;
}
void InkHUD::Events::begin()
{
// Register our callbacks for the various events
deepSleepObserver.observe(&notifyDeepSleep);
rebootObserver.observe(&notifyReboot);
textMessageObserver.observe(textMessageModule);
#if !MESHTASTIC_EXCLUDE_ADMIN
adminMessageObserver.observe((Observable<AdminModule_ObserverData *> *)adminModule);
#endif
#ifdef ARCH_ESP32
lightSleepObserver.observe(&notifyLightSleep);
#endif
}
void InkHUD::Events::onButtonShort()
{
// Audio feedback (via buzzer)
// Short tone
playChirp();
// Cancel any beeping, buzzing, blinking
// Some button handling suppressed if we are dismissing an external notification (see below)
bool dismissedExt = dismissExternalNotification();
// Check which system applet wants to handle the button press (if any)
SystemApplet *consumer = nullptr;
for (SystemApplet *sa : inkhud->systemApplets) {
if (sa->handleInput) {
consumer = sa;
break;
}
}
// If no system applet is handling input, default behavior instead is to cycle applets
// or open menu if joystick is enabled
if (consumer) {
consumer->onButtonShortPress();
} else if (!dismissedExt) { // Don't change applet if this button press silenced the external notification module
Applet *userConsumer = inkhud->getActiveApplet();
if (userConsumer != nullptr && userConsumer->isInputSubscribed(Applet::BUTTON_SHORT))
userConsumer->onButtonShortPress();
else {
if (!settings->joystick.enabled)
inkhud->nextApplet();
else
inkhud->openMenu();
}
}
}
void InkHUD::Events::onButtonLong()
{
// Audio feedback (via buzzer)
// Slightly longer than playChirp
playBoop();
// Check which system applet wants to handle the button press (if any)
SystemApplet *consumer = nullptr;
for (SystemApplet *sa : inkhud->systemApplets) {
if (sa->handleInput) {
consumer = sa;
break;
}
}
// If no system applet is handling input, default behavior instead is to open the menu
if (consumer)
consumer->onButtonLongPress();
else {
Applet *userConsumer = inkhud->getActiveApplet();
if (userConsumer != nullptr && userConsumer->isInputSubscribed(Applet::BUTTON_LONG))
userConsumer->onButtonLongPress();
else
inkhud->openMenu();
}
}
void InkHUD::Events::onExitShort()
{
if (settings->joystick.enabled) {
// Audio feedback (via buzzer)
// Short tone
playChirp();
// Cancel any beeping, buzzing, blinking
// Some button handling suppressed if we are dismissing an external notification (see below)
bool dismissedExt = dismissExternalNotification();
// Check which system applet wants to handle the button press (if any)
SystemApplet *consumer = nullptr;
for (SystemApplet *sa : inkhud->systemApplets) {
if (sa->handleInput) {
consumer = sa;
break;
}
}
// If no system applet is handling input, default behavior instead is change tiles
if (consumer)
consumer->onExitShort();
else if (!dismissedExt) { // Don't change tile if this button press silenced the external notification module
Applet *userConsumer = inkhud->getActiveApplet();
if (userConsumer != nullptr && userConsumer->isInputSubscribed(Applet::EXIT_SHORT))
userConsumer->onExitShort();
else
inkhud->nextTile();
}
}
}
void InkHUD::Events::onExitLong()
{
if (settings->joystick.enabled) {
// Audio feedback (via buzzer)
// Slightly longer than playChirp
playBoop();
// Check which system applet wants to handle the button press (if any)
SystemApplet *consumer = nullptr;
for (SystemApplet *sa : inkhud->systemApplets) {
if (sa->handleInput) {
consumer = sa;
break;
}
}
if (consumer)
consumer->onExitLong();
else {
Applet *userConsumer = inkhud->getActiveApplet();
if (userConsumer != nullptr && userConsumer->isInputSubscribed(Applet::EXIT_LONG))
userConsumer->onExitLong();
// Nothing uses exit long yet
}
}
}
void InkHUD::Events::onNavUp()
{
if (settings->joystick.enabled) {
// Audio feedback (via buzzer)
// Short tone
playChirp();
// Cancel any beeping, buzzing, blinking
// Some button handling suppressed if we are dismissing an external notification (see below)
bool dismissedExt = dismissExternalNotification();
// Check which system applet wants to handle the button press (if any)
SystemApplet *consumer = nullptr;
for (SystemApplet *sa : inkhud->systemApplets) {
if (sa->handleInput) {
consumer = sa;
break;
}
}
if (consumer)
consumer->onNavUp();
else if (!dismissedExt) {
Applet *userConsumer = inkhud->getActiveApplet();
if (userConsumer != nullptr && userConsumer->isInputSubscribed(Applet::NAV_UP))
userConsumer->onNavUp();
}
}
}
void InkHUD::Events::onNavDown()
{
if (settings->joystick.enabled) {
// Audio feedback (via buzzer)
// Short tone
playChirp();
// Cancel any beeping, buzzing, blinking
// Some button handling suppressed if we are dismissing an external notification (see below)
bool dismissedExt = dismissExternalNotification();
// Check which system applet wants to handle the button press (if any)
SystemApplet *consumer = nullptr;
for (SystemApplet *sa : inkhud->systemApplets) {
if (sa->handleInput) {
consumer = sa;
break;
}
}
if (consumer)
consumer->onNavDown();
else if (!dismissedExt) {
Applet *userConsumer = inkhud->getActiveApplet();
if (userConsumer != nullptr && userConsumer->isInputSubscribed(Applet::NAV_DOWN))
userConsumer->onNavDown();
}
}
}
void InkHUD::Events::onNavLeft()
{
if (settings->joystick.enabled) {
// Audio feedback (via buzzer)
// Short tone
playChirp();
// Cancel any beeping, buzzing, blinking
// Some button handling suppressed if we are dismissing an external notification (see below)
bool dismissedExt = dismissExternalNotification();
// Check which system applet wants to handle the button press (if any)
SystemApplet *consumer = nullptr;
for (SystemApplet *sa : inkhud->systemApplets) {
if (sa->handleInput) {
consumer = sa;
break;
}
}
// If no system applet is handling input, default behavior instead is to cycle applets
if (consumer)
consumer->onNavLeft();
else if (!dismissedExt) { // Don't change applet if this button press silenced the external notification module
Applet *userConsumer = inkhud->getActiveApplet();
if (userConsumer != nullptr && userConsumer->isInputSubscribed(Applet::NAV_LEFT))
userConsumer->onNavLeft();
else
inkhud->prevApplet();
}
}
}
void InkHUD::Events::onNavRight()
{
if (settings->joystick.enabled) {
// Audio feedback (via buzzer)
// Short tone
playChirp();
// Cancel any beeping, buzzing, blinking
// Some button handling suppressed if we are dismissing an external notification (see below)
bool dismissedExt = dismissExternalNotification();
// Check which system applet wants to handle the button press (if any)
SystemApplet *consumer = nullptr;
for (SystemApplet *sa : inkhud->systemApplets) {
if (sa->handleInput) {
consumer = sa;
break;
}
}
// If no system applet is handling input, default behavior instead is to cycle applets
if (consumer)
consumer->onNavRight();
else if (!dismissedExt) { // Don't change applet if this button press silenced the external notification module
Applet *userConsumer = inkhud->getActiveApplet();
if (userConsumer != nullptr && userConsumer->isInputSubscribed(Applet::NAV_RIGHT))
userConsumer->onNavRight();
else
inkhud->nextApplet();
}
}
}
void InkHUD::Events::onFreeText(char c)
{
// Trigger the first system applet that wants to handle the new character
for (SystemApplet *sa : inkhud->systemApplets) {
if (sa->handleFreeText) {
sa->onFreeText(c);
break;
}
}
}
void InkHUD::Events::onFreeTextDone()
{
// Trigger the first system applet that wants to handle it
for (SystemApplet *sa : inkhud->systemApplets) {
if (sa->handleFreeText) {
sa->onFreeTextDone();
break;
}
}
}
void InkHUD::Events::onFreeTextCancel()
{
// Trigger the first system applet that wants to handle it
for (SystemApplet *sa : inkhud->systemApplets) {
if (sa->handleFreeText) {
sa->onFreeTextCancel();
break;
}
}
}
// Callback for deepSleepObserver
// Returns 0 to signal that we agree to sleep now
int InkHUD::Events::beforeDeepSleep(void *unused)
{
// If a previous display update is in progress, wait for it to complete.
inkhud->awaitUpdate();
// Notify all applets that we're shutting down
for (Applet *ua : inkhud->userApplets) {
ua->onDeactivate();
ua->onShutdown();
}
for (SystemApplet *sa : inkhud->systemApplets) {
// Note: no onDeactivate. System applets are always active.
sa->onShutdown();
}
// User has successful executed a safe shutdown
// We don't need to nag at boot anymore
settings->tips.safeShutdownSeen = true;
inkhud->persistence->saveSettings();
inkhud->persistence->saveLatestMessage();
// LogoApplet::onShutdown attempted to heal the display by drawing a "shutting down" screen twice,
// then prepared a final powered-off screen for us, which shows device shortname.
// We're updating to show that one now.
inkhud->forceUpdate(Drivers::EInk::UpdateTypes::FULL, true, false);
delay(1000); // Cooldown, before potentially yanking display power
// InkHUD shutdown complete
// Firmware shutdown continues for several seconds more; flash write still pending
playShutdownMelody();
return 0; // We agree: deep sleep now
}
// Display an intermediate screen while configuration changes are applied
void InkHUD::Events::applyingChanges()
{
// Bring the logo applet forward with a temporary message
for (SystemApplet *sa : inkhud->systemApplets) {
sa->onApplyingChanges();
}
}
// Callback for rebootObserver
// Same as shutdown, without drawing the logoApplet
// Makes sure we don't lose message history / InkHUD config
int InkHUD::Events::beforeReboot(void *unused)
{
// Notify all applets that we're "shutting down"
// They don't need to know that it's really a reboot
for (Applet *a : inkhud->userApplets) {
a->onDeactivate();
a->onShutdown();
}
for (SystemApplet *sa : inkhud->systemApplets) {
// Note: no onDeactivate. System applets are always active.
sa->onReboot();
}
// Save settings to flash, or erase if factory reset in progress
if (!eraseOnReboot) {
inkhud->persistence->saveSettings();
inkhud->persistence->saveLatestMessage();
} else {
NicheGraphics::clearFlashData();
}
// Note: no forceUpdate call here
// We don't have any final screen to draw, although LogoApplet::onReboot did already display a "rebooting" screen
return 0; // No special status to report. Ignored anyway by this Observable
}
// Callback when a new text message is received
// Caches the most recently received message, for use by applets
// Rx does not trigger a save to flash, however the data *will* be saved alongside other during shutdown, etc.
// Note: this is different from devicestate.rx_text_message, which may contain an *outgoing* message
int InkHUD::Events::onReceiveTextMessage(const meshtastic_MeshPacket *packet)
{
// Short circuit: don't store outgoing messages
if (getFrom(packet) == nodeDB->getNodeNum())
return 0;
// Determine whether the message is broadcast or a DM
// Store this info to prevent confusion after a reboot
// Avoids need to compare timestamps, because of situation where "future" messages block newly received, if time not set
inkhud->persistence->latestMessage.wasBroadcast = isBroadcast(packet->to);
// Pick the appropriate variable to store the message in
MessageStore::Message *storedMessage = inkhud->persistence->latestMessage.wasBroadcast
? &inkhud->persistence->latestMessage.broadcast
: &inkhud->persistence->latestMessage.dm;
// Store nodenum of the sender
// Applets can use this to fetch user data from nodedb, if they want
storedMessage->sender = packet->from;
// Store the time (epoch seconds) when message received
storedMessage->timestamp = getValidTime(RTCQuality::RTCQualityDevice, true); // Current RTC time
// Store the channel
// - (potentially) used to determine whether notification shows
// - (potentially) used to determine which applet to focus
storedMessage->channelIndex = packet->channel;
// Store the text
// Need to specify manually how many bytes, because source not null-terminated
storedMessage->text =
std::string(&packet->decoded.payload.bytes[0], &packet->decoded.payload.bytes[packet->decoded.payload.size]);
return 0; // Tell caller to continue notifying other observers. (No reason to abort this event)
}
int InkHUD::Events::onAdminMessage(AdminModule_ObserverData *data)
{
switch (data->request->which_payload_variant) {
// Factory reset
// Two possible messages. One preserves BLE bonds, other wipes. Both should clear InkHUD data.
case meshtastic_AdminMessage_factory_reset_device_tag:
case meshtastic_AdminMessage_factory_reset_config_tag:
eraseOnReboot = true;
*data->result = AdminMessageHandleResult::HANDLED;
break;
default:
break;
}
return 0; // Tell caller to continue notifying other observers. (No reason to abort this event)
}
#ifdef ARCH_ESP32
// Callback for lightSleepObserver
// Make sure the display is not partway through an update when we begin light sleep
// This is because some displays require active input from us to terminate the update process, and protect the panel hardware
int InkHUD::Events::beforeLightSleep(void *unused)
{
inkhud->awaitUpdate();
return 0; // No special status to report. Ignored anyway by this Observable
}
#endif
// Silence all ongoing beeping, blinking, buzzing, coming from the external notification module
// Returns true if an external notification was active, and we dismissed it
// Button handling changes depending on our result
bool InkHUD::Events::dismissExternalNotification()
{
// Abort if not using external notifications
if (!moduleConfig.external_notification.enabled)
return false;
// Abort if nothing to dismiss
if (!externalNotificationModule->nagging())
return false;
// Stop the beep buzz blink
externalNotificationModule->stopNow();
// Inform that we did indeed dismiss an external notification
return true;
}
#endif

Some files were not shown because too many files have changed in this diff Show More