|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2021 nono project ! 4: // Licensed under nono-license.txt ! 5: // ! 6: ! 7: // ! 8: // フォント管理 ! 9: // ! 10: ! 11: #include "fontmanager.h" ! 12: #include "privatechar.h" ! 13: #include "wxtextpanel.h" ! 14: #include "cgrom.h" ! 15: #include "kaname12.h" ! 16: ! 17: // グローバル参照用 ! 18: FontManager *gFontManager; ! 19: ! 20: // コンストラクタ ! 21: FontManager::FontManager() ! 22: { ! 23: } ! 24: ! 25: // デストラクタ ! 26: FontManager::~FontManager() ! 27: { ! 28: gFontManager = NULL; ! 29: } ! 30: ! 31: // フォントを変更(設定) ! 32: void ! 33: FontManager::SetFont(FontId fontid_) ! 34: { ! 35: fontid = fontid_; ! 36: ! 37: // フォントデータを更新。 ! 38: // 6x12, 8x16 半角は X68030 CGROM にあるのでそれを使う。 ! 39: const uint8 *base; ! 40: switch (fontid) { ! 41: case FontId::_6x12: ! 42: base = BuiltinCGROM::Get6x12(); ! 43: break; ! 44: case FontId::_8x16: ! 45: base = BuiltinCGROM::Get8x16(); ! 46: break; ! 47: default: ! 48: PANIC("fontid=%d", fontid); ! 49: } ! 50: ! 51: font_width = fontinfo[fontid].GetWidth(); ! 52: font_height = fontinfo[fontid].GetHeight(); ! 53: ! 54: // フォントの行ストライド[byte] を計算。 ! 55: font_stride = (font_width + 7) / 8; ! 56: font_bytes = font_stride * font_height; ! 57: ! 58: // 半角文字領域 256 文字全部をキャッシュする。 ! 59: // ASCII は 0x7f までだが X680x0 の CGROM の 0x80, 0x81, 0x82 には ! 60: // '\\', '~', '|' が収納されている。 ! 61: // 制御文字領域を外字として使う。 ! 62: ! 63: ascii_glyph.resize(256 * font_bytes); ! 64: bold_glyph.resize(256 * font_bytes); ! 65: ! 66: // CGROM に収録されている文字のうち半角ひらがななど使わないものもあるが ! 67: // 避けるのも手間なので気にせずデータを作っておく。 ! 68: for (int ch = 0; ch < 256; ch++) { ! 69: int idx = ch * font_bytes; ! 70: memcpy(&ascii_glyph[idx], base + idx, font_bytes); ! 71: } ! 72: ! 73: // 外字を上書きで割り当てる ! 74: for (int i = 0; private_chars[i].code != 0; i++) { ! 75: const auto& pchar = private_chars[i]; ! 76: const char *ptr; ! 77: ! 78: switch (fontid) { ! 79: case FontId::_6x12: ! 80: ptr = (const char *)pchar.data12; ! 81: break; ! 82: case FontId::_8x16: ! 83: ptr = (const char *)pchar.data16; ! 84: break; ! 85: default: ! 86: __unreachable(); ! 87: } ! 88: ! 89: int idx = pchar.code * font_bytes; ! 90: memcpy(&ascii_glyph[idx], ptr, font_bytes); ! 91: } ! 92: ! 93: // 続いてボールドに加工 ! 94: for (int i = 0; i < bold_glyph.size(); i++) { ! 95: bold_glyph[i] = ascii_glyph[i] | (ascii_glyph[i] >> 1); ! 96: } ! 97: } ! 98: ! 99: // ASCII のグリフを返す ! 100: const uint8 * ! 101: FontManager::AsciiGlyph(uint8 code, uint attr) const ! 102: { ! 103: const std::vector<uint8> *glyph; ! 104: ! 105: // ボールドかどうかでテーブルが別 ! 106: if ((attr & TA::Em)) { ! 107: glyph = &bold_glyph; ! 108: } else { ! 109: glyph = &ascii_glyph; ! 110: } ! 111: ! 112: // 変更可能なグリフ ! 113: if (__predict_false(code == 0x5c)) { ! 114: if (glyph_5c) { ! 115: code = 0x80; ! 116: } ! 117: } else if (__predict_false(code == 0x7e)) { ! 118: if (glyph_7e) { ! 119: code = 0x81; ! 120: } ! 121: } else if (__predict_false(code == 0x7c)) { ! 122: if (glyph_7c) { ! 123: code = 0x82; ! 124: } ! 125: } ! 126: ! 127: return &((*glyph)[code * font_bytes]); ! 128: } ! 129: ! 130: // 漢字のグリフを返す ! 131: std::vector<uint8> ! 132: FontManager::KanjiGlyph(uint16 sjiscode, uint attr) const ! 133: { ! 134: // Shift_JIS を JIS というかコードポイントに変換 ! 135: uint sh = (sjiscode >> 8); ! 136: uint sl = sjiscode & 0xff; ! 137: uint jh; ! 138: uint jl; ! 139: if (sh < 0xa0) { ! 140: jh = sh - 0x71; ! 141: } else { ! 142: jh = sh - 0xb1; ! 143: } ! 144: jh = jh * 2 + 1; ! 145: jl = sl; ! 146: if (sl > 0x7f) { ! 147: jl--; ! 148: } ! 149: if (jl < 0x9e) { ! 150: jl -= 0x1f; ! 151: } else { ! 152: jl -= 0x7d; ! 153: jh++; ! 154: } ! 155: // ここで JIS。これを CGROM 格納コードポイントに変換。 ! 156: jh -= 0x21; ! 157: jl -= 0x21; ! 158: if (jh >= 15) { ! 159: jh -= 7; ! 160: } ! 161: int code = jh * 94 + jl; ! 162: ! 163: // XXX 見付からなかったらゲタ文字にしたい ! 164: if (code < 0) { ! 165: code = 0x6b; ! 166: } ! 167: ! 168: // フォント領域 ! 169: const uint8 *base; ! 170: switch (fontid) { ! 171: case FontId::_6x12: ! 172: // 12x12 は内蔵フォントデータ ! 173: base = builtin_kanji12; ! 174: break; ! 175: case FontId::_8x16: ! 176: // 16x16 は X680x0 CGROM のを使う。 ! 177: base = BuiltinCGROM::Get16x16(); ! 178: break; ! 179: default: ! 180: // ここより先に必ず半角のほうでエラーが出るはず ! 181: __unreachable(); ! 182: } ! 183: ! 184: int bytes = (((font_width * 2) + 7) / 8) * font_height; ! 185: std::vector<uint8> buf(bytes); ! 186: ! 187: memcpy(&buf[0], base + code * bytes, bytes); ! 188: ! 189: if (attr == TA::Em) { ! 190: for (int i = 0; i < bytes; i++) { ! 191: buf[i] |= buf[i] >> 1; ! 192: } ! 193: } ! 194: ! 195: return buf; ! 196: } ! 197: ! 198: // フォント種別一覧 ! 199: /*static*/ const std::array<wxSize, FontId::Max> ! 200: FontManager::fontinfo = { ! 201: // 順序はヘッダの FontId_* 識別子の順と揃えること ! 202: FONT_6x12, ! 203: FONT_8x16, ! 204: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.