This commit is contained in:
eafton 2026-06-05 16:00:34 +08:00 committed by GitHub
commit aad84143d7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 1628 additions and 3 deletions

View file

@ -367,6 +367,8 @@ dep_option(SDL_WAYLAND "Use Wayland video driver" ${UNIX_SYS} "SDL_V
dep_option(SDL_WAYLAND_SHARED "Dynamically load Wayland support" ON "SDL_WAYLAND;SDL_DEPS_SHARED" OFF)
dep_option(SDL_WAYLAND_LIBDECOR "Use client-side window decorations on Wayland" ON "SDL_WAYLAND" OFF)
dep_option(SDL_WAYLAND_LIBDECOR_SHARED "Dynamically load libdecor support" ON "SDL_WAYLAND_LIBDECOR;SDL_WAYLAND_SHARED;SDL_DEPS_SHARED" OFF)
dep_option(SDL_WAYLAND_FCFT "International text rendering for Wayland toolkit functionality" ON "SDL_WAYLAND" OFF)
dep_option(SDL_WAYLAND_FCFT_SHARED "Dynamically load fcft support" ON "SDL_WAYLAND_FCFT;SDL_WAYLAND_SHARED;SDL_DEPS_SHARED" OFF)
dep_option(SDL_RPI "Use Raspberry Pi video driver" ON "SDL_VIDEO;UNIX_SYS;SDL_CPU_ARM32 OR SDL_CPU_ARM64" OFF)
dep_option(SDL_ROCKCHIP "Use ROCKCHIP Hardware Acceleration video driver" ON "SDL_VIDEO;UNIX_SYS;SDL_CPU_ARM32 OR SDL_CPU_ARM64" OFF)
dep_option(SDL_COCOA "Use Cocoa video driver" ON "APPLE" OFF)

View file

@ -758,10 +758,33 @@ macro(CheckWayland)
sdl_link_dependency(libdecor INCLUDES $<TARGET_PROPERTY:PkgConfig::PC_LIBDECOR,INTERFACE_INCLUDE_DIRECTORIES>)
else()
sdl_link_dependency(libdecor LIBS PkgConfig::PC_LIBDECOR PKG_CONFIG_PREFIX PC_LIBDECOR PKG_CONFIG_SPECS ${LibDecor_PKG_CONFIG_SPEC})
endif()
endif()
endif()
endif()
if(SDL_WAYLAND_FCFT)
set(LibFcft_PKG_CONFIG_SPEC fcft)
pkg_check_modules(PC_LIBFCFT IMPORTED_TARGET ${LibFcft_PKG_CONFIG_SPEC})
if(PC_LIBFCFT_FOUND)
if(PC_LIBFCFT_VERSION VERSION_GREATER_EQUAL "3.0.0")
set(LibFcft_PKG_CONFIG_SPEC "fcft>=3.0.0")
endif()
set(HAVE_WAYLAND_FCFT TRUE)
set(HAVE_FCFT_H 1)
if(SDL_WAYLAND_FCFT_SHARED AND NOT HAVE_SDL_LOADSO)
message(WARNING "You must have SDL_LoadObject() support for dynamic fcft loading")
endif()
FindLibraryAndSONAME(fcft LIBDIRS ${PC_LIBFCFT_LIBRARY_DIRS})
if(SDL_WAYLAND_FCFT_SHARED AND FCFT_LIB AND HAVE_SDL_LOADSO)
set(HAVE_WAYLAND_FCFT_SHARED TRUE)
set(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_FCFT "\"${FCFT_LIB_SONAME}\"")
sdl_link_dependency(libfcft INCLUDES $<TARGET_PROPERTY:PkgConfig::PC_LIBFCFT,INTERFACE_INCLUDE_DIRECTORIES>)
else()
sdl_link_dependency(libfcft LIBS PkgConfig::PC_LIBFCFT PKG_CONFIG_PREFIX PC_LIBFCFT PKG_CONFIG_SPECS ${LibFcft_PKG_CONFIG_SPEC})
endif()
endif()
endif()
set(SDL_VIDEO_DRIVER_WAYLAND 1)
endif()
endif()

View file

@ -4145,6 +4145,43 @@ extern "C" {
*/
#define SDL_HINT_VIDEO_WAYLAND_SCALE_TO_DISPLAY "SDL_VIDEO_WAYLAND_SCALE_TO_DISPLAY"
/**
* A variable controlling whether the built in SDL toolkit is prefered over Zenity
* under the Wayland driver.
*
* When this hint is set, the Wayland driver will use the built in toolkit even
* in cases where Zenity is avalible.
*
* The variable can be set to the following values:
*
* - "0": The built in toolkit is only used in cases where Zenity fails or is unavalible.
* (default)
* - "1": The built in toolkit is always used if available.
*
* This hint should be set before SDL is initialized.
*
* \since This hint is available since SDL 3.?.?.
*/
#define SDL_HINT_VIDEO_WAYLAND_PREFER_TOOLKIT "SDL_VIDEO_WAYLAND_PREFER_TOOLKIT"
/**
* A variable controlling whether the built in SDL toolkit uses fcft or
* built in bitmap fonts.
*
* The fcft library is used over the built in bitmap fonts in cases
* where it is avalible.
*
* The variable can be set to the following values:
*
* - "0": Usage of the fcft library is disabled.
* - "1": Usage of the fcft library is enabled. (default)
*
* This hint should be set before SDL is initialized.
*
* \since This hint is available since SDL 3.?.?.
*/
#define SDL_HINT_VIDEO_WAYLAND_ALLOW_FCFT "SDL_VIDEO_WAYLAND_ALLOW_FCFT"
/**
* A variable specifying which shader compiler to preload when using the
* Chrome ANGLE binaries.

View file

@ -216,6 +216,7 @@
#cmakedefine HAVE_LINUX_INPUT_H 1
#cmakedefine HAVE_LIBUDEV_H 1
#cmakedefine HAVE_LIBDECOR_H 1
#cmakedefine HAVE_FCFT_H 1
#cmakedefine HAVE_LIBURING_H 1
#cmakedefine HAVE_FRIBIDI_H 1
#cmakedefine SDL_FRIBIDI_DYNAMIC @SDL_FRIBIDI_DYNAMIC@
@ -425,6 +426,7 @@
#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL@
#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR@
#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON@
#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_FCFT @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_FCFT@
#cmakedefine SDL_VIDEO_DRIVER_WINDOWS 1
#cmakedefine SDL_VIDEO_DRIVER_X11 1
#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC @SDL_VIDEO_DRIVER_X11_DYNAMIC@

View file

@ -24,8 +24,33 @@
#ifdef SDL_VIDEO_DRIVER_WAYLAND
#include "SDL_waylandmessagebox.h"
#include "SDL_waylandtoolkit.h"
#include "../../dialog/unix/SDL_zenitymessagebox.h"
typedef struct SDL_MessageBoxDataToolkit
{
SDL_WaylandTextRenderer *text_renderer;
const SDL_MessageBoxData *messageboxdata;
} SDL_MessageBoxDataToolkit;
bool Wayland_ShowToolkitMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID) {
SDL_MessageBoxDataToolkit data;
SDL_Color color;
data.messageboxdata = messageboxdata;
color.r = 255;
color.g = 0;
color.b = 255;
color.a = 255;
data.text_renderer = WaylandToolkit_CreateTextRenderer();
WaylandToolkit_RenderText(data.text_renderer, (char *)messageboxdata->message, &color);
WaylandToolkit_FreeTextRenderer(data.text_renderer);
return true;
}
bool Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
{
// Are we trying to connect to or are currently in a Wayland session?
@ -35,8 +60,19 @@ bool Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *butto
return SDL_SetError("Not on a wayland display");
}
}
return SDL_Zenity_ShowMessageBox(messageboxdata, buttonID);
if (SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_PREFER_TOOLKIT, false)) {
return Wayland_ShowToolkitMessageBox(messageboxdata, buttonID);
} else {
bool ret;
ret = SDL_Zenity_ShowMessageBox(messageboxdata, buttonID);
if (!ret) {
return Wayland_ShowToolkitMessageBox(messageboxdata, buttonID);
} else {
return ret;
}
}
}
#endif // SDL_VIDEO_DRIVER_WAYLAND

View file

@ -0,0 +1,175 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifdef SDL_VIDEO_DRIVER_WAYLAND
#include "SDL_internal.h"
#include "SDL_waylandtoolkit.h"
#include "SDL_waylandtoolkitbitmap.h"
#ifdef HAVE_FCFT_H
#include "SDL_waylandtoolkitfcft.h"
#endif
/* Nasty struct definition needed because of macro hell :( */
struct SDL_Surface
{
SDL_SurfaceFlags flags;
SDL_PixelFormat format;
int w;
int h;
int pitch;
void *pixels;
int refcount;
void *reserved;
};
extern SDL_WaylandTextRenderer *WaylandToolkit_CreateTextRenderer() {
SDL_WaylandTextRenderer *ret;
#ifdef HAVE_FCFT_H
if (SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_ALLOW_FCFT, true)) {
ret = WaylandToolkit_CreateTextRendererFcft();
} else {
ret = NULL;
}
#else
ret = NULL;
#endif
if (!ret) {
return WaylandToolkit_CreateTextRendererBitmap();
} else {
return ret;
}
}
/* For debugging */
void rand_str(char *dest, size_t length) {
char charset[] = "0123456789"
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
while (length-- > 0) {
size_t index = (size_t)((double) rand() / RAND_MAX * (sizeof charset - 1));
*dest++ = charset[index];
}
*dest = '\0';
}
SDL_Surface *WaylandToolkit_RenderText(SDL_WaylandTextRenderer *renderer, char *utf8, SDL_Color *bg_fill) {
if (renderer) {
SDL_Surface **surfaces;
SDL_Surface *ret;
char *utf8t;
char *start;
char *end;
size_t utf8t_sz;
int surfaces_count;
int max_surface_width;
int total_surface_height;
int i;
SDL_Rect rct;
surfaces = NULL;
max_surface_width = 0;
surfaces_count = 0;
total_surface_height = 0;
rct.x = 0;
rct.y = 0;
ret = NULL;
utf8t_sz = SDL_strlen(utf8) + 2;
utf8t = SDL_malloc(utf8t_sz);
if (!utf8t) {
return NULL;
}
SDL_strlcpy(utf8t, utf8, utf8t_sz);
SDL_strlcat(utf8t, "\n", utf8t_sz);
start = end = utf8t;
while ((end = SDL_strpbrk(start, "\n\r\f\v"))) {
Uint32 *utf32;
char *utf8ta;
size_t sz;
size_t ci;
i = surfaces_count;
surfaces_count++;
if (surfaces_count == 1) {
surfaces = SDL_calloc(surfaces_count, sizeof(SDL_Surface *));
} else {
surfaces = SDL_realloc(surfaces, surfaces_count * sizeof(SDL_Surface *));
}
utf8ta = SDL_strndup(start, (size_t)(end - start));
sz = SDL_utf8strlen(utf8ta);
utf32 = SDL_iconv_utf8_ucs4(utf8ta);
for (ci = 0; ci < sz; ci++) {
utf32[ci] = SDL_Swap32BE(utf32[ci]);
}
surfaces[i] = renderer->render(renderer, utf32, sz, bg_fill);
max_surface_width = SDL_max(max_surface_width, surfaces[i]->w);
total_surface_height += surfaces[i]->h;
SDL_free(utf32);
SDL_free(utf8ta);
start = end + 1;
}
ret = SDL_CreateSurface(max_surface_width, total_surface_height, SDL_PIXELFORMAT_ARGB8888);
puts(SDL_GetError()); /* debug */
for (i = 0; i < surfaces_count; i++) {
SDL_BlitSurface(surfaces[i], NULL, ret, &rct);
rct.y += surfaces[i]->h;
SDL_DestroySurface(surfaces[i]);
}
/* debug */
char a[256];
strcpy(a, "tkdbg_");
rand_str(a+6, 6);
strcpy(a+11, ".bmp");
a[15] = '\0';
SDL_SaveBMP(ret, a);
SDL_free(utf8t);
return ret;
} else {
return NULL;
}
}
void WaylandToolkit_FreeTextRenderer(SDL_WaylandTextRenderer *renderer) {
if (renderer) {
renderer->free(renderer);
}
}
void WaylandToolkit_SetTextRendererSize(SDL_WaylandTextRenderer *renderer, int pt_sz) {
if (renderer) {
renderer->set_pt_sz(renderer, pt_sz);
}
}
void WaylandToolkit_SetTextRendererColor(SDL_WaylandTextRenderer *renderer, SDL_Color *color) {
if (renderer) {
renderer->set_color(renderer, color);
}
}
#endif // SDL_VIDEO_DRIVER_WAYLAND

View file

@ -0,0 +1,43 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_waylandtoolkit_h_
#define SDL_waylandtoolkit_h_
#ifdef SDL_VIDEO_DRIVER_WAYLAND
/* TEXT RENDERING */
typedef struct SDL_WaylandTextRenderer {
SDL_Surface *(*render)(struct SDL_WaylandTextRenderer *renderer, Uint32 *utf32, int sz, SDL_Color *bg_fill);
void (*set_color)(struct SDL_WaylandTextRenderer *renderer, SDL_Color *color);
void (*set_pt_sz)(struct SDL_WaylandTextRenderer *renderer, int pt_sz);
void (*free)(struct SDL_WaylandTextRenderer *renderer);
} SDL_WaylandTextRenderer;
extern SDL_WaylandTextRenderer *WaylandToolkit_CreateTextRenderer();
extern void WaylandToolkit_SetTextRendererSize(SDL_WaylandTextRenderer *renderer, int pt_sz);
extern void WaylandToolkit_SetTextRendererColor(SDL_WaylandTextRenderer *renderer, SDL_Color *color);
extern SDL_Surface *WaylandToolkit_RenderText(SDL_WaylandTextRenderer *renderer, char *utf8, SDL_Color *bg_fill);
extern void WaylandToolkit_FreeTextRenderer(SDL_WaylandTextRenderer *renderer);
#endif // SDL_VIDEO_DRIVER_WAYLAND
#endif // SDL_waylandtoolkit_h_

View file

@ -0,0 +1,223 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_WAYLAND
#include "SDL_waylandtoolkit.h"
#include "SDL_waylandtoolkitbitmap.h"
#include "SDL_waylandtoolkitfont.h"
typedef struct {
SDL_WaylandTextRenderer base;
SDL_HashTable *map;
SDL_Palette *palette;
SDL_Color palette_colors[2];
int px_sz;
} SDL_WaylandTextRendererBitmap;
void WaylandToolkit_FreeTextRendererBitmap(SDL_WaylandTextRenderer *renderer) {
SDL_WaylandTextRendererBitmap *renderer_bmp;
renderer_bmp = (SDL_WaylandTextRendererBitmap *)renderer;
if (renderer_bmp->map) {
SDL_DestroyHashTable(renderer_bmp->map);
}
if (renderer_bmp->palette) {
SDL_DestroyPalette(renderer_bmp->palette);
}
SDL_free(renderer_bmp);
}
static SDL_Surface *WaylandToolkit_RenderTextBitmap(SDL_WaylandTextRenderer *renderer, Uint32 *utf32, int sz, SDL_Color *bg_fill) {
SDL_WaylandTextRendererBitmap *renderer_bmp;
SDL_Surface *complete_surface;
SDL_Rect rct;
SDL_ScaleMode mode;
int i;
int csz;
#define COMPLETE_SURFACE_FORMAT SDL_PIXELFORMAT_ARGB8888
/* Get renderer */
renderer_bmp = (SDL_WaylandTextRendererBitmap *)renderer;
/* Zero out coords of rect */
rct.y = 0;
rct.x = 0;
/* Calculate surface width */
csz = renderer_bmp->px_sz * sz;
if (csz <= 0) {
csz = 1;
}
/* Create surface for rendering */
complete_surface = SDL_CreateSurface(csz, renderer_bmp->px_sz, COMPLETE_SURFACE_FORMAT);
if (!complete_surface) {
return NULL;
}
/* Background fill */
if (bg_fill) {
SDL_Rect rect;
Uint32 color;
rect.x = rect.y = 0;
rect.w = csz;
rect.h = renderer_bmp->px_sz;
color = SDL_MapRGBA(SDL_GetPixelFormatDetails(COMPLETE_SURFACE_FORMAT), NULL, bg_fill->r, bg_fill->g, bg_fill->b, bg_fill->a);
SDL_FillSurfaceRect(complete_surface, &rect, color);
}
/* Set scaling mode */
if (renderer_bmp->px_sz <= 8) {
mode = SDL_SCALEMODE_LINEAR;
} else {
mode = SDL_SCALEMODE_PIXELART;
}
/* Render */
for (i = 0; i < sz; i++) {
SDL_Surface *char_surface;
if (!SDL_FindInHashTable(renderer_bmp->map, (const void *)(uintptr_t)(utf32[i]), (const void **)&char_surface)) {
SDL_FindInHashTable(renderer_bmp->map, (const void *)(uintptr_t)('?'), (const void **)&char_surface);
}
if (renderer_bmp->px_sz == 8) {
SDL_BlitSurface(char_surface, NULL, complete_surface, &rct);
} else {
rct.w = renderer_bmp->px_sz;
rct.h = renderer_bmp->px_sz;
SDL_BlitSurfaceScaled(char_surface, NULL, complete_surface, &rct, mode);
}
rct.x += renderer_bmp->px_sz;
}
return complete_surface;
}
void WaylandToolkit_SetTextRendererSizeBitmap(SDL_WaylandTextRenderer *renderer, int pt_sz) {
SDL_WaylandTextRendererBitmap *renderer_bmp;
double px_sz;
renderer_bmp = (SDL_WaylandTextRendererBitmap *)renderer;
px_sz = pt_sz * 0.75; /* 96 DPI assumed */
renderer_bmp->px_sz = (int)px_sz;
}
static void WaylandToolkit_SetTextRendererColorBitmap(SDL_WaylandTextRenderer *renderer, SDL_Color *color) {
SDL_WaylandTextRendererBitmap *renderer_bmp;
renderer_bmp = (SDL_WaylandTextRendererBitmap *)renderer;
renderer_bmp->palette_colors[1] = *color;
}
static void WaylandToolkit_InsertCharIntoBitmapMap(SDL_HashTable *map, SDL_Palette *palette, char *bmp, long codepoint) {
SDL_Surface *char_surface;
char_surface = SDL_CreateSurfaceFrom(8, 8, SDL_PIXELFORMAT_INDEX1LSB, bmp, 1);
if (char_surface) {
SDL_SetSurfacePalette(char_surface, palette);
SDL_InsertIntoHashTable(map, (const void *)(uintptr_t)codepoint, (void *)char_surface, false);
}
}
SDL_WaylandTextRenderer *WaylandToolkit_CreateTextRendererBitmap() {
SDL_WaylandTextRendererBitmap *renderer;
int i;
/* Alloc */
renderer = (SDL_WaylandTextRendererBitmap *)SDL_malloc(sizeof(SDL_WaylandTextRendererBitmap));
if (!renderer) {
return NULL;
}
renderer->px_sz = 8;
/* Char map */
renderer->map = SDL_CreateHashTable(606, false, SDL_HashID, SDL_KeyMatchID, NULL, NULL);
if (!renderer->map) {
SDL_free(renderer);
return NULL;
}
/* Palette */
renderer->palette = SDL_CreatePalette(2);
if (!renderer->palette) {
SDL_DestroyHashTable(renderer->map);
SDL_free(renderer);
return NULL;
}
renderer->palette_colors[0].r = 0;
renderer->palette_colors[0].g = 0;
renderer->palette_colors[0].b = 0;
renderer->palette_colors[0].a = 0;
renderer->palette_colors[1].r = 255;
renderer->palette_colors[1].g = 255;
renderer->palette_colors[1].b = 255;
renderer->palette_colors[1].a = 255;
SDL_SetPaletteColors(renderer->palette, renderer->palette_colors, 0, 2);
/* Populate char map */
for (i = 0; i < 128; i++) {
WaylandToolkit_InsertCharIntoBitmapMap(renderer->map, renderer->palette, font8x8_basic[i], i);
}
for (i = 0; i < 32; i++) {
WaylandToolkit_InsertCharIntoBitmapMap(renderer->map, renderer->palette, font8x8_control[i], 128 + i);
}
for (i = 0; i < 96; i++) {
WaylandToolkit_InsertCharIntoBitmapMap(renderer->map, renderer->palette, font8x8_ext_latin[i], 160 + i);
}
for (i = 0; i < 58; i++) {
WaylandToolkit_InsertCharIntoBitmapMap(renderer->map, renderer->palette, font8x8_greek[i], 912 + i);
}
WaylandToolkit_InsertCharIntoBitmapMap(renderer->map, renderer->palette, font8x8_misc[0], 0x20A7);
WaylandToolkit_InsertCharIntoBitmapMap(renderer->map, renderer->palette, font8x8_misc[1], 0x0192);
WaylandToolkit_InsertCharIntoBitmapMap(renderer->map, renderer->palette, font8x8_misc[4], 0x2310);
for (i = 0; i < 128; i++) {
WaylandToolkit_InsertCharIntoBitmapMap(renderer->map, renderer->palette, font8x8_box[i], 9472 + i);
}
for (i = 0; i < 32; i++) {
WaylandToolkit_InsertCharIntoBitmapMap(renderer->map, renderer->palette, font8x8_block[i], 0x2580 + i);
}
for (i = 0; i < 96; i++) {
WaylandToolkit_InsertCharIntoBitmapMap(renderer->map, renderer->palette, font8x8_hiragana[i], 0x3040 + i);
}
for (i = 0; i < 26; i++) {
WaylandToolkit_InsertCharIntoBitmapMap(renderer->map, renderer->palette, font8x8_sga[i], 0xE541 + i);
}
/* Functions */
renderer->base.free = WaylandToolkit_FreeTextRendererBitmap;
renderer->base.render = WaylandToolkit_RenderTextBitmap;
renderer->base.set_color = WaylandToolkit_SetTextRendererColorBitmap;
renderer->base.set_pt_sz = WaylandToolkit_SetTextRendererSizeBitmap;
return (SDL_WaylandTextRenderer *)renderer;
}
#endif // SDL_VIDEO_DRIVER_WAYLAND

View file

@ -0,0 +1,33 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_waylandtoolkitfcft_h_
#define SDL_waylandtoolkitfcft_h_
#if defined(SDL_VIDEO_DRIVER_WAYLAND) && defined(HAVE_FCFT_H)
#include "SDL_waylandtoolkit.h"
extern SDL_WaylandTextRenderer *WaylandToolkit_CreateTextRendererFcft();
#endif // defined(SDL_VIDEO_DRIVER_WAYLAND) && defined(HAVE_FCFT_H)
#endif // SDL_waylandtoolkitfcft_h_

View file

@ -0,0 +1,376 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if defined(SDL_VIDEO_DRIVER_WAYLAND) && defined(HAVE_FCFT_H)
#include "SDL_waylandtoolkit.h"
#include "SDL_waylandtoolkitfcft.h"
#include <fcft/fcft.h>
/* #define SDL_WAYLAND_TOOLKIT_FCFT_FINI */
#define SDL_WAYLAND_TOOLKIT_FCFT_DEBUG
/* fcft symbols */
typedef bool (*SDL_WaylandFcftInit)(enum fcft_log_colorize, bool, enum fcft_log_class);
typedef void (*SDL_WaylandFcftFini)(void);
typedef struct fcft_font *(*SDL_WaylandFcftFromName)(size_t count, const char *names[static count], const char *);
typedef void (*SDL_WaylandFcftDestroy)(struct fcft_font *);
typedef enum fcft_capabilities (*SDL_WaylandFcftCaps)(void);
typedef bool (*SDL_WaylandFcftKern)(struct fcft_font *, uint32_t, uint32_t, long *restrict, long *restrict);
typedef struct fcft_glyph *(*SDL_WaylandFcftRastChr)(struct fcft_font *, uint32_t, enum fcft_subpixel);
typedef struct fcft_text_run *(*SDL_WaylandFcftRastRun)(struct fcft_font *, size_t len, const uint32_t text[static len], enum fcft_subpixel);
typedef void (*SDL_WaylandFcftDestroyRun)(struct fcft_text_run *);
/* pixman symbols */
typedef pixman_bool_t (*SDL_WaylandFcftPixmanImgUnref)(pixman_image_t *);
typedef pixman_image_t *(*SDL_WaylandFcftPixmanImgColFill)(const pixman_color_t *);
typedef pixman_image_t *(*SDL_WaylandFcftPixmanImgCreate)(pixman_format_code_t, int, int, uint32_t *, int);
typedef pixman_image_t *(*SDL_WaylandFcftPixmanImgComposite)(pixman_op_t, pixman_image_t *, pixman_image_t *, pixman_image_t *, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t , int32_t, int32_t);
typedef pixman_format_code_t (*SDL_WaylandFcftPixmanImgGetFmt)(pixman_image_t *);
struct SDL_WaylandTextRendererFcft {
SDL_WaylandTextRenderer base;
/* font and color */
struct fcft_font *cfont;
pixman_image_t *color_fill;
/* fcft library and functions */
SDL_SharedObject *fcft_lib;
SDL_WaylandFcftInit fcft_init;
SDL_WaylandFcftFini fcft_fini;
SDL_WaylandFcftFromName fcft_from_name;
SDL_WaylandFcftDestroy fcft_destroy;
SDL_WaylandFcftCaps fcft_capabilities;
SDL_WaylandFcftKern fcft_kerning;
SDL_WaylandFcftRastChr fcft_rasterize_char_utf32;
SDL_WaylandFcftRastRun fcft_rasterize_text_run_utf32;
SDL_WaylandFcftDestroyRun fcft_text_run_destroy;
/* pixman functions */
SDL_WaylandFcftPixmanImgUnref pixman_image_unref;
SDL_WaylandFcftPixmanImgColFill pixman_image_create_solid_fill;
SDL_WaylandFcftPixmanImgCreate pixman_image_create_bits_no_clear;
SDL_WaylandFcftPixmanImgComposite pixman_image_composite32;
SDL_WaylandFcftPixmanImgGetFmt pixman_image_get_format;
};
/* Nasty struct definition needed because of macro hell :( */
struct SDL_Surface
{
SDL_SurfaceFlags flags;
SDL_PixelFormat format;
int w;
int h;
int pitch;
void *pixels;
int refcount;
void *reserved;
};
void WaylandToolkit_SetTextRendererSizeFcft(SDL_WaylandTextRenderer *renderer, int pt_sz) {
struct SDL_WaylandTextRendererFcft *renderer_fcft;
char *attrib;
char *name;
renderer_fcft = (struct SDL_WaylandTextRendererFcft *)renderer;
if(renderer_fcft->cfont) {
renderer_fcft->fcft_destroy(renderer_fcft->cfont);
}
name = "sans";
SDL_asprintf(&attrib, "size=%d", pt_sz);
renderer_fcft->cfont = renderer_fcft->fcft_from_name(1, (const char **)&name, attrib);
SDL_free(attrib);
}
static void WaylandToolkit_SetTextRendererColorFcft(SDL_WaylandTextRenderer *renderer, SDL_Color *color) {
struct SDL_WaylandTextRendererFcft *renderer_fcft;
pixman_color_t pcolor;
renderer_fcft = (struct SDL_WaylandTextRendererFcft *)renderer;
if (renderer_fcft->color_fill) {
renderer_fcft->pixman_image_unref(renderer_fcft->color_fill);
}
pcolor.red = color->r * 257;
pcolor.green = color->g * 257;
pcolor.blue = color->b * 257;
pcolor.alpha = color->a * 257;
renderer_fcft->color_fill = renderer_fcft->pixman_image_create_solid_fill(&pcolor);
}
static void WaylandToolkit_FreeTextRendererFcft(SDL_WaylandTextRenderer *renderer) {
struct SDL_WaylandTextRendererFcft *renderer_fcft;
renderer_fcft = (struct SDL_WaylandTextRendererFcft *)renderer;
if(renderer_fcft->cfont) {
renderer_fcft->fcft_destroy(renderer_fcft->cfont);
}
if(renderer_fcft->color_fill) {
renderer_fcft->pixman_image_unref(renderer_fcft->color_fill);
}
#ifdef SDL_WAYLAND_TOOLKIT_FCFT_FINI
renderer_fcft->fcft_fini();
#endif
if(renderer_fcft->fcft_lib) {
SDL_UnloadObject(renderer_fcft->fcft_lib);
}
SDL_free(renderer_fcft);
}
static SDL_Surface *WaylandToolkit_RenderTextFcft(SDL_WaylandTextRenderer *renderer, Uint32 *utf32, int sz, SDL_Color *bg_fill) {
SDL_Surface *complete_surface;
pixman_image_t *complete_surface_pixman;
struct SDL_WaylandTextRendererFcft *renderer_fcft;
SDL_Rect rct;
enum fcft_capabilities caps;
int i;
complete_surface = NULL;
renderer_fcft = (struct SDL_WaylandTextRendererFcft *)renderer;
caps = renderer_fcft->fcft_capabilities();
rct.x = 0;
rct.y = 0;
rct.h = 0;
rct.w = 0;
/* TODO: FCFT_CAPABILITY_GRAPHEME_SHAPING */
if (caps & FCFT_CAPABILITY_TEXT_RUN_SHAPING) {
struct fcft_text_run *run;
run = renderer_fcft->fcft_rasterize_text_run_utf32(renderer_fcft->cfont, sz, utf32, FCFT_SUBPIXEL_DEFAULT);
/* Calculate extents */
for (i = 0; i < run->count; i++) {
const struct fcft_glyph *glyph;
glyph = run->glyphs[i];
if (i > 0) {
long x_kern;
x_kern = 0;
renderer_fcft->fcft_kerning(renderer_fcft->cfont, utf32[i - 1], utf32[i], &x_kern, NULL);
rct.w += x_kern;
}
rct.w += glyph->advance.x;
rct.h = SDL_max(rct.h, (renderer_fcft->cfont->ascent - glyph->y + glyph->height));
}
/* Create target surface */
complete_surface = SDL_CreateSurface(rct.w, rct.h, SDL_PIXELFORMAT_ARGB8888);
complete_surface_pixman = renderer_fcft->pixman_image_create_bits_no_clear(PIXMAN_a8r8g8b8, rct.w, rct.h, complete_surface->pixels, complete_surface->pitch);
/* Background fill */
if (bg_fill) {
pixman_image_t *bg_fill_img;
pixman_color_t bg_pcolor;
bg_pcolor.red = bg_fill->r * 257;
bg_pcolor.green = bg_fill->g * 257;
bg_pcolor.blue = bg_fill->b * 257;
bg_pcolor.alpha = bg_fill->a * 257;
bg_fill_img = renderer_fcft->pixman_image_create_solid_fill(&bg_pcolor);
renderer_fcft->pixman_image_composite32(PIXMAN_OP_OVER, bg_fill_img, NULL, complete_surface_pixman, 0, 0, 0, 0, 0, 0, rct.w, rct.h);
renderer_fcft->pixman_image_unref(bg_fill_img);
}
/* Blit glyphs on to target */
for (i = 0; i < run->count; i++) {
const struct fcft_glyph *glyph;
glyph = run->glyphs[i];
if (i > 0) {
long x_kern;
x_kern = 0;
renderer_fcft->fcft_kerning(renderer_fcft->cfont, utf32[i - 1], utf32[i], &x_kern, NULL);
rct.x += x_kern;
}
if (renderer_fcft->pixman_image_get_format(glyph->pix) == PIXMAN_a8r8g8b8) {
renderer_fcft->pixman_image_composite32(PIXMAN_OP_OVER, glyph->pix, NULL, complete_surface_pixman, 0, 0, 0, 0, rct.x + glyph->x, renderer_fcft->cfont->ascent - glyph->y, glyph->width, glyph->height);
} else {
renderer_fcft->pixman_image_composite32(PIXMAN_OP_OVER, renderer_fcft->color_fill, glyph->pix, complete_surface_pixman, 0, 0, 0, 0, rct.x + glyph->x, renderer_fcft->cfont->ascent - glyph->y, glyph->width, glyph->height);
}
rct.x += glyph->advance.x;
}
renderer_fcft->fcft_text_run_destroy(run);
} else {
for (i = 0; i < sz; i++) {
const struct fcft_glyph *glyph;
glyph = renderer_fcft->fcft_rasterize_char_utf32(renderer_fcft->cfont, utf32[i], FCFT_SUBPIXEL_DEFAULT);
if (!glyph) {
continue;
}
if (i > 0) {
long x_kern;
x_kern = 0;
renderer_fcft->fcft_kerning(renderer_fcft->cfont, utf32[i - 1], utf32[i], &x_kern, NULL);
rct.w += x_kern;
}
rct.w += glyph->advance.x;
rct.h = SDL_max(rct.h, (renderer_fcft->cfont->ascent - glyph->y + glyph->height));
}
complete_surface = SDL_CreateSurface(rct.w, rct.h, SDL_PIXELFORMAT_ARGB8888);
complete_surface_pixman = renderer_fcft->pixman_image_create_bits_no_clear(PIXMAN_a8r8g8b8, rct.w, rct.h, complete_surface->pixels, complete_surface->pitch);
if (bg_fill) {
pixman_image_t *bg_fill_img;
pixman_color_t bg_pcolor;
bg_pcolor.red = bg_fill->r * 257;
bg_pcolor.green = bg_fill->g * 257;
bg_pcolor.blue = bg_fill->b * 257;
bg_pcolor.alpha = bg_fill->a * 257;
bg_fill_img = renderer_fcft->pixman_image_create_solid_fill(&bg_pcolor);
renderer_fcft->pixman_image_composite32(PIXMAN_OP_OVER, bg_fill_img, NULL, complete_surface_pixman, 0, 0, 0, 0, 0, 0, rct.w, rct.h);
renderer_fcft->pixman_image_unref(bg_fill_img);
}
for (i = 0; i < sz; i++) {
const struct fcft_glyph *glyph;
glyph = renderer_fcft->fcft_rasterize_char_utf32(renderer_fcft->cfont, utf32[i], FCFT_SUBPIXEL_DEFAULT);
if (!glyph) {
continue;
}
if (i > 0) {
long x_kern;
x_kern = 0;
renderer_fcft->fcft_kerning(renderer_fcft->cfont, utf32[i - 1], utf32[i], &x_kern, NULL);
rct.x += x_kern;
}
if (renderer_fcft->pixman_image_get_format(glyph->pix) == PIXMAN_a8r8g8b8) {
renderer_fcft->pixman_image_composite32(PIXMAN_OP_OVER, glyph->pix, NULL, complete_surface_pixman, 0, 0, 0, 0, rct.x + glyph->x, renderer_fcft->cfont->ascent - glyph->y, glyph->width, glyph->height);
} else {
renderer_fcft->pixman_image_composite32(PIXMAN_OP_OVER, renderer_fcft->color_fill, glyph->pix, complete_surface_pixman, 0, 0, 0, 0, rct.x + glyph->x, renderer_fcft->cfont->ascent - glyph->y, glyph->width, glyph->height);
}
rct.x += glyph->advance.x;
}
renderer_fcft->pixman_image_unref(complete_surface_pixman);
}
return complete_surface;
}
SDL_WaylandTextRenderer *WaylandToolkit_CreateTextRendererFcft() {
struct SDL_WaylandTextRendererFcft *renderer;
SDL_Color default_col;
// Alloc renderer struct
renderer = (struct SDL_WaylandTextRendererFcft *)SDL_malloc(sizeof(struct SDL_WaylandTextRendererFcft));
if (!renderer) {
return NULL;
}
// Symbols
#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_FCFT
#define SDL_WAYLAND_TOOLKIT_FCFT_LOAD_SYM(x, n, t) x = ((t)SDL_LoadFunction(renderer->fcft_lib, n)); if (!x) { SDL_UnloadObject(renderer->fcft_lib); SDL_free(renderer); return NULL; }
renderer->fcft_lib = SDL_LoadObject(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_FCFT);
if (!renderer->fcft_lib) {
SDL_free(renderer);
return NULL;
}
SDL_WAYLAND_TOOLKIT_FCFT_LOAD_SYM(renderer->fcft_init, "fcft_init", SDL_WaylandFcftInit);
SDL_WAYLAND_TOOLKIT_FCFT_LOAD_SYM(renderer->fcft_fini, "fcft_fini", SDL_WaylandFcftFini);
SDL_WAYLAND_TOOLKIT_FCFT_LOAD_SYM(renderer->fcft_from_name, "fcft_from_name", SDL_WaylandFcftFromName);
SDL_WAYLAND_TOOLKIT_FCFT_LOAD_SYM(renderer->fcft_destroy, "fcft_destroy", SDL_WaylandFcftDestroy);
SDL_WAYLAND_TOOLKIT_FCFT_LOAD_SYM(renderer->fcft_capabilities, "fcft_capabilities", SDL_WaylandFcftCaps);
SDL_WAYLAND_TOOLKIT_FCFT_LOAD_SYM(renderer->fcft_kerning, "fcft_kerning", SDL_WaylandFcftKern);
SDL_WAYLAND_TOOLKIT_FCFT_LOAD_SYM(renderer->fcft_rasterize_char_utf32, "fcft_rasterize_char_utf32", SDL_WaylandFcftRastChr);
SDL_WAYLAND_TOOLKIT_FCFT_LOAD_SYM(renderer->fcft_rasterize_text_run_utf32, "fcft_rasterize_text_run_utf32", SDL_WaylandFcftRastRun);
SDL_WAYLAND_TOOLKIT_FCFT_LOAD_SYM(renderer->fcft_text_run_destroy, "fcft_text_run_destroy", SDL_WaylandFcftDestroyRun);
SDL_WAYLAND_TOOLKIT_FCFT_LOAD_SYM(renderer->pixman_image_get_format, "pixman_image_get_format", SDL_WaylandFcftPixmanImgGetFmt);
SDL_WAYLAND_TOOLKIT_FCFT_LOAD_SYM(renderer->pixman_image_create_bits_no_clear, "pixman_image_create_bits_no_clear", SDL_WaylandFcftPixmanImgCreate);
SDL_WAYLAND_TOOLKIT_FCFT_LOAD_SYM(renderer->pixman_image_unref, "pixman_image_unref", SDL_WaylandFcftPixmanImgUnref);
SDL_WAYLAND_TOOLKIT_FCFT_LOAD_SYM(renderer->pixman_image_create_solid_fill, "pixman_image_create_solid_fill", SDL_WaylandFcftPixmanImgColFill);
SDL_WAYLAND_TOOLKIT_FCFT_LOAD_SYM(renderer->pixman_image_composite32, "pixman_image_composite32", SDL_WaylandFcftPixmanImgComposite);
#else
renderer->fcft_lib = NULL;
renderer->fcft_init = fcft_init;
renderer->fcft_fini = fcft_fini;
renderer->fcft_from_name = fcft_from_name;
renderer->fcft_destroy = fcft_destroy;
renderer->fcft_capabilities = fcft_capabilities;
renderer->fcft_rasterize_char_utf32 = fcft_rasterize_char_utf32;
renderer->fcft_kerning = fcft_kerning;
renderer->fcft_rasterize_text_run_utf32 = fcft_rasterize_text_run_utf32;
renderer->fcft_text_run_destroy = fcft_text_run_destroy;
renderer->pixman_image_create_bits_no_clear = pixman_image_create_bits_no_clear;
renderer->pixman_image_unref = pixman_image_unref;
renderer->pixman_image_create_solid_fill = pixman_image_create_solid_fill;
renderer->pixman_image_composite32 = pixman_image_composite32;
renderer->pixman_image_get_format = pixman_image_get_format;
#endif
// Init
#ifdef SDL_WAYLAND_TOOLKIT_FCFT_DEBUG
renderer->fcft_init(FCFT_LOG_COLORIZE_AUTO, false, FCFT_LOG_CLASS_DEBUG);
#else
renderer->fcft_init(FCFT_LOG_COLORIZE_NEVER, false, FCFT_LOG_CLASS_NONE);
#endif
renderer->color_fill = NULL;
renderer->cfont = NULL;
default_col.r = 255;
default_col.g = 255;
default_col.b = 255;
default_col.a = 255;
WaylandToolkit_SetTextRendererSizeFcft((SDL_WaylandTextRenderer *)renderer, 11);
WaylandToolkit_SetTextRendererColorFcft((SDL_WaylandTextRenderer *)renderer, &default_col);
// Object vtable
renderer->base.free = WaylandToolkit_FreeTextRendererFcft;
renderer->base.set_color = WaylandToolkit_SetTextRendererColorFcft;
renderer->base.set_pt_sz = WaylandToolkit_SetTextRendererSizeFcft;
renderer->base.render = WaylandToolkit_RenderTextFcft;
return (SDL_WaylandTextRenderer *)renderer;
}
#endif // defined(SDL_VIDEO_DRIVER_WAYLAND) && defined(HAVE_FCFT_H)

View file

@ -0,0 +1,33 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_waylandtoolkitbitmap_h_
#define SDL_waylandtoolkitbitmap_h_
#ifdef SDL_VIDEO_DRIVER_WAYLAND
#include "SDL_waylandtoolkit.h"
extern SDL_WaylandTextRenderer *WaylandToolkit_CreateTextRendererBitmap();
#endif // SDL_VIDEO_DRIVER_WAYLAND
#endif // SDL_waylandtoolkitbitmap_h_

View file

@ -0,0 +1,642 @@
/**
* 8x8 monochrome bitmap fonts for rendering
* Author: Daniel Hepper <daniel@hepper.net>
*
* License: Public Domain
*
* Based on:
* http://dimensionalrift.homelinux.net/combuster/mos3/?p=viewsource&file=/modules/gfx/font8_8.asm
**/
char font8x8_basic[128][8] = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0001
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0002
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0003
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0004
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0005
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0006
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0007
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0008
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0009
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000A
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000B
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000C
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space)
{ 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!)
{ 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (")
{ 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#)
{ 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($)
{ 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%)
{ 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&)
{ 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (')
{ 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (()
{ 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ())
{ 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*)
{ 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,)
{ 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.)
{ 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/)
{ 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0)
{ 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1)
{ 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2)
{ 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3)
{ 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4)
{ 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5)
{ 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6)
{ 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7)
{ 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8)
{ 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9)
{ 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:)
{ 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (;)
{ 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<)
{ 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=)
{ 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>)
{ 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?)
{ 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@)
{ 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A)
{ 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B)
{ 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C)
{ 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D)
{ 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E)
{ 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F)
{ 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G)
{ 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H)
{ 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I)
{ 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J)
{ 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K)
{ 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L)
{ 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M)
{ 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N)
{ 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O)
{ 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P)
{ 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q)
{ 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R)
{ 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S)
{ 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T)
{ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U)
{ 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V)
{ 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W)
{ 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X)
{ 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y)
{ 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z)
{ 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([)
{ 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\)
{ 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (])
{ 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_)
{ 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`)
{ 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a)
{ 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b)
{ 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c)
{ 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d)
{ 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e)
{ 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f)
{ 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g)
{ 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h)
{ 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i)
{ 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j)
{ 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k)
{ 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l)
{ 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m)
{ 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n)
{ 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o)
{ 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p)
{ 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q)
{ 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r)
{ 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s)
{ 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t)
{ 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u)
{ 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v)
{ 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w)
{ 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x)
{ 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y)
{ 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z)
{ 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({)
{ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|)
{ 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (})
{ 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F
};
char font8x8_control[32][8] = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0080
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0081
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0082
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0083
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0084
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0085
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0086
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0087
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0088
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0089
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+008A
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+008B
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+008C
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+008D
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+008E
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+008F
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0090
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0091
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0092
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0093
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0094
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0095
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0096
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0097
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0098
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0099
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+009A
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+009B
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+009C
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+009D
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+009E
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+009F
};
char font8x8_ext_latin[96][8] = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+00A0 (no break space)
{ 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00}, // U+00A1 (inverted !)
{ 0x18, 0x18, 0x7E, 0x03, 0x03, 0x7E, 0x18, 0x18}, // U+00A2 (dollarcents)
{ 0x1C, 0x36, 0x26, 0x0F, 0x06, 0x67, 0x3F, 0x00}, // U+00A3 (pound sterling)
{ 0x00, 0x00, 0x63, 0x3E, 0x36, 0x3E, 0x63, 0x00}, // U+00A4 (currency mark)
{ 0x33, 0x33, 0x1E, 0x3F, 0x0C, 0x3F, 0x0C, 0x0C}, // U+00A5 (yen)
{ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+00A6 (broken pipe)
{ 0x7C, 0xC6, 0x1C, 0x36, 0x36, 0x1C, 0x33, 0x1E}, // U+00A7 (paragraph)
{ 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+00A8 (diaeresis)
{ 0x3C, 0x42, 0x99, 0x85, 0x85, 0x99, 0x42, 0x3C}, // U+00A9 (copyright symbol)
{ 0x3C, 0x36, 0x36, 0x7C, 0x00, 0x00, 0x00, 0x00}, // U+00AA (superscript a)
{ 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00}, // U+00AB (<<)
{ 0x00, 0x00, 0x00, 0x3F, 0x30, 0x30, 0x00, 0x00}, // U+00AC (gun pointing left)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+00AD (soft hyphen)
{ 0x3C, 0x42, 0x9D, 0xA5, 0x9D, 0xA5, 0x42, 0x3C}, // U+00AE (registered symbol)
{ 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+00AF (macron)
{ 0x1C, 0x36, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00}, // U+00B0 (degree)
{ 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00}, // U+00B1 (plusminus)
{ 0x1C, 0x30, 0x18, 0x0C, 0x3C, 0x00, 0x00, 0x00}, // U+00B2 (superscript 2)
{ 0x1C, 0x30, 0x18, 0x30, 0x1C, 0x00, 0x00, 0x00}, // U+00B2 (superscript 3)
{ 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+00B2 (aigu)
{ 0x00, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x03}, // U+00B5 (mu)
{ 0xFE, 0xDB, 0xDB, 0xDE, 0xD8, 0xD8, 0xD8, 0x00}, // U+00B6 (pilcrow)
{ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00}, // U+00B7 (central dot)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x1E}, // U+00B8 (cedille)
{ 0x08, 0x0C, 0x08, 0x1C, 0x00, 0x00, 0x00, 0x00}, // U+00B9 (superscript 1)
{ 0x1C, 0x36, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00}, // U+00BA (superscript 0)
{ 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00}, // U+00BB (>>)
{ 0xC3, 0x63, 0x33, 0xBD, 0xEC, 0xF6, 0xF3, 0x03}, // U+00BC (1/4)
{ 0xC3, 0x63, 0x33, 0x7B, 0xCC, 0x66, 0x33, 0xF0}, // U+00BD (1/2)
{ 0x03, 0xC4, 0x63, 0xB4, 0xDB, 0xAC, 0xE6, 0x80}, // U+00BE (3/4)
{ 0x0C, 0x00, 0x0C, 0x06, 0x03, 0x33, 0x1E, 0x00}, // U+00BF (inverted ?)
{ 0x07, 0x00, 0x1C, 0x36, 0x63, 0x7F, 0x63, 0x00}, // U+00C0 (A grave)
{ 0x70, 0x00, 0x1C, 0x36, 0x63, 0x7F, 0x63, 0x00}, // U+00C1 (A aigu)
{ 0x1C, 0x36, 0x00, 0x3E, 0x63, 0x7F, 0x63, 0x00}, // U+00C2 (A circumflex)
{ 0x6E, 0x3B, 0x00, 0x3E, 0x63, 0x7F, 0x63, 0x00}, // U+00C3 (A ~)
{ 0x63, 0x1C, 0x36, 0x63, 0x7F, 0x63, 0x63, 0x00}, // U+00C4 (A umlaut)
{ 0x0C, 0x0C, 0x00, 0x1E, 0x33, 0x3F, 0x33, 0x00}, // U+00C5 (A ring)
{ 0x7C, 0x36, 0x33, 0x7F, 0x33, 0x33, 0x73, 0x00}, // U+00C6 (AE)
{ 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x18, 0x30, 0x1E}, // U+00C7 (C cedille)
{ 0x07, 0x00, 0x3F, 0x06, 0x1E, 0x06, 0x3F, 0x00}, // U+00C8 (E grave)
{ 0x38, 0x00, 0x3F, 0x06, 0x1E, 0x06, 0x3F, 0x00}, // U+00C9 (E aigu)
{ 0x0C, 0x12, 0x3F, 0x06, 0x1E, 0x06, 0x3F, 0x00}, // U+00CA (E circumflex)
{ 0x36, 0x00, 0x3F, 0x06, 0x1E, 0x06, 0x3F, 0x00}, // U+00CB (E umlaut)
{ 0x07, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+00CC (I grave)
{ 0x38, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+00CD (I aigu)
{ 0x0C, 0x12, 0x00, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+00CE (I circumflex)
{ 0x33, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+00CF (I umlaut)
{ 0x3F, 0x66, 0x6F, 0x6F, 0x66, 0x66, 0x3F, 0x00}, // U+00D0 (Eth)
{ 0x3F, 0x00, 0x33, 0x37, 0x3F, 0x3B, 0x33, 0x00}, // U+00D1 (N ~)
{ 0x0E, 0x00, 0x18, 0x3C, 0x66, 0x3C, 0x18, 0x00}, // U+00D2 (O grave)
{ 0x70, 0x00, 0x18, 0x3C, 0x66, 0x3C, 0x18, 0x00}, // U+00D3 (O aigu)
{ 0x3C, 0x66, 0x18, 0x3C, 0x66, 0x3C, 0x18, 0x00}, // U+00D4 (O circumflex)
{ 0x6E, 0x3B, 0x00, 0x3E, 0x63, 0x63, 0x3E, 0x00}, // U+00D5 (O ~)
{ 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00}, // U+00D6 (O umlaut)
{ 0x00, 0x36, 0x1C, 0x08, 0x1C, 0x36, 0x00, 0x00}, // U+00D7 (multiplicative x)
{ 0x5C, 0x36, 0x73, 0x7B, 0x6F, 0x36, 0x1D, 0x00}, // U+00D8 (O stroke)
{ 0x0E, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00}, // U+00D9 (U grave)
{ 0x70, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00}, // U+00DA (U aigu)
{ 0x3C, 0x66, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x00}, // U+00DB (U circumflex)
{ 0x33, 0x00, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+00DC (U umlaut)
{ 0x70, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x00}, // U+00DD (Y aigu)
{ 0x0F, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+00DE (Thorn)
{ 0x00, 0x1E, 0x33, 0x1F, 0x33, 0x1F, 0x03, 0x03}, // U+00DF (beta)
{ 0x07, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00}, // U+00E0 (a grave)
{ 0x38, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00}, // U+00E1 (a aigu)
{ 0x7E, 0xC3, 0x3C, 0x60, 0x7C, 0x66, 0xFC, 0x00}, // U+00E2 (a circumflex)
{ 0x6E, 0x3B, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00}, // U+00E3 (a ~)
{ 0x33, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00}, // U+00E4 (a umlaut)
{ 0x0C, 0x0C, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00}, // U+00E5 (a ring)
{ 0x00, 0x00, 0xFE, 0x30, 0xFE, 0x33, 0xFE, 0x00}, // U+00E6 (ae)
{ 0x00, 0x00, 0x1E, 0x03, 0x03, 0x1E, 0x30, 0x1C}, // U+00E7 (c cedille)
{ 0x07, 0x00, 0x1E, 0x33, 0x3F, 0x03, 0x1E, 0x00}, // U+00E8 (e grave)
{ 0x38, 0x00, 0x1E, 0x33, 0x3F, 0x03, 0x1E, 0x00}, // U+00E9 (e aigu)
{ 0x7E, 0xC3, 0x3C, 0x66, 0x7E, 0x06, 0x3C, 0x00}, // U+00EA (e circumflex)
{ 0x33, 0x00, 0x1E, 0x33, 0x3F, 0x03, 0x1E, 0x00}, // U+00EB (e umlaut)
{ 0x07, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+00EC (i grave)
{ 0x1C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+00ED (i augu)
{ 0x3E, 0x63, 0x1C, 0x18, 0x18, 0x18, 0x3C, 0x00}, // U+00EE (i circumflex)
{ 0x33, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+00EF (i umlaut)
{ 0x1B, 0x0E, 0x1B, 0x30, 0x3E, 0x33, 0x1E, 0x00}, // U+00F0 (eth)
{ 0x00, 0x1F, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x00}, // U+00F1 (n ~)
{ 0x00, 0x07, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+00F2 (o grave)
{ 0x00, 0x38, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+00F3 (o aigu)
{ 0x1E, 0x33, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+00F4 (o circumflex)
{ 0x6E, 0x3B, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+00F5 (o ~)
{ 0x00, 0x33, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+00F6 (o umlaut)
{ 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00}, // U+00F7 (division)
{ 0x00, 0x60, 0x3C, 0x76, 0x7E, 0x6E, 0x3C, 0x06}, // U+00F8 (o stroke)
{ 0x00, 0x07, 0x00, 0x33, 0x33, 0x33, 0x7E, 0x00}, // U+00F9 (u grave)
{ 0x00, 0x38, 0x00, 0x33, 0x33, 0x33, 0x7E, 0x00}, // U+00FA (u aigu)
{ 0x1E, 0x33, 0x00, 0x33, 0x33, 0x33, 0x7E, 0x00}, // U+00FB (u circumflex)
{ 0x00, 0x33, 0x00, 0x33, 0x33, 0x33, 0x7E, 0x00}, // U+00FC (u umlaut)
{ 0x00, 0x38, 0x00, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+00FD (y aigu)
{ 0x00, 0x00, 0x06, 0x3E, 0x66, 0x3E, 0x06, 0x00}, // U+00FE (thorn)
{ 0x00, 0x33, 0x00, 0x33, 0x33, 0x3E, 0x30, 0x1F} // U+00FF (y umlaut)
};
char font8x8_greek[58][8] = {
{ 0x2D, 0x00, 0x0C, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0390 (iota with tonos and diaeresis)
{ 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0391 (Alpha)
{ 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0392 (Beta)
{ 0x3F, 0x33, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00}, // U+0393 (Gamma)
{ 0x08, 0x1C, 0x1C, 0x36, 0x36, 0x63, 0x7F, 0x00}, // U+0394 (Delta)
{ 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0395 (Epsilon)
{ 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+0396 (Zeta)
{ 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0397 (Eta)
{ 0x1C, 0x36, 0x63, 0x7F, 0x63, 0x36, 0x1C, 0x00}, // U+0398 (Theta)
{ 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0399 (Iota)
{ 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+039A (Kappa)
{ 0x08, 0x1C, 0x1C, 0x36, 0x36, 0x63, 0x63, 0x00}, // U+039B (Lambda)
{ 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+039C (Mu)
{ 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+039D (Nu)
{ 0x7F, 0x63, 0x00, 0x3E, 0x00, 0x63, 0x7F, 0x00}, // U+039E (Xi)
{ 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+039F (Omikron)
{ 0x7F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00}, // U+03A0 (Pi)
{ 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+03A1 (Rho)
{ 0x00, 0x01, 0x02, 0x04, 0x4F, 0x90, 0xA0, 0x40}, // U+03A2
{ 0x7F, 0x63, 0x06, 0x0C, 0x06, 0x63, 0x7F, 0x00}, // U+03A3 (Sigma 2)
{ 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+03A4 (Tau)
{ 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+03A5 (Upsilon)
{ 0x18, 0x7E, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x00}, // U+03A6 (Phi)
{ 0x63, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x63, 0x00}, // U+03A7 (Chi)
{ 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x18, 0x3C, 0x00}, // U+03A8 (Psi)
{ 0x3E, 0x63, 0x63, 0x63, 0x36, 0x36, 0x77, 0x00}, // U+03A9 (Omega)
{ 0x33, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0399 (Iota with diaeresis)
{ 0x33, 0x00, 0x33, 0x33, 0x1E, 0x0C, 0x1E, 0x00}, // U+03A5 (Upsilon with diaeresis)
{ 0x70, 0x00, 0x6E, 0x3B, 0x13, 0x3B, 0x6E, 0x00}, // U+03AC (alpha aigu)
{ 0x38, 0x00, 0x1E, 0x03, 0x0E, 0x03, 0x1E, 0x00}, // U+03AD (epsilon aigu)
{ 0x38, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x30}, // U+03AE (eta aigu)
{ 0x38, 0x00, 0x0C, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+03AF (iota aigu)
{ 0x2D, 0x00, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+03B0 (upsilon with tonos and diaeresis)
{ 0x00, 0x00, 0x6E, 0x3B, 0x13, 0x3B, 0x6E, 0x00}, // U+03B1 (alpha)
{ 0x00, 0x1E, 0x33, 0x1F, 0x33, 0x1F, 0x03, 0x03}, // U+03B2 (beta)
{ 0x00, 0x00, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x00}, // U+03B3 (gamma)
{ 0x38, 0x0C, 0x18, 0x3E, 0x33, 0x33, 0x1E, 0x00}, // U+03B4 (delta)
{ 0x00, 0x00, 0x1E, 0x03, 0x0E, 0x03, 0x1E, 0x00}, // U+03B5 (epsilon)
{ 0x00, 0x3F, 0x06, 0x03, 0x03, 0x1E, 0x30, 0x1C}, // U+03B6 (zeta)
{ 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x30}, // U+03B7 (eta)
{ 0x00, 0x00, 0x1E, 0x33, 0x3F, 0x33, 0x1E, 0x00}, // U+03B8 (theta)
{ 0x00, 0x00, 0x0C, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+03B9 (iota)
{ 0x00, 0x00, 0x33, 0x1B, 0x0F, 0x1B, 0x33, 0x00}, // U+03BA (kappa)
{ 0x00, 0x03, 0x06, 0x0C, 0x1C, 0x36, 0x63, 0x00}, // U+03BB (lambda)
{ 0x00, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x03}, // U+03BC (mu)
{ 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+03BD (nu)
{ 0x1E, 0x03, 0x0E, 0x03, 0x03, 0x1E, 0x30, 0x1C}, // U+03BE (xi)
{ 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+03BF (omikron)
{ 0x00, 0x00, 0x7F, 0x36, 0x36, 0x36, 0x36, 0x00}, // U+03C0 (pi)
{ 0x00, 0x00, 0x3C, 0x66, 0x66, 0x36, 0x06, 0x06}, // U+03C1 (rho)
{ 0x00, 0x00, 0x3E, 0x03, 0x03, 0x1E, 0x30, 0x1C}, // U+03C2 (sigma 1)
{ 0x00, 0x00, 0x7E, 0x1B, 0x1B, 0x1B, 0x0E, 0x00}, // U+03C3 (sigma 2)
{ 0x00, 0x00, 0x7E, 0x18, 0x18, 0x58, 0x30, 0x00}, // U+03C4 (tau)
{ 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+03C5 (upsilon)
{ 0x00, 0x00, 0x76, 0xDB, 0xDB, 0x7E, 0x18, 0x00}, // U+03C6 (phi)
{ 0x00, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+03C7 (chi)
{ 0x00, 0x00, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x00}, // U+03C8 (psi)
{ 0x00, 0x00, 0x36, 0x63, 0x6B, 0x7F, 0x36, 0x00} // U+03C9 (omega)
};
char font8x8_misc[10][8] = {
{ 0x1F, 0x33, 0x33, 0x5F, 0x63, 0xF3, 0x63, 0xE3}, // U+20A7 (Spanish Pesetas/Pt)
{ 0x70, 0xD8, 0x18, 0x3C, 0x18, 0x18, 0x1B, 0x0E}, // U+0192 (dutch florijn)
{ 0x3C, 0x36, 0x36, 0x7C, 0x00, 0x7E, 0x00, 0x00}, // U+ (underlined superscript a)
{ 0x1C, 0x36, 0x36, 0x1C, 0x00, 0x3E, 0x00, 0x00}, // U+ (underlined superscript 0)
{ 0x00, 0x00, 0x00, 0x3F, 0x03, 0x03, 0x00, 0x00}, // U+2310 (gun pointing right)
{ 0x30, 0x18, 0x0C, 0x18, 0x30, 0x00, 0x7E, 0x00}, // U+ (less than or equal)
{ 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x00, 0x7E, 0x00}, // U+ (greater than or equal)
{ 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+ (grave)
{ 0x0E, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x00}, // U+ (Y grave)
{ 0x00, 0x07, 0x00, 0x33, 0x33, 0x3E, 0x30, 0x1F} // U+ (y grave)
};
char font8x8_box[128][8] = {
{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00}, // U+2500 (thin horizontal)
{ 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00}, // U+2501 (thick horizontal)
{ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}, // U+2502 (thin vertical)
{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, // U+2503 (thich vertical)
{ 0x00, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00}, // U+2504 (thin horizontal dashed)
{ 0x00, 0x00, 0x00, 0xBB, 0xBB, 0x00, 0x00, 0x00}, // U+2505 (thick horizontal dashed)
{ 0x08, 0x00, 0x08, 0x08, 0x08, 0x00, 0x08, 0x08}, // U+2506 (thin vertical dashed)
{ 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18}, // U+2507 (thich vertical dashed)
{ 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00}, // U+2508 (thin horizontal dotted)
{ 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00}, // U+2509 (thick horizontal dotted)
{ 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08}, // U+250A (thin vertical dotted)
{ 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18}, // U+250B (thich vertical dotted)
{ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08}, // U+250C (down L, right L)
{ 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x08, 0x08, 0x08}, // U+250D (down L, right H)
{ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18}, // U+250E (down H, right L)
{ 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18}, // U+250F (down H, right H)
{ 0x00, 0x00, 0x00, 0x00, 0x0f, 0x08, 0x08, 0x08}, // U+2510 (down L, left L)
{ 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x08, 0x08, 0x08}, // U+2511 (down L, left H)
{ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18}, // U+2512 (down H, left L)
{ 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18}, // U+2513 (down H, left H)
{ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x00, 0x00, 0x00}, // U+2514 (up L, right L)
{ 0x08, 0x08, 0x08, 0xf8, 0xf8, 0x00, 0x00, 0x00}, // U+2515 (up L, right H)
{ 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00}, // U+2516 (up H, right L)
{ 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00}, // U+2517 (up H, right H)
{ 0x08, 0x08, 0x08, 0x08, 0x0f, 0x00, 0x00, 0x00}, // U+2518 (up L, left L)
{ 0x08, 0x08, 0x08, 0x0f, 0x0f, 0x00, 0x00, 0x00}, // U+2519 (up L, left H)
{ 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00}, // U+251A (up H, left L)
{ 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00}, // U+251B (up H, left H)
{ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x08, 0x08}, // U+251C (down L, right L, up L)
{ 0x08, 0x08, 0x08, 0xf8, 0xf8, 0x08, 0x08, 0x08}, // U+251D (down L, right H, up L)
{ 0x18, 0x18, 0x18, 0x18, 0xf8, 0x08, 0x08, 0x08}, // U+251E (down L, right L, up H)
{ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x18, 0x18, 0x18}, // U+251F (down H, right L, up L)
{ 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18}, // U+2520 (down H, right L, up H)
{ 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x08, 0x08, 0x08}, // U+2521 (down L, right H, up H)
{ 0x08, 0x08, 0x08, 0xf8, 0xf8, 0x18, 0x18, 0x18}, // U+2522 (down H, right H, up L)
{ 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18}, // U+2523 (down H, right H, up H)
{ 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08}, // U+2524 (down L, left L, up L)
{ 0x08, 0x08, 0x08, 0x0f, 0x0f, 0x08, 0x08, 0x08}, // U+2525 (down L, left H, up L)
{ 0x18, 0x18, 0x18, 0x18, 0x1f, 0x08, 0x08, 0x08}, // U+2526 (down L, left L, up H)
{ 0x08, 0x08, 0x08, 0x08, 0x1f, 0x18, 0x18, 0x18}, // U+2527 (down H, left L, up L)
{ 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18}, // U+2528 (down H, left L, up H)
{ 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x08, 0x08, 0x08}, // U+2529 (down L, left H, up H)
{ 0x08, 0x08, 0x08, 0x1f, 0x1f, 0x18, 0x18, 0x18}, // U+252A (down H, left H, up L)
{ 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18}, // U+252B (down H, left H, up H)
{ 0x00, 0x00, 0x00, 0x00, 0xff, 0x08, 0x08, 0x08}, // U+252C (down L, right L, left L)
{ 0x00, 0x00, 0x00, 0x0f, 0xff, 0x08, 0x08, 0x08}, // U+252D (down L, right L, left H)
{ 0x00, 0x00, 0x00, 0xf8, 0xff, 0x08, 0x08, 0x08}, // U+252E (down L, right H, left L)
{ 0x00, 0x00, 0x00, 0xff, 0xff, 0x08, 0x08, 0x08}, // U+252F (down L, right H, left H)
{ 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18}, // U+2530 (down H, right L, left L)
{ 0x00, 0x00, 0x00, 0x1f, 0xff, 0x18, 0x18, 0x18}, // U+2531 (down H, right L, left H)
{ 0x00, 0x00, 0x00, 0xf8, 0xff, 0x18, 0x18, 0x18}, // U+2532 (down H, right H, left L)
{ 0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18}, // U+2533 (down H, right H, left H)
{ 0x08, 0x08, 0x08, 0x08, 0xff, 0x00, 0x00, 0x00}, // U+2534 (up L, right L, left L)
{ 0x08, 0x08, 0x08, 0x0f, 0xff, 0x00, 0x00, 0x00}, // U+2535 (up L, right L, left H)
{ 0x08, 0x08, 0x08, 0xf8, 0xff, 0x00, 0x00, 0x00}, // U+2536 (up L, right H, left L)
{ 0x08, 0x08, 0x08, 0xff, 0xff, 0x00, 0x00, 0x00}, // U+2537 (up L, right H, left H)
{ 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00}, // U+2538 (up H, right L, left L)
{ 0x18, 0x18, 0x18, 0x1f, 0xff, 0x00, 0x00, 0x00}, // U+2539 (up H, right L, left H)
{ 0x18, 0x18, 0x18, 0xf8, 0xff, 0x00, 0x00, 0x00}, // U+253A (up H, right H, left L)
{ 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00}, // U+253B (up H, right H, left H)
{ 0x08, 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08}, // U+253C (up L, right L, left L, down L)
{ 0x08, 0x08, 0x08, 0x0f, 0xff, 0x08, 0x08, 0x08}, // U+253D (up L, right L, left H, down L)
{ 0x08, 0x08, 0x08, 0xf8, 0xff, 0x08, 0x08, 0x08}, // U+253E (up L, right H, left L, down L)
{ 0x08, 0x08, 0x08, 0xff, 0xff, 0x08, 0x08, 0x08}, // U+253F (up L, right H, left H, down L)
{ 0x18, 0x18, 0x18, 0x18, 0xff, 0x08, 0x08, 0x08}, // U+2540 (up H, right L, left L, down L)
{ 0x08, 0x08, 0x08, 0x08, 0xff, 0x18, 0x18, 0x18}, // U+2541 (up L, right L, left L, down H)
{ 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18}, // U+2542 (up H, right L, left L, down H)
{ 0x18, 0x18, 0x18, 0x1f, 0xff, 0x08, 0x08, 0x08}, // U+2543 (up H, right L, left H, down L)
{ 0x18, 0x18, 0x18, 0xf8, 0xff, 0x08, 0x08, 0x08}, // U+2544 (up H, right H, left L, down L)
{ 0x08, 0x08, 0x08, 0x1f, 0xff, 0x18, 0x18, 0x18}, // U+2545 (up L, right L, left H, down H)
{ 0x08, 0x08, 0x08, 0xf8, 0xff, 0x18, 0x18, 0x18}, // U+2546 (up L, right H, left L, down H)
{ 0x08, 0x08, 0x08, 0xff, 0xff, 0x18, 0x18, 0x18}, // U+2547 (up L, right H, left H, down H)
{ 0x18, 0x18, 0x18, 0xff, 0xff, 0x08, 0x08, 0x08}, // U+254B (up H, right H, left H, down L)
{ 0x18, 0x18, 0x18, 0xf8, 0xff, 0x18, 0x18, 0x18}, // U+254A (up H, right H, left L, down H)
{ 0x18, 0x18, 0x18, 0x1f, 0xff, 0x18, 0x18, 0x18}, // U+2549 (up H, right L, left H, down H)
{ 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18}, // U+254B (up H, right H, left H, down H)
{ 0x00, 0x00, 0x00, 0x00, 0xE7, 0x00, 0x00, 0x00}, // U+254C (thin horizontal broken)
{ 0x00, 0x00, 0x00, 0xE7, 0xE7, 0x00, 0x00, 0x00}, // U+254D (thick horizontal broken)
{ 0x08, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x08}, // U+254E (thin vertical broken)
{ 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18}, // U+254F (thich vertical broken)
{ 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00}, // U+2550 (double horizontal)
{ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14}, // U+2551 (double vertical)
{ 0x00, 0x00, 0x00, 0xF8, 0x08, 0xF8, 0x08, 0x08}, // U+2552 (down L, right D)
{ 0x00, 0x00, 0x00, 0x00, 0xFC, 0x14, 0x14, 0x14}, // U+2553 (down D, right L)
{ 0x00, 0x00, 0x00, 0xFC, 0x04, 0xF4, 0x14, 0x14}, // U+2554 (down D, right D)
{ 0x00, 0x00, 0x00, 0x0F, 0x08, 0x0F, 0x08, 0x08}, // U+2555 (down L, left D)
{ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x14, 0x14, 0x14}, // U+2556 (down D, left L)
{ 0x00, 0x00, 0x00, 0x1F, 0x10, 0x17, 0x14, 0x14}, // U+2557 (down D, left D)
{ 0x08, 0x08, 0x08, 0xF8, 0x08, 0xF8, 0x00, 0x00}, // U+2558 (up L, right D)
{ 0x14, 0x14, 0x14, 0x14, 0xFC, 0x00, 0x00, 0x00}, // U+2559 (up D, right L)
{ 0x14, 0x14, 0x14, 0xF4, 0x04, 0xFC, 0x00, 0x00}, // U+255A (up D, right D)
{ 0x08, 0x08, 0x08, 0x0F, 0x08, 0x0F, 0x00, 0x00}, // U+255B (up L, left D)
{ 0x14, 0x14, 0x14, 0x14, 0x1F, 0x00, 0x00, 0x00}, // U+255C (up D, left L)
{ 0x14, 0x14, 0x14, 0x17, 0x10, 0x1F, 0x00, 0x00}, // U+255D (up D, left D)
{ 0x08, 0x08, 0x08, 0xF8, 0x08, 0xF8, 0x08, 0x08}, // U+255E (up L, down L, right D)
{ 0x14, 0x14, 0x14, 0x14, 0xF4, 0x14, 0x14, 0x14}, // U+255F (up D, down D, right L)
{ 0x14, 0x14, 0x14, 0xF4, 0x04, 0xF4, 0x14, 0x14}, // U+2560 (up D, down D, right D)
{ 0x08, 0x08, 0x08, 0x0F, 0x08, 0x0F, 0x08, 0x08}, // U+2561 (up L, down L, left D)
{ 0x14, 0x14, 0x14, 0x14, 0x17, 0x14, 0x14, 0x14}, // U+2562 (up D, down D, left L)
{ 0x14, 0x14, 0x14, 0x17, 0x10, 0x17, 0x14, 0x14}, // U+2563 (up D, down D, left D)
{ 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x08, 0x08}, // U+2564 (left D, right D, down L)
{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x14, 0x14, 0x14}, // U+2565 (left L, right L, down D)
{ 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x14, 0x14}, // U+2566 (left D, right D, down D)
{ 0x08, 0x08, 0x08, 0xFF, 0x00, 0xFF, 0x00, 0x00}, // U+2567 (left D, right D, up L)
{ 0x14, 0x14, 0x14, 0x14, 0xFF, 0x00, 0x00, 0x00}, // U+2568 (left L, right L, up D)
{ 0x14, 0x14, 0x14, 0xF7, 0x00, 0xFF, 0x00, 0x00}, // U+2569 (left D, right D, up D)
{ 0x08, 0x08, 0x08, 0xFF, 0x08, 0xFF, 0x08, 0x08}, // U+256A (left D, right D, down L, up L)
{ 0x14, 0x14, 0x14, 0x14, 0xFF, 0x14, 0x14, 0x14}, // U+256B (left L, right L, down D, up D)
{ 0x14, 0x14, 0x14, 0xF7, 0x00, 0xF7, 0x14, 0x14}, // U+256C (left D, right D, down D, up D)
{ 0x00, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x08, 0x08}, // U+256D (curve down-right)
{ 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x08, 0x08}, // U+256E (curve down-left)
{ 0x08, 0x08, 0x08, 0x04, 0x03, 0x00, 0x00, 0x00}, // U+256F (curve up-left)
{ 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00}, // U+2570 (curve up-right)
{ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}, // U+2571 (diagonal bottom-left to top-right)
{ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}, // U+2572 (diagonal bottom-right to top-left)
{ 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81}, // U+2573 (diagonal cross)
{ 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00}, // U+2574 (left L)
{ 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00}, // U+2575 (up L)
{ 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00}, // U+2576 (right L)
{ 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08}, // U+2577 (down L)
{ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00}, // U+2578 (left H)
{ 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, // U+2579 (up H)
{ 0x00, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x00, 0x00}, // U+257A (right H)
{ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18}, // U+257B (down H)
{ 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00}, // U+257C (right H, left L)
{ 0x08, 0x08, 0x08, 0x08, 0x18, 0x18, 0x18, 0x18}, // U+257D (up L, down H)
{ 0x00, 0x00, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00}, // U+257E (right L, left H)
{ 0x18, 0x18, 0x18, 0x18, 0x08, 0x08, 0x08, 0x08} // U+257F (up H, down L)
};
char font8x8_block[32][8] = {
{ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}, // U+2580 (top half)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+2581 (box 1/8)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF}, // U+2582 (box 2/8)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF}, // U+2583 (box 3/8)
{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}, // U+2584 (bottom half)
{ 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // U+2585 (box 5/8)
{ 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // U+2586 (box 6/8)
{ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // U+2587 (box 7/8)
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // U+2588 (solid)
{ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F}, // U+2589 (box 7/8)
{ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F}, // U+258A (box 6/8)
{ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F}, // U+258B (box 5/8)
{ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F}, // U+258C (left half)
{ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07}, // U+258D (box 3/8)
{ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}, // U+258E (box 2/8)
{ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, // U+258F (box 1/8)
{ 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0}, // U+2590 (right half)
{ 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00}, // U+2591 (25% solid)
{ 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA}, // U+2592 (50% solid)
{ 0xFF, 0xAA, 0xFF, 0x55, 0xFF, 0xAA, 0xFF, 0x55}, // U+2593 (75% solid)
{ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+2594 (box 1/8)
{ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}, // U+2595 (box 1/8)
{ 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F}, // U+2596 (box bottom left)
{ 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0}, // U+2597 (box bottom right)
{ 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00}, // U+2598 (box top left)
{ 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF}, // U+2599 (boxes left and bottom)
{ 0x0F, 0x0F, 0x0F, 0x0F, 0xF0, 0xF0, 0xF0, 0xF0}, // U+259A (boxes top-left and bottom right)
{ 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F}, // U+259B (boxes top and left)
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0}, // U+259C (boxes top and right)
{ 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00}, // U+259D (box top right)
{ 0xF0, 0xF0, 0xF0, 0xF0, 0x0F, 0x0F, 0x0F, 0x0F}, // U+259E (boxes top right and bottom left)
{ 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF}, // U+259F (boxes right and bottom)
};
char font8x8_hiragana[96][8] = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+3040
{ 0x04, 0x3F, 0x04, 0x3C, 0x56, 0x4D, 0x26, 0x00}, // U+3041 (Hiragana a)
{ 0x04, 0x3F, 0x04, 0x3C, 0x56, 0x4D, 0x26, 0x00}, // U+3042 (Hiragana A)
{ 0x00, 0x00, 0x00, 0x11, 0x21, 0x25, 0x02, 0x00}, // U+3043 (Hiragana i)
{ 0x00, 0x01, 0x11, 0x21, 0x21, 0x25, 0x02, 0x00}, // U+3044 (Hiragana I)
{ 0x00, 0x1C, 0x00, 0x1C, 0x22, 0x20, 0x18, 0x00}, // U+3045 (Hiragana u)
{ 0x3C, 0x00, 0x3C, 0x42, 0x40, 0x20, 0x18, 0x00}, // U+3046 (Hiragana U)
{ 0x1C, 0x00, 0x3E, 0x10, 0x38, 0x24, 0x62, 0x00}, // U+3047 (Hiragana e)
{ 0x1C, 0x00, 0x3E, 0x10, 0x38, 0x24, 0x62, 0x00}, // U+3048 (Hiragana E)
{ 0x24, 0x4F, 0x04, 0x3C, 0x46, 0x45, 0x22, 0x00}, // U+3049 (Hiragana o)
{ 0x24, 0x4F, 0x04, 0x3C, 0x46, 0x45, 0x22, 0x00}, // U+304A (Hiragana O)
{ 0x04, 0x24, 0x4F, 0x54, 0x52, 0x12, 0x09, 0x00}, // U+304B (Hiragana KA)
{ 0x44, 0x24, 0x0F, 0x54, 0x52, 0x52, 0x09, 0x00}, // U+304C (Hiragana GA)
{ 0x08, 0x1F, 0x08, 0x3F, 0x1C, 0x02, 0x3C, 0x00}, // U+304D (Hiragana KI)
{ 0x44, 0x2F, 0x04, 0x1F, 0x0E, 0x01, 0x1E, 0x00}, // U+304E (Hiragana GI)
{ 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00}, // U+304F (Hiragana KU)
{ 0x28, 0x44, 0x12, 0x21, 0x02, 0x04, 0x08, 0x00}, // U+3050 (Hiragana GU)
{ 0x00, 0x22, 0x79, 0x21, 0x21, 0x22, 0x10, 0x00}, // U+3051 (Hiragana KE)
{ 0x40, 0x22, 0x11, 0x3D, 0x11, 0x12, 0x08, 0x00}, // U+3052 (Hiragana GE)
{ 0x00, 0x00, 0x3C, 0x00, 0x02, 0x02, 0x3C, 0x00}, // U+3053 (Hiragana KO)
{ 0x20, 0x40, 0x16, 0x20, 0x01, 0x01, 0x0E, 0x00}, // U+3054 (Hiragana GO)
{ 0x10, 0x7E, 0x10, 0x3C, 0x02, 0x02, 0x1C, 0x00}, // U+3055 (Hiragana SA)
{ 0x24, 0x4F, 0x14, 0x2E, 0x01, 0x01, 0x0E, 0x00}, // U+3056 (Hiragana ZA)
{ 0x00, 0x02, 0x02, 0x02, 0x42, 0x22, 0x1C, 0x00}, // U+3057 (Hiragana SI)
{ 0x20, 0x42, 0x12, 0x22, 0x02, 0x22, 0x1C, 0x00}, // U+3058 (Hiragana ZI)
{ 0x10, 0x7E, 0x18, 0x14, 0x18, 0x10, 0x0C, 0x00}, // U+3059 (Hiragana SU)
{ 0x44, 0x2F, 0x06, 0x05, 0x06, 0x04, 0x03, 0x00}, // U+305A (Hiragana ZU)
{ 0x20, 0x72, 0x2F, 0x22, 0x1A, 0x02, 0x1C, 0x00}, // U+305B (Hiragana SE)
{ 0x80, 0x50, 0x3A, 0x17, 0x1A, 0x02, 0x1C, 0x00}, // U+305C (Hiragana ZE)
{ 0x1E, 0x08, 0x04, 0x7F, 0x08, 0x04, 0x38, 0x00}, // U+305D (Hiragana SO)
{ 0x4F, 0x24, 0x02, 0x7F, 0x08, 0x04, 0x38, 0x00}, // U+305E (Hiragana ZO)
{ 0x02, 0x0F, 0x02, 0x72, 0x02, 0x09, 0x71, 0x00}, // U+305F (Hiragana TA)
{ 0x42, 0x2F, 0x02, 0x72, 0x02, 0x09, 0x71, 0x00}, // U+3060 (Hiragana DA)
{ 0x08, 0x7E, 0x08, 0x3C, 0x40, 0x40, 0x38, 0x00}, // U+3061 (Hiragana TI)
{ 0x44, 0x2F, 0x04, 0x1E, 0x20, 0x20, 0x1C, 0x00}, // U+3062 (Hiragana DI)
{ 0x00, 0x00, 0x00, 0x1C, 0x22, 0x20, 0x1C, 0x00}, // U+3063 (Hiragana tu)
{ 0x00, 0x1C, 0x22, 0x41, 0x40, 0x20, 0x1C, 0x00}, // U+3064 (Hiragana TU)
{ 0x40, 0x20, 0x1E, 0x21, 0x20, 0x20, 0x1C, 0x00}, // U+3065 (Hiragana DU)
{ 0x00, 0x3E, 0x08, 0x04, 0x04, 0x04, 0x38, 0x00}, // U+3066 (Hiragana TE)
{ 0x00, 0x3E, 0x48, 0x24, 0x04, 0x04, 0x38, 0x00}, // U+3067 (Hiragana DE)
{ 0x04, 0x04, 0x08, 0x3C, 0x02, 0x02, 0x3C, 0x00}, // U+3068 (Hiragana TO)
{ 0x44, 0x24, 0x08, 0x3C, 0x02, 0x02, 0x3C, 0x00}, // U+3069 (Hiragana DO)
{ 0x32, 0x02, 0x27, 0x22, 0x72, 0x29, 0x11, 0x00}, // U+306A (Hiragana NA)
{ 0x00, 0x02, 0x7A, 0x02, 0x0A, 0x72, 0x02, 0x00}, // U+306B (Hiragana NI)
{ 0x08, 0x09, 0x3E, 0x4B, 0x65, 0x55, 0x22, 0x00}, // U+306C (Hiragana NU)
{ 0x04, 0x07, 0x34, 0x4C, 0x66, 0x54, 0x24, 0x00}, // U+306D (Hiragana NE)
{ 0x00, 0x00, 0x3C, 0x4A, 0x49, 0x45, 0x22, 0x00}, // U+306E (Hiragana NO)
{ 0x00, 0x22, 0x7A, 0x22, 0x72, 0x2A, 0x12, 0x00}, // U+306F (Hiragana HA)
{ 0x80, 0x51, 0x1D, 0x11, 0x39, 0x15, 0x09, 0x00}, // U+3070 (Hiragana BA)
{ 0x40, 0xB1, 0x5D, 0x11, 0x39, 0x15, 0x09, 0x00}, // U+3071 (Hiragana PA)
{ 0x00, 0x00, 0x13, 0x32, 0x51, 0x11, 0x0E, 0x00}, // U+3072 (Hiragana HI)
{ 0x40, 0x20, 0x03, 0x32, 0x51, 0x11, 0x0E, 0x00}, // U+3073 (Hiragana BI)
{ 0x40, 0xA0, 0x43, 0x32, 0x51, 0x11, 0x0E, 0x00}, // U+3074 (Hiragana PI)
{ 0x1C, 0x00, 0x08, 0x2A, 0x49, 0x10, 0x0C, 0x00}, // U+3075 (Hiragana HU)
{ 0x4C, 0x20, 0x08, 0x2A, 0x49, 0x10, 0x0C, 0x00}, // U+3076 (Hiragana BU)
{ 0x4C, 0xA0, 0x48, 0x0A, 0x29, 0x48, 0x0C, 0x00}, // U+3077 (Hiragana PU)
{ 0x00, 0x00, 0x04, 0x0A, 0x11, 0x20, 0x40, 0x00}, // U+3078 (Hiragana HE)
{ 0x20, 0x40, 0x14, 0x2A, 0x11, 0x20, 0x40, 0x00}, // U+3079 (Hiragana BE)
{ 0x20, 0x50, 0x24, 0x0A, 0x11, 0x20, 0x40, 0x00}, // U+307A (Hiragana PE)
{ 0x7D, 0x11, 0x7D, 0x11, 0x39, 0x55, 0x09, 0x00}, // U+307B (Hiragana HO)
{ 0x9D, 0x51, 0x1D, 0x11, 0x39, 0x55, 0x09, 0x00}, // U+307C (Hiragana BO)
{ 0x5D, 0xB1, 0x5D, 0x11, 0x39, 0x55, 0x09, 0x00}, // U+307D (Hiragana PO)
{ 0x7E, 0x08, 0x3E, 0x08, 0x1C, 0x2A, 0x04, 0x00}, // U+307E (Hiragana MA)
{ 0x00, 0x07, 0x24, 0x24, 0x7E, 0x25, 0x12, 0x00}, // U+307F (Hiragana MI)
{ 0x04, 0x0F, 0x64, 0x06, 0x05, 0x26, 0x3C, 0x00}, // U+3080 (Hiragana MU)
{ 0x00, 0x09, 0x3D, 0x4A, 0x4B, 0x45, 0x2A, 0x00}, // U+3081 (Hiragana ME)
{ 0x02, 0x0F, 0x02, 0x0F, 0x62, 0x42, 0x3C, 0x00}, // U+3082 (Hiragana MO)
{ 0x00, 0x00, 0x12, 0x1F, 0x22, 0x12, 0x04, 0x00}, // U+3083 (Hiragana ya)
{ 0x00, 0x12, 0x3F, 0x42, 0x42, 0x34, 0x04, 0x00}, // U+3084 (Hiragana YA)
{ 0x00, 0x00, 0x11, 0x3D, 0x53, 0x39, 0x11, 0x00}, // U+3085 (Hiragana yu)
{ 0x00, 0x11, 0x3D, 0x53, 0x51, 0x39, 0x11, 0x00}, // U+3086 (Hiragana YU)
{ 0x00, 0x08, 0x38, 0x08, 0x1C, 0x2A, 0x04, 0x00}, // U+3087 (Hiragana yo)
{ 0x08, 0x08, 0x38, 0x08, 0x1C, 0x2A, 0x04, 0x00}, // U+3088 (Hiragana YO)
{ 0x1E, 0x00, 0x02, 0x3A, 0x46, 0x42, 0x30, 0x00}, // U+3089 (Hiragana RA)
{ 0x00, 0x20, 0x22, 0x22, 0x2A, 0x24, 0x10, 0x00}, // U+308A (Hiragana RI)
{ 0x1F, 0x08, 0x3C, 0x42, 0x49, 0x54, 0x38, 0x00}, // U+308B (Hiragana RU)
{ 0x04, 0x07, 0x04, 0x0C, 0x16, 0x55, 0x24, 0x00}, // U+308C (Hiragana RE)
{ 0x3F, 0x10, 0x08, 0x3C, 0x42, 0x41, 0x30, 0x00}, // U+308D (Hiragana RO)
{ 0x00, 0x00, 0x08, 0x0E, 0x38, 0x4C, 0x2A, 0x00}, // U+308E (Hiragana wa)
{ 0x04, 0x07, 0x04, 0x3C, 0x46, 0x45, 0x24, 0x00}, // U+308F (Hiragana WA)
{ 0x0E, 0x08, 0x3C, 0x4A, 0x69, 0x55, 0x32, 0x00}, // U+3090 (Hiragana WI)
{ 0x06, 0x3C, 0x42, 0x39, 0x04, 0x36, 0x49, 0x00}, // U+3091 (Hiragana WE)
{ 0x04, 0x0F, 0x04, 0x6E, 0x11, 0x08, 0x70, 0x00}, // U+3092 (Hiragana WO)
{ 0x08, 0x08, 0x04, 0x0C, 0x56, 0x52, 0x21, 0x00}, // U+3093 (Hiragana N)
{ 0x40, 0x2E, 0x00, 0x3C, 0x42, 0x40, 0x38, 0x00}, // U+3094 (Hiragana VU)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+3095
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+3096
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+3097
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+3098
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+3099 (voiced combinator mark)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+309A (semivoiced combinator mark)
{ 0x40, 0x80, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00}, // U+309B (Hiragana voiced mark)
{ 0x40, 0xA0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+309C (Hiragana semivoiced mark)
{ 0x00, 0x00, 0x08, 0x08, 0x10, 0x30, 0x0C, 0x00}, // U+309D (Hiragana iteration mark)
{ 0x20, 0x40, 0x14, 0x24, 0x08, 0x18, 0x06, 0x00}, // U+309E (Hiragana voiced iteration mark)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+309F
};
char font8x8_sga[26][8] = {
{ 0x00, 0x00, 0x38, 0x66, 0x06, 0x06, 0x07, 0x00}, // U+E541 (SGA A)
{ 0x00, 0x00, 0x0C, 0x0C, 0x18, 0x30, 0x7F, 0x00}, // U+E542 (SGA B)
{ 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x30, 0x30, 0x00}, // U+E543 (SGA C)
{ 0x00, 0x00, 0x7F, 0x00, 0x03, 0x1C, 0x60, 0x00}, // U+E544 (SGA D)
{ 0x00, 0x00, 0x63, 0x03, 0x03, 0x03, 0x7F, 0x00}, // U+E545 (SGA E)
{ 0x00, 0x00, 0x00, 0xFF, 0x00, 0xDB, 0x00, 0x00}, // U+E546 (SGA F)
{ 0x00, 0x00, 0x30, 0x30, 0x3E, 0x30, 0x30, 0x00}, // U+E547 (SGA G)
{ 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x18, 0x18, 0x00}, // U+E548 (SGA H)
{ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00}, // U+E549 (SGA I)
{ 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00}, // U+E54A (SGA J)
{ 0x00, 0x00, 0x18, 0x18, 0x5A, 0x18, 0x18, 0x00}, // U+E54B (SGA K)
{ 0x00, 0x00, 0x03, 0x33, 0x03, 0x33, 0x03, 0x00}, // U+E54C (SGA L)
{ 0x00, 0x00, 0x63, 0x60, 0x60, 0x60, 0x7F, 0x00}, // U+E54D (SGA M)
{ 0x00, 0x00, 0x66, 0x60, 0x30, 0x18, 0x0C, 0x00}, // U+E54E (SGA N)
{ 0x00, 0x00, 0x3C, 0x60, 0x30, 0x18, 0x0C, 0x00}, // U+E54F (SGA O)
{ 0x00, 0x00, 0x66, 0x60, 0x66, 0x06, 0x66, 0x00}, // U+E550 (SGA P)
{ 0x00, 0x00, 0x18, 0x00, 0x7E, 0x60, 0x7E, 0x00}, // U+E551 (SGA Q)
{ 0x00, 0x00, 0x00, 0x66, 0x00, 0x66, 0x00, 0x00}, // U+E552 (SGA R)
{ 0x00, 0x00, 0x0C, 0x0C, 0x3C, 0x30, 0x30, 0x00}, // U+E553 (SGA S)
{ 0x00, 0x00, 0x3C, 0x30, 0x30, 0x00, 0x30, 0x00}, // U+E554 (SGA T)
{ 0x00, 0x00, 0x00, 0x36, 0x00, 0x7F, 0x00, 0x00}, // U+E555 (SGA U)
{ 0x00, 0x00, 0x18, 0x18, 0x7E, 0x00, 0x7E, 0x00}, // U+E556 (SGA V)
{ 0x00, 0x00, 0x00, 0x18, 0x00, 0x66, 0x00, 0x00}, // U+E557 (SGA W)
{ 0x00, 0x00, 0x66, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+E558 (SGA X)
{ 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00}, // U+E559 (SGA Y)
{ 0x00, 0x00, 0x18, 0x3C, 0x66, 0x66, 0x66, 0x00} // U+E55A (SGA Z)
};