scummvm/scumm/charset.cpp
2005-05-15 10:40:28 +00:00

1798 lines
58 KiB
C++

/* ScummVM - Scumm Interpreter
* Copyright (C) 2001-2005 The ScummVM project
*
* 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 2
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*/
#include "stdafx.h"
#include "scumm/charset.h"
#include "scumm/scumm.h"
#include "scumm/nut_renderer.h"
#include "scumm/util.h"
#include "scumm/wiz_he.h"
namespace Scumm {
void ScummEngine::loadCJKFont() {
Common::File fp;
_useCJKMode = false;
if (_language == Common::JA_JPN && _version <= 5) { // FM-TOWNS v3 / v5 Kanji
int numChar = 256 * 32;
_2byteWidth = 16;
_2byteHeight = 16;
// use FM-TOWNS font rom, since game files don't have kanji font resources
if (fp.open("fmt_fnt.rom", Common::File::kFileReadMode)) {
_useCJKMode = true;
debug(2, "Loading FM-TOWNS Kanji rom");
_2byteFontPtr = new byte[((_2byteWidth + 7) / 8) * _2byteHeight * numChar];
fp.read(_2byteFontPtr, ((_2byteWidth + 7) / 8) * _2byteHeight * numChar);
fp.close();
}
} else if (_language == Common::KO_KOR || _language == Common::JA_JPN || _language == Common::ZH_TWN) {
int numChar = 0;
const char *fontFile = NULL;
switch (_language) {
case Common::KO_KOR:
fontFile = "korean.fnt";
numChar = 2350;
break;
case Common::JA_JPN:
fontFile = (_gameId == GID_DIG) ? "kanji16.fnt" : "japanese.fnt";
numChar = 1024; //FIXME
break;
case Common::ZH_TWN:
if (_gameId == GID_CMI) {
fontFile = "chinese.fnt";
numChar = 1; //FIXME
}
break;
default:
break;
}
if (fontFile && fp.open(fontFile)) {
debug(2, "Loading CJK Font");
_useCJKMode = true;
fp.seek(2, SEEK_CUR);
_2byteWidth = fp.readByte();
_2byteHeight = fp.readByte();
_2byteFontPtr = new byte[((_2byteWidth + 7) / 8) * _2byteHeight * numChar];
fp.read(_2byteFontPtr, ((_2byteWidth + 7) / 8) * _2byteHeight * numChar);
fp.close();
} else {
warning("Couldn't load any font");
}
}
}
static int SJIStoFMTChunk(int f, int s) { //converts sjis code to fmt font offset
enum {
KANA = 0,
KANJI = 1,
EKANJI = 2
};
int base = s - ((s + 1) % 32);
int c = 0, p = 0, chunk_f = 0, chunk = 0, cr = 0, kanjiType = KANA;
if (f >= 0x81 && f <= 0x84) kanjiType = KANA;
if (f >= 0x88 && f <= 0x9f) kanjiType = KANJI;
if (f >= 0xe0 && f <= 0xea) kanjiType = EKANJI;
if ((f > 0xe8 || (f == 0xe8 && base >= 0x9f)) || (f > 0x90 || (f == 0x90 && base >= 0x9f))) {
c = 48; //correction
p = -8; //correction
}
if (kanjiType == KANA) {//Kana
chunk_f = (f - 0x81) * 2;
} else if (kanjiType == KANJI) {//Standard Kanji
p += f - 0x88;
chunk_f = c + 2 * p;
} else if (kanjiType == EKANJI) {//Enhanced Kanji
p += f - 0xe0;
chunk_f = c + 2 * p;
}
// Base corrections
if (base == 0x7f && s == 0x7f)
base -= 0x20;
if (base == 0x9f && s == 0xbe)
base += 0x20;
if (base == 0xbf && s == 0xde)
base += 0x20;
//if (base == 0x7f && s == 0x9e)
// base += 0x20;
switch (base) {
case 0x3f:
cr = 0; //3f
if (kanjiType == KANA) chunk = 1;
else if (kanjiType == KANJI) chunk = 31;
else if (kanjiType == EKANJI) chunk = 111;
break;
case 0x5f:
cr = 0; //5f
if (kanjiType == KANA) chunk = 17;
else if (kanjiType == KANJI) chunk = 47;
else if (kanjiType == EKANJI) chunk = 127;
break;
case 0x7f:
cr = -1; //80
if (kanjiType == KANA) chunk = 9;
else if (kanjiType == KANJI) chunk = 63;
else if (kanjiType == EKANJI) chunk = 143;
break;
case 0x9f:
cr = 1; //9e
if (kanjiType == KANA) chunk = 2;
else if (kanjiType == KANJI) chunk = 32;
else if (kanjiType == EKANJI) chunk = 112;
break;
case 0xbf:
cr = 1; //be
if (kanjiType == KANA) chunk = 18;
else if (kanjiType == KANJI) chunk = 48;
else if (kanjiType == EKANJI) chunk = 128;
break;
case 0xdf:
cr = 1; //de
if (kanjiType == KANA) chunk = 10;
else if (kanjiType == KANJI) chunk = 64;
else if (kanjiType == EKANJI) chunk = 144;
break;
default:
warning("Invaild Char! f %x s %x base %x c %d p %d", f, s, base, c, p);
return 0;
}
debug(6, "Kanji: %c%c f 0x%x s 0x%x base 0x%x c %d p %d chunk %d cr %d index %d", f, s, f, s, base, c, p, chunk, cr, ((chunk_f + chunk) * 32 + (s - base)) + cr);
return ((chunk_f + chunk) * 32 + (s - base)) + cr;
}
byte *ScummEngine::get2byteCharPtr(int idx) {
switch (_language) {
case Common::KO_KOR:
idx = ((idx % 256) - 0xb0) * 94 + (idx / 256) - 0xa1;
break;
case Common::JA_JPN:
idx = SJIStoFMTChunk((idx % 256), (idx / 256));
break;
case Common::ZH_TWN:
default:
idx = 0;
}
return _2byteFontPtr + ((_2byteWidth + 7) / 8) * _2byteHeight * idx;
}
#pragma mark -
CharsetRenderer::CharsetRenderer(ScummEngine *vm) {
_nextLeft = 0;
_nextTop = 0;
_top = 0;
_left = 0;
_startLeft = 0;
_right = 0;
_color = 0;
_dropShadow = false;
_center = false;
_hasMask = false;
_textScreenID = kMainVirtScreen;
_ignoreCharsetMask = false;
_blitAlso = false;
_firstChar = false;
_disableOffsX = false;
_vm = vm;
_curId = 0;
const int size = _vm->_screenWidth * _vm->_screenHeight;
_textSurface.pixels = malloc(size);
_textSurface.w = _vm->_screenWidth;
_textSurface.h = _vm->_screenHeight;
_textSurface.pitch = _vm->_screenWidth;
_textSurface.bytesPerPixel = 1;
clearTextSurface();
}
CharsetRenderer::~CharsetRenderer() {
free(_textSurface.pixels);
}
void CharsetRendererCommon::setCurID(byte id) {
checkRange(_vm->_numCharsets - 1, 0, id, "Printing with bad charset %d");
_curId = id;
_fontPtr = _vm->getResourceAddress(rtCharset, id);
if (_fontPtr == 0)
error("CharsetRendererCommon::setCurID: charset %d not found!", id);
if (_vm->_version == 4)
_fontPtr += 17;
else
_fontPtr += 29;
}
void CharsetRendererV3::setCurID(byte id) {
checkRange(_vm->_numCharsets - 1, 0, id, "Printing with bad charset %d");
_curId = id;
_fontPtr = _vm->getResourceAddress(rtCharset, id);
if (_fontPtr == 0)
error("CharsetRendererCommon::setCurID: charset %d not found!", id);
_numChars = _fontPtr[4];
_fontPtr += 6;
_widthTable = _fontPtr;
_fontPtr += _numChars;
}
int CharsetRendererCommon::getFontHeight() {
if (_vm->_useCJKMode)
return MAX(_vm->_2byteHeight + 1, (int)_fontPtr[1]);
else
return _fontPtr[1];
}
int CharsetRendererV3::getFontHeight() {
if (_vm->_useCJKMode)
return MAX(_vm->_2byteHeight + 1, 8);
else
return 8;
}
// do spacing for variable width old-style font
int CharsetRendererClassic::getCharWidth(byte chr) {
if (chr >= 0x80 && _vm->_useCJKMode)
return _vm->_2byteWidth / 2;
int spacing = 0;
int offs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
if (offs) {
spacing = _fontPtr[offs] + (signed char)_fontPtr[offs + 2];
}
return spacing;
}
int CharsetRenderer::getStringWidth(int arg, const byte *text) {
int pos = 0;
int width = 1;
byte chr;
int oldID = getCurID();
int code = (_vm->_heversion >= 80) ? 127 : 64;
while ((chr = text[pos++]) != 0) {
if (_vm->_heversion >= 72 && chr == code) {
chr = text[pos++];
if (chr == 84) { // Strings of speech offset/size
while (chr != code)
chr = text[pos++];
continue;
}
if (chr == 119) // 'Wait'
break;
if (chr == 104|| chr == 110) // 'Newline'
break;
} else if (chr == '@')
continue;
if (chr == 0xD)
break;
if (chr == 254 || chr == 255) {
//process in LE
if (chr == 254 && checkKSCode(text[pos], chr) && _vm->_useCJKMode) {
goto loc_avoid_ks_fe;
}
chr = text[pos++];
if (chr == 3) // 'WAIT'
break;
if (chr == 8) { // 'Verb on next line'
if (arg == 1)
break;
while (text[pos++] == ' ')
;
continue;
}
if (chr == 10 || chr == 21 || chr == 12 || chr == 13) {
pos += 2;
continue;
}
if (chr == 9 || chr == 1 || chr == 2) // 'Newline'
break;
if (chr == 14) {
int set = text[pos] | (text[pos + 1] << 8);
pos += 2;
setCurID(set);
continue;
}
}
loc_avoid_ks_fe:
if ((chr & 0x80) && _vm->_useCJKMode) {
pos++;
width += _vm->_2byteWidth;
} else {
width += getCharWidth(chr);
}
}
setCurID(oldID);
return width;
}
void CharsetRenderer::addLinebreaks(int a, byte *str, int pos, int maxwidth) {
int lastspace = -1;
int curw = 1;
byte chr;
int oldID = getCurID();
int code = (_vm->_heversion >= 80) ? 127 : 64;
while ((chr = str[pos++]) != 0) {
if (_vm->_heversion >= 72 && chr == code) {
chr = str[pos++];
if (chr == 84) { // Strings of speech offset/size
while (chr != code)
chr = str[pos++];
continue;
}
if (chr == 119) // 'Wait'
break;
if (chr == 110) { // 'Newline'
curw = 1;
continue;
}
if (chr == 104) // 'Don't terminate with \n'
break;
} else if (chr == '@')
continue;
if (chr == 254 || chr == 255) {
//process in LE
if (chr == 254 && checkKSCode(str[pos], chr) && _vm->_useCJKMode) {
goto loc_avoid_ks_fe;
}
chr = str[pos++];
if (chr == 3) // 'Wait'
break;
if (chr == 8) { // 'Verb on next line'
if (a == 1) {
curw = 1;
} else {
while (str[pos] == ' ')
str[pos++] = '@';
}
continue;
}
if (chr == 10 || chr == 21 || chr == 12 || chr == 13) {
pos += 2;
continue;
}
if (chr == 1) { // 'Newline'
curw = 1;
continue;
}
if (chr == 2) // 'Don't terminate with \n'
break;
if (chr == 14) {
int set = str[pos] | (str[pos + 1] << 8);
pos += 2;
setCurID(set);
continue;
}
}
if (chr == ' ')
lastspace = pos - 1;
loc_avoid_ks_fe:
if ((chr & 0x80) && _vm->_useCJKMode) {
pos++;
curw += _vm->_2byteWidth;
} else {
curw += getCharWidth(chr);
}
if (lastspace == -1)
continue;
if (curw > maxwidth) {
str[lastspace] = 0xD;
curw = 1;
pos = lastspace + 1;
lastspace = -1;
}
}
setCurID(oldID);
}
#ifdef __PALM_OS__
static byte *englishCharsetDataV2;
static byte *germanCharsetDataV2;
static byte *frenchCharsetDataV2;
static byte *italianCharsetDataV2;
static byte *spanishCharsetDataV2;
#else
// English Zak font
static byte englishCharsetDataV2[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x03, 0x06, 0x0C, 0x18, 0x3E, 0x03, 0x00,
0x80, 0xC0, 0x60, 0x30, 0x18, 0x7C, 0xC0, 0x00,
0x00, 0x03, 0x3E, 0x18, 0x0C, 0x06, 0x03, 0x01,
0x00, 0xC0, 0x7C, 0x18, 0x30, 0x60, 0xC0, 0x80,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x07, 0x07, 0x0F, 0x1F, 0x7F,
0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xE0,
0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0C, 0x18,
0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x18,
0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00,
0x18, 0x0C, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1F, 0x1F, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0xF8, 0xF8, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xF8, 0xF8, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x1F, 0x1F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x07, 0x0C, 0x18, 0x18,
0x00, 0x00, 0x00, 0xC0, 0xE0, 0x30, 0x18, 0x18,
0x18, 0x18, 0x30, 0xE0, 0xC0, 0x00, 0x00, 0x00,
0x18, 0x18, 0x0C, 0x07, 0x03, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x1F, 0x1F, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xF8, 0xF8, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xFF, 0xFF, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x18, 0x3C, 0x66, 0xC3, 0xC3, 0x66, 0x3C, 0x18,
0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x3C, 0x18,
0x18, 0x66, 0xC3, 0xDB, 0xDB, 0xC3, 0x66, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00,
0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
0x66, 0x66, 0xFF, 0x66, 0xFF, 0x66, 0x66, 0x00,
0x18, 0x3E, 0x58, 0x3C, 0x1A, 0x7C, 0x18, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x49, 0x00,
0x3C, 0x66, 0x3C, 0x38, 0x67, 0x66, 0x3F, 0x00,
0x06, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0C, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00,
0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00,
0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00,
0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
0x00, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00,
0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
0x18, 0x18, 0x38, 0x18, 0x18, 0x18, 0x7E, 0x00,
0x3C, 0x66, 0x06, 0x0C, 0x30, 0x60, 0x7E, 0x00,
0x3C, 0x66, 0x06, 0x1C, 0x06, 0x66, 0x3C, 0x00,
0x06, 0x0E, 0x1E, 0x66, 0x7F, 0x06, 0x06, 0x00,
0x7E, 0x60, 0x7C, 0x06, 0x06, 0x66, 0x3C, 0x00,
0x3C, 0x66, 0x60, 0x7C, 0x66, 0x66, 0x3C, 0x00,
0x7E, 0x66, 0x0C, 0x18, 0x18, 0x18, 0x18, 0x00,
0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00,
0x3C, 0x66, 0x66, 0x3E, 0x06, 0x66, 0x3C, 0x00,
0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00,
0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
0x0E, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0E, 0x00,
0x7C, 0x82, 0xBA, 0xA2, 0xBA, 0x82, 0x7C, 0x00,
0x70, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x70, 0x00,
0x3C, 0x66, 0x06, 0x0C, 0x18, 0x00, 0x18, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x18, 0x3C, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00,
0x7C, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x7C, 0x00,
0x3C, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3C, 0x00,
0x78, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0x78, 0x00,
0x7E, 0x60, 0x60, 0x78, 0x60, 0x60, 0x7E, 0x00,
0x7E, 0x60, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00,
0x3C, 0x66, 0x60, 0x6E, 0x66, 0x66, 0x3C, 0x00,
0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00,
0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00,
0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C, 0x38, 0x00,
0x66, 0x6C, 0x78, 0x70, 0x78, 0x6C, 0x66, 0x00,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7E, 0x00,
0x63, 0x77, 0x7F, 0x6B, 0x63, 0x63, 0x63, 0x00,
0x66, 0x76, 0x7E, 0x7E, 0x6E, 0x66, 0x66, 0x00,
0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x00,
0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x0E, 0x00,
0x7C, 0x66, 0x66, 0x7C, 0x78, 0x6C, 0x66, 0x00,
0x3C, 0x66, 0x60, 0x3C, 0x06, 0x66, 0x3C, 0x00,
0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00,
0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00,
0x66, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00,
0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00,
0x7E, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x7E, 0x00,
0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00,
0x0C, 0x12, 0x30, 0x7C, 0x30, 0x62, 0xFC, 0x00,
0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xDB, 0xDB, 0x00,
0x00, 0x10, 0x30, 0x7F, 0x7F, 0x30, 0x10, 0x00,
0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3C, 0x06, 0x3E, 0x66, 0x3E, 0x00,
0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00,
0x00, 0x00, 0x3C, 0x60, 0x60, 0x60, 0x3C, 0x00,
0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x00,
0x00, 0x00, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00,
0x00, 0x0E, 0x18, 0x3E, 0x18, 0x18, 0x18, 0x00,
0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x7C,
0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x00,
0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3C, 0x00,
0x00, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x3C,
0x00, 0x60, 0x60, 0x6C, 0x78, 0x6C, 0x66, 0x00,
0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00,
0x00, 0x00, 0x66, 0x7F, 0x7F, 0x6B, 0x63, 0x00,
0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00,
0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00,
0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60,
0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x06,
0x00, 0x00, 0x7C, 0x66, 0x60, 0x60, 0x60, 0x00,
0x00, 0x00, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x00,
0x00, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x0E, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00,
0x00, 0x00, 0x63, 0x6B, 0x7F, 0x3E, 0x36, 0x00,
0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x0C, 0x78,
0x00, 0x00, 0x7E, 0x0C, 0x18, 0x30, 0x7E, 0x00,
0x01, 0x03, 0x06, 0x6C, 0x78, 0x70, 0x60, 0x00,
0x18, 0x3C, 0x7E, 0xFF, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0xFF, 0x7E, 0x3C, 0x18,
0x10, 0x30, 0x70, 0xFF, 0xFF, 0x70, 0x30, 0x10,
0x08, 0x0C, 0x0E, 0xFF, 0xFF, 0x0E, 0x0C, 0x08,
};
// German Zak font
static byte germanCharsetDataV2[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x03, 0x06, 0x0c, 0x18, 0x3e, 0x03, 0x00,
0x80, 0xc0, 0x60, 0x30, 0x18, 0x7c, 0xc0, 0x00,
0x00, 0x03, 0x3e, 0x18, 0x0c, 0x06, 0x03, 0x01,
0x00, 0xc0, 0x7c, 0x18, 0x30, 0x60, 0xc0, 0x80,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x1f, 0x7f,
0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0,
0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18,
0x00, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x30, 0x18,
0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00,
0x18, 0x0c, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x18, 0x18,
0x00, 0x00, 0x00, 0xc0, 0xe0, 0x30, 0x18, 0x18,
0x18, 0x18, 0x30, 0xe0, 0xc0, 0x00, 0x00, 0x00,
0x18, 0x18, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x66, 0x3c, 0x18,
0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x3c, 0x18,
0x18, 0x66, 0xc3, 0xdb, 0xdb, 0xc3, 0x66, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00,
0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
0x66, 0x66, 0xff, 0x66, 0xff, 0x66, 0x66, 0x00,
0x18, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x18, 0x00,
0x62, 0x66, 0x0c, 0x18, 0x30, 0x66, 0x46, 0x00,
0x3c, 0x66, 0x3c, 0x38, 0x67, 0x66, 0x3f, 0x00,
0x30, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00,
0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00,
0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
0x00, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00,
0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x18, 0x18, 0x38, 0x18, 0x18, 0x18, 0x7e, 0x00,
0x3c, 0x66, 0x06, 0x0c, 0x30, 0x60, 0x7e, 0x00,
0x3c, 0x66, 0x06, 0x1c, 0x06, 0x66, 0x3c, 0x00,
0x06, 0x0e, 0x1e, 0x66, 0x7f, 0x06, 0x06, 0x00,
0x7e, 0x60, 0x7c, 0x06, 0x06, 0x66, 0x3c, 0x00,
0x3c, 0x66, 0x60, 0x7c, 0x66, 0x66, 0x3c, 0x00,
0x7e, 0x66, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x00,
0x3c, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00,
0x3c, 0x66, 0x66, 0x3e, 0x06, 0x66, 0x3c, 0x00,
0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00,
0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
0x0e, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0e, 0x00,
0x7c, 0x82, 0xba, 0xa2, 0xa2, 0xba, 0x82, 0x7c,
0x70, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x70, 0x00,
0x3c, 0x66, 0x06, 0x0c, 0x18, 0x00, 0x18, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0x18, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
0x7c, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x7c, 0x00,
0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x00,
0x78, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x00,
0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x7e, 0x00,
0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00,
0x3c, 0x66, 0x60, 0x6e, 0x66, 0x66, 0x3c, 0x00,
0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38, 0x00,
0x66, 0x6c, 0x78, 0x70, 0x78, 0x6c, 0x66, 0x00,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x00,
0x63, 0x77, 0x7f, 0x6b, 0x63, 0x63, 0x63, 0x00,
0x66, 0x76, 0x7e, 0x7e, 0x6e, 0x66, 0x66, 0x00,
0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x00,
0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x0e, 0x00,
0x7c, 0x66, 0x66, 0x7c, 0x78, 0x6c, 0x66, 0x00,
0x3c, 0x66, 0x60, 0x3c, 0x06, 0x66, 0x3c, 0x00,
0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
0x63, 0x63, 0x63, 0x6b, 0x7f, 0x77, 0x63, 0x00,
0x66, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x66, 0x00,
0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00,
0x7e, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x7e, 0x00,
0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
0x66, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x00,
0x00, 0x10, 0x30, 0x7f, 0x7f, 0x30, 0x10, 0x00,
0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00,
0x00, 0x00, 0x3c, 0x60, 0x60, 0x60, 0x3c, 0x00,
0x00, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x3e, 0x00,
0x00, 0x00, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
0x00, 0x0e, 0x18, 0x3e, 0x18, 0x18, 0x18, 0x00,
0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x7c,
0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x00,
0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
0x00, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x3c,
0x00, 0x60, 0x60, 0x6c, 0x78, 0x6c, 0x66, 0x00,
0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
0x00, 0x00, 0x66, 0x7f, 0x7f, 0x6b, 0x63, 0x00,
0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x00,
0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x00, 0x00, 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60,
0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x06,
0x00, 0x00, 0x7c, 0x66, 0x60, 0x60, 0x60, 0x00,
0x00, 0x00, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x00,
0x00, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x0e, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
0x00, 0x00, 0x63, 0x6b, 0x7f, 0x3e, 0x36, 0x00,
0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x0c, 0x78,
0x00, 0x00, 0x7e, 0x0c, 0x18, 0x30, 0x7e, 0x00,
0x66, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x66, 0x18, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x00,
0x42, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x1c, 0x36, 0x36, 0x7c, 0x66, 0x66, 0x7c, 0x40,
0x08, 0x0c, 0x0e, 0xff, 0xff, 0x0e, 0x0c, 0x08,
};
// French Zak font.
static byte frenchCharsetDataV2[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x03, 0x06, 0x0c, 0x18, 0x3e, 0x03, 0x00,
0x80, 0xc0, 0x60, 0x30, 0x18, 0x7c, 0xc0, 0x00,
0x00, 0x03, 0x3e, 0x18, 0x0c, 0x06, 0x03, 0x01,
0x00, 0xc0, 0x7c, 0x18, 0x30, 0x60, 0xc0, 0x80,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x1f, 0x7f,
0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0,
0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18,
0x00, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x30, 0x18,
0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00,
0x18, 0x0c, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x18, 0x18,
0x00, 0x00, 0x00, 0xc0, 0xe0, 0x30, 0x18, 0x18,
0x18, 0x18, 0x30, 0xe0, 0xc0, 0x00, 0x00, 0x00,
0x18, 0x18, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x66, 0x3c, 0x18,
0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x3c, 0x18,
0x18, 0x66, 0xc3, 0xdb, 0xdb, 0xc3, 0x66, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00,
0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
0x66, 0x66, 0xff, 0x66, 0xff, 0x66, 0x66, 0x00,
0x18, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x18, 0x00,
0x62, 0x66, 0x0c, 0x18, 0x30, 0x66, 0x46, 0x00,
0x3c, 0x66, 0x3c, 0x38, 0x67, 0x66, 0x3f, 0x00,
0x30, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00,
0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00,
0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
0x00, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00,
0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x18, 0x18, 0x38, 0x18, 0x18, 0x18, 0x7e, 0x00,
0x3c, 0x66, 0x06, 0x0c, 0x30, 0x60, 0x7e, 0x00,
0x3c, 0x66, 0x06, 0x1c, 0x06, 0x66, 0x3c, 0x00,
0x06, 0x0e, 0x1e, 0x66, 0x7f, 0x06, 0x06, 0x00,
0x7e, 0x60, 0x7c, 0x06, 0x06, 0x66, 0x3c, 0x00,
0x3c, 0x66, 0x60, 0x7c, 0x66, 0x66, 0x3c, 0x00,
0x7e, 0x66, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x00,
0x3c, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00,
0x3c, 0x66, 0x66, 0x3e, 0x06, 0x66, 0x3c, 0x00,
0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00,
0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
0x10, 0x08, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
0x18, 0x24, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
0x00, 0x00, 0x3c, 0x60, 0x60, 0x3c, 0x18, 0x38,
0x3c, 0x66, 0x06, 0x0c, 0x18, 0x00, 0x18, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0x18, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
0x7c, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x7c, 0x00,
0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x00,
0x78, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x00,
0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x7e, 0x00,
0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00,
0x3c, 0x66, 0x60, 0x6e, 0x66, 0x66, 0x3c, 0x00,
0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38, 0x00,
0x66, 0x6c, 0x78, 0x70, 0x78, 0x6c, 0x66, 0x00,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x00,
0x63, 0x77, 0x7f, 0x6b, 0x63, 0x63, 0x63, 0x00,
0x66, 0x76, 0x7e, 0x7e, 0x6e, 0x66, 0x66, 0x00,
0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x00,
0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x0e, 0x00,
0x7c, 0x66, 0x66, 0x7c, 0x78, 0x6c, 0x66, 0x00,
0x3c, 0x66, 0x60, 0x3c, 0x06, 0x66, 0x3c, 0x00,
0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
0x63, 0x63, 0x63, 0x6b, 0x7f, 0x77, 0x63, 0x00,
0x66, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x66, 0x00,
0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00,
0x7e, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x7e, 0x00,
0x08, 0x10, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
0x10, 0x08, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
0x18, 0x24, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x00,
0x00, 0x6c, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00,
0x00, 0x00, 0x3c, 0x60, 0x60, 0x60, 0x3c, 0x00,
0x00, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x3e, 0x00,
0x00, 0x00, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
0x00, 0x0e, 0x18, 0x3e, 0x18, 0x18, 0x18, 0x00,
0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x7c,
0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x00,
0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
0x00, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x3c,
0x00, 0x60, 0x60, 0x6c, 0x78, 0x6c, 0x66, 0x00,
0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
0x00, 0x00, 0x66, 0x7f, 0x7f, 0x6b, 0x63, 0x00,
0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x00,
0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x00, 0x00, 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60,
0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x06,
0x00, 0x00, 0x7c, 0x66, 0x60, 0x60, 0x60, 0x00,
0x00, 0x00, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x00,
0x00, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x0e, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
0x00, 0x00, 0x63, 0x6b, 0x7f, 0x3e, 0x36, 0x00,
0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x0c, 0x78,
0x00, 0x00, 0x7e, 0x0c, 0x18, 0x30, 0x7e, 0x00,
0x18, 0x24, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
0x18, 0x24, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x00,
0x10, 0x08, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x00,
0x18, 0x24, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x00,
0x08, 0x0c, 0x0e, 0xff, 0xff, 0x0e, 0x0c, 0x08,
};
// Italian Zak font.
static byte italianCharsetDataV2[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x03, 0x06, 0x0c, 0x18, 0x3e, 0x03, 0x00,
0x80, 0xc0, 0x60, 0x30, 0x18, 0x7c, 0xc0, 0x00,
0x00, 0x03, 0x3e, 0x18, 0x0c, 0x06, 0x03, 0x01,
0x00, 0xc0, 0x7c, 0x18, 0x30, 0x60, 0xc0, 0x80,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x1f, 0x7f,
0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0,
0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18,
0x00, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x30, 0x18,
0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00,
0x18, 0x0c, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x18, 0x18,
0x00, 0x00, 0x00, 0xc0, 0xe0, 0x30, 0x18, 0x18,
0x18, 0x18, 0x30, 0xe0, 0xc0, 0x00, 0x00, 0x00,
0x18, 0x18, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x66, 0x3c, 0x18,
0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x3c, 0x18,
0x18, 0x66, 0xc3, 0xdb, 0xdb, 0xc3, 0x66, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00,
0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
0x66, 0x66, 0xff, 0x66, 0xff, 0x66, 0x66, 0x00,
0x18, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x18, 0x00,
0x62, 0x66, 0x0c, 0x18, 0x30, 0x66, 0x46, 0x00,
0x3c, 0x66, 0x3c, 0x38, 0x67, 0x66, 0x3f, 0x00,
0x30, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00,
0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00,
0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
0x00, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00,
0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x18, 0x18, 0x38, 0x18, 0x18, 0x18, 0x7e, 0x00,
0x3c, 0x66, 0x06, 0x0c, 0x30, 0x60, 0x7e, 0x00,
0x3c, 0x66, 0x06, 0x1c, 0x06, 0x66, 0x3c, 0x00,
0x06, 0x0e, 0x1e, 0x66, 0x7f, 0x06, 0x06, 0x00,
0x7e, 0x60, 0x7c, 0x06, 0x06, 0x66, 0x3c, 0x00,
0x3c, 0x66, 0x60, 0x7c, 0x66, 0x66, 0x3c, 0x00,
0x7e, 0x66, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x00,
0x3c, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00,
0x3c, 0x66, 0x66, 0x3e, 0x06, 0x66, 0x3c, 0x00,
0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00,
0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
0x10, 0x08, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
0x08, 0x10, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
0x10, 0x08, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
0x3c, 0x66, 0x06, 0x0c, 0x18, 0x00, 0x18, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0x18, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
0x7c, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x7c, 0x00,
0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x00,
0x78, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x00,
0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x7e, 0x00,
0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00,
0x3c, 0x66, 0x60, 0x6e, 0x66, 0x66, 0x3c, 0x00,
0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38, 0x00,
0x66, 0x6c, 0x78, 0x70, 0x78, 0x6c, 0x66, 0x00,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x00,
0x63, 0x77, 0x7f, 0x6b, 0x63, 0x63, 0x63, 0x00,
0x66, 0x76, 0x7e, 0x7e, 0x6e, 0x66, 0x66, 0x00,
0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x00,
0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x0e, 0x00,
0x7c, 0x66, 0x66, 0x7c, 0x78, 0x6c, 0x66, 0x00,
0x3c, 0x66, 0x60, 0x3c, 0x06, 0x66, 0x3c, 0x00,
0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
0x63, 0x63, 0x63, 0x6b, 0x7f, 0x77, 0x63, 0x00,
0x66, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x66, 0x00,
0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00,
0x7e, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x7e, 0x00,
0x08, 0x10, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
0x10, 0x08, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
0x18, 0x24, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x00,
0x00, 0x6c, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00,
0x00, 0x00, 0x3c, 0x60, 0x60, 0x60, 0x3c, 0x00,
0x00, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x3e, 0x00,
0x00, 0x00, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
0x00, 0x0e, 0x18, 0x3e, 0x18, 0x18, 0x18, 0x00,
0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x7c,
0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x00,
0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
0x00, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x3c,
0x00, 0x60, 0x60, 0x6c, 0x78, 0x6c, 0x66, 0x00,
0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
0x00, 0x00, 0x66, 0x7f, 0x7f, 0x6b, 0x63, 0x00,
0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x00,
0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x00, 0x00, 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60,
0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x06,
0x00, 0x00, 0x7c, 0x66, 0x60, 0x60, 0x60, 0x00,
0x00, 0x00, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x00,
0x00, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x0e, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
0x00, 0x00, 0x63, 0x6b, 0x7f, 0x3e, 0x36, 0x00,
0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x0c, 0x78,
0x00, 0x00, 0x7e, 0x0c, 0x18, 0x30, 0x7e, 0x00,
0x10, 0x08, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
0x10, 0x08, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x00,
0x10, 0x08, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x00,
0x18, 0x24, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x00,
0x08, 0x0c, 0x0e, 0xff, 0xff, 0x0e, 0x0c, 0x08,
};
// Spanish Zak font.
// FIXME: This is identical to germanCharsetDataV2 it seems?!
static byte spanishCharsetDataV2[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x03, 0x06, 0x0c, 0x18, 0x3e, 0x03, 0x00,
0x80, 0xc0, 0x60, 0x30, 0x18, 0x7c, 0xc0, 0x00,
0x00, 0x03, 0x3e, 0x18, 0x0c, 0x06, 0x03, 0x01,
0x00, 0xc0, 0x7c, 0x18, 0x30, 0x60, 0xc0, 0x80,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x1f, 0x7f,
0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0,
0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18,
0x00, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x30, 0x18,
0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00,
0x18, 0x0c, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x07, 0x0c, 0x18, 0x18,
0x00, 0x00, 0x00, 0xc0, 0xe0, 0x30, 0x18, 0x18,
0x18, 0x18, 0x30, 0xe0, 0xc0, 0x00, 0x00, 0x00,
0x18, 0x18, 0x0c, 0x07, 0x03, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x66, 0x3c, 0x18,
0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x3c, 0x18,
0x18, 0x66, 0xc3, 0xdb, 0xdb, 0xc3, 0x66, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00,
0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
0x66, 0x66, 0xff, 0x66, 0xff, 0x66, 0x66, 0x00,
0x18, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x18, 0x00,
0x62, 0x66, 0x0c, 0x18, 0x30, 0x66, 0x46, 0x00,
0x3c, 0x66, 0x3c, 0x38, 0x67, 0x66, 0x3f, 0x00,
0x30, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00,
0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00,
0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
0x00, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00,
0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x18, 0x18, 0x38, 0x18, 0x18, 0x18, 0x7e, 0x00,
0x3c, 0x66, 0x06, 0x0c, 0x30, 0x60, 0x7e, 0x00,
0x3c, 0x66, 0x06, 0x1c, 0x06, 0x66, 0x3c, 0x00,
0x06, 0x0e, 0x1e, 0x66, 0x7f, 0x06, 0x06, 0x00,
0x7e, 0x60, 0x7c, 0x06, 0x06, 0x66, 0x3c, 0x00,
0x3c, 0x66, 0x60, 0x7c, 0x66, 0x66, 0x3c, 0x00,
0x7e, 0x66, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x00,
0x3c, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00,
0x3c, 0x66, 0x66, 0x3e, 0x06, 0x66, 0x3c, 0x00,
0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00,
0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
0x0e, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0e, 0x00,
0x7c, 0x82, 0xba, 0xa2, 0xa2, 0xba, 0x82, 0x7c,
0x70, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x70, 0x00,
0x3c, 0x66, 0x06, 0x0c, 0x18, 0x00, 0x18, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0x18, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
0x7c, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x7c, 0x00,
0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x00,
0x78, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x00,
0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x7e, 0x00,
0x7e, 0x60, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00,
0x3c, 0x66, 0x60, 0x6e, 0x66, 0x66, 0x3c, 0x00,
0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00,
0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38, 0x00,
0x66, 0x6c, 0x78, 0x70, 0x78, 0x6c, 0x66, 0x00,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x00,
0x63, 0x77, 0x7f, 0x6b, 0x63, 0x63, 0x63, 0x00,
0x66, 0x76, 0x7e, 0x7e, 0x6e, 0x66, 0x66, 0x00,
0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x00,
0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x0e, 0x00,
0x7c, 0x66, 0x66, 0x7c, 0x78, 0x6c, 0x66, 0x00,
0x3c, 0x66, 0x60, 0x3c, 0x06, 0x66, 0x3c, 0x00,
0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
0x63, 0x63, 0x63, 0x6b, 0x7f, 0x77, 0x63, 0x00,
0x66, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x66, 0x00,
0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00,
0x7e, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x7e, 0x00,
0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
0x66, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x00,
0x00, 0x10, 0x30, 0x7f, 0x7f, 0x30, 0x10, 0x00,
0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00,
0x00, 0x00, 0x3c, 0x60, 0x60, 0x60, 0x3c, 0x00,
0x00, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x3e, 0x00,
0x00, 0x00, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
0x00, 0x0e, 0x18, 0x3e, 0x18, 0x18, 0x18, 0x00,
0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x7c,
0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x00,
0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
0x00, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x3c,
0x00, 0x60, 0x60, 0x6c, 0x78, 0x6c, 0x66, 0x00,
0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
0x00, 0x00, 0x66, 0x7f, 0x7f, 0x6b, 0x63, 0x00,
0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x00,
0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x00, 0x00, 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x60,
0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x06,
0x00, 0x00, 0x7c, 0x66, 0x60, 0x60, 0x60, 0x00,
0x00, 0x00, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x00,
0x00, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x0e, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
0x00, 0x00, 0x63, 0x6b, 0x7f, 0x3e, 0x36, 0x00,
0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x0c, 0x78,
0x00, 0x00, 0x7e, 0x0c, 0x18, 0x30, 0x7e, 0x00,
0x66, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x66, 0x18, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x00,
0x42, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x1c, 0x36, 0x36, 0x7c, 0x66, 0x66, 0x7c, 0x40,
0x08, 0x0c, 0x0e, 0xff, 0xff, 0x0e, 0x0c, 0x08,
};
#endif
CharsetRendererV2::CharsetRendererV2(ScummEngine *vm, Common::Language language)
: CharsetRendererV3(vm) {
switch (language) {
case Common::DE_DEU:
_fontPtr = germanCharsetDataV2;
break;
case Common::FR_FRA:
_fontPtr = frenchCharsetDataV2;
break;
case Common::IT_ITA:
_fontPtr = italianCharsetDataV2;
break;
case Common::ES_ESP:
_fontPtr = spanishCharsetDataV2;
break;
default:
_fontPtr = englishCharsetDataV2;
break;
}
#if 0
// Decompress weird encoding in which the Zak executable contains the font.
// I leave the code around in case we need to use it again (e.g. we might
// have to include different fonts for french/spanish/russian/... version
// of MM / Zak
//
int count = 0, len;
byte b;
const byte *data = spanishCharsetDataV2;
const int size = sizeof(spanishCharsetDataV2);
for (int offset = 0; offset < size; offset++) {
if (data[offset+1] == 0x00 && data[offset+2] == 0xB2 &&
data[offset+5] == 0x00 && data[offset+6] == 0xB0) {
b = data[offset+3];
len = data[offset+4];
while (len--) {
printf("0x%02x, ", b);
count++;
if (count % 8 == 0)
printf("\n");
}
offset += 6;
} else {
printf("0x%02x, ", data[offset]);
count++;
if (count % 8 == 0)
printf("\n");
}
}
printf("\n");
_vm->_system->quit();
#endif
}
int CharsetRendererV3::getCharWidth(byte chr) {
if (chr & 0x80 && _vm->_useCJKMode)
return _vm->_2byteWidth / 2;
int spacing = 0;
spacing = *(_widthTable + chr);
return spacing;
}
void CharsetRendererV3::setColor(byte color)
{
_color = color;
_shadowColor = (_vm->_platform == Common::kPlatformFMTowns) ? 8 : 0;
// FM-TOWNS version of Loom uses old colour method as well
if ((_vm->_version >= 2) && (_vm->_features & GF_16COLOR || _vm->_gameId == GID_LOOM)) {
_dropShadow = ((_color & 0xF0) != 0);
_color &= 0x0f;
} else if (_vm->_features & GF_OLD256) {
_dropShadow = ((_color & 0x80) != 0);
_color &= 0x7f;
} else
_dropShadow = false;
translateColor();
}
void CharsetRendererV3::printChar(int chr) {
// Indy3 / Zak256 / Loom
int width, height, origWidth, origHeight;
VirtScreen *vs;
byte *charPtr, *dst;
int is2byte = (chr >= 0x80 && _vm->_useCJKMode) ? 1 : 0;
checkRange(_vm->_numCharsets - 1, 0, _curId, "Printing with bad charset %d");
if ((vs = _vm->findVirtScreen(_top)) == NULL)
return;
if (chr == '@')
return;
if (is2byte) {
charPtr = _vm->get2byteCharPtr(chr);
width = _vm->_2byteWidth;
height = _vm->_2byteHeight;
} else {
charPtr = _fontPtr + chr * 8;
// width = height = 8;
width = getCharWidth(chr);
height = 8;
}
origWidth = width;
origHeight = height;
if (_dropShadow) {
width++;
height++;
}
if (_firstChar) {
_str.left = _left;
_str.top = _top;
_str.right = _left;
_str.bottom = _top;
_firstChar = false;
}
int drawTop = _top - vs->topline;
_vm->markRectAsDirty(vs->number, _left, _left + width, drawTop, drawTop + height);
if (!_ignoreCharsetMask) {
_hasMask = true;
_textScreenID = vs->number;
}
if (_ignoreCharsetMask || !vs->hasTwoBuffers) {
dst = vs->getPixels(_left, drawTop);
drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight);
} else {
dst = (byte *)_textSurface.pixels + _top * _textSurface.pitch + _left;
drawBits1(_textSurface, dst, charPtr, drawTop, origWidth, origHeight);
}
if (_str.left > _left)
_str.left = _left;
_left += origWidth;
if (_str.right < _left) {
_str.right = _left;
if (_dropShadow)
_str.right++;
}
if (_str.bottom < _top + height)
_str.bottom = _top + height;
}
void CharsetRendererV3::drawChar(int chr, const Graphics::Surface &s, int x, int y) {
byte *charPtr, *dst;
int width, height;
int is2byte = (chr >= 0x80 && _vm->_useCJKMode) ? 1 : 0;
if (is2byte) {
charPtr = _vm->get2byteCharPtr(chr);
width = _vm->_2byteWidth;
height = _vm->_2byteHeight;
} else {
charPtr = _fontPtr + chr * 8;
// width = height = 8;
width = getCharWidth(chr);
height = 8;
}
dst = (byte *)s.pixels + y * s.pitch + x;
drawBits1(s, dst, charPtr, y, width, height);
}
void CharsetRenderer::translateColor() {
// Based on disassembly
if (_vm->_renderMode == Common::kRenderCGA) {
static byte CGAtextColorMap[16] = {0, 3, 3, 3, 5, 5, 5, 15,
15, 3, 3, 3, 5, 5, 15, 15};
_color = CGAtextColorMap[_color & 0x0f];
}
if (_vm->_renderMode == Common::kRenderHercA || _vm->_renderMode == Common::kRenderHercG) {
static byte HercTextColorMap[16] = {0, 15, 2, 15, 15, 5, 15, 15,
8, 15, 15, 15, 15, 15, 15, 15};
_color = HercTextColorMap[_color & 0x0f];
}
}
void CharsetRendererClassic::printChar(int chr) {
int width, height, origWidth, origHeight;
int offsX, offsY;
VirtScreen *vs;
const byte *charPtr;
int is2byte = (chr >= 0x80 && _vm->_useCJKMode) ? 1 : 0;
checkRange(_vm->_numCharsets - 1, 1, _curId, "Printing with bad charset %d");
if ((vs = _vm->findVirtScreen(_top)) == NULL && (vs = _vm->findVirtScreen(_top + getFontHeight())) == NULL)
return;
if (chr == '@')
return;
translateColor();
_vm->_charsetColorMap[1] = _color;
int type = *_fontPtr;
if (is2byte) {
_dropShadow = true;
_shadowColor = (_vm->_platform == Common::kPlatformFMTowns) ? 8 : 0;
charPtr = _vm->get2byteCharPtr(chr);
width = _vm->_2byteWidth;
height = _vm->_2byteHeight;
offsX = offsY = 0;
} else {
uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
assert(charOffs < 0x10000);
if (!charOffs)
return;
charPtr = _fontPtr + charOffs;
width = charPtr[0];
height = charPtr[1];
if (_disableOffsX) {
offsX = 0;
} else {
offsX = (signed char)charPtr[2];
}
offsY = (signed char)charPtr[3];
charPtr += 4; // Skip over char header
}
origWidth = width;
origHeight = height;
if (_dropShadow) {
width++;
height++;
}
if (_firstChar) {
_str.left = 0;
_str.top = 0;
_str.right = 0;
_str.bottom = 0;
}
_top += offsY;
_left += offsX;
if (_left + origWidth > _right + 1 || _left < 0) {
_left += origWidth;
_top -= offsY;
return;
}
_disableOffsX = false;
if (_firstChar) {
_str.left = _left;
_str.top = _top;
_str.right = _left;
_str.bottom = _top;
_firstChar = false;
}
if (_left < _str.left)
_str.left = _left;
if (_top < _str.top)
_str.top = _top;
int drawTop = _top - vs->topline;
_vm->markRectAsDirty(vs->number, _left, _left + width, drawTop, drawTop + height);
byte *dstPtr;
byte *back = NULL;
if (!_ignoreCharsetMask) {
_hasMask = true;
_textScreenID = vs->number;
}
if ((_vm->_heversion >= 71 && type >= 8) || (_vm->_heversion >= 90 && type == 0)) {
#ifndef DISABLE_HE
if (_ignoreCharsetMask || !vs->hasTwoBuffers) {
dstPtr = vs->getPixels(0, 0);
} else {
dstPtr = (byte *)_textSurface.pixels;
}
if (_blitAlso && vs->hasTwoBuffers) {
dstPtr = vs->getBackPixels(0, 0);
}
Common::Rect rScreen(vs->w, vs->h);
if (type >= 8) {
byte imagePalette[256];
memset(imagePalette, 0, sizeof(imagePalette));
memcpy(imagePalette, _vm->_charsetColorMap, 16);
Wiz::copyWizImage(dstPtr, charPtr, vs->w, vs->h, _left, _top, origWidth, origHeight, &rScreen, imagePalette);
} else {
Wiz::copyWizImage(dstPtr, charPtr, vs->w, vs->h, _left, _top, origWidth, origHeight, &rScreen);
}
if (_blitAlso && vs->hasTwoBuffers) {
Common::Rect dst(_left, _top, _left + origWidth, _top + origHeight);
_vm->gdi.copyVirtScreenBuffers(dst);
}
#endif
} else {
Graphics::Surface dstSurface;
Graphics::Surface backSurface;
if (_ignoreCharsetMask || !vs->hasTwoBuffers) {
dstSurface = *vs;
dstPtr = vs->getPixels(_left, drawTop);
} else {
dstSurface = _textSurface;
dstPtr = (byte *)_textSurface.pixels + (_top - _vm->_screenTop) * _textSurface.pitch + _left;
}
if (_blitAlso && vs->hasTwoBuffers) {
backSurface = dstSurface;
back = dstPtr;
dstSurface = *vs;
dstPtr = vs->getBackPixels(_left, drawTop);
}
if (!_ignoreCharsetMask && vs->hasTwoBuffers) {
drawTop = _top - _vm->_screenTop;
}
if (is2byte) {
drawBits1(dstSurface, dstPtr, charPtr, drawTop, origWidth, origHeight);
} else {
drawBitsN(dstSurface, dstPtr, charPtr, *_fontPtr, drawTop, origWidth, origHeight);
}
if (_blitAlso && vs->hasTwoBuffers) {
// FIXME: Revisiting this code, I think the _blitAlso mode is likely broken
// right now -- we are copying stuff from "dstPtr" to "back", but "dstPtr" really
// only conatains charset data...
// One way to fix this: don't copy etc.; rather simply render the char twice,
// once to each of the two buffers. That should hypothetically yield
// identical results, though I didn't try it and right now I don't know
// any spots where I can test this...
if (!_ignoreCharsetMask)
warning("This might be broken -- please report where you encountered this to Fingolfin");
// Perform some clipping
int w = MIN(width, dstSurface.w - _left);
int h = MIN(height, dstSurface.h - drawTop);
if (_left < 0) {
w += _left;
back -= _left;
dstPtr -= _left;
}
if (drawTop < 0) {
h += drawTop;
back -= drawTop * backSurface.pitch;
dstPtr -= drawTop * dstSurface.pitch;
}
// Blit the image data
if (w > 0) {
while (h-- > 0) {
memcpy(back, dstPtr, w);
back += backSurface.pitch;
dstPtr += dstSurface.pitch;
}
}
}
}
_left += origWidth;
if (_str.right < _left) {
_str.right = _left;
if (_dropShadow)
_str.right++;
}
if (_str.bottom < _top + height)
_str.bottom = _top + height;
_top -= offsY;
}
void CharsetRendererClassic::drawChar(int chr, const Graphics::Surface &s, int x, int y) {
const byte *charPtr;
byte *dst;
int width, height;
int is2byte = (chr >= 0x80 && _vm->_useCJKMode) ? 1 : 0;
if (is2byte) {
_dropShadow = true;
_shadowColor = (_vm->_platform == Common::kPlatformFMTowns) ? 8 : 0;
charPtr = _vm->get2byteCharPtr(chr);
width = _vm->_2byteWidth;
height = _vm->_2byteHeight;
} else {
uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
assert(charOffs < 0x10000);
if (!charOffs)
return;
charPtr = _fontPtr + charOffs;
width = charPtr[0];
height = charPtr[1];
charPtr += 4; // Skip over char header
}
dst = (byte *)s.pixels + y * s.pitch + x;
if (is2byte) {
drawBits1(s, dst, charPtr, y, width, height);
} else {
drawBitsN(s, dst, charPtr, *_fontPtr, y, width, height);
}
}
void CharsetRendererClassic::drawBitsN(const Graphics::Surface &s, byte *dst, const byte *src, byte bpp, int drawTop, int width, int height) {
int y, x;
int color;
byte numbits, bits;
assert(bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8);
bits = *src++;
numbits = 8;
for (y = 0; y < height && y + drawTop < s.h; y++) {
for (x = 0; x < width; x++) {
color = (bits >> (8 - bpp)) & 0xFF;
if (color && y + drawTop >= 0) {
*dst = _vm->_charsetColorMap[color];
}
dst++;
bits <<= bpp;
numbits -= bpp;
if (numbits == 0) {
bits = *src++;
numbits = 8;
}
}
dst += s.pitch - width;
}
}
void CharsetRendererCommon::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height) {
int y, x;
byte bits = 0;
for (y = 0; y < height && y + drawTop < s.h; y++) {
for (x = 0; x < width; x++) {
if ((x % 8) == 0)
bits = *src++;
if ((bits & revBitMask(x % 8)) && y + drawTop >= 0) {
if (_dropShadow) {
*(dst + 1) = _shadowColor;
*(dst + s.pitch) = _shadowColor;
*(dst + s.pitch + 1) = _shadowColor;
}
*dst = _color;
}
dst++;
}
dst += s.pitch - width;
}
}
CharsetRendererNut::CharsetRendererNut(ScummEngine *vm)
: CharsetRenderer(vm) {
_current = 0;
for (int i = 0; i < 5; i++) {
char fontname[256];
if ((_vm->_gameId == GID_CMI) && (_vm->_features & GF_DEMO) && (i == 4))
break;
sprintf(fontname, "font%d.nut", i);
_fr[i] = new NutRenderer(_vm);
if (!(_fr[i]->loadFont(fontname))) {
delete _fr[i];
_fr[i] = NULL;
}
}
}
CharsetRendererNut::~CharsetRendererNut() {
for (int i = 0; i < 5; i++) {
if ((_vm->_gameId == GID_CMI) && (_vm->_features & GF_DEMO) && (i == 4))
break;
delete _fr[i];
}
}
void CharsetRendererNut::setCurID(byte id) {
assert(id < 5);
_curId = id;
_current = _fr[id];
assert(_current);
}
int CharsetRendererNut::getCharWidth(byte chr) {
assert(_current);
return _current->getCharWidth(chr);
}
int CharsetRendererNut::getFontHeight() {
// FIXME / TODO: how to implement this properly???
assert(_current);
return _current->getCharHeight('|');
}
void CharsetRendererNut::printChar(int chr) {
Common::Rect shadow;
assert(_current);
if (chr == '@')
return;
shadow.left = _left - 1;
shadow.top = _top - 1;
// Note that the character is drawn with a shadow, so it is slightly
// larger than the advertised dimensions. See drawShadowChar() for
// details.
if (_firstChar) {
_str.left = (shadow.left >= 0) ? shadow.left : 0;
_str.top = (shadow.top >= 0) ? shadow.top : 0;
_str.right = _str.left;
_str.bottom = _str.top;
_firstChar = false;
}
int width = _current->getCharWidth(chr);
int height = _current->getCharHeight(chr);
if (chr >= 256 && _vm->_useCJKMode)
width = _vm->_2byteWidth;
shadow.right = _left + width + 2;
shadow.bottom = _top + height + 2;
Graphics::Surface s;
if (!_ignoreCharsetMask) {
_hasMask = true;
_textScreenID = kMainVirtScreen;
}
int drawTop = _top;
if (_ignoreCharsetMask) {
VirtScreen *vs = &_vm->virtscr[kMainVirtScreen];
s = *vs;
s.pixels = vs->getPixels(0, 0);
} else {
s = _textSurface;
drawTop -= _vm->_screenTop;
}
_current->drawShadowChar(s, chr, _left, drawTop, _color, _curId != 3);
_vm->markRectAsDirty(kMainVirtScreen, shadow);
if (_str.left > _left)
_str.left = _left;
_left += width;
if (_str.right < shadow.right)
_str.right = shadow.right;
if (_str.bottom < shadow.bottom)
_str.bottom = shadow.bottom;
}
CharsetRendererNES::CharsetRendererNES(ScummEngine *vm, Common::Language language)
: CharsetRendererCommon(vm) {
_trTable = NULL; // can't init it here, since resources aren't yet loaded!
}
void CharsetRendererNES::printChar(int chr) {
int width, height, origWidth, origHeight;
VirtScreen *vs;
byte *charPtr, *dst;
if (!_trTable) // have to init it here instead
_trTable = _vm->getResourceAddress(rtCostume, 77) + 2;
// HACK: how to set it properly?
if (_top == 0)
_top = 16;
if ((vs = _vm->findVirtScreen(_top)) == NULL)
return;
if (chr == '@')
return;
charPtr = _vm->_NESPatTable[1] + _trTable[chr - 32] * 16;
width = getCharWidth(chr);
height = 8;
origWidth = width;
origHeight = height;
if (_firstChar) {
_str.left = _left;
_str.top = _top;
_str.right = _left;
_str.bottom = _top;
_firstChar = false;
}
int drawTop = _top - vs->topline;
_vm->markRectAsDirty(vs->number, _left, _left + width, drawTop, drawTop + height);
if (!_ignoreCharsetMask) {
_hasMask = true;
_textScreenID = vs->number;
}
if (_ignoreCharsetMask || !vs->hasTwoBuffers) {
dst = vs->getPixels(_left, drawTop);
drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight);
} else {
dst = (byte *)_textSurface.pixels + _top * _textSurface.pitch + _left;
drawBits1(_textSurface, dst, charPtr, drawTop, origWidth, origHeight);
}
if (_str.left > _left)
_str.left = _left;
_left += origWidth;
if (_str.right < _left) {
_str.right = _left;
if (_dropShadow)
_str.right++;
}
if (_str.bottom < _top + height)
_str.bottom = _top + height;
}
void CharsetRendererNES::drawChar(int chr, const Graphics::Surface &s, int x, int y) {
byte *charPtr, *dst;
int width, height;
if (!_trTable)
_trTable = _vm->getResourceAddress(rtCostume, 77) + 2;
charPtr = _vm->_NESPatTable[1] + _trTable[chr - 32] * 16;
width = getCharWidth(chr);
height = 8;
dst = (byte *)s.pixels + y * s.pitch + x;
drawBits1(s, dst, charPtr, y, width, height);
}
void CharsetRendererNES::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height) {
for (int i = 0; i < 8; i++) {
byte c0 = src[i];
byte c1 = src[i + 8];
for (int j = 0; j < 8; j++)
dst[j] = _vm->_NESPalette[0][((c0 >> (7 - j)) & 1) | (((c1 >> (7 - j)) & 1) << 1) |
(_color ? 12 : 8)];
dst += s.pitch;
}
}
} // End of namespace Scumm
#ifdef __PALM_OS__
#include "scumm_globals.h"
_GINIT(Charset)
_GSETPTR(Scumm::germanCharsetDataV2, GBVARS_GERMANCHARSETDATAV2_INDEX, byte, GBVARS_SCUMM)
_GSETPTR(Scumm::frenchCharsetDataV2, GBVARS_FRENCHCHARSETDATAV2_INDEX, byte, GBVARS_SCUMM)
_GSETPTR(Scumm::englishCharsetDataV2, GBVARS_ENGLISHCHARSETDATAV2_INDEX, byte, GBVARS_SCUMM)
_GSETPTR(Scumm::italianCharsetDataV2, GBVARS_ITALIANCHARSETDATAV2_INDEX, byte, GBVARS_SCUMM)
_GSETPTR(Scumm::spanishCharsetDataV2, GBVARS_SPANISHCHARSETDATAV2_INDEX, byte, GBVARS_SCUMM)
_GEND
_GRELEASE(Charset)
_GRELEASEPTR(GBVARS_GERMANCHARSETDATAV2_INDEX, GBVARS_SCUMM)
_GRELEASEPTR(GBVARS_FRENCHCHARSETDATAV2_INDEX, GBVARS_SCUMM)
_GRELEASEPTR(GBVARS_ENGLISHCHARSETDATAV2_INDEX, GBVARS_SCUMM)
_GRELEASEPTR(GBVARS_ITALIANCHARSETDATAV2_INDEX, GBVARS_SCUMM)
_GRELEASEPTR(GBVARS_SPANISHCHARSETDATAV2_INDEX, GBVARS_SCUMM)
_GEND
#endif