diff --git a/README.md b/README.md index f15df971..e2584a8e 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,14 @@ I2C|SPI,width=,height=[,address=][,HFlip][,VFlip] ``` - VFlip and HFlip are optional can be used to change display orientation +The NVS parameter "metadata_config" sets how metadata is displayed for AirPlay and Bluetooth. Syntax is +``` +[format=][,speed=] +``` +- 'speed' is the scrolling speed in ms (default is 33ms) + +- 'format' can contain free text and any of the 3 keywords %artist%, %album%, %title%. Using that format string, the keywords are replaced by their value to build the string to be displayed. Note that the plain text following a keyword that happens to be empty during playback of a track will be removed. For example, if you have set format=%artist% - %title% and there is no artist in the metadata then only will be displayed not " - <title>". + ### Vcc GPIO The parameter "Vcc_GPIO" is a comma-separated list of GPIO that will be configured as output with their value set to 1 (Vcc) at boot. Be careful because there is no conflict checks being made wrt which GPIO you're changing, so you might damage your board or create a conflict here. diff --git a/components/driver_bt/bt_app_sink.c b/components/driver_bt/bt_app_sink.c index 746080b0..56cd4ca3 100644 --- a/components/driver_bt/bt_app_sink.c +++ b/components/driver_bt/bt_app_sink.c @@ -28,6 +28,7 @@ #include "trace.h" #include "audio_controls.h" #include "sys/lock.h" +#include "display.h" // AVRCP used transaction label #define APP_RC_CT_TL_GET_CAPS (0) @@ -63,16 +64,29 @@ static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param); static void bt_av_hdl_avrc_tg_evt(uint16_t event, void *p_param); static void volume_set_by_local_host(uint8_t volume); -static esp_a2d_audio_state_t s_audio_state = ESP_A2D_AUDIO_STATE_STOPPED; static const char *s_a2d_conn_state_str[] = {"Disconnected", "Connecting", "Connected", "Disconnecting"}; static const char *s_a2d_audio_state_str[] = {"Suspended", "Stopped", "Started"}; static esp_avrc_rn_evt_cap_mask_t s_avrc_peer_rn_cap; + static _lock_t s_volume_lock; static uint8_t s_volume = 0; static bool s_volume_notify; -static esp_avrc_playback_stat_t s_play_status = ESP_AVRC_PLAYBACK_STOPPED; -static uint8_t s_remote_bda[6]; +static bool s_playing = false; +static enum { AUDIO_IDLE, AUDIO_CONNECTED, AUDIO_ACTIVATED } s_audio = AUDIO_IDLE; + +static int s_sample_rate; static int tl; +static bt_cmd_vcb_t cmd_handler_chain; + +#define METADATA_LEN 128 + +static EXT_RAM_ATTR struct { + char artist[METADATA_LEN + 1]; + char album[METADATA_LEN + 1]; + char title[METADATA_LEN + 1]; + int duration; + bool updated; +} s_metadata; static void bt_volume_up(void) { // volume UP/DOWN buttons are not supported by iPhone/Android @@ -88,9 +102,8 @@ static void bt_volume_down(void) { } static void bt_toggle(void) { - if (s_play_status != ESP_AVRC_PLAYBACK_PLAYING) esp_avrc_ct_send_passthrough_cmd(tl++, ESP_AVRC_PT_CMD_PLAY, ESP_AVRC_PT_CMD_STATE_PRESSED); - else esp_avrc_ct_send_passthrough_cmd(tl++ & 0x0f, ESP_AVRC_PT_CMD_STOP, ESP_AVRC_PT_CMD_STATE_PRESSED); - //s_audio_state = ESP_A2D_AUDIO_STATE_STOPPED; + if (s_playing) esp_avrc_ct_send_passthrough_cmd(tl++ & 0x0f, ESP_AVRC_PT_CMD_STOP, ESP_AVRC_PT_CMD_STATE_PRESSED); + else esp_avrc_ct_send_passthrough_cmd(tl++, ESP_AVRC_PT_CMD_PLAY, ESP_AVRC_PT_CMD_STATE_PRESSED); } static void bt_play(void) { @@ -121,20 +134,70 @@ const static actrls_t controls = { bt_prev, bt_next, // prev, next }; -/* taking/giving audio system's control */ -void bt_master(bool on) { - if (on) actrls_set(controls, NULL); - else actrls_unset(); -} - /* disconnection */ void bt_disconnect(void) { - esp_avrc_ct_send_passthrough_cmd(tl++ & 0x0f, ESP_AVRC_PT_CMD_STOP, ESP_AVRC_PT_CMD_STATE_PRESSED); - esp_a2d_sink_disconnect(s_remote_bda); + displayer_control(DISPLAYER_SHUTDOWN); + if (s_playing) esp_avrc_ct_send_passthrough_cmd(tl++ & 0x0f, ESP_AVRC_PT_CMD_STOP, ESP_AVRC_PT_CMD_STATE_PRESSED); actrls_unset(); ESP_LOGI(BT_AV_TAG, "forced disconnection"); } +/* update metadata if any */ +void update_metadata(bool force) { + if ((s_metadata.updated || force) && s_audio == AUDIO_ACTIVATED) { + (*bt_app_a2d_cmd_cb)(BT_SINK_PROGRESS, -1, s_metadata.duration); + (*bt_app_a2d_cmd_cb)(BT_SINK_METADATA, s_metadata.artist, s_metadata.album, s_metadata.title); + s_metadata.updated = false; + } else s_metadata.updated = force; +} + +/* command handler */ +static bool cmd_handler(bt_sink_cmd_t cmd, ...) { + va_list args; + + va_start(args, cmd); + + // handle audio event and stop if forbidden + if (!cmd_handler_chain(cmd, args)) { + va_end(args); + return false; + } + + // now handle events for display + switch(cmd) { + case BT_SINK_AUDIO_STARTED: + displayer_control(DISPLAYER_ACTIVATE, "BLUETOOTH"); + break; + case BT_SINK_AUDIO_STOPPED: + displayer_control(DISPLAYER_SUSPEND); + break; + case BT_SINK_PLAY: + displayer_control(DISPLAYER_TIMER_RUN); + break; + case BT_SINK_STOP: + // not sure of difference between pause and stop for displayer + case BT_SINK_PAUSE: + displayer_control(DISPLAYER_TIMER_PAUSE); + break; + case BT_SINK_METADATA: { + char *artist = va_arg(args, char*), *album = va_arg(args, char*), *title = va_arg(args, char*); + displayer_metadata(artist, album, title); + break; + } + case BT_SINK_PROGRESS: { + int elapsed = va_arg(args, int), duration = va_arg(args, int); + displayer_timer(DISPLAYER_ELAPSED, elapsed, duration); + break; + } + default: + break; + } + + va_end(args); + + return true; +} + /* callback for A2DP sink */ void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) { @@ -210,26 +273,40 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param) if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) { esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); (*bt_app_a2d_cmd_cb)(BT_SINK_DISCONNECTED); - actrls_unset(); } else if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_CONNECTED){ - memcpy(s_remote_bda, bda, 6); esp_bt_gap_set_scan_mode(ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE); - if (!(*bt_app_a2d_cmd_cb)(BT_SINK_CONNECTED)){ - esp_avrc_ct_send_passthrough_cmd(tl++ & 0x0f, ESP_AVRC_PT_CMD_STOP, ESP_AVRC_PT_CMD_STATE_PRESSED); - esp_a2d_sink_disconnect(s_remote_bda); - } + (*bt_app_a2d_cmd_cb)(BT_SINK_CONNECTED); } break; } case ESP_A2D_AUDIO_STATE_EVT: { a2d = (esp_a2d_cb_param_t *)(p_param); ESP_LOGI(BT_AV_TAG, "A2DP audio state: %s", s_a2d_audio_state_str[a2d->audio_stat.state]); - s_audio_state = a2d->audio_stat.state; + if (ESP_A2D_AUDIO_STATE_STARTED == a2d->audio_stat.state) { - (*bt_app_a2d_cmd_cb)(BT_SINK_PLAY); + s_audio = AUDIO_CONNECTED; + + // verify that we can take control + if ((*bt_app_a2d_cmd_cb)(BT_SINK_AUDIO_STARTED, s_sample_rate)) { + // resynchronize events as¨PLAY might be sent before STARTED ... + s_audio = AUDIO_ACTIVATED; + + // send PLAY there, in case it was sent before AUDIO_STATE + if (s_playing) (*bt_app_a2d_cmd_cb)(BT_SINK_PLAY); + + // force metadata update + update_metadata(true); + + actrls_set(controls, NULL); + } else if (s_playing) { + // if decoder is busy but BT is playing, stop it (would be better to not ACK this command, but don't know how) + esp_avrc_ct_send_passthrough_cmd(tl++ & 0x0f, ESP_AVRC_PT_CMD_STOP, ESP_AVRC_PT_CMD_STATE_PRESSED); + } } else if (ESP_A2D_AUDIO_STATE_STOPPED == a2d->audio_stat.state || ESP_A2D_AUDIO_STATE_REMOTE_SUSPEND == a2d->audio_stat.state) { - (*bt_app_a2d_cmd_cb)(BT_SINK_STOP); + (*bt_app_a2d_cmd_cb)(BT_SINK_AUDIO_STOPPED); + s_audio = AUDIO_IDLE; + actrls_unset(); } break; } @@ -238,23 +315,23 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param) ESP_LOGI(BT_AV_TAG, "A2DP audio stream configuration, codec type %d", a2d->audio_cfg.mcc.type); // for now only SBC stream is supported if (a2d->audio_cfg.mcc.type == ESP_A2D_MCT_SBC) { - int sample_rate = 16000; + s_sample_rate = 16000; char oct0 = a2d->audio_cfg.mcc.cie.sbc[0]; if (oct0 & (0x01 << 6)) { - sample_rate = 32000; + s_sample_rate = 32000; } else if (oct0 & (0x01 << 5)) { - sample_rate = 44100; + s_sample_rate = 44100; } else if (oct0 & (0x01 << 4)) { - sample_rate = 48000; + s_sample_rate = 48000; } - (*bt_app_a2d_cmd_cb)(BT_SINK_RATE, sample_rate); + (*bt_app_a2d_cmd_cb)(BT_SINK_RATE, s_sample_rate); ESP_LOGI(BT_AV_TAG, "Configure audio player %x-%x-%x-%x", a2d->audio_cfg.mcc.cie.sbc[0], a2d->audio_cfg.mcc.cie.sbc[1], a2d->audio_cfg.mcc.cie.sbc[2], a2d->audio_cfg.mcc.cie.sbc[3]); - ESP_LOGI(BT_AV_TAG, "Audio player configured, sample rate=%d", sample_rate); + ESP_LOGI(BT_AV_TAG, "Audio player configured, sample rate=%d", s_sample_rate); } break; } @@ -267,7 +344,7 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param) static void bt_av_new_track(void) { // request metadata - uint8_t attr_mask = ESP_AVRC_MD_ATTR_TITLE | ESP_AVRC_MD_ATTR_ARTIST | ESP_AVRC_MD_ATTR_ALBUM | ESP_AVRC_MD_ATTR_GENRE; + uint8_t attr_mask = ESP_AVRC_MD_ATTR_TITLE | ESP_AVRC_MD_ATTR_ARTIST | ESP_AVRC_MD_ATTR_ALBUM | ESP_AVRC_MD_ATTR_PLAYING_TIME; esp_avrc_ct_send_metadata_cmd(APP_RC_CT_TL_GET_META_DATA, attr_mask); // register notification if peer support the event_id @@ -287,7 +364,7 @@ static void bt_av_playback_changed(void) static void bt_av_play_pos_changed(void) { - if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_peer_rn_cap, + if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_peer_rn_cap, ESP_AVRC_RN_PLAY_POS_CHANGED)) { esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_PLAY_POS_CHANGE, ESP_AVRC_RN_PLAY_POS_CHANGED, 10); } @@ -297,15 +374,31 @@ void bt_av_notify_evt_handler(uint8_t event_id, esp_avrc_rn_param_t *event_param { switch (event_id) { case ESP_AVRC_RN_TRACK_CHANGE: + ESP_LOGI(BT_AV_TAG, "Track changed"); bt_av_new_track(); + (*bt_app_a2d_cmd_cb)(BT_SINK_PROGRESS, 0, 0); break; case ESP_AVRC_RN_PLAY_STATUS_CHANGE: ESP_LOGI(BT_AV_TAG, "Playback status changed: 0x%x", event_parameter->playback); - s_play_status = event_parameter->playback; + // re-synchronize events + s_playing = (event_parameter->playback == ESP_AVRC_PLAYBACK_PLAYING); + if (event_parameter->playback == ESP_AVRC_PLAYBACK_PLAYING && s_audio != AUDIO_IDLE) { + // if decoder is busy then stop (would be better to not ACK this command, but don't know how) + if (s_audio == AUDIO_CONNECTED || !(*bt_app_a2d_cmd_cb)(BT_SINK_PLAY)) { + esp_avrc_ct_send_passthrough_cmd(tl++ & 0x0f, ESP_AVRC_PT_CMD_STOP, ESP_AVRC_PT_CMD_STATE_PRESSED); + } else { + update_metadata(false); + } + } else if (event_parameter->playback == ESP_AVRC_PLAYBACK_PAUSED) (*bt_app_a2d_cmd_cb)(BT_SINK_PAUSE); + else if (event_parameter->playback == ESP_AVRC_PLAYBACK_STOPPED) { + (*bt_app_a2d_cmd_cb)(BT_SINK_PROGRESS, 0, -1); + (*bt_app_a2d_cmd_cb)(BT_SINK_STOP); + } bt_av_playback_changed(); break; case ESP_AVRC_RN_PLAY_POS_CHANGED: ESP_LOGI(BT_AV_TAG, "Play position changed: %d-ms", event_parameter->play_pos); + (*bt_app_a2d_cmd_cb)(BT_SINK_PROGRESS, event_parameter->play_pos, -1); bt_av_play_pos_changed(); break; } @@ -336,6 +429,13 @@ static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param) } case ESP_AVRC_CT_METADATA_RSP_EVT: { ESP_LOGI(BT_RC_CT_TAG, "AVRC metadata rsp: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text); + + if (rc->meta_rsp.attr_id == ESP_AVRC_MD_ATTR_PLAYING_TIME) s_metadata.duration = atoi((char*) rc->meta_rsp.attr_text); + else if (rc->meta_rsp.attr_id == ESP_AVRC_MD_ATTR_TITLE) strncpy(s_metadata.title, (char*) rc->meta_rsp.attr_text, METADATA_LEN); + else if (rc->meta_rsp.attr_id == ESP_AVRC_MD_ATTR_ARTIST) strncpy(s_metadata.artist, (char*) rc->meta_rsp.attr_text, METADATA_LEN); + else if (rc->meta_rsp.attr_id == ESP_AVRC_MD_ATTR_ALBUM) strncpy(s_metadata.album, (char*) rc->meta_rsp.attr_text, METADATA_LEN); + update_metadata(true); + free(rc->meta_rsp.attr_text); break; } @@ -427,12 +527,13 @@ static void bt_av_hdl_avrc_tg_evt(uint16_t event, void *p_param) } } -void bt_sink_init(bt_cmd_cb_t cmd_cb, bt_data_cb_t data_cb) +void bt_sink_init(bt_cmd_vcb_t cmd_cb, bt_data_cb_t data_cb) { esp_err_t err; - bt_app_a2d_cmd_cb = cmd_cb; - bt_app_a2d_data_cb = data_cb; + bt_app_a2d_cmd_cb = cmd_handler; + cmd_handler_chain = cmd_cb; + bt_app_a2d_data_cb = data_cb; ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE)); diff --git a/components/driver_bt/bt_app_sink.h b/components/driver_bt/bt_app_sink.h index 33e77195..6fc7b962 100644 --- a/components/driver_bt/bt_app_sink.h +++ b/components/driver_bt/bt_app_sink.h @@ -11,27 +11,22 @@ #include <stdint.h> -typedef enum { BT_SINK_CONNECTED, BT_SINK_DISCONNECTED, BT_SINK_PLAY, BT_SINK_STOP, BT_SINK_PAUSE, - BT_SINK_RATE, BT_SINK_VOLUME, } bt_sink_cmd_t; +typedef enum { BT_SINK_CONNECTED, BT_SINK_DISCONNECTED, BT_SINK_AUDIO_STARTED, BT_SINK_AUDIO_STOPPED, BT_SINK_PLAY, BT_SINK_STOP, BT_SINK_PAUSE, + BT_SINK_RATE, BT_SINK_VOLUME, BT_SINK_METADATA, BT_SINK_PROGRESS } bt_sink_cmd_t; -typedef bool (*bt_cmd_cb_t)(bt_sink_cmd_t cmd, ...); +typedef bool (*bt_cmd_vcb_t)(bt_sink_cmd_t cmd, va_list args); typedef void (*bt_data_cb_t)(const uint8_t *data, uint32_t len); /** * @brief init sink mode (need to be provided) */ -void bt_sink_init(bt_cmd_cb_t cmd_cb, bt_data_cb_t data_cb); +void bt_sink_init(bt_cmd_vcb_t cmd_cb, bt_data_cb_t data_cb); /** * @brief deinit sink mode (need to be provided) */ void bt_sink_deinit(void); -/** - * @brief * @brief do what's necessary when becoming in charge - */ -void bt_master(bool on); - /** * @brief force disconnection */ diff --git a/components/raop/raop.c b/components/raop/raop.c index 91144dd6..1f06810f 100644 --- a/components/raop/raop.c +++ b/components/raop/raop.c @@ -532,7 +532,7 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock) short unsigned tport = 0, cport = 0; // we are about to stream, do something if needed - success = ctx->cmd_cb(RAOP_SETUP, NULL); + success = ctx->cmd_cb(RAOP_SETUP); if ((p = strcasestr(buf, "timing_port")) != NULL) sscanf(p, "%*[^=]=%hu", &tport); if ((p = strcasestr(buf, "control_port")) != NULL) sscanf(p, "%*[^=]=%hu", &cport); @@ -571,7 +571,7 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock) if (ctx->rtp) rtp_record(ctx->rtp, seqno, rtptime); - success = ctx->cmd_cb(RAOP_STREAM, NULL); + success = ctx->cmd_cb(RAOP_STREAM); } else if (!strcmp(method, "FLUSH")) { unsigned short seqno = 0; @@ -584,7 +584,7 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock) // only send FLUSH if useful (discards frames above buffer head and top) if (ctx->rtp && rtp_flush(ctx->rtp, seqno, rtptime)) - success = ctx->cmd_cb(RAOP_FLUSH, NULL); + success = ctx->cmd_cb(RAOP_FLUSH); } else if (!strcmp(method, "TEARDOWN")) { @@ -615,7 +615,7 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock) NFREE(ctx->rtsp.aesiv); NFREE(ctx->rtsp.fmtp); - success = ctx->cmd_cb(RAOP_STOP, NULL); + success = ctx->cmd_cb(RAOP_STOP); } else if (!strcmp(method, "SET_PARAMETER")) { char *p; @@ -626,9 +626,18 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock) sscanf(p, "%*[^:]:%f", &volume); LOG_INFO("[%p]: SET PARAMETER volume %f", ctx, volume); volume = (volume == -144.0) ? 0 : (1 + volume / 30); - success = ctx->cmd_cb(RAOP_VOLUME, &volume); + success = ctx->cmd_cb(RAOP_VOLUME, volume); + } else if (body && (p = strcasestr(body, "progress")) != NULL) { + int start, current, stop = 0; + + sscanf(p, "%*[^:]:%u/%u/%u", &start, ¤t, &stop); + current = (current - start) / 44100; + if (stop) stop = (stop - start) / 44100; + else stop = -1; + LOG_INFO("[%p]: SET PARAMETER progress %u/%u %s", ctx, current, stop, p); + success = ctx->cmd_cb(RAOP_PROGRESS, current, stop); } -/* + if (body && ((p = kd_lookup(headers, "Content-Type")) != NULL) && !strcasecmp(p, "application/x-dmap-tagged")) { struct metadata_s metadata; dmap_settings settings = { @@ -636,23 +645,28 @@ static bool handle_rtsp(raop_ctx_t *ctx, int sock) NULL }; + LOG_INFO("[%p]: received metadata"); settings.ctx = &metadata; memset(&metadata, 0, sizeof(struct metadata_s)); if (!dmap_parse(&settings, body, len)) { LOG_INFO("[%p]: received metadata\n\tartist: %s\n\talbum: %s\n\ttitle: %s", ctx, metadata.artist, metadata.album, metadata.title); + success = ctx->cmd_cb(RAOP_METADATA, metadata.artist, metadata.album, metadata.title); free_metadata(&metadata); } } -*/ } // don't need to free "buf" because kd_lookup return a pointer, not a strdup kd_add(resp, "Audio-Jack-Status", "connected; type=analog"); kd_add(resp, "CSeq", kd_lookup(headers, "CSeq")); - if (success) buf = http_send(sock, "RTSP/1.0 200 OK", resp); - else buf = http_send(sock, "RTSP/1.0 500 ERROR", NULL); + if (success) { + buf = http_send(sock, "RTSP/1.0 200 OK", resp); + } else { + buf = http_send(sock, "RTSP/1.0 503 ERROR", NULL); + closesocket(sock); + } if (strcmp(method, "OPTIONS")) { LOG_INFO("[%p]: responding:\n%s", ctx, buf ? buf : "<void>"); diff --git a/components/raop/raop_sink.c b/components/raop/raop_sink.c index 684fc991..2743b275 100644 --- a/components/raop/raop_sink.c +++ b/components/raop/raop_sink.c @@ -14,9 +14,10 @@ #include "config.h" #include "raop.h" #include "audio_controls.h" +#include "display.h" +#include "accessors.h" #include "log_util.h" - #include "trace.h" #ifndef CONFIG_AIRPLAY_NAME @@ -28,6 +29,7 @@ log_level util_loglevel; static log_level *loglevel = &raop_loglevel; static struct raop_ctx_s *raop; +static raop_cmd_vcb_t cmd_handler_chain; static void raop_volume_up(void) { raop_cmd(raop, RAOP_VOLUME_UP, NULL); @@ -78,11 +80,52 @@ const static actrls_t controls = { }; /**************************************************************************************** - * Airplay taking/giving audio system's control + * Command handler */ -void raop_master(bool on) { - if (on) actrls_set(controls, NULL); - else actrls_unset(); +static bool cmd_handler(raop_event_t event, ...) { + va_list args; + + va_start(args, event); + + // handle audio event and stop if forbidden + if (!cmd_handler_chain(event, args)) { + va_end(args); + return false; + } + + // now handle events for display + switch(event) { + case RAOP_SETUP: + actrls_set(controls, NULL); + displayer_control(DISPLAYER_ACTIVATE, "AIRPLAY"); + break; + case RAOP_PLAY: + displayer_control(DISPLAYER_TIMER_RUN); + break; + case RAOP_FLUSH: + displayer_control(DISPLAYER_TIMER_PAUSE); + break; + case RAOP_STOP: + actrls_unset(); + displayer_control(DISPLAYER_SUSPEND); + break; + case RAOP_METADATA: { + char *artist = va_arg(args, char*), *album = va_arg(args, char*), *title = va_arg(args, char*); + displayer_metadata(artist, album, title); + break; + } + case RAOP_PROGRESS: { + int elapsed = va_arg(args, int), duration = va_arg(args, int); + displayer_timer(DISPLAYER_ELAPSED, elapsed, duration); + break; + } + default: + break; + } + + va_end(args); + + return true; } /**************************************************************************************** @@ -96,7 +139,7 @@ void raop_sink_deinit(void) { /**************************************************************************************** * Airplay sink initialization */ -void raop_sink_init(raop_cmd_cb_t cmd_cb, raop_data_cb_t data_cb) { +void raop_sink_init(raop_cmd_vcb_t cmd_cb, raop_data_cb_t data_cb) { const char *hostname; char sink_name[64-6] = CONFIG_AIRPLAY_NAME; tcpip_adapter_ip_info_t ipInfo; @@ -123,7 +166,8 @@ void raop_sink_init(raop_cmd_cb_t cmd_cb, raop_data_cb_t data_cb) { // create RAOP instance, latency is set by controller uint8_t mac[6]; esp_read_mac(mac, ESP_MAC_WIFI_STA); - raop = raop_create(host, sink_name, mac, 0, cmd_cb, data_cb); + cmd_handler_chain = cmd_cb; + raop = raop_create(host, sink_name, mac, 0, cmd_handler, data_cb); } /**************************************************************************************** @@ -131,6 +175,7 @@ void raop_sink_init(raop_cmd_cb_t cmd_cb, raop_data_cb_t data_cb) { */ void raop_disconnect(void) { LOG_INFO("forced disconnection"); + displayer_control(DISPLAYER_SHUTDOWN); raop_cmd(raop, RAOP_STOP, NULL); actrls_unset(); } diff --git a/components/raop/raop_sink.h b/components/raop/raop_sink.h index 66d9bb84..a3cb87d4 100644 --- a/components/raop/raop_sink.h +++ b/components/raop/raop_sink.h @@ -10,31 +10,28 @@ #define RAOP_SINK_H #include <stdint.h> +#include <stdarg.h> #define RAOP_SAMPLE_RATE 44100 -typedef enum { RAOP_SETUP, RAOP_STREAM, RAOP_PLAY, RAOP_FLUSH, RAOP_PAUSE, RAOP_STOP, +typedef enum { RAOP_SETUP, RAOP_STREAM, RAOP_PLAY, RAOP_FLUSH, RAOP_METADATA, RAOP_PROGRESS, RAOP_PAUSE, RAOP_STOP, RAOP_VOLUME, RAOP_TIMING, RAOP_PREV, RAOP_NEXT, RAOP_REW, RAOP_FWD, RAOP_VOLUME_UP, RAOP_VOLUME_DOWN, RAOP_RESUME, RAOP_TOGGLE } raop_event_t ; -typedef bool (*raop_cmd_cb_t)(raop_event_t event, void *param); +typedef bool (*raop_cmd_cb_t)(raop_event_t event, ...); +typedef bool (*raop_cmd_vcb_t)(raop_event_t event, va_list args); typedef void (*raop_data_cb_t)(const u8_t *data, size_t len, u32_t playtime); /** * @brief init sink mode (need to be provided) */ -void raop_sink_init(raop_cmd_cb_t cmd_cb, raop_data_cb_t data_cb); +void raop_sink_init(raop_cmd_vcb_t cmd_cb, raop_data_cb_t data_cb); /** * @brief deinit sink mode (need to be provided) */ void raop_sink_deinit(void); -/** - * @brief do what's necessary when becoming in charge - */ -void raop_master(bool on); - /** * @brief force disconnection */ diff --git a/components/raop/rtp.c b/components/raop/rtp.c index 7cc57e1a..fbb9e2de 100644 --- a/components/raop/rtp.c +++ b/components/raop/rtp.c @@ -429,7 +429,7 @@ static void buffer_put_packet(rtp_t *ctx, seq_t seqno, unsigned rtptime, bool fi ctx->playing = true; ctx->resent_req = ctx->resent_rec = ctx->silent_frames = ctx->discarded = 0; playtime = ctx->synchro.time + (((s32_t)(rtptime - ctx->synchro.rtp)) * 1000) / RAOP_SAMPLE_RATE; - ctx->cmd_cb(RAOP_PLAY, &playtime); + ctx->cmd_cb(RAOP_PLAY, playtime); } else { pthread_mutex_unlock(&ctx->ab_mutex); return; @@ -671,7 +671,7 @@ static void *rtp_thread_func(void *arg) { count = 3; } - if ((ctx->synchro.status & RTP_SYNC) && (ctx->synchro.status & NTP_SYNC)) ctx->cmd_cb(RAOP_TIMING, NULL); + if ((ctx->synchro.status & RTP_SYNC) && (ctx->synchro.status & NTP_SYNC)) ctx->cmd_cb(RAOP_TIMING); break; } diff --git a/components/raop/util.h b/components/raop/util.h index 23eadba5..40b57704 100644 --- a/components/raop/util.h +++ b/components/raop/util.h @@ -47,11 +47,8 @@ typedef struct metadata_s { u8_t channels; } metadata_t; -/* void free_metadata(struct metadata_s *metadata); void dup_metadata(struct metadata_s *dst, struct metadata_s *src); -*/ - u32_t gettime_ms(void); #ifdef WIN32 diff --git a/components/services/accessors.c b/components/services/accessors.c index 52876d2f..e2e4607b 100644 --- a/components/services/accessors.c +++ b/components/services/accessors.c @@ -16,6 +16,8 @@ static const char *TAG = "services"; +#define min(a,b) (((a) < (b)) ? (a) : (b)) + /**************************************************************************************** * */ diff --git a/components/services/accessors.h b/components/services/accessors.h index 7ad53f29..615a8c52 100644 --- a/components/services/accessors.h +++ b/components/services/accessors.h @@ -12,4 +12,4 @@ #include "driver/i2c.h" esp_err_t config_i2c_set(const i2c_config_t * config, int port); -const i2c_config_t * config_i2c_get(int * i2c_port); \ No newline at end of file +const i2c_config_t * config_i2c_get(int * i2c_port); diff --git a/components/services/component.mk b/components/services/component.mk index 5bdf84c6..501d3b4b 100644 --- a/components/services/component.mk +++ b/components/services/component.mk @@ -9,5 +9,4 @@ COMPONENT_SRCDIRS := . tarablessd1306 tarablessd1306/fonts tarablessd1306/ifaces COMPONENT_ADD_INCLUDEDIRS := . -COMPONENT_ADD_INCLUDEDIRS := . -COMPONENT_ADD_INCLUDEDIRS += ./tarablessd1306 +COMPONENT_ADD_INCLUDEDIRS += ./tarablessd1306 \ No newline at end of file diff --git a/components/services/display.c b/components/services/display.c index da3c472c..6b6ab350 100644 --- a/components/services/display.c +++ b/components/services/display.c @@ -23,6 +23,7 @@ #include <arpa/inet.h> #include "esp_log.h" #include "config.h" +#include "tools.h" #include "display.h" // here we should include all possible drivers @@ -32,10 +33,35 @@ struct display_s *display; static const char *TAG = "display"; +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#define max(a,b) (((a) > (b)) ? (a) : (b)) + +#define DISPLAYER_STACK_SIZE 2048 +#define SCROLLABLE_SIZE 384 +#define HEADER_SIZE 64 +#define DEFAULT_SLEEP 3600 + +static EXT_RAM_ATTR struct { + TaskHandle_t task; + SemaphoreHandle_t mutex; + int pause, speed, by; + enum { DISPLAYER_DOWN, DISPLAYER_IDLE, DISPLAYER_ACTIVE } state; + char header[HEADER_SIZE + 1]; + char string[SCROLLABLE_SIZE + 1]; + int offset, boundary; + char *metadata_config; + bool timer, refresh; + uint32_t elapsed, duration; + TickType_t tick; +} displayer; + +static void displayer_task(void *args); + /**************************************************************************************** * */ void display_init(char *welcome) { + bool init = false; char *item = config_alloc_get(NVS_TYPE_STR, "display_config"); if (item && *item) { @@ -43,6 +69,7 @@ void display_init(char *welcome) { if (!drivername || (drivername && strcasestr(drivername,"SSD1306"))) { display = &SSD1306_display; if (display->init(item, welcome)) { + init = true; ESP_LOGI(TAG, "Display initialization successful"); } else { ESP_LOGE(TAG, "Display initialization failed"); @@ -54,5 +81,230 @@ void display_init(char *welcome) { ESP_LOGW(TAG, "no display"); } + if (init) { + static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__ ((aligned (4))); + static EXT_RAM_ATTR StackType_t xStack[DISPLAYER_STACK_SIZE] __attribute__ ((aligned (4))); + + // start the task that will handle scrolling & counting + displayer.mutex = xSemaphoreCreateMutex(); + displayer.by = 2; + displayer.pause = 3600; + displayer.speed = 33; + displayer.task = xTaskCreateStatic( (TaskFunction_t) displayer_task, "displayer_thread", DISPLAYER_STACK_SIZE, NULL, ESP_TASK_PRIO_MIN + 1, xStack, &xTaskBuffer); + + // set lines for "fixed" text mode + display->set_font(1, DISPLAY_FONT_LINE_1, -3); + display->set_font(2, DISPLAY_FONT_LINE_2, -3); + + displayer.metadata_config = config_alloc_get(NVS_TYPE_STR, "metadata_config"); + } + if (item) free(item); } + +/**************************************************************************************** + * This is not really thread-safe as displayer_task might be in the middle of line drawing + * but it won't crash (I think) and making it thread-safe would be complicated for a + * feature which is secondary (the LMS version of scrolling is thread-safe) + */ +static void displayer_task(void *args) { + int scroll_sleep = 0, timer_sleep; + + while (1) { + // suspend ourselves if nothing to do + if (displayer.state < DISPLAYER_ACTIVE) { + if (displayer.state == DISPLAYER_IDLE) display->line(2, 0, DISPLAY_CLEAR | DISPLAY_UPDATE, displayer.string); + vTaskSuspend(NULL); + scroll_sleep = 0; + display->clear(); + display->line(1, DISPLAY_LEFT, DISPLAY_UPDATE, displayer.header); + } else if (displayer.refresh) { + // little trick when switching master while in IDLE and missing it + display->line(1, DISPLAY_LEFT, DISPLAY_CLEAR | DISPLAY_UPDATE, displayer.header); + displayer.refresh = false; + } + + // we have been waken up before our requested time + if (scroll_sleep <= 10) { + // something to scroll (or we'll wake-up every pause ms ... no big deal) + if (*displayer.string && displayer.state == DISPLAYER_ACTIVE) { + display->line(2, -displayer.offset, DISPLAY_CLEAR | DISPLAY_UPDATE, displayer.string); + xSemaphoreTake(displayer.mutex, portMAX_DELAY); + scroll_sleep = displayer.offset ? displayer.speed : displayer.pause; + displayer.offset = displayer.offset >= displayer.boundary ? 0 : (displayer.offset + min(displayer.by, displayer.boundary - displayer.offset)); + xSemaphoreGive(displayer.mutex); + } else { + scroll_sleep = DEFAULT_SLEEP; + } + } + + // handler elapsed track time + if (displayer.timer && displayer.state == DISPLAYER_ACTIVE) { + char counter[12]; + TickType_t tick = xTaskGetTickCount(); + uint32_t elapsed = (tick - displayer.tick) * portTICK_PERIOD_MS; + + if (elapsed >= 1000) { + xSemaphoreTake(displayer.mutex, portMAX_DELAY); + displayer.tick = tick; + displayer.elapsed += elapsed / 1000; + xSemaphoreGive(displayer.mutex); + if (displayer.elapsed < 3600) sprintf(counter, "%2u:%02u", displayer.elapsed / 60, displayer.elapsed % 60); + else sprintf(counter, "%2u:%2u:%02u", displayer.elapsed / 3600, (displayer.elapsed % 3600) / 60, displayer.elapsed % 60); + display->line(1, DISPLAY_RIGHT, (DISPLAY_CLEAR | DISPLAY_ONLY_EOL) | DISPLAY_UPDATE, counter); + timer_sleep = 1000; + } else timer_sleep = max(1000 - elapsed, 0); + } else timer_sleep = DEFAULT_SLEEP; + + // then sleep the min amount of time + int sleep = min(scroll_sleep, timer_sleep); + ESP_LOGD(TAG, "timers s:%d t:%d", scroll_sleep, timer_sleep); + scroll_sleep -= sleep; + vTaskDelay(sleep / portTICK_PERIOD_MS); + } +} + +/**************************************************************************************** + * + */ +void displayer_metadata(char *artist, char *album, char *title) { + char *string = displayer.string, *p; + int len = SCROLLABLE_SIZE; + + if (!displayer.metadata_config) { + strncpy(displayer.string, title ? title : "", SCROLLABLE_SIZE); + return; + } + + xSemaphoreTake(displayer.mutex, portMAX_DELAY); + + // format metadata parameters and write them directly + if ((p = strcasestr(displayer.metadata_config, "format")) != NULL) { + char token[16], *q; + int space = len; + bool skip = false; + + displayer.string[0] = '\0'; + p = strchr(displayer.metadata_config, '='); + + while (p++) { + // find token and copy what's after when reaching last one + if (sscanf(p, "%*[^%%]%%%[^%]%%", token) < 0) { + q = strchr(p, ','); + strncat(string, p, q ? min(q - p, space) : space); + break; + } + + // copy what's before token (be safe) + if ((q = strchr(p, '%')) == NULL) break; + + // skip whatever is after a token if this token is empty + if (!skip) { + strncat(string, p, min(q - p, space)); + space = len - strlen(string); + } + + // then copy token's content + if (!strncasecmp(q + 1, "artist", 6) && artist) strncat(string, p = artist, space); + else if (!strncasecmp(q + 1, "album", 5) && album) strncat(string, p = album, space); + else if (!strncasecmp(q + 1, "title", 5) && title) strncat(string, p = title, space); + space = len - strlen(string); + + // flag to skip the data following an empty field + if (*p) skip = false; + else skip = true; + + // advance to next separator + p = strchr(q + 1, '%'); + } + } else { + string = strdup(title ? title : ""); + } + + // get optional scroll speed + if ((p = strcasestr(displayer.metadata_config, "speed")) != NULL) sscanf(p, "%*[^=]=%d", &displayer.speed); + + displayer.offset = 0; + utf8_decode(displayer.string); + ESP_LOGI(TAG, "playing %s", displayer.string); + displayer.boundary = display->stretch(2, displayer.string, SCROLLABLE_SIZE); + + xSemaphoreGive(displayer.mutex); +} + + +/**************************************************************************************** + * + */ +void displayer_scroll(char *string, int speed) { + xSemaphoreTake(displayer.mutex, portMAX_DELAY); + + if (speed) displayer.speed = speed; + displayer.offset = 0; + strncpy(displayer.string, string, SCROLLABLE_SIZE); + displayer.string[SCROLLABLE_SIZE] = '\0'; + displayer.boundary = display->stretch(2, displayer.string, SCROLLABLE_SIZE); + + xSemaphoreGive(displayer.mutex); +} + +/**************************************************************************************** + * + */ +void displayer_timer(enum displayer_time_e mode, int elapsed, int duration) { + xSemaphoreTake(displayer.mutex, portMAX_DELAY); + + if (elapsed >= 0) displayer.elapsed = elapsed; + if (duration >= 0) displayer.duration = duration; + if (displayer.timer) displayer.tick = xTaskGetTickCount(); + + xSemaphoreGive(displayer.mutex); +} + +/**************************************************************************************** + * See above comment + */ +void displayer_control(enum displayer_cmd_e cmd, ...) { + va_list args; + + va_start(args, cmd); + xSemaphoreTake(displayer.mutex, portMAX_DELAY); + + switch(cmd) { + case DISPLAYER_ACTIVATE: { + char *header = va_arg(args, char*); + strncpy(displayer.header, header, HEADER_SIZE); + displayer.header[HEADER_SIZE] = '\0'; + displayer.state = DISPLAYER_ACTIVE; + displayer.timer = false; + displayer.refresh = true; + displayer.string[0] = '\0'; + displayer.elapsed = displayer.duration = 0; + displayer.offset = displayer.boundary = 0; + vTaskResume(displayer.task); + break; + } + case DISPLAYER_SUSPEND: + // task will display the line 2 from beginning and suspend + displayer.state = DISPLAYER_IDLE; + break; + case DISPLAYER_SHUTDOWN: + // let the task self-suspend (we might be doing i2c_write) + displayer.state = DISPLAYER_DOWN; + break; + case DISPLAYER_TIMER_RUN: + if (!displayer.timer) { + displayer.timer = true; + displayer.tick = xTaskGetTickCount(); + } + break; + case DISPLAYER_TIMER_PAUSE: + displayer.timer = false; + break; + default: + break; + } + + xSemaphoreGive(displayer.mutex); + va_end(args); +} \ No newline at end of file diff --git a/components/services/display.h b/components/services/display.h index fdd7d852..c8753254 100644 --- a/components/services/display.h +++ b/components/services/display.h @@ -18,19 +18,53 @@ #pragma once -#define DISPLAY_CLEAR 0x01 -#define DISPLAY_UPDATE 0x02 +/* + The displayer is not thread-safe and the caller must ensure use its own + mutexes if it wants something better. Especially, text() line() and draw() + are not protected against each other. + In text mode (text/line) when using DISPLAY_SUSPEND, the displayer will + refreshed line 2 one last time before suspending itself. As a result if it + is in a long sleep (scrolling pause), the refresh will happen after wakeup. + So it can conflict with other display direct writes that have been made during + sleep. Note that if DISPLAY_SHUTDOWN has been called meanwhile, it (almost) + never happens +*/ + +#define DISPLAY_CLEAR 0x01 +#define DISPLAY_ONLY_EOL 0x02 +#define DISPLAY_UPDATE 0x04 +#define DISPLAY_MONOSPACE 0x08 -enum display_pos_e { DISPLAY_TOP_LEFT, DISPLAY_MIDDLE_LEFT, DISPLAY_BOTTOM_LEFT, DISPLAY_CENTER }; +// these ones are for 'x' parameter of line() function +#define DISPLAY_LEFT 0 +#define DISPLAY_RIGHT 0xff00 +#define DISPLAY_CENTER 0xff01 + +enum display_pos_e { DISPLAY_TOP_LEFT, DISPLAY_MIDDLE_LEFT, DISPLAY_BOTTOM_LEFT, DISPLAY_CENTERED }; +enum display_font_e { DISPLAY_FONT_DEFAULT, + DISPLAY_FONT_LINE_1, DISPLAY_FONT_LINE_2, DISPLAY_FONT_SEGMENT, + DISPLAY_FONT_TINY, DISPLAY_FONT_SMALL, DISPLAY_FONT_MEDIUM, DISPLAY_FONT_LARGE, DISPLAY_FONT_HUGE }; + +enum displayer_cmd_e { DISPLAYER_SHUTDOWN, DISPLAYER_ACTIVATE, DISPLAYER_SUSPEND, DISPLAYER_TIMER_PAUSE, DISPLAYER_TIMER_RUN }; +enum displayer_time_e { DISPLAYER_ELAPSED, DISPLAYER_REMAINING }; // don't change anything there w/o changing all drivers init code extern struct display_s { int width, height; bool (*init)(char *config, char *welcome); + void (*clear)(void); + bool (*set_font)(int num, enum display_font_e font, int space); void (*on)(bool state); - void (*brightness)(u8_t level); - void (*text)(enum display_pos_e pos, int attribute, char *msg); + void (*brightness)(uint8_t level); + void (*text)(enum display_font_e font, enum display_pos_e pos, int attribute, char *msg, ...); + bool (*line)(int num, int x, int attribute, char *text); + int (*stretch)(int num, char *string, int max); void (*update)(void); - void (*draw)(int x1, int y1, int x2, int y2, bool by_column, u8_t *data); - void (*draw_cbr)(u8_t *data, int height); // height is the # of columns in data, as oppoosed to display height (0 = display height) -} *display; \ No newline at end of file + void (*draw)(int x1, int y1, int x2, int y2, bool by_column, uint8_t *data); + void (*draw_cbr)(uint8_t *data, int height); // height is the # of columns in data, as oppoosed to display height (0 = display height) +} *display; + +void displayer_scroll(char *string, int speed); +void displayer_control(enum displayer_cmd_e cmd, ...); +void displayer_metadata(char *artist, char *album, char *title); +void displayer_timer(enum displayer_time_e mode, int elapsed, int duration); \ No newline at end of file diff --git a/components/services/driver_SSD1306.c b/components/services/driver_SSD1306.c index e860bf28..6e2319e5 100644 --- a/components/services/driver_SSD1306.c +++ b/components/services/driver_SSD1306.c @@ -34,9 +34,15 @@ static const char *TAG = "display"; +#define max(a,b) (((a) > (b)) ? (a) : (b)) + // handlers static bool init(char *config, char *welcome); -static void text(enum display_pos_e pos, int attribute, char *text); +static void clear(void); +static bool set_font(int num, enum display_font_e font, int space); +static void text(enum display_font_e font, enum display_pos_e pos, int attribute, char *text, ...); +static bool line(int num, int x, int attribute, char *text); +static int stretch(int num, char *string, int max); static void draw_cbr(u8_t *data, int height); static void draw(int x1, int y1, int x2, int y2, bool by_column, u8_t *data); static void brightness(u8_t level); @@ -44,7 +50,9 @@ static void on(bool state); static void update(void); // display structure for others to use -struct display_s SSD1306_display = { 0, 0, init, on, brightness, text, update, draw, draw_cbr, NULL }; +struct display_s SSD1306_display = { 0, 0, + init, clear, set_font, on, brightness, + text, line, stretch, update, draw, draw_cbr, NULL }; // SSD1306 specific function static struct SSD1306_Device Display; @@ -70,6 +78,13 @@ static const unsigned char BitReverseTable256[] = 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF }; +#define MAX_LINES 8 + +static struct { + int y, space; + const struct SSD1306_FontDef *font; +} lines[MAX_LINES]; + /**************************************************************************************** * */ @@ -93,7 +108,7 @@ static bool init(char *config, char *welcome) { SSD1306_SetFont( &Display, &Font_droid_sans_fallback_15x17 ); SSD1306_display.width = width; SSD1306_display.height = height; - text(DISPLAY_CENTER, DISPLAY_CLEAR | DISPLAY_UPDATE, welcome); + text(DISPLAY_FONT_MEDIUM, DISPLAY_CENTERED, DISPLAY_CLEAR | DISPLAY_UPDATE, welcome); ESP_LOGI(TAG, "Initialized I2C display %dx%d", width, height); res = true; } else { @@ -109,35 +124,191 @@ static bool init(char *config, char *welcome) { /**************************************************************************************** * */ -static void text(enum display_pos_e pos, int attribute, char *text) { +static void clear(void) { + SSD1306_Clear( &Display, SSD_COLOR_BLACK ); + SSD1306_Update( &Display ); +} + +/**************************************************************************************** + * Set fonts for each line in text mode + */ +static bool set_font(int num, enum display_font_e font, int space) { + if (--num >= MAX_LINES) return false; + + switch(font) { + case DISPLAY_FONT_LINE_1: + lines[num].font = &Font_line_1; + break; + case DISPLAY_FONT_LINE_2: + lines[num].font = &Font_line_2; + break; + case DISPLAY_FONT_SMALL: + lines[num].font = &Font_droid_sans_fallback_11x13; + break; + case DISPLAY_FONT_MEDIUM: + case DISPLAY_FONT_DEFAULT: + default: + lines[num].font = &Font_droid_sans_fallback_15x17; + break; + case DISPLAY_FONT_LARGE: + lines[num].font = &Font_droid_sans_fallback_24x28; + break; + case DISPLAY_FONT_SEGMENT: + if (Display.Height == 32) lines[num].font = &Font_Tarable7Seg_16x32; + else lines[num].font = &Font_Tarable7Seg_32x64; + break; + } + + // re-calculate lines absolute position + lines[num].space = space; + lines[0].y = lines[0].space; + for (int i = 1; i <= num; i++) lines[i].y = lines[i-1].y + lines[i-1].font->Height + lines[i].space; + + ESP_LOGI(TAG, "adding line %u at %u (height:%u)", num + 1, lines[num].y, lines[num].font->Height); + + if (lines[num].y + lines[num].font->Height > Display.Height) { + ESP_LOGW(TAG, "line does not fit display"); + return false; + } + + return true; +} + +/**************************************************************************************** + * + */ +static bool line(int num, int x, int attribute, char *text) { + int width; + + // counting 1..n + num--; + + // always horizontal mode for text display + if (AddressMode != AddressMode_Horizontal) { + AddressMode = AddressMode_Horizontal; + SSD1306_SetDisplayAddressMode( &Display, AddressMode ); + } + + SSD1306_SetFont( &Display, lines[num].font ); + if (attribute & DISPLAY_MONOSPACE) SSD1306_FontForceMonospace( &Display, true ); + + width = SSD1306_FontMeasureString( &Display, text ); + + // adjusting position, erase only EoL for rigth-justified + if (x == DISPLAY_RIGHT) x = Display.Width - width - 1; + else if (x == DISPLAY_CENTER) x = (Display.Width - width) / 2; + + // erase if requested + if (attribute & DISPLAY_CLEAR) { + for (int c = (attribute & DISPLAY_ONLY_EOL) ? x : 0; c < Display.Width; c++) + for (int y = lines[num].y; y < lines[num].y + lines[num].font->Height; y++) + SSD1306_DrawPixelFast( &Display, c, y, SSD_COLOR_BLACK ); + } + + SSD1306_FontDrawString( &Display, x, lines[num].y, text, SSD_COLOR_WHITE ); + + ESP_LOGD(TAG, "displaying %s line %u (x:%d, attr:%u)", text, num+1, x, attribute); + + // update whole display if requested + if (attribute & DISPLAY_UPDATE) SSD1306_Update( &Display ); + + return width + x < Display.Width; +} + +/**************************************************************************************** + * Try to align string for better scrolling visual. there is probably much better to do + */ +static int stretch(int num, char *string, int max) { + char space[] = " "; + int len = strlen(string), extra = 0, boundary; + + num--; + + // we might already fit + SSD1306_SetFont( &Display, lines[num].font ); + if (SSD1306_FontMeasureString( &Display, string ) <= Display.Width) return 0; + + // add some space for better visual + strncat(string, space, max-len); + string[max] = '\0'; + len = strlen(string); + + // mark the end of the extended string + boundary = SSD1306_FontMeasureString( &Display, string ); + + // add a full display width + while (len < max && SSD1306_FontMeasureString( &Display, string ) - boundary < Display.Width) { + string[len++] = string[extra++]; + string[len] = '\0'; + } + + return boundary; +} + +/**************************************************************************************** + * + */ +static void text(enum display_font_e font, enum display_pos_e pos, int attribute, char *text, ...) { + va_list args; + + va_start(args, text); TextAnchor Anchor = TextAnchor_Center; if (attribute & DISPLAY_CLEAR) SSD1306_Clear( &Display, SSD_COLOR_BLACK ); if (!text) return; + switch(font) { + case DISPLAY_FONT_LINE_1: + SSD1306_SetFont( &Display, &Font_line_1 ); + break; + case DISPLAY_FONT_LINE_2: + SSD1306_SetFont( &Display, &Font_line_2 ); + break; + case DISPLAY_FONT_SMALL: + SSD1306_SetFont( &Display, &Font_droid_sans_fallback_11x13 ); + break; + case DISPLAY_FONT_MEDIUM: + case DISPLAY_FONT_DEFAULT: + default: + SSD1306_SetFont( &Display, &Font_droid_sans_fallback_15x17 ); + break; + case DISPLAY_FONT_LARGE: + SSD1306_SetFont( &Display, &Font_droid_sans_fallback_24x28 ); + break; + case DISPLAY_FONT_SEGMENT: + if (Display.Height == 32) SSD1306_SetFont( &Display, &Font_Tarable7Seg_16x32 ); + else SSD1306_SetFont( &Display, &Font_Tarable7Seg_32x64 ); + break; + } + switch(pos) { case DISPLAY_TOP_LEFT: + default: Anchor = TextAnchor_NorthWest; break; case DISPLAY_MIDDLE_LEFT: + Anchor = TextAnchor_West; break; case DISPLAY_BOTTOM_LEFT: Anchor = TextAnchor_SouthWest; break; - case DISPLAY_CENTER: + case DISPLAY_CENTERED: Anchor = TextAnchor_Center; break; } ESP_LOGD(TAG, "SSDD1306 displaying %s at %u with attribute %u", text, Anchor, attribute); - + if (AddressMode != AddressMode_Horizontal) { AddressMode = AddressMode_Horizontal; SSD1306_SetDisplayAddressMode( &Display, AddressMode ); } + SSD1306_FontDrawAnchoredString( &Display, Anchor, text, SSD_COLOR_WHITE ); if (attribute & DISPLAY_UPDATE) SSD1306_Update( &Display ); + + va_end(args); } /**************************************************************************************** @@ -191,7 +362,7 @@ static void draw_cbr(u8_t *data, int height) { SSD1306_SetDisplayAddressMode( &Display, AddressMode ); } - SSD1306_WriteRawData(&Display, Display.Framebuffer, Display.Width * Display.Heigth); + SSD1306_WriteRawData(&Display, Display.Framebuffer, Display.Width * Display.Height/8); #endif } diff --git a/components/services/tarablessd1306/fonts/font_line_1.c b/components/services/tarablessd1306/fonts/font_line_1.c new file mode 100644 index 00000000..d041166e --- /dev/null +++ b/components/services/tarablessd1306/fonts/font_line_1.c @@ -0,0 +1,224 @@ +#include <ssd1306_font.h> + +//WARNING: This Font Require X-GLCD Lib. +// You can not use it with MikroE GLCD Lib. + +//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0 +//MikroElektronika 2011 +//http://www.mikroe.com + +//GLCD FontName : Square721_BT11x14 +//GLCD FontSize : 11 x 14 + +static const uint8_t Square721_BT11x14[] = { + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + 0x02, 0x00, 0x00, 0xF8, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ! + 0x03, 0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char " + 0x08, 0x00, 0x00, 0x00, 0x01, 0x40, 0x07, 0xE0, 0x01, 0x58, 0x07, 0xC0, 0x01, 0x78, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char # + 0x07, 0x30, 0x03, 0x48, 0x04, 0x48, 0x04, 0xFC, 0x0F, 0x48, 0x04, 0x48, 0x04, 0x98, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char $ + 0x09, 0xF8, 0x00, 0x88, 0x00, 0x88, 0x00, 0xF8, 0x07, 0xE0, 0x00, 0xD8, 0x07, 0x40, 0x04, 0x40, 0x04, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, // Code for char % + 0x08, 0x00, 0x00, 0x80, 0x03, 0x78, 0x04, 0x48, 0x04, 0xC8, 0x04, 0x08, 0x05, 0x98, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char & + 0x02, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ' + 0x03, 0x00, 0x00, 0xF8, 0x07, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ( + 0x02, 0x08, 0x04, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ) + 0x06, 0x00, 0x00, 0x10, 0x00, 0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char * + 0x08, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xF0, 0x07, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + + 0x02, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char , + 0x04, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char . + 0x04, 0x00, 0x0C, 0x80, 0x03, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char / + 0x08, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 0 + 0x08, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x04, 0x08, 0x04, 0xF8, 0x07, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 1 + 0x08, 0x00, 0x00, 0x00, 0x00, 0x30, 0x07, 0x08, 0x05, 0x88, 0x04, 0x88, 0x04, 0x88, 0x04, 0x70, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 2 + 0x08, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x08, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0xB8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 3 + 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x40, 0x01, 0x30, 0x01, 0x08, 0x01, 0xF8, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 4 + 0x08, 0x00, 0x00, 0x00, 0x00, 0x78, 0x03, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x88, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 5 + 0x08, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0xD8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 6 + 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x04, 0x08, 0x03, 0x88, 0x00, 0x68, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 7 + 0x08, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x03, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0xB8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 8 + 0x08, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x06, 0x88, 0x04, 0x88, 0x04, 0x88, 0x04, 0x88, 0x04, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 9 + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char : + 0x02, 0x00, 0x00, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ; + 0x07, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x02, 0x40, 0x02, 0x40, 0x04, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char < + 0x07, 0x00, 0x00, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char = + 0x07, 0x00, 0x00, 0x20, 0x04, 0x40, 0x04, 0x40, 0x02, 0x80, 0x02, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char > + 0x06, 0x00, 0x00, 0x30, 0x00, 0x08, 0x00, 0x88, 0x05, 0x88, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ? + 0x0B, 0x00, 0x00, 0xC0, 0x03, 0x30, 0x04, 0xD0, 0x0F, 0x68, 0x0A, 0x28, 0x0A, 0xA8, 0x09, 0x68, 0x0A, 0x08, 0x0A, 0x10, 0x01, 0xE0, 0x00, // Code for char @ + 0x08, 0x00, 0x00, 0x00, 0x06, 0xC0, 0x01, 0x30, 0x01, 0x08, 0x01, 0x70, 0x01, 0x80, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char A + 0x08, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0xB8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char B + 0x08, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x30, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char C + 0x09, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, // Code for char D + 0x08, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char E + 0x07, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char F + 0x09, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x88, 0x04, 0x88, 0x04, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, // Code for char G + 0x08, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char H + 0x05, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0xF8, 0x07, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char I + 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char J + 0x08, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x40, 0x00, 0xE0, 0x00, 0x10, 0x01, 0x08, 0x06, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char K + 0x07, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char L + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x38, 0x00, 0xC0, 0x01, 0x00, 0x06, 0x00, 0x07, 0xE0, 0x00, 0x18, 0x00, 0xF8, 0x07, 0x00, 0x00, // Code for char M + 0x09, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x18, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x01, 0x00, 0x06, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, // Code for char N + 0x09, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, // Code for char O + 0x08, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char P + 0x09, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x05, 0x08, 0x06, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, // Code for char Q + 0x08, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x78, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char R + 0x08, 0x00, 0x00, 0x00, 0x00, 0x78, 0x03, 0x48, 0x04, 0x48, 0x04, 0x88, 0x04, 0x88, 0x04, 0x98, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char S + 0x07, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0xF8, 0x07, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T + 0x08, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char U + 0x08, 0x00, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x03, 0x00, 0x04, 0x80, 0x03, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char V + 0x0B, 0x00, 0x00, 0x18, 0x00, 0xE0, 0x01, 0x00, 0x06, 0xC0, 0x03, 0x38, 0x00, 0x78, 0x00, 0x80, 0x03, 0x00, 0x06, 0xE0, 0x01, 0x18, 0x00, // Code for char W + 0x08, 0x00, 0x00, 0x08, 0x04, 0x18, 0x02, 0xA0, 0x01, 0xC0, 0x00, 0x20, 0x01, 0x18, 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char X + 0x08, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x60, 0x00, 0x80, 0x07, 0x60, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Y + 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x08, 0x05, 0x88, 0x04, 0x48, 0x04, 0x28, 0x04, 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Z + 0x03, 0x00, 0x00, 0xF8, 0x07, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [ + 0x04, 0x18, 0x00, 0xE0, 0x00, 0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char BackSlash + 0x02, 0x08, 0x04, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ] + 0x08, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ^ + 0x06, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char _ + 0x03, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ` + 0x06, 0x00, 0x00, 0xA0, 0x07, 0xA0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char a + 0x06, 0x00, 0x00, 0xF8, 0x07, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char b + 0x06, 0x00, 0x00, 0xC0, 0x07, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char c + 0x06, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char d + 0x06, 0x00, 0x00, 0xE0, 0x03, 0xA0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xE0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char e + 0x04, 0x20, 0x00, 0xF8, 0x07, 0x28, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f + 0x06, 0x00, 0x00, 0xC0, 0x13, 0x20, 0x14, 0x20, 0x14, 0x20, 0x14, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char g + 0x06, 0x00, 0x00, 0xF8, 0x07, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char h + 0x02, 0x00, 0x00, 0xE8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char i + 0x02, 0x00, 0x10, 0xE8, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j + 0x05, 0x00, 0x00, 0xF8, 0x07, 0x80, 0x01, 0x60, 0x02, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char k + 0x02, 0x00, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char l + 0x08, 0x00, 0x00, 0xE0, 0x07, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x07, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char m + 0x06, 0x00, 0x00, 0xE0, 0x07, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char n + 0x06, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char o + 0x06, 0x00, 0x00, 0xE0, 0x1F, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char p + 0x06, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x04, 0x20, 0x04, 0x20, 0x04, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char q + 0x05, 0x00, 0x00, 0xE0, 0x07, 0x20, 0x00, 0x20, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char r + 0x06, 0x00, 0x00, 0xE0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xA0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s + 0x05, 0x20, 0x00, 0xF0, 0x07, 0x20, 0x04, 0x20, 0x04, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t + 0x06, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char u + 0x05, 0x60, 0x00, 0x80, 0x03, 0x00, 0x04, 0x80, 0x03, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char v + 0x08, 0xE0, 0x00, 0x00, 0x07, 0x00, 0x07, 0xE0, 0x00, 0xE0, 0x01, 0x00, 0x06, 0x80, 0x07, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char w + 0x05, 0x20, 0x04, 0x40, 0x03, 0x80, 0x01, 0x60, 0x02, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char x + 0x05, 0x60, 0x00, 0x80, 0x13, 0x00, 0x0E, 0xC0, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y + 0x06, 0x00, 0x00, 0x20, 0x06, 0x20, 0x05, 0xA0, 0x04, 0x60, 0x04, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char z + 0x05, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x78, 0x1F, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char { + 0x03, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char | + 0x05, 0x00, 0x00, 0x08, 0x10, 0x78, 0x1F, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char } + 0x07, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ~ + 0x03, 0xF8, 0x07, 0x08, 0x04, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char € + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‚ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ƒ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char „ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char … + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char † + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‡ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˆ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‰ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Š + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‹ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Œ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ž + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‘ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ’ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char “ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ” + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char • + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char – + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char — + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˜ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ™ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char š + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char › + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char œ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ž + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ÿ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char   + 0x02, 0x00, 0x00, 0xE8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¡ + 0x06, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x0E, 0xE0, 0x05, 0x30, 0x04, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¢ + 0x07, 0x00, 0x00, 0x80, 0x04, 0xF8, 0x07, 0x88, 0x04, 0x88, 0x04, 0x08, 0x04, 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char £ + 0x06, 0x08, 0x01, 0xF0, 0x00, 0x90, 0x00, 0x90, 0x00, 0xF0, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¤ + 0x07, 0xA8, 0x00, 0xB0, 0x00, 0xE0, 0x00, 0x80, 0x07, 0xE0, 0x00, 0xB0, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¥ + 0x03, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¦ + 0x05, 0xF8, 0x06, 0xA8, 0x04, 0x48, 0x05, 0x58, 0x05, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char § + 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¨ + 0x09, 0x00, 0x00, 0xE0, 0x01, 0x10, 0x02, 0xC8, 0x04, 0x28, 0x05, 0x28, 0x05, 0xC8, 0x04, 0x10, 0x02, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char © + 0x05, 0x00, 0x00, 0x78, 0x00, 0x58, 0x00, 0x58, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ª + 0x05, 0x00, 0x00, 0x00, 0x01, 0x80, 0x02, 0x00, 0x01, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char « + 0x07, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¬ + 0x04, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ­ + 0x09, 0x00, 0x00, 0xE0, 0x01, 0x10, 0x02, 0xE8, 0x05, 0xA8, 0x04, 0xA8, 0x05, 0x68, 0x06, 0x10, 0x02, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char ® + 0x04, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¯ + 0x03, 0x38, 0x00, 0x28, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ° + 0x08, 0x00, 0x00, 0x40, 0x04, 0x40, 0x04, 0x40, 0x04, 0xF0, 0x05, 0x40, 0x04, 0x40, 0x04, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ± + 0x05, 0x00, 0x00, 0xD8, 0x00, 0xC8, 0x00, 0xA8, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ² + 0x05, 0x00, 0x00, 0xD8, 0x00, 0x88, 0x00, 0xA8, 0x00, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ³ + 0x04, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ´ + 0x05, 0xC0, 0x07, 0x20, 0x04, 0x00, 0x04, 0x80, 0x03, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char µ + 0x06, 0x00, 0x00, 0x78, 0x00, 0xF8, 0x07, 0x08, 0x00, 0xF8, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¶ + 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char · + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¸ + 0x04, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¹ + 0x05, 0x00, 0x00, 0x78, 0x00, 0x48, 0x00, 0x48, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char º + 0x05, 0x00, 0x00, 0x80, 0x02, 0x00, 0x01, 0x80, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char » + 0x0A, 0x10, 0x00, 0x08, 0x00, 0xF8, 0x00, 0x00, 0x06, 0x80, 0x01, 0x70, 0x00, 0x88, 0x01, 0x80, 0x01, 0xC0, 0x07, 0x00, 0x01, 0x00, 0x00, // Code for char ¼ + 0x0A, 0x10, 0x00, 0x08, 0x00, 0xF8, 0x00, 0x00, 0x06, 0x80, 0x01, 0x60, 0x00, 0x58, 0x07, 0x48, 0x05, 0x40, 0x05, 0xC0, 0x04, 0x00, 0x00, // Code for char ½ + 0x0B, 0x00, 0x00, 0xC8, 0x00, 0x88, 0x00, 0x98, 0x04, 0xE8, 0x02, 0x80, 0x01, 0x40, 0x00, 0x30, 0x00, 0x88, 0x01, 0x80, 0x01, 0xC0, 0x07, // Code for char ¾ + 0x05, 0x80, 0x07, 0x40, 0x04, 0x28, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¿ + 0x07, 0x00, 0x06, 0xC0, 0x01, 0x32, 0x01, 0x0C, 0x01, 0x70, 0x01, 0x80, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char À + 0x07, 0x00, 0x06, 0xC0, 0x01, 0x30, 0x01, 0x0C, 0x01, 0x72, 0x01, 0x80, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Á + 0x07, 0x00, 0x06, 0xC0, 0x01, 0x34, 0x01, 0x0A, 0x01, 0x74, 0x01, 0x80, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  + 0x07, 0x00, 0x06, 0xC0, 0x01, 0x32, 0x01, 0x0A, 0x01, 0x72, 0x01, 0x80, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à + 0x07, 0x00, 0x06, 0xC0, 0x01, 0x32, 0x01, 0x08, 0x01, 0x72, 0x01, 0x80, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ä + 0x07, 0x00, 0x06, 0xC0, 0x01, 0x37, 0x01, 0x0D, 0x01, 0x77, 0x01, 0x80, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Å + 0x0B, 0x00, 0x03, 0xC0, 0x01, 0x20, 0x01, 0x18, 0x01, 0x08, 0x01, 0xF8, 0x07, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, // Code for char Æ + 0x07, 0x00, 0x00, 0xF0, 0x03, 0x08, 0x04, 0x08, 0x14, 0x08, 0x1C, 0x08, 0x04, 0x30, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ç + 0x07, 0x00, 0x00, 0xF8, 0x07, 0x4A, 0x04, 0x4C, 0x04, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char È + 0x07, 0x00, 0x00, 0xF8, 0x07, 0x48, 0x04, 0x4C, 0x04, 0x4A, 0x04, 0x48, 0x04, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char É + 0x07, 0x00, 0x00, 0xF8, 0x07, 0x4C, 0x04, 0x4A, 0x04, 0x4C, 0x04, 0x48, 0x04, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ê + 0x07, 0x00, 0x00, 0xF8, 0x07, 0x4A, 0x04, 0x48, 0x04, 0x4A, 0x04, 0x48, 0x04, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ë + 0x02, 0x02, 0x00, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ì + 0x03, 0x00, 0x00, 0xFC, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Í + 0x03, 0x04, 0x00, 0xFA, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Î + 0x03, 0x02, 0x00, 0xF8, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ï + 0x08, 0x40, 0x00, 0xF8, 0x07, 0x48, 0x04, 0x48, 0x04, 0x48, 0x04, 0x08, 0x04, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ð + 0x08, 0x00, 0x00, 0xF8, 0x07, 0x18, 0x00, 0x22, 0x00, 0xC2, 0x00, 0x02, 0x01, 0x00, 0x06, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ñ + 0x08, 0x00, 0x00, 0xF0, 0x03, 0x0A, 0x04, 0x0C, 0x04, 0x08, 0x04, 0x08, 0x04, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ò + 0x08, 0x00, 0x00, 0xF0, 0x03, 0x08, 0x04, 0x0C, 0x04, 0x0A, 0x04, 0x08, 0x04, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ó + 0x08, 0x00, 0x00, 0xF0, 0x03, 0x0C, 0x04, 0x0A, 0x04, 0x0C, 0x04, 0x08, 0x04, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ô + 0x08, 0x00, 0x00, 0xF0, 0x03, 0x0A, 0x04, 0x0A, 0x04, 0x0A, 0x04, 0x08, 0x04, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Õ + 0x08, 0x00, 0x00, 0xF0, 0x03, 0x0A, 0x04, 0x08, 0x04, 0x0A, 0x04, 0x08, 0x04, 0x08, 0x04, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ö + 0x08, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x40, 0x02, 0x80, 0x01, 0x80, 0x01, 0x40, 0x02, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char × + 0x08, 0x00, 0x00, 0xF0, 0x07, 0x08, 0x06, 0x08, 0x05, 0xC8, 0x04, 0x28, 0x04, 0x18, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ø + 0x07, 0x00, 0x00, 0xF8, 0x03, 0x02, 0x04, 0x04, 0x04, 0x00, 0x04, 0x00, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ù + 0x07, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x04, 0x04, 0x04, 0x02, 0x04, 0x00, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ú + 0x07, 0x00, 0x00, 0xF8, 0x03, 0x04, 0x04, 0x02, 0x04, 0x04, 0x04, 0x00, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Û + 0x07, 0x00, 0x00, 0xF8, 0x03, 0x02, 0x04, 0x00, 0x04, 0x02, 0x04, 0x00, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ü + 0x07, 0x08, 0x00, 0x10, 0x00, 0x60, 0x00, 0x84, 0x07, 0x62, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ý + 0x07, 0x00, 0x00, 0xF8, 0x07, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Þ + 0x06, 0x00, 0x00, 0xF0, 0x07, 0x08, 0x00, 0x48, 0x04, 0x48, 0x04, 0xB0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ß + 0x06, 0x00, 0x00, 0xA8, 0x07, 0xB0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à + 0x06, 0x00, 0x00, 0xA0, 0x07, 0xB0, 0x04, 0xA8, 0x04, 0xA0, 0x04, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char á + 0x06, 0x00, 0x00, 0xB0, 0x07, 0xA8, 0x04, 0xB0, 0x04, 0xA0, 0x04, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char â + 0x06, 0x00, 0x00, 0xA8, 0x07, 0xA8, 0x04, 0xA8, 0x04, 0xA0, 0x04, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ã + 0x06, 0x00, 0x00, 0xA8, 0x07, 0xA0, 0x04, 0xA8, 0x04, 0xA0, 0x04, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ä + 0x06, 0x00, 0x00, 0xA0, 0x07, 0xAE, 0x04, 0xAA, 0x04, 0xAE, 0x04, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char å + 0x0A, 0x00, 0x00, 0xA0, 0x07, 0xA0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xC0, 0x03, 0xA0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xE0, 0x02, 0x00, 0x00, // Code for char æ + 0x06, 0x00, 0x00, 0xC0, 0x07, 0x20, 0x14, 0x20, 0x1C, 0x20, 0x04, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ç + 0x06, 0x00, 0x00, 0xE8, 0x03, 0xB0, 0x04, 0xA0, 0x04, 0xA0, 0x04, 0xE0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char è + }; + +const struct SSD1306_FontDef Font_line_1 = { + Square721_BT11x14, + 11, + 14, + ' ', + '\xFF', + false +}; diff --git a/components/services/tarablessd1306/fonts/font_line_2.c b/components/services/tarablessd1306/fonts/font_line_2.c new file mode 100644 index 00000000..39231967 --- /dev/null +++ b/components/services/tarablessd1306/fonts/font_line_2.c @@ -0,0 +1,247 @@ +#include <ssd1306_font.h> + +//WARNING: This Font Require X-GLCD Lib. +// You can not use it with MikroE GLCD Lib. + +//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0 +//MikroElektronika 2011 +//http://www.mikroe.com + +//GLCD FontName : Archivo_Narrow18x24 +//GLCD FontSize : 18 x 24 + +static const uint8_t Archivo_Narrow18x24[] = { + 0x06, 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, // Code for char + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x1F, 0x0E, 0xF0, 0xFF, 0x0E, 0xF0, 0x1F, 0x0E, 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, // Code for char ! + 0x08, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xF0, 0x03, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xF0, 0x03, 0x00, 0xF0, 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, // Code for char " + 0x0A, 0x00, 0xC0, 0x08, 0x00, 0xC3, 0x0F, 0x00, 0xFF, 0x0F, 0xC0, 0xFF, 0x00, 0xF0, 0xC3, 0x0C, 0x30, 0xC3, 0x0F, 0x00, 0xFF, 0x03, 0xF0, 0xFF, 0x00, 0xF0, 0xC3, 0x00, 0x10, 0x03, 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, // Code for char # + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x87, 0x01, 0x80, 0x8F, 0x03, 0xC0, 0x9F, 0x03, 0xC0, 0x1D, 0x07, 0xF8, 0xFF, 0x1F, 0xC0, 0x39, 0x07, 0xC0, 0xF3, 0x03, 0x80, 0xF3, 0x03, 0x00, 0xE3, 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, // Code for char $ + 0x10, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0xE0, 0x07, 0x00, 0x30, 0x0C, 0x08, 0x30, 0x0C, 0x0E, 0xE0, 0x87, 0x03, 0xC0, 0xC3, 0x01, 0x00, 0x70, 0x00, 0x00, 0x38, 0x00, 0x00, 0x0E, 0x00, 0x80, 0xC3, 0x03, 0xC0, 0xE1, 0x07, 0x70, 0x30, 0x0C, 0x10, 0x30, 0x0C, 0x00, 0xE0, 0x07, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char % + 0x0E, 0x00, 0x00, 0x00, 0x80, 0xE1, 0x01, 0xE0, 0xF7, 0x03, 0xE0, 0xFF, 0x07, 0x70, 0x3E, 0x0F, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0xE0, 0xFD, 0x07, 0xE0, 0xFD, 0x03, 0x80, 0xFD, 0x01, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char & + 0x04, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xF0, 0x03, 0x00, 0xF0, 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, 0x00, // Code for char ' + 0x06, 0x00, 0xFC, 0x01, 0x80, 0xFF, 0x0F, 0xE0, 0xFF, 0x3F, 0xF0, 0x01, 0x7C, 0x38, 0x00, 0xE0, 0x08, 0x00, 0x80, 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, // Code for char ( + 0x06, 0x08, 0x00, 0x80, 0x38, 0x00, 0xE0, 0xF0, 0x01, 0x7C, 0xE0, 0xFF, 0x3F, 0x80, 0xFF, 0x0F, 0x00, 0xFC, 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, // Code for char ) + 0x08, 0x40, 0x02, 0x00, 0x60, 0x06, 0x00, 0xC0, 0x03, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xC0, 0x03, 0x00, 0x60, 0x06, 0x00, 0x40, 0x02, 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, // Code for char * + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 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, // Code for char + + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x1E, 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, // Code for char , + 0x06, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 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, // Code for char - + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 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, // Code for char . + 0x05, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0x1F, 0x80, 0xFF, 0x01, 0xF8, 0x0F, 0x00, 0x38, 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, // Code for char / + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xC0, 0xFF, 0x03, 0xE0, 0xFF, 0x07, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0xE0, 0xFF, 0x07, 0xC0, 0xFF, 0x03, 0x00, 0xFF, 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, // Code for char 0 + 0x0A, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x0E, 0xC0, 0x00, 0x0E, 0xE0, 0x00, 0x0E, 0xE0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 1 + 0x0A, 0x00, 0x00, 0x00, 0x80, 0x03, 0x0E, 0xE0, 0x83, 0x0F, 0xE0, 0xC3, 0x0F, 0x70, 0xE0, 0x0F, 0x70, 0xF0, 0x0E, 0x70, 0x7C, 0x0E, 0xE0, 0x3F, 0x0E, 0xE0, 0x0F, 0x0E, 0xC0, 0x03, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 2 + 0x0A, 0x00, 0x00, 0x00, 0x80, 0x81, 0x01, 0xE0, 0x81, 0x07, 0xE0, 0x81, 0x07, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0xE0, 0xFF, 0x07, 0xE0, 0xF7, 0x07, 0xC0, 0xC3, 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, // Code for char 3 + 0x0A, 0x00, 0xC0, 0x01, 0x00, 0xF0, 0x01, 0x00, 0xFC, 0x01, 0x80, 0xDF, 0x01, 0xF0, 0xC7, 0x01, 0xF0, 0xC1, 0x01, 0x30, 0xFC, 0x0F, 0x80, 0xFF, 0x0F, 0xC0, 0xFF, 0x0F, 0x00, 0xC0, 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, // Code for char 4 + 0x0A, 0x00, 0x00, 0x00, 0xF0, 0x9F, 0x01, 0xF0, 0x9F, 0x03, 0xF0, 0x9F, 0x07, 0x70, 0x0C, 0x0E, 0x70, 0x0E, 0x0E, 0x70, 0x0E, 0x0F, 0x70, 0xFE, 0x07, 0x70, 0xFC, 0x03, 0x00, 0xF0, 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, // Code for char 5 + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xC0, 0xFF, 0x03, 0xE0, 0xFF, 0x07, 0x70, 0x18, 0x0E, 0x70, 0x1C, 0x0E, 0xE0, 0x1D, 0x0E, 0xE0, 0xF9, 0x07, 0x80, 0xF9, 0x07, 0x00, 0xE0, 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, // Code for char 6 + 0x0A, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x0F, 0x70, 0xE0, 0x0F, 0x70, 0xFC, 0x0F, 0x70, 0x7F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x03, 0x00, 0xF0, 0x00, 0x00, 0x30, 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, // Code for char 7 + 0x0A, 0x00, 0x00, 0x00, 0x80, 0xE3, 0x01, 0xE0, 0xF7, 0x07, 0xE0, 0xFF, 0x07, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0xE0, 0xFF, 0x07, 0xE0, 0xF7, 0x07, 0x80, 0xE3, 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, // Code for char 8 + 0x0A, 0x00, 0x00, 0x00, 0x80, 0x8F, 0x01, 0xE0, 0xBF, 0x07, 0xE0, 0xBF, 0x07, 0x70, 0x70, 0x0E, 0x70, 0x70, 0x0E, 0xF0, 0x38, 0x0E, 0xE0, 0xFF, 0x07, 0xC0, 0xFF, 0x03, 0x00, 0xFF, 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, // Code for char 9 + 0x04, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0E, 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, // Code for char : + 0x04, 0x00, 0x00, 0x00, 0x00, 0x07, 0x4E, 0x00, 0x07, 0x7E, 0x00, 0x07, 0x1E, 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, // Code for char ; + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x98, 0x01, 0x00, 0x9C, 0x03, 0x00, 0x0C, 0x03, 0x00, 0x0E, 0x07, 0x00, 0x06, 0x06, 0x00, 0x07, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char < + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char = + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0E, 0x00, 0x06, 0x06, 0x00, 0x0E, 0x07, 0x00, 0x0C, 0x03, 0x00, 0x9C, 0x03, 0x00, 0x98, 0x01, 0x00, 0xF8, 0x01, 0x00, 0xF0, 0x00, 0x00, 0xF0, 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, // Code for char > + 0x0A, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0xE0, 0x03, 0x00, 0xE0, 0x03, 0x00, 0x70, 0x00, 0x00, 0x70, 0xE0, 0x0E, 0x70, 0xF8, 0x0E, 0xE0, 0xFF, 0x0E, 0xE0, 0x1F, 0x00, 0x80, 0x07, 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, // Code for char ? + 0x12, 0x00, 0xF8, 0x00, 0x00, 0xFF, 0x07, 0x80, 0x03, 0x1C, 0xC0, 0x00, 0x30, 0x60, 0x00, 0x60, 0x60, 0xC0, 0x63, 0x20, 0xE4, 0x47, 0x30, 0xE6, 0xC7, 0x30, 0x37, 0xC6, 0x30, 0x33, 0xC6, 0x30, 0xFF, 0xC3, 0x30, 0xFE, 0x67, 0x60, 0xFC, 0x07, 0x60, 0x00, 0x06, 0xC0, 0x00, 0x06, 0xC0, 0x01, 0x03, 0x00, 0xFF, 0x01, 0x00, 0x7C, 0x00, // Code for char @ + 0x0E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0xFC, 0x03, 0x80, 0xFF, 0x01, 0xF0, 0xCF, 0x01, 0xF0, 0xC1, 0x01, 0xF0, 0xC1, 0x01, 0xF0, 0xCF, 0x01, 0x80, 0xFF, 0x01, 0x00, 0xFC, 0x07, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char A + 0x0D, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0xF0, 0x3F, 0x0F, 0xE0, 0xF7, 0x07, 0xC0, 0xF1, 0x07, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char B + 0x0D, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x07, 0xE0, 0x81, 0x07, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0xE0, 0x00, 0x07, 0xE0, 0xC3, 0x07, 0xC0, 0xC3, 0x03, 0x00, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char C + 0x0D, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0xE0, 0x00, 0x07, 0xE0, 0x81, 0x07, 0xC0, 0xFF, 0x03, 0x80, 0xFF, 0x01, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char D + 0x0B, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char E + 0x0A, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 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, // Code for char F + 0x0D, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x03, 0xC0, 0xFF, 0x07, 0xE0, 0x00, 0x07, 0x60, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0x70, 0x38, 0x0E, 0x70, 0x38, 0x06, 0xE0, 0x38, 0x07, 0xE0, 0xFB, 0x03, 0xC0, 0xFB, 0x0F, 0x00, 0xFB, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char G + 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char H + 0x04, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 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, // Code for char I + 0x09, 0x00, 0x80, 0x03, 0x00, 0x80, 0x07, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x03, 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, // Code for char J + 0x0D, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x00, 0x78, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x7F, 0x00, 0xC0, 0xFB, 0x01, 0xF0, 0xE1, 0x07, 0x70, 0x80, 0x0F, 0x30, 0x00, 0x0E, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char K + 0x0B, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char L + 0x0F, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0x03, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0xFF, 0x07, 0x00, 0xF0, 0x0F, 0x00, 0x80, 0x0F, 0x00, 0xFC, 0x07, 0xC0, 0x3F, 0x00, 0xF0, 0x03, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char M + 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xE0, 0x07, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x7E, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xE0, 0x07, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char N + 0x0E, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x03, 0xE0, 0x81, 0x07, 0xE0, 0x00, 0x06, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0xE0, 0x00, 0x07, 0xE0, 0x81, 0x07, 0xC0, 0xFF, 0x03, 0x80, 0xFF, 0x01, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char O + 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x3C, 0x00, 0xE0, 0x1F, 0x00, 0xE0, 0x1F, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char P + 0x0E, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x03, 0xE0, 0x81, 0x07, 0xE0, 0x00, 0x06, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x1E, 0xE0, 0x00, 0x3F, 0xE0, 0x81, 0x3F, 0xC0, 0xFF, 0x33, 0x80, 0xFF, 0x21, 0x00, 0x7E, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Q + 0x0D, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x70, 0xF8, 0x00, 0x70, 0xF8, 0x03, 0xE0, 0xFF, 0x0F, 0xE0, 0x8F, 0x0F, 0x80, 0x07, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char R + 0x0C, 0x00, 0x00, 0x00, 0x80, 0x83, 0x01, 0xE0, 0x8F, 0x03, 0xE0, 0x8F, 0x07, 0x70, 0x0E, 0x0F, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x38, 0x0E, 0xE0, 0x39, 0x0E, 0xE0, 0xF1, 0x07, 0x80, 0xF1, 0x07, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char S + 0x0B, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T + 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x01, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x07, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0F, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char U + 0x0D, 0x10, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xFF, 0x03, 0x00, 0xF0, 0x0F, 0x00, 0x80, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xFE, 0x03, 0xC0, 0x7F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char V + 0x12, 0x30, 0x00, 0x00, 0xF0, 0x03, 0x00, 0xF0, 0x7F, 0x00, 0xC0, 0xFF, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0x80, 0x0F, 0x00, 0xFE, 0x0F, 0xF0, 0x7F, 0x00, 0xF0, 0x03, 0x00, 0xF0, 0x03, 0x00, 0xF0, 0x7F, 0x00, 0x80, 0xFF, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0xFF, 0x0F, 0xF0, 0x7F, 0x00, 0xF0, 0x03, 0x00, 0x30, 0x00, 0x00, // Code for char W + 0x0D, 0x00, 0x00, 0x08, 0x30, 0x00, 0x0E, 0xF0, 0x00, 0x0F, 0xF0, 0xC1, 0x07, 0xE0, 0xF7, 0x03, 0x80, 0xFF, 0x00, 0x00, 0x3E, 0x00, 0x00, 0xFF, 0x00, 0xC0, 0xF7, 0x03, 0xF0, 0xC1, 0x0F, 0xF0, 0x00, 0x0F, 0x30, 0x00, 0x0E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char X + 0x0D, 0x10, 0x00, 0x00, 0x70, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xF0, 0x07, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0xF8, 0x0F, 0x00, 0xFE, 0x0F, 0x80, 0x1F, 0x00, 0xE0, 0x07, 0x00, 0xF0, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Y + 0x0B, 0x00, 0x00, 0x0C, 0x70, 0x00, 0x0F, 0x70, 0xC0, 0x0F, 0x70, 0xE0, 0x0F, 0x70, 0xF8, 0x0F, 0x70, 0x7E, 0x0E, 0xF0, 0x1F, 0x0E, 0xF0, 0x07, 0x0E, 0xF0, 0x01, 0x0E, 0x70, 0x00, 0x0E, 0x30, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Z + 0x06, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 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, // Code for char [ + 0x05, 0x38, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x80, 0xFF, 0x01, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0x1C, 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, // Code for char BackSlash + 0x05, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 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, // Code for char ] + 0x0B, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x1F, 0x00, 0xE0, 0x07, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ^ + 0x0A, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char _ + 0x05, 0x08, 0x00, 0x00, 0x18, 0x00, 0x00, 0x38, 0x00, 0x00, 0x30, 0x00, 0x00, 0x20, 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, // Code for char ` + 0x0A, 0x00, 0x80, 0x03, 0x00, 0xCC, 0x07, 0x00, 0xCE, 0x0F, 0x00, 0x6F, 0x0E, 0x00, 0x67, 0x06, 0x00, 0x67, 0x06, 0x00, 0xFF, 0x03, 0x00, 0xFE, 0x07, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char a + 0x0B, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0x00, 0x06, 0x06, 0x00, 0x06, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x0F, 0x0E, 0x00, 0xFE, 0x07, 0x00, 0xFE, 0x07, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char b + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFE, 0x07, 0x00, 0xFE, 0x07, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x9E, 0x07, 0x00, 0x9E, 0x07, 0x00, 0x98, 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, // Code for char c + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFE, 0x07, 0x00, 0xFF, 0x0F, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x06, 0x06, 0xF8, 0xFF, 0x07, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char d + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x00, 0xFE, 0x07, 0x00, 0x67, 0x0E, 0x00, 0x67, 0x0E, 0x00, 0x67, 0x0E, 0x00, 0x7E, 0x07, 0x00, 0x7C, 0x07, 0x00, 0x78, 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, // Code for char e + 0x06, 0x00, 0x07, 0x00, 0xE0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0x38, 0x07, 0x00, 0x38, 0x07, 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, // Code for char f + 0x0B, 0x00, 0x00, 0x18, 0x00, 0x9E, 0x3D, 0x00, 0xFF, 0x3F, 0x80, 0xFF, 0x33, 0x80, 0xB1, 0x33, 0x80, 0xB1, 0x33, 0x80, 0xB1, 0x33, 0x80, 0x3F, 0x33, 0x80, 0x3F, 0x3F, 0xC0, 0x1E, 0x1E, 0x40, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char g + 0x0A, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x07, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char h + 0x04, 0x00, 0x00, 0x00, 0x38, 0xFF, 0x0F, 0x38, 0xFF, 0x0F, 0x38, 0xFF, 0x0F, 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, // Code for char i + 0x04, 0x00, 0x00, 0x38, 0x38, 0xFF, 0x3F, 0x38, 0xFF, 0x3F, 0x38, 0xFF, 0x1F, 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, // Code for char j + 0x0A, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0x00, 0x70, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x8F, 0x0F, 0x00, 0x03, 0x0F, 0x00, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char k + 0x04, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 0xF8, 0xFF, 0x0F, 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, // Code for char l + 0x10, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x07, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0xFC, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x07, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char m + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x07, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char n + 0x0B, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x00, 0xFE, 0x07, 0x00, 0x07, 0x0F, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0F, 0x00, 0xFE, 0x07, 0x00, 0xFC, 0x03, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char o + 0x0B, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0xFF, 0x3F, 0x00, 0xFE, 0x3F, 0x00, 0x06, 0x07, 0x00, 0x06, 0x07, 0x00, 0x07, 0x07, 0x00, 0x0F, 0x03, 0x00, 0xFE, 0x03, 0x00, 0xFE, 0x01, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char p + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFE, 0x03, 0x00, 0xFF, 0x07, 0x00, 0x07, 0x07, 0x00, 0x07, 0x07, 0x00, 0x06, 0x07, 0x00, 0xFF, 0x3F, 0x00, 0xFF, 0x3F, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char q + 0x07, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 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, // Code for char r + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x3E, 0x07, 0x00, 0x3F, 0x07, 0x00, 0x77, 0x0E, 0x00, 0x67, 0x0E, 0x00, 0x6F, 0x0E, 0x00, 0xEE, 0x07, 0x00, 0xCC, 0x07, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s + 0x06, 0x00, 0x07, 0x00, 0xE0, 0xFF, 0x03, 0xE0, 0xFF, 0x07, 0xE0, 0xFF, 0x0F, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0E, 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, // Code for char t + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0xFF, 0x07, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0xFF, 0x07, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char u + 0x0A, 0x00, 0x03, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFC, 0x07, 0x00, 0xC0, 0x0F, 0x00, 0x80, 0x0F, 0x00, 0xF8, 0x07, 0x00, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x03, 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, // Code for char v + 0x0F, 0x00, 0x01, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xFF, 0x01, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xFF, 0x01, 0x00, 0x07, 0x00, 0x00, 0xFF, 0x01, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0xF0, 0x0F, 0x00, 0xFF, 0x03, 0x00, 0x1F, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char w + 0x0A, 0x00, 0x01, 0x08, 0x00, 0x03, 0x0E, 0x00, 0x8F, 0x0F, 0x00, 0xFF, 0x07, 0x00, 0xFC, 0x01, 0x00, 0xF8, 0x01, 0x00, 0xFE, 0x07, 0x00, 0x8F, 0x0F, 0x00, 0x03, 0x0E, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char x + 0x0A, 0x00, 0x01, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x7F, 0xE0, 0x00, 0xFC, 0xF3, 0x00, 0xE0, 0x7F, 0x00, 0x80, 0x3F, 0x00, 0xF8, 0x07, 0x00, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x03, 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, // Code for char y + 0x09, 0x00, 0x07, 0x0C, 0x00, 0x07, 0x0F, 0x00, 0x87, 0x0F, 0x00, 0xE7, 0x0F, 0x00, 0xFF, 0x0E, 0x00, 0x7F, 0x0E, 0x00, 0x1F, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x03, 0x0E, 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, // Code for char z + 0x07, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0xE0, 0xFF, 0x3F, 0xF0, 0xDF, 0x7F, 0xF8, 0x87, 0xFF, 0x18, 0x00, 0xC0, 0x18, 0x00, 0xC0, 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, // Code for char { + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 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, // Code for char | + 0x07, 0x0C, 0x00, 0x60, 0x0C, 0x00, 0x60, 0xFC, 0xC3, 0x7F, 0xF8, 0xFF, 0x3F, 0xF0, 0xFF, 0x1F, 0x00, 0x18, 0x00, 0x00, 0x18, 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, // Code for char } + 0x0B, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x30, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ~ + 0x06, 0xE0, 0xFF, 0x07, 0xE0, 0xFF, 0x07, 0x20, 0x00, 0x04, 0x20, 0x00, 0x04, 0xE0, 0xFF, 0x07, 0xE0, 0xFF, 0x07, 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, // Code for char  + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char € + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‚ + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ƒ + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char „ + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char … + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char † + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‡ + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˆ + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‰ + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Š + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‹ + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Œ + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ž + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ‘ + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ’ + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char “ + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ” + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char • + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char – + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char — + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ˜ + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ™ + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char š + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char › + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char œ + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ž + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ÿ + 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char   + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC3, 0x3F, 0x80, 0xFB, 0x3F, 0x80, 0xC3, 0x3F, 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, // Code for char ¡ + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x03, 0xC0, 0x81, 0x03, 0xF8, 0xFF, 0x1F, 0xC0, 0x80, 0x03, 0xC0, 0xE3, 0x03, 0x80, 0xE3, 0x01, 0x00, 0xE3, 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, // Code for char ¢ + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0E, 0x80, 0xFF, 0x0F, 0xE0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x70, 0x38, 0x0E, 0x70, 0x38, 0x0E, 0xF0, 0x01, 0x0E, 0xE0, 0x01, 0x0E, 0x80, 0x01, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char £ + 0x0A, 0x80, 0xBD, 0x01, 0x00, 0xFF, 0x00, 0x00, 0xC3, 0x00, 0x80, 0x81, 0x01, 0x80, 0x81, 0x01, 0x80, 0x81, 0x01, 0x80, 0x81, 0x01, 0x00, 0xC3, 0x00, 0x00, 0xFF, 0x00, 0x80, 0xBD, 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, // Code for char ¤ + 0x0B, 0x10, 0x00, 0x00, 0x70, 0x98, 0x01, 0xF0, 0x99, 0x01, 0xF0, 0x9F, 0x01, 0x80, 0xFF, 0x0F, 0x00, 0xFC, 0x0F, 0x00, 0xFF, 0x0F, 0xE0, 0x9F, 0x01, 0xF0, 0x99, 0x01, 0x70, 0x98, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¥ + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x8F, 0x3F, 0xF0, 0x8F, 0x3F, 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, // Code for char ¦ + 0x0A, 0x00, 0x00, 0x00, 0xE0, 0x39, 0x18, 0xE0, 0x7F, 0x38, 0xF0, 0xFF, 0x38, 0x30, 0xC7, 0x31, 0x30, 0xCE, 0x31, 0x30, 0x8E, 0x33, 0x70, 0xFC, 0x3F, 0x70, 0xF8, 0x3F, 0x60, 0x70, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char § + 0x06, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 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, // Code for char ¨ + 0x0D, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xC0, 0x00, 0x03, 0x20, 0x7E, 0x04, 0x10, 0xFF, 0x08, 0x90, 0x81, 0x09, 0x90, 0x81, 0x09, 0x90, 0x81, 0x09, 0x10, 0xE7, 0x08, 0x20, 0x66, 0x04, 0x40, 0x00, 0x02, 0x80, 0x81, 0x01, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char © + 0x07, 0x00, 0x07, 0x00, 0xB0, 0x0F, 0x00, 0xB8, 0x0C, 0x00, 0x98, 0x04, 0x00, 0xF8, 0x07, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x0C, 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, // Code for char ª + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xC7, 0x01, 0x00, 0x11, 0x01, 0x00, 0x7C, 0x00, 0x00, 0xFE, 0x01, 0x00, 0xC7, 0x01, 0x00, 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, // Code for char « + 0x0B, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¬ + 0x06, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 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, // Code for char ­ + 0x0D, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xC0, 0x80, 0x03, 0x60, 0x00, 0x06, 0xA0, 0xFF, 0x05, 0x90, 0xFF, 0x09, 0x90, 0x19, 0x08, 0x90, 0x19, 0x08, 0x90, 0xFF, 0x08, 0x20, 0xE7, 0x05, 0x60, 0x00, 0x07, 0xC0, 0x81, 0x03, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ® + 0x06, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 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, // Code for char ¯ + 0x08, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0xE0, 0x03, 0x00, 0x30, 0x06, 0x00, 0x30, 0x06, 0x00, 0x30, 0x06, 0x00, 0xE0, 0x03, 0x00, 0xC0, 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, // Code for char ° + 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0xC0, 0xFF, 0x0E, 0xC0, 0xFF, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x1C, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ± + 0x06, 0x70, 0x18, 0x00, 0x70, 0x1E, 0x00, 0x18, 0x1F, 0x00, 0x98, 0x1B, 0x00, 0xF0, 0x19, 0x00, 0x70, 0x18, 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, // Code for char ² + 0x06, 0x30, 0x0C, 0x00, 0x30, 0x0C, 0x00, 0x98, 0x19, 0x00, 0x98, 0x19, 0x00, 0xF0, 0x0F, 0x00, 0x70, 0x0E, 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, // Code for char ³ + 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x38, 0x00, 0x00, 0x18, 0x00, 0x00, 0x08, 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, // Code for char ´ + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x06, 0x00, 0xFF, 0x07, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char µ + 0x0A, 0x80, 0x07, 0x00, 0xC0, 0x1F, 0x00, 0xE0, 0x3F, 0x00, 0xF0, 0x3F, 0x00, 0xF0, 0xFF, 0x3F, 0xF0, 0xFF, 0x3F, 0x30, 0x00, 0x00, 0xF0, 0xFF, 0x3F, 0xF0, 0xFF, 0x3F, 0x30, 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, // Code for char ¶ + 0x04, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 0x00, 0x00, 0x38, 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, // Code for char · + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x08, 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, // Code for char ¸ + 0x05, 0x20, 0x18, 0x00, 0x20, 0x18, 0x00, 0xF0, 0x1F, 0x00, 0xF8, 0x1F, 0x00, 0x00, 0x18, 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, // Code for char ¹ + 0x07, 0xE0, 0x03, 0x00, 0xF0, 0x07, 0x00, 0x18, 0x0C, 0x00, 0x18, 0x0C, 0x00, 0x18, 0x0C, 0x00, 0xF0, 0x07, 0x00, 0xE0, 0x03, 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, // Code for char º + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0xC7, 0x01, 0x00, 0xFE, 0x01, 0x00, 0x7C, 0x00, 0x00, 0x11, 0x01, 0x00, 0xC7, 0x01, 0x00, 0xFE, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x10, 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, // Code for char » + 0x0F, 0x60, 0x30, 0x00, 0x60, 0x30, 0x00, 0xF0, 0x3F, 0x00, 0xF0, 0x3F, 0x0C, 0x00, 0x30, 0x06, 0x00, 0x80, 0x03, 0x00, 0xE0, 0x00, 0x00, 0x38, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x87, 0x03, 0xC0, 0xE1, 0x03, 0x60, 0x78, 0x03, 0x10, 0x88, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¼ + 0x0F, 0x60, 0x30, 0x00, 0x60, 0x30, 0x00, 0xF0, 0x3F, 0x08, 0xF0, 0x3F, 0x0C, 0x00, 0x30, 0x06, 0x00, 0xB0, 0x01, 0x00, 0xE0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x07, 0x00, 0x80, 0x39, 0x0C, 0x60, 0x3C, 0x0F, 0x10, 0x8C, 0x0F, 0x00, 0xFC, 0x0C, 0x00, 0x38, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ½ + 0x0F, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x70, 0x38, 0x00, 0x30, 0x33, 0x08, 0xE0, 0x3F, 0x0E, 0xC0, 0x1C, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x87, 0x03, 0xC0, 0xE1, 0x03, 0x60, 0x78, 0x03, 0x30, 0x88, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¾ + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0xC0, 0x1F, 0x00, 0xE0, 0x3F, 0xC0, 0x7D, 0x38, 0xC0, 0x3D, 0x38, 0xC0, 0x1D, 0x38, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ¿ + 0x0E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0xFC, 0x03, 0x80, 0xFF, 0x01, 0xF2, 0xCF, 0x01, 0xF6, 0xC1, 0x01, 0xF6, 0xC1, 0x01, 0xF4, 0xCF, 0x01, 0x80, 0xFF, 0x01, 0x00, 0xFC, 0x07, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char À + 0x0E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0xFC, 0x03, 0x80, 0xFF, 0x01, 0xF4, 0xCF, 0x01, 0xF6, 0xC1, 0x01, 0xF6, 0xC1, 0x01, 0xF2, 0xCF, 0x01, 0x80, 0xFF, 0x01, 0x00, 0xFC, 0x07, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Á + 0x0E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0xFC, 0x03, 0x84, 0xFF, 0x01, 0xF6, 0xCF, 0x01, 0xF2, 0xC1, 0x01, 0xF2, 0xC1, 0x01, 0xF6, 0xCF, 0x01, 0x84, 0xFF, 0x01, 0x00, 0xFC, 0x07, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char  + 0x0E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xE0, 0x0F, 0x04, 0xFC, 0x03, 0x86, 0xFF, 0x01, 0xF2, 0xCF, 0x01, 0xF2, 0xC1, 0x01, 0xF6, 0xC1, 0x01, 0xF6, 0xCF, 0x01, 0x82, 0xFF, 0x01, 0x00, 0xFC, 0x07, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à + 0x0E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0xFC, 0x07, 0x86, 0xFF, 0x01, 0xF6, 0xCF, 0x01, 0xF0, 0xC0, 0x01, 0xF0, 0xC1, 0x01, 0xF6, 0xCF, 0x01, 0x86, 0xFF, 0x01, 0x00, 0xFC, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ä + 0x0E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0E, 0x00, 0xE0, 0x0F, 0x00, 0xFC, 0x07, 0x80, 0xFF, 0x01, 0xE6, 0xCF, 0x01, 0xE9, 0xC1, 0x01, 0xE9, 0xC1, 0x01, 0xE6, 0xDF, 0x01, 0x80, 0xFF, 0x01, 0x00, 0xFC, 0x0F, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Å + 0x12, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0F, 0x00, 0xE0, 0x0F, 0x00, 0xF8, 0x03, 0x00, 0xFF, 0x01, 0xC0, 0xCF, 0x01, 0xF0, 0xC3, 0x01, 0xF0, 0xC0, 0x01, 0xF0, 0xCF, 0x01, 0xF0, 0xFF, 0x01, 0x70, 0xFF, 0x0F, 0x70, 0xFC, 0x0F, 0x70, 0x1C, 0x0F, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x00, 0x0E, // Code for char Æ + 0x0D, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0xE0, 0xFF, 0x00, 0xF0, 0xFF, 0x01, 0x78, 0xC0, 0x01, 0x18, 0x80, 0x23, 0x1C, 0x80, 0x2F, 0x1C, 0x00, 0x3F, 0x1C, 0x80, 0x13, 0x38, 0xC0, 0x03, 0xF8, 0xF0, 0x01, 0xF0, 0xF0, 0x00, 0xC0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ç + 0x0B, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x72, 0x1C, 0x0E, 0x76, 0x1C, 0x0E, 0x74, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char È + 0x0B, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x74, 0x1C, 0x0E, 0x76, 0x1C, 0x0E, 0x76, 0x1C, 0x0E, 0x72, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char É + 0x0B, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF4, 0xFF, 0x0F, 0x76, 0x1C, 0x0E, 0x72, 0x1C, 0x0E, 0x72, 0x1C, 0x0E, 0x76, 0x1C, 0x0E, 0x74, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ê + 0x0B, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF6, 0xFF, 0x0F, 0x76, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x76, 0x1C, 0x0E, 0x76, 0x1C, 0x0E, 0x70, 0x1C, 0x0E, 0x70, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ë + 0x04, 0x00, 0x00, 0x00, 0xF2, 0xFF, 0x0F, 0xF6, 0xFF, 0x0F, 0xF4, 0xFF, 0x0F, 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, // Code for char Ì + 0x04, 0x00, 0x00, 0x00, 0xF4, 0xFF, 0x0F, 0xF6, 0xFF, 0x0F, 0xF2, 0xFF, 0x0F, 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, // Code for char Í + 0x06, 0x04, 0x00, 0x00, 0xF6, 0xFF, 0x0F, 0xF2, 0xFF, 0x0F, 0xF6, 0xFF, 0x0F, 0x06, 0x00, 0x00, 0x04, 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, // Code for char Î + 0x06, 0x06, 0x00, 0x00, 0xE6, 0xFF, 0x0F, 0xE0, 0xFF, 0x0F, 0xE0, 0xFF, 0x0F, 0x06, 0x00, 0x00, 0x06, 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, // Code for char Ï + 0x0D, 0x00, 0x18, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x70, 0x18, 0x0E, 0x70, 0x18, 0x0E, 0x70, 0x18, 0x0E, 0x70, 0x00, 0x0E, 0xE0, 0x00, 0x07, 0xE0, 0x81, 0x07, 0xC0, 0xFF, 0x03, 0x80, 0xFF, 0x01, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ð + 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF4, 0xFF, 0x0F, 0xF6, 0xFF, 0x0F, 0xE2, 0x07, 0x00, 0x82, 0x1F, 0x00, 0x02, 0x7E, 0x00, 0x06, 0xF8, 0x01, 0x04, 0xE0, 0x07, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ñ + 0x0E, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x03, 0xE0, 0x81, 0x07, 0xE2, 0x00, 0x06, 0x76, 0x00, 0x0E, 0x76, 0x00, 0x0E, 0x74, 0x00, 0x0E, 0xE0, 0x00, 0x07, 0xE0, 0x81, 0x07, 0xC0, 0xFF, 0x03, 0x80, 0xFF, 0x01, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ò + 0x0E, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x03, 0xE0, 0x81, 0x07, 0xE0, 0x00, 0x06, 0x74, 0x00, 0x0E, 0x76, 0x00, 0x0E, 0x76, 0x00, 0x0E, 0xE2, 0x00, 0x07, 0xE0, 0x81, 0x07, 0xC0, 0xFF, 0x03, 0x80, 0xFF, 0x01, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ó + 0x0E, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x03, 0xE4, 0x81, 0x07, 0xE6, 0x00, 0x06, 0x76, 0x00, 0x0E, 0x72, 0x00, 0x0E, 0x76, 0x00, 0x0E, 0xE6, 0x00, 0x07, 0xE4, 0x81, 0x07, 0xC0, 0xFF, 0x03, 0x80, 0xFF, 0x01, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ô + 0x0E, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x03, 0xE4, 0x81, 0x07, 0xE2, 0x00, 0x06, 0x72, 0x00, 0x0E, 0x72, 0x00, 0x0E, 0x72, 0x00, 0x0E, 0xE6, 0x00, 0x07, 0xE2, 0x81, 0x07, 0xC0, 0xFF, 0x03, 0x80, 0xFF, 0x01, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Õ + 0x0E, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x80, 0xFF, 0x01, 0xC0, 0xFF, 0x03, 0xE6, 0x81, 0x07, 0xE6, 0x00, 0x06, 0x70, 0x00, 0x0E, 0x70, 0x00, 0x0E, 0x76, 0x00, 0x0E, 0xE6, 0x00, 0x07, 0xE0, 0x81, 0x07, 0xC0, 0xFF, 0x03, 0x80, 0xFF, 0x01, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ö + 0x0B, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x0E, 0x07, 0x00, 0x9C, 0x03, 0x00, 0xF8, 0x01, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x9C, 0x03, 0x00, 0x0E, 0x07, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char × + 0x0E, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x10, 0x80, 0xFF, 0x0D, 0xC0, 0xFF, 0x0F, 0xE0, 0x81, 0x07, 0xE0, 0xE0, 0x0E, 0x70, 0x70, 0x0E, 0x70, 0x18, 0x0E, 0x70, 0x0E, 0x0E, 0x70, 0x07, 0x07, 0xE0, 0x81, 0x07, 0xF0, 0xFF, 0x03, 0xB8, 0xFF, 0x01, 0x08, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ø + 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x01, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x07, 0x02, 0x00, 0x0F, 0x06, 0x00, 0x0E, 0x06, 0x00, 0x0E, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x0F, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ù + 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x01, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x07, 0x00, 0x00, 0x0F, 0x04, 0x00, 0x0E, 0x06, 0x00, 0x0E, 0x06, 0x00, 0x0E, 0x02, 0x00, 0x0F, 0xF0, 0xFF, 0x07, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ú + 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x01, 0xF0, 0xFF, 0x03, 0xF4, 0xFF, 0x07, 0x04, 0x00, 0x0F, 0x06, 0x00, 0x0E, 0x02, 0x00, 0x0E, 0x06, 0x00, 0x0E, 0x04, 0x00, 0x0F, 0xF4, 0xFF, 0x07, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Û + 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x01, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x07, 0x06, 0x00, 0x0F, 0x06, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0E, 0x06, 0x00, 0x0F, 0xF6, 0xFF, 0x07, 0xF0, 0xFF, 0x03, 0xF0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ü + 0x0D, 0x10, 0x00, 0x00, 0x70, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xF0, 0x07, 0x00, 0x80, 0x1F, 0x00, 0x04, 0xFE, 0x0F, 0x06, 0xF8, 0x0F, 0x02, 0xFE, 0x0F, 0x80, 0x1F, 0x00, 0xE0, 0x07, 0x00, 0xF0, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Ý + 0x0C, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x80, 0xC3, 0x01, 0x80, 0xC3, 0x01, 0x80, 0xC3, 0x01, 0x80, 0xC3, 0x01, 0x80, 0xE3, 0x01, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Þ + 0x0B, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x0F, 0xE0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0x38, 0x00, 0x00, 0x38, 0x1C, 0x0E, 0x38, 0x1C, 0x0E, 0x38, 0x1E, 0x0E, 0xF0, 0xFF, 0x07, 0xF0, 0xF3, 0x03, 0xC0, 0xE1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ß + 0x0A, 0x00, 0x80, 0x03, 0x00, 0xCC, 0x07, 0x08, 0xCE, 0x0F, 0x18, 0x6F, 0x0E, 0x38, 0x67, 0x06, 0x20, 0x67, 0x06, 0x00, 0xFF, 0x03, 0x00, 0xFE, 0x07, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char à + 0x0A, 0x00, 0x80, 0x03, 0x00, 0xCC, 0x07, 0x00, 0xCE, 0x0F, 0x20, 0x6F, 0x0E, 0x30, 0x67, 0x06, 0x38, 0x67, 0x06, 0x18, 0xFF, 0x03, 0x08, 0xFE, 0x07, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char á + 0x0A, 0x00, 0x80, 0x03, 0x00, 0xCC, 0x07, 0x20, 0xCE, 0x0F, 0x38, 0x6F, 0x0E, 0x18, 0x67, 0x06, 0x38, 0x67, 0x06, 0x30, 0xFF, 0x03, 0x20, 0xFE, 0x07, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char â + 0x0A, 0x00, 0x80, 0x03, 0x30, 0xCC, 0x07, 0x38, 0xCE, 0x0F, 0x18, 0x6F, 0x0E, 0x10, 0x67, 0x06, 0x30, 0x67, 0x06, 0x30, 0xFF, 0x03, 0x38, 0xFE, 0x07, 0x08, 0xFC, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ã + 0x0A, 0x00, 0x80, 0x03, 0x00, 0xCC, 0x07, 0x38, 0xCE, 0x0F, 0x38, 0x6F, 0x0E, 0x00, 0x67, 0x06, 0x00, 0x67, 0x06, 0x38, 0xFF, 0x03, 0x38, 0xFE, 0x07, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ä + 0x0A, 0x00, 0x80, 0x03, 0x00, 0xCC, 0x07, 0x00, 0xCE, 0x0F, 0x30, 0x6F, 0x0E, 0x48, 0x67, 0x06, 0x48, 0x67, 0x06, 0x30, 0xFF, 0x03, 0x00, 0xFE, 0x07, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char å + 0x10, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x03, 0x00, 0xCE, 0x07, 0x00, 0xCE, 0x0F, 0x00, 0x67, 0x0E, 0x00, 0x67, 0x0E, 0x00, 0x67, 0x06, 0x00, 0xFE, 0x07, 0x00, 0xFE, 0x03, 0x00, 0xFE, 0x07, 0x00, 0x67, 0x0E, 0x00, 0x67, 0x0E, 0x00, 0x67, 0x0E, 0x00, 0x7E, 0x07, 0x00, 0x7C, 0x07, 0x00, 0x78, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char æ + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x07, 0x00, 0xFE, 0x8F, 0x00, 0x07, 0xBE, 0x00, 0x07, 0xBC, 0x00, 0x07, 0xEC, 0x00, 0x1E, 0x4F, 0x00, 0x1E, 0x07, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ç + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x08, 0xFC, 0x03, 0x08, 0xFE, 0x07, 0x18, 0x67, 0x0E, 0x30, 0x67, 0x0E, 0x20, 0x67, 0x0E, 0x00, 0x7E, 0x07, 0x00, 0x7C, 0x07, 0x00, 0x78, 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, // Code for char è + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x00, 0xFE, 0x07, 0x20, 0x67, 0x0E, 0x30, 0x67, 0x0E, 0x38, 0x67, 0x0E, 0x08, 0x7E, 0x07, 0x08, 0x7C, 0x07, 0x00, 0x78, 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, // Code for char é + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x30, 0xFE, 0x07, 0x38, 0x67, 0x0E, 0x18, 0x67, 0x0E, 0x38, 0x67, 0x0E, 0x30, 0x7E, 0x07, 0x20, 0x7C, 0x07, 0x00, 0x78, 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, // Code for char ê + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x38, 0xFC, 0x03, 0x38, 0xFE, 0x07, 0x00, 0x67, 0x0E, 0x00, 0x67, 0x0E, 0x38, 0x67, 0x0E, 0x38, 0x7E, 0x07, 0x00, 0x7C, 0x07, 0x00, 0x78, 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, // Code for char ë + 0x04, 0x08, 0x00, 0x00, 0x38, 0xFF, 0x0F, 0x30, 0xFF, 0x0F, 0x20, 0xFF, 0x0F, 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, // Code for char ì + 0x06, 0x00, 0x00, 0x00, 0x20, 0xFF, 0x0F, 0x30, 0xFF, 0x0F, 0x38, 0xFF, 0x0F, 0x08, 0x00, 0x00, 0x08, 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, // Code for char í + 0x06, 0x30, 0x00, 0x00, 0x38, 0xFF, 0x0F, 0x18, 0xFF, 0x0F, 0x38, 0xFF, 0x0F, 0x30, 0x00, 0x00, 0x20, 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, // Code for char î + 0x06, 0x38, 0x00, 0x00, 0x38, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x38, 0x00, 0x00, 0x38, 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, // Code for char ï + 0x0B, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x28, 0xFE, 0x07, 0x38, 0x07, 0x0F, 0x38, 0x07, 0x0E, 0xF8, 0x07, 0x0E, 0xF0, 0x07, 0x0F, 0xF0, 0xFF, 0x07, 0x30, 0xFF, 0x03, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ð + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x30, 0xFF, 0x0F, 0x18, 0xFE, 0x0F, 0x18, 0x06, 0x00, 0x10, 0x06, 0x00, 0x30, 0x07, 0x00, 0x30, 0xFF, 0x0F, 0x18, 0xFE, 0x0F, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ñ + 0x0B, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x08, 0xFE, 0x07, 0x18, 0x07, 0x0F, 0x38, 0x07, 0x0E, 0x30, 0x07, 0x0E, 0x20, 0x07, 0x0F, 0x00, 0xFE, 0x07, 0x00, 0xFC, 0x03, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ò + 0x0B, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x00, 0xFE, 0x07, 0x20, 0x07, 0x0F, 0x30, 0x07, 0x0E, 0x38, 0x07, 0x0E, 0x18, 0x07, 0x0F, 0x08, 0xFE, 0x07, 0x00, 0xFC, 0x03, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ó + 0x0B, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x20, 0xFE, 0x07, 0x30, 0x07, 0x0F, 0x18, 0x07, 0x0E, 0x18, 0x07, 0x0E, 0x30, 0x07, 0x0F, 0x20, 0xFE, 0x07, 0x00, 0xFC, 0x03, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ô + 0x0B, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x30, 0xFC, 0x03, 0x38, 0xFE, 0x07, 0x18, 0x07, 0x0F, 0x18, 0x07, 0x0E, 0x30, 0x07, 0x0E, 0x30, 0x07, 0x0F, 0x38, 0xFE, 0x07, 0x18, 0xFC, 0x03, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char õ + 0x0B, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xFC, 0x03, 0x38, 0xFE, 0x07, 0x38, 0x07, 0x0F, 0x00, 0x07, 0x0E, 0x00, 0x07, 0x0E, 0x38, 0x07, 0x0F, 0x38, 0xFE, 0x07, 0x00, 0xFC, 0x03, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ö + 0x0C, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xEE, 0x07, 0x00, 0xEE, 0x07, 0x00, 0xEE, 0x07, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ÷ + 0x0B, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x11, 0x00, 0xFC, 0x0F, 0x00, 0xFE, 0x07, 0x00, 0x87, 0x0F, 0x00, 0xE7, 0x0E, 0x00, 0x77, 0x0E, 0x00, 0x1E, 0x0F, 0x00, 0xFE, 0x07, 0x00, 0xFF, 0x03, 0x80, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ø + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x08, 0xFF, 0x07, 0x08, 0xFF, 0x0F, 0x18, 0x00, 0x0E, 0x30, 0x00, 0x06, 0x20, 0x00, 0x06, 0x00, 0xFF, 0x07, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ù + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0xFF, 0x07, 0x00, 0xFF, 0x0F, 0x20, 0x00, 0x0E, 0x30, 0x00, 0x06, 0x18, 0x00, 0x06, 0x08, 0xFF, 0x07, 0x08, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ú + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0xFF, 0x07, 0x30, 0xFF, 0x0F, 0x38, 0x00, 0x0E, 0x18, 0x00, 0x06, 0x38, 0x00, 0x06, 0x30, 0xFF, 0x07, 0x00, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char û + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0xFF, 0x07, 0x38, 0xFF, 0x0F, 0x38, 0x00, 0x0E, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x38, 0xFF, 0x07, 0x38, 0xFF, 0x0F, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ü + 0x0A, 0x00, 0x01, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x7F, 0xE0, 0x20, 0xFC, 0xF3, 0x30, 0xE0, 0x7F, 0x38, 0x80, 0x3F, 0x18, 0xF8, 0x07, 0x08, 0xFF, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x03, 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, // Code for char ý + 0x0B, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0x00, 0x06, 0x06, 0x00, 0x06, 0x0E, 0x00, 0x07, 0x0E, 0x00, 0x0F, 0x0E, 0x00, 0xFE, 0x07, 0x00, 0xFE, 0x07, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char þ + 0x0A, 0x00, 0x01, 0x00, 0x00, 0x1F, 0xE0, 0x38, 0xFF, 0xE0, 0x38, 0xFC, 0xF7, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0x3F, 0x38, 0xF0, 0x0F, 0x38, 0xFF, 0x01, 0x00, 0x1F, 0x00, 0x00, 0x03, 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 // Code for char ÿ + }; + +const struct SSD1306_FontDef Font_line_2 = { + Archivo_Narrow18x24, + 18, + 24, + ' ', + '\xFF', + false +}; diff --git a/components/services/tarablessd1306/ssd1306.c b/components/services/tarablessd1306/ssd1306.c index 343652cd..739cb975 100644 --- a/components/services/tarablessd1306/ssd1306.c +++ b/components/services/tarablessd1306/ssd1306.c @@ -136,6 +136,8 @@ void SSD1306_SetDisplayAddressMode( struct SSD1306_Device* DeviceHandle, SSD1306 void SSD1306_Update( struct SSD1306_Device* DeviceHandle ) { NullCheck( DeviceHandle, return ); + SSD1306_SetColumnAddress( DeviceHandle, 0, DeviceHandle->Width - 1); + SSD1306_SetPageAddress( DeviceHandle, 0, DeviceHandle->Height / 8 - 1); SSD1306_WriteData( DeviceHandle, DeviceHandle->Framebuffer, DeviceHandle->FramebufferSize ); } diff --git a/components/services/tarablessd1306/ssd1306_draw.c b/components/services/tarablessd1306/ssd1306_draw.c index c241ae96..c1329986 100644 --- a/components/services/tarablessd1306/ssd1306_draw.c +++ b/components/services/tarablessd1306/ssd1306_draw.c @@ -40,7 +40,7 @@ __attribute__( ( always_inline ) ) static inline void SwapInt( int* a, int* b ) *a = Temp; } -static inline void IRAM_ATTR SSD1306_DrawPixelFast( struct SSD1306_Device* DeviceHandle, int X, int Y, int Color ) { +inline void IRAM_ATTR SSD1306_DrawPixelFast( struct SSD1306_Device* DeviceHandle, int X, int Y, int Color ) { uint32_t YBit = ( Y & 0x07 ); uint8_t* FBOffset = NULL; diff --git a/components/services/tarablessd1306/ssd1306_draw.h b/components/services/tarablessd1306/ssd1306_draw.h index 9d325a75..35251cd5 100644 --- a/components/services/tarablessd1306/ssd1306_draw.h +++ b/components/services/tarablessd1306/ssd1306_draw.h @@ -40,6 +40,7 @@ extern "C" { void SSD1306_Clear( struct SSD1306_Device* DeviceHandle, int Color ); void SSD1306_DrawPixel( struct SSD1306_Device* DeviceHandle, int X, int Y, int Color ); +void SSD1306_DrawPixelFast( struct SSD1306_Device* DeviceHandle, int X, int Y, int Color ); void SSD1306_DrawHLine( struct SSD1306_Device* DeviceHandle, int x, int y, int Width, int Color ); void SSD1306_DrawVLine( struct SSD1306_Device* DeviceHandle, int x, int y, int Height, int Color ); void SSD1306_DrawLine( struct SSD1306_Device* DeviceHandle, int x0, int y0, int x1, int y1, int Color ); diff --git a/components/services/tarablessd1306/ssd1306_font.h b/components/services/tarablessd1306/ssd1306_font.h index 2e88400c..942bb026 100644 --- a/components/services/tarablessd1306/ssd1306_font.h +++ b/components/services/tarablessd1306/ssd1306_font.h @@ -81,6 +81,9 @@ extern const struct SSD1306_FontDef Font_liberation_mono_17x30; extern const struct SSD1306_FontDef Font_Tarable7Seg_16x32; extern const struct SSD1306_FontDef Font_Tarable7Seg_32x64; +extern const struct SSD1306_FontDef Font_line_1; +extern const struct SSD1306_FontDef Font_line_2; + #ifdef __cplusplus } #endif diff --git a/components/squeezelite/decode_external.c b/components/squeezelite/decode_external.c index 66ffc6d3..a79d4d16 100644 --- a/components/squeezelite/decode_external.c +++ b/components/squeezelite/decode_external.c @@ -100,10 +100,8 @@ static void sink_data_handler(const uint8_t *data, uint32_t len) * BT sink command handler */ -static bool bt_sink_cmd_handler(bt_sink_cmd_t cmd, ...) +static bool bt_sink_cmd_handler(bt_sink_cmd_t cmd, va_list args) { - va_list args; - // don't LOCK_O as there is always a chance that LMS takes control later anyway if (output.external != DECODE_BT && output.state > OUTPUT_STOPPED) { LOG_WARN("Cannot use BT sink while LMS/AirPlay is controlling player"); @@ -112,24 +110,22 @@ static bool bt_sink_cmd_handler(bt_sink_cmd_t cmd, ...) LOCK_D; - va_start(args, cmd); - if (cmd != BT_SINK_VOLUME) LOCK_O; switch(cmd) { - case BT_SINK_CONNECTED: + case BT_SINK_AUDIO_STARTED: + output.next_sample_rate = output.current_sample_rate = va_arg(args, u32_t); output.external = DECODE_BT; output.state = OUTPUT_STOPPED; output.frames_played = 0; _buf_flush(outputbuf); if (decode.state != DECODE_STOPPED) decode.state = DECODE_ERROR; - bt_master(true); LOG_INFO("BT sink started"); break; - case BT_SINK_DISCONNECTED: + case BT_SINK_AUDIO_STOPPED: + // do we still need that? if (output.external == DECODE_BT) { output.state = OUTPUT_OFF; - bt_master(false); LOG_INFO("BT sink stopped"); } break; @@ -139,10 +135,12 @@ static bool bt_sink_cmd_handler(bt_sink_cmd_t cmd, ...) break; case BT_SINK_STOP: _buf_flush(outputbuf); - case BT_SINK_PAUSE: output.state = OUTPUT_STOPPED; LOG_INFO("BT sink stopped"); break; + case BT_SINK_PAUSE: + LOG_INFO("BT sink paused, just silence"); + break; case BT_SINK_RATE: output.next_sample_rate = output.current_sample_rate = va_arg(args, u32_t); LOG_INFO("Setting BT sample rate %u", output.next_sample_rate); @@ -152,13 +150,14 @@ static bool bt_sink_cmd_handler(bt_sink_cmd_t cmd, ...) volume = 65536 * powf(volume / 128.0f, 3); set_volume(volume, volume); break; + default: + break; } } if (cmd != BT_SINK_VOLUME) UNLOCK_O; UNLOCK_D; - va_end(args); return true; } @@ -176,7 +175,7 @@ static void raop_sink_data_handler(const uint8_t *data, uint32_t len, u32_t play /**************************************************************************************** * AirPlay sink command handler */ -static bool raop_sink_cmd_handler(raop_event_t event, void *param) +static bool raop_sink_cmd_handler(raop_event_t event, va_list args) { // don't LOCK_O as there is always a chance that LMS takes control later anyway if (output.external != DECODE_RAOP && output.state > OUTPUT_STOPPED) { @@ -242,7 +241,6 @@ static bool raop_sink_cmd_handler(raop_event_t event, void *param) output.external = DECODE_RAOP; output.state = OUTPUT_STOPPED; if (decode.state != DECODE_STOPPED) decode.state = DECODE_ERROR; - raop_master(true); LOG_INFO("resizing buffer %u", outputbuf->size); break; case RAOP_STREAM: @@ -259,7 +257,6 @@ static bool raop_sink_cmd_handler(raop_event_t event, void *param) output.state = OUTPUT_OFF; output.frames_played = 0; raop_state = event; - raop_master(false); break; case RAOP_FLUSH: LOG_INFO("Flush", NULL); @@ -273,7 +270,7 @@ static bool raop_sink_cmd_handler(raop_event_t event, void *param) LOG_INFO("Play", NULL); if (raop_state != RAOP_PLAY) { output.state = OUTPUT_START_AT; - output.start_at = *(u32_t*) param; + output.start_at = va_arg(args, u32_t); raop_sync.start_time = output.start_at; LOG_INFO("Starting at %u (in %d ms)", output.start_at, output.start_at - gettime_ms()); } @@ -281,7 +278,7 @@ static bool raop_sink_cmd_handler(raop_event_t event, void *param) break; } case RAOP_VOLUME: { - float volume = *((float*) param); + float volume = va_arg(args, double); LOG_INFO("Volume[0..1] %0.4f", volume); volume = 65536 * powf(volume, 3); set_volume((u16_t) volume, (u16_t) volume); @@ -339,7 +336,7 @@ void deregister_external(void) { } } -void decode_resume(int external) { +void decode_restore(int external) { switch (external) { case DECODE_BT: bt_disconnect(); diff --git a/components/squeezelite/display.c b/components/squeezelite/display.c index 442f3470..2b5663c1 100644 --- a/components/squeezelite/display.c +++ b/components/squeezelite/display.c @@ -53,8 +53,16 @@ struct grfg_packet { u16_t width; // # of pixels of scrollable }; +struct ANIC_header { + char opcode[4]; + u32_t length; + u8_t mode; +}; + #pragma pack(pop) +extern struct outputstate output; + static struct scroller_s { // copy of grfs content u8_t screen, direction; @@ -69,30 +77,28 @@ static struct scroller_s { int scroll_len, scroll_step; } scroller; -/* - ANIM_SCREEN_1 => end of first scroll on screen 1 - ANIM_SCREEN_2 => end of first scroll on screen 2 - ANIM_SCROLL_ONCE | ANIM_SCREEN_1 => end of scroll once on screen 1 - ANIM_SCROLL_ONCE | ANIM_SCREEN_2 => end of scroll once on screen 2 -*/ +#define ANIM_NONE 0x00 #define ANIM_TRANSITION 0x01 // A transition animation has finished #define ANIM_SCROLL_ONCE 0x02 #define ANIM_SCREEN_1 0x04 #define ANIM_SCREEN_2 0x08 -#define SCROLL_STACK_SIZE 2048 +static u8_t ANIC_resp = ANIM_NONE; +#define SCROLL_STACK_SIZE 2048 #define LINELEN 40 -#define HEIGHT 32 static log_level loglevel = lINFO; -static SemaphoreHandle_t display_sem; +static SemaphoreHandle_t display_mutex; static bool (*slimp_handler_chain)(u8_t *data, int len); +static void (*slimp_loop_chain)(void); static void (*notify_chain)(in_addr_t ip, u16_t hport, u16_t cport); +static int display_width, display_height; #define max(a,b) (((a) > (b)) ? (a) : (b)) static void server(in_addr_t ip, u16_t hport, u16_t cport); +static void send_server(void); static bool handler(u8_t *data, int len); static void vfdc_handler( u8_t *_data, int bytes_read); static void grfe_handler( u8_t *data, int len); @@ -135,30 +141,62 @@ void sb_display_init(void) { static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__ ((aligned (4))); static EXT_RAM_ATTR StackType_t xStack[SCROLL_STACK_SIZE] __attribute__ ((aligned (4))); + // need to force height to 32 maximum + display_width = display->width; + display_height = min(display->height, 32); + // create scroll management task - display_sem = xSemaphoreCreateMutex(); + display_mutex = xSemaphoreCreateMutex(); scroller.task = xTaskCreateStatic( (TaskFunction_t) scroll_task, "scroll_thread", SCROLL_STACK_SIZE, NULL, ESP_TASK_PRIO_MIN + 1, xStack, &xTaskBuffer); // size scroller - scroller.max = (display->width * display->height / 8) * 10; + scroller.max = (display_width * display_height / 8) * 10; scroller.scroll_frame = malloc(scroller.max); - scroller.back_frame = malloc(display->width * display->height / 8); + scroller.back_frame = malloc(display_width * display_height / 8); // chain handlers slimp_handler_chain = slimp_handler; slimp_handler = handler; + slimp_loop_chain = slimp_loop; + slimp_loop = send_server; + notify_chain = server_notify; server_notify = server; } +/**************************************************************************************** + * Send message to server (ANIC at that time) + */ +static void send_server(void) { + /* + This complication is needed as we cannot send direclty to LMS, because + send_packet is not thread safe. So must subscribe to slimproto busy loop + end send from there + */ + if (ANIC_resp != ANIM_NONE) { + struct ANIC_header pkt_header; + + memset(&pkt_header, 0, sizeof(pkt_header)); + memcpy(&pkt_header.opcode, "ANIC", 4); + pkt_header.length = htonl(sizeof(pkt_header) - 8); + pkt_header.mode = ANIC_resp; + + send_packet((u8_t *)&pkt_header, sizeof(pkt_header)); + + ANIC_resp = ANIM_NONE; + } + + if (slimp_loop_chain) (*slimp_loop_chain)(); +} + /**************************************************************************************** * */ static void server(in_addr_t ip, u16_t hport, u16_t cport) { char msg[32]; sprintf(msg, "%s:%hu", inet_ntoa(ip), hport); - display->text(DISPLAY_CENTER, DISPLAY_CLEAR | DISPLAY_UPDATE, msg); + display->text(DISPLAY_FONT_DEFAULT, DISPLAY_CENTERED, DISPLAY_CLEAR | DISPLAY_UPDATE, msg); if (notify_chain) (*notify_chain)(ip, hport, cport); } @@ -167,6 +205,9 @@ static void server(in_addr_t ip, u16_t hport, u16_t cport) { */ static bool handler(u8_t *data, int len){ bool res = true; + + // don't do anything if we dont own the display (no lock needed) + if (output.external && output.state >= OUTPUT_STOPPED) return true; if (!strncmp((char*) data, "vfdc", 4)) { vfdc_handler(data, len); @@ -249,8 +290,8 @@ static void show_display_buffer(char *ddram) { LOG_INFO("\n\t%.40s\n\t%.40s", line1, line2); - display->text(DISPLAY_TOP_LEFT, DISPLAY_CLEAR, line1); - display->text(DISPLAY_BOTTOM_LEFT, DISPLAY_UPDATE, line2); + display->line(1, DISPLAY_LEFT, DISPLAY_CLEAR, line1); + display->line(2, DISPLAY_LEFT, DISPLAY_CLEAR | DISPLAY_UPDATE, line2); } /**************************************************************************************** @@ -304,12 +345,12 @@ static void vfdc_handler( u8_t *_data, int bytes_read) { * Process graphic display data */ static void grfe_handler( u8_t *data, int len) { - xSemaphoreTake(display_sem, portMAX_DELAY); + xSemaphoreTake(display_mutex, portMAX_DELAY); scroller.active = false; - display->draw_cbr(data + sizeof(struct grfe_packet), HEIGHT); + display->draw_cbr(data + sizeof(struct grfe_packet), display_height); - xSemaphoreGive(display_sem); + xSemaphoreGive(display_mutex); LOG_DEBUG("grfe frame %u", len); } @@ -353,7 +394,7 @@ static void grfs_handler(u8_t *data, int len) { // new grfs frame, build scroller info if (!offset) { // use the display as a general lock - xSemaphoreTake(display_sem, portMAX_DELAY); + xSemaphoreTake(display_mutex, portMAX_DELAY); // copy & set scroll parameters scroller.screen = pkt->screen; @@ -365,7 +406,7 @@ static void grfs_handler(u8_t *data, int len) { scroller.full_width = htons(pkt->width); scroller.updated = scroller.active = true; - xSemaphoreGive(display_sem); + xSemaphoreGive(display_mutex); } // copy scroll frame data (no semaphore needed) @@ -389,17 +430,17 @@ static void grfg_handler(u8_t *data, int len) { memcpy(scroller.back_frame, data + sizeof(struct grfg_packet), len - sizeof(struct grfg_packet)); scroller.window_width = htons(pkt->width); - xSemaphoreTake(display_sem, portMAX_DELAY); + xSemaphoreTake(display_mutex, portMAX_DELAY); // can't be in grfs as we need full size & scroll_width if (scroller.updated) { - scroller.scroll_len = display->width * display->height / 8 - (display->width - scroller.window_width) * display->height / 8; + scroller.scroll_len = display_width * display_height / 8 - (display_width - scroller.window_width) * display_height / 8; if (scroller.direction == 1) { scroller.scroll_ptr = scroller.scroll_frame; - scroller.scroll_step = scroller.by * display->height / 8; + scroller.scroll_step = scroller.by * display_height / 8; } else { scroller.scroll_ptr = scroller.scroll_frame + scroller.size - scroller.scroll_len; - scroller.scroll_step = -scroller.by * display->height / 8; + scroller.scroll_step = -scroller.by * display_height / 8; } scroller.updated = false; @@ -407,10 +448,10 @@ static void grfg_handler(u8_t *data, int len) { if (!scroller.active) { // this is a background update and scroller has been finished, so need to update here - u8_t *frame = malloc(display->width * display->height / 8); - memcpy(frame, scroller.back_frame, display->width * display->height / 8); + u8_t *frame = malloc(display_width * display_height / 8); + memcpy(frame, scroller.back_frame, display_width * display_height / 8); for (int i = 0; i < scroller.scroll_len; i++) frame[i] |= scroller.scroll_ptr[i]; - display->draw_cbr(frame, HEIGHT); + display->draw_cbr(frame, display_height); free(frame); LOG_DEBUG("direct drawing"); } @@ -420,7 +461,7 @@ static void grfg_handler(u8_t *data, int len) { vTaskResume(scroller.task); } - xSemaphoreGive(display_sem); + xSemaphoreGive(display_mutex); } /**************************************************************************************** @@ -428,20 +469,20 @@ static void grfg_handler(u8_t *data, int len) { */ static void scroll_task(void *args) { u8_t *frame = NULL; - int len = display->width * display->height / 8; + int len = display_width * display_height / 8; while (1) { - xSemaphoreTake(display_sem, portMAX_DELAY); + xSemaphoreTake(display_mutex, portMAX_DELAY); // suspend ourselves if nothing to do, grfg will wake us up if (!scroller.active) { - xSemaphoreGive(display_sem); + xSemaphoreGive(display_mutex); vTaskSuspend(NULL); - xSemaphoreTake(display_sem, portMAX_DELAY); + xSemaphoreTake(display_mutex, portMAX_DELAY); } // lock screen & active status - frame = malloc(display->width * display->height / 8); + frame = malloc(display_width * display_height / 8); // scroll required amount of columns (within the window) while (scroller.direction == 1 ? (scroller.scroll_ptr <= scroller.scroll_frame + scroller.size - scroller.scroll_step - len) : @@ -451,14 +492,15 @@ static void scroll_task(void *args) { if (!scroller.active) break; // scroll required amount of columns (within the window) - memcpy(frame, scroller.back_frame, display->width * display->height / 8); + memcpy(frame, scroller.back_frame, display_width * display_height / 8); for (int i = 0; i < scroller.scroll_len; i++) frame[i] |= scroller.scroll_ptr[i]; scroller.scroll_ptr += scroller.scroll_step; - display->draw_cbr(frame, HEIGHT); + display->draw_cbr(frame, display_height); - xSemaphoreGive(display_sem); - usleep(scroller.speed * 1000); - xSemaphoreTake(display_sem, portMAX_DELAY); + xSemaphoreGive(display_mutex); + vTaskDelay(scroller.speed / portTICK_PERIOD_MS); + + xSemaphoreTake(display_mutex, portMAX_DELAY); } // done with scrolling cycle reset scroller ptr @@ -468,23 +510,24 @@ static void scroll_task(void *args) { if (scroller.active) { memcpy(frame, scroller.back_frame, len); for (int i = 0; i < scroller.scroll_len; i++) frame[i] |= scroller.scroll_ptr[i]; - display->draw_cbr(frame, HEIGHT); + display->draw_cbr(frame, display_height); free(frame); // see if we need to pause or if we are done if (scroller.mode) { scroller.active = false; - xSemaphoreGive(display_sem); - //sendANIC(ANIM_SCROLL_ONCE | ANIM_SCREEN_1); + xSemaphoreGive(display_mutex); + // can't call directly send_packet from slimproto as it's not re-entrant + ANIC_resp = ANIM_SCROLL_ONCE | ANIM_SCREEN_1; LOG_INFO("scroll-once terminated"); } else { - xSemaphoreGive(display_sem); - usleep(scroller.pause * 1000); + xSemaphoreGive(display_mutex); + vTaskDelay(scroller.pause / portTICK_PERIOD_MS); LOG_DEBUG("scroll cycle done, pausing for %u (ms)", scroller.pause); } } else { free(frame); - xSemaphoreGive(display_sem); + xSemaphoreGive(display_mutex); LOG_INFO("scroll aborted"); } } diff --git a/components/squeezelite/embedded.h b/components/squeezelite/embedded.h index b0fad3e5..5f75cd77 100644 --- a/components/squeezelite/embedded.h +++ b/components/squeezelite/embedded.h @@ -49,10 +49,11 @@ int pthread_create_name(pthread_t *thread, _CONST pthread_attr_t *attr, void embedded_init(void); void register_external(void); void deregister_external(void); -void decode_resume(int external); +void decode_restore(int external); -// optional, please chain +// optional, please chain if used bool (*slimp_handler)(u8_t *data, int len); +void (*slimp_loop)(void); void (*server_notify)(in_addr_t ip, u16_t hport, u16_t cport); #endif // EMBEDDED_H diff --git a/components/squeezelite/slimproto.c b/components/squeezelite/slimproto.c index 7a45b6ac..982f3b0f 100644 --- a/components/squeezelite/slimproto.c +++ b/components/squeezelite/slimproto.c @@ -87,13 +87,13 @@ static struct { stream_state stream_state; } status; -int autostart; -bool sentSTMu, sentSTMo, sentSTMl; -u32_t new_server; -char *new_server_cap; +static int autostart; +static bool sentSTMu, sentSTMo, sentSTMl; +static u32_t new_server; +static char *new_server_cap; #define PLAYER_NAME_LEN 64 -char player_name[PLAYER_NAME_LEN + 1] = ""; -const char *name_file = NULL; +static char player_name[PLAYER_NAME_LEN + 1] = ""; +static const char *name_file = NULL; void send_packet(u8_t *packet, size_t len) { u8_t *ptr = packet; @@ -377,7 +377,7 @@ static void process_strm(u8_t *pkt, int len) { sentSTMu = sentSTMo = sentSTMl = false; LOCK_O; #if EMBEDDED - if (output.external) decode_resume(output.external); + if (output.external) decode_restore(output.external); output.external = 0; _buf_resize(outputbuf, output.init_size); #endif @@ -770,6 +770,7 @@ static void slimproto_run() { #if IR if (_sendIR) sendIR(ir_code, ir_ts); #endif + if (*slimp_loop) (*slimp_loop)(); } } } diff --git a/components/squeezelite/squeezelite.h b/components/squeezelite/squeezelite.h index ea6eefc0..2544de34 100644 --- a/components/squeezelite/squeezelite.h +++ b/components/squeezelite/squeezelite.h @@ -553,6 +553,7 @@ void buf_destroy(struct buffer *buf); void slimproto(log_level level, char *server, u8_t mac[6], const char *name, const char *namefile, const char *modelname, int maxSampleRate); void slimproto_stop(void); void wake_controller(void); +void send_packet(u8_t *packet, size_t len); // stream.c typedef enum { STOPPED = 0, DISCONNECT, STREAMING_WAIT, diff --git a/components/tools/component.mk b/components/tools/component.mk new file mode 100644 index 00000000..ace79fdb --- /dev/null +++ b/components/tools/component.mk @@ -0,0 +1,11 @@ +# +# Component Makefile +# +# This Makefile should, at the very least, just include $(SDK_PATH)/Makefile. By default, +# this will take the sources in the src/ directory, compile them and link them into +# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, +# please read the SDK documents if you need to do this. +# + +COMPONENT_SRCDIRS := . +COMPONENT_ADD_INCLUDEDIRS := . diff --git a/components/tools/tools.h b/components/tools/tools.h new file mode 100644 index 00000000..00da007d --- /dev/null +++ b/components/tools/tools.h @@ -0,0 +1,23 @@ +/* + * Tools + * + * Philippe G. 2019, philippe_44@outlook.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#pragma once + +void utf8_decode(char *src); diff --git a/components/tools/utf8.c b/components/tools/utf8.c new file mode 100644 index 00000000..210fa311 --- /dev/null +++ b/components/tools/utf8.c @@ -0,0 +1,93 @@ +// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de> +// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. +// Copyright (c) 2017 ZephRay <zephray@outlook.com> +// +// utf8to1252 - almost equivalent to iconv -f utf-8 -t windows-1252, but better + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include "esp_log.h" + +#define TAG "aa" + +#define UTF8_ACCEPT 0 +#define UTF8_REJECT 1 + +static const uint8_t utf8d[] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df + 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef + 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff + 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2 + 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4 + 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6 + 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8 +}; + +static uint32_t decode(uint32_t* state, uint32_t* codep, uint32_t byte) { + uint32_t type = utf8d[byte]; + + *codep = (*state != UTF8_ACCEPT) ? + (byte & 0x3fu) | (*codep << 6) : + (0xff >> type) & (byte); + + *state = utf8d[256 + *state*16 + type]; + return *state; +} + +static uint8_t UNICODEtoCP1252(uint16_t chr) { + if (chr <= 0xff) + return (chr&0xff); + else { + ESP_LOGI(TAG, "some multi-byte %hx", chr); + switch(chr) { + case 0x20ac: return 0x80; break; + case 0x201a: return 0x82; break; + case 0x0192: return 0x83; break; + case 0x201e: return 0x84; break; + case 0x2026: return 0x85; break; + case 0x2020: return 0x86; break; + case 0x2021: return 0x87; break; + case 0x02c6: return 0x88; break; + case 0x2030: return 0x89; break; + case 0x0160: return 0x8a; break; + case 0x2039: return 0x8b; break; + case 0x0152: return 0x8c; break; + case 0x017d: return 0x8e; break; + case 0x2018: return 0x91; break; + case 0x2019: return 0x92; break; + case 0x201c: return 0x93; break; + case 0x201d: return 0x94; break; + case 0x2022: return 0x95; break; + case 0x2013: return 0x96; break; + case 0x2014: return 0x97; break; + case 0x02dc: return 0x98; break; + case 0x2122: return 0x99; break; + case 0x0161: return 0x9a; break; + case 0x203a: return 0x9b; break; + case 0x0153: return 0x9c; break; + case 0x017e: return 0x9e; break; + case 0x0178: return 0x9f; break; + default: return 0x00; break; + } + } +} + +void utf8_decode(char *src) { + uint32_t codep = 0, state = UTF8_ACCEPT; + char *dst = src; + + while (src && *src) { + if (!decode(&state, &codep, *src++)) *dst++ = UNICODEtoCP1252(codep); + } + + *dst = '\0'; +} \ No newline at end of file diff --git a/main/esp_app_main.c b/main/esp_app_main.c index 118db2ab..a6ab3802 100644 --- a/main/esp_app_main.c +++ b/main/esp_app_main.c @@ -308,6 +308,9 @@ void register_default_nvs(){ ESP_LOGD(TAG,"Registering default value for key %s", "Vcc_GPIO"); config_set_default(NVS_TYPE_STR, "Vcc_GPIO", "", 0); + ESP_LOGD(TAG,"Registering default value for key %s", "metadata_config"); + config_set_default(NVS_TYPE_STR, "metadata_config", "", 0); + ESP_LOGD(TAG,"Done setting default values in nvs."); }