|
|
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"
1.1.1.2 root 14: #include "builtinrom.h"
1.1 root 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: // フォントデータを更新。
1.1.1.3 root 38: // 6x12, 8x16, 12x24 半角は X68030 CGROM にあるのでそれを使う。
1.1 root 39: const uint8 *base;
40: switch (fontid) {
41: case FontId::_6x12:
1.1.1.2 root 42: base = Builtin::CGROM6x12();
1.1 root 43: break;
44: case FontId::_8x16:
1.1.1.2 root 45: base = Builtin::CGROM8x16();
1.1 root 46: break;
1.1.1.3 root 47: case FontId::_12x24:
48: base = Builtin::CGROM12x24();
49: break;
1.1 root 50: default:
51: PANIC("fontid=%d", fontid);
52: }
53:
54: font_width = fontinfo[fontid].GetWidth();
55: font_height = fontinfo[fontid].GetHeight();
56:
57: // フォントの行ストライド[byte] を計算。
58: font_stride = (font_width + 7) / 8;
59: font_bytes = font_stride * font_height;
60:
61: // 半角文字領域 256 文字全部をキャッシュする。
62: // ASCII は 0x7f までだが X680x0 の CGROM の 0x80, 0x81, 0x82 には
63: // '\\', '~', '|' が収納されている。
64: // 制御文字領域を外字として使う。
65:
66: ascii_glyph.resize(256 * font_bytes);
67:
68: // CGROM に収録されている文字のうち半角ひらがななど使わないものもあるが
69: // 避けるのも手間なので気にせずデータを作っておく。
70: for (int ch = 0; ch < 256; ch++) {
71: int idx = ch * font_bytes;
72: memcpy(&ascii_glyph[idx], base + idx, font_bytes);
73: }
74:
75: // 外字を上書きで割り当てる
76: for (int i = 0; private_chars[i].code != 0; i++) {
77: const auto& pchar = private_chars[i];
78: const char *ptr;
79:
80: switch (fontid) {
81: case FontId::_6x12:
82: ptr = (const char *)pchar.data12;
83: break;
84: case FontId::_8x16:
85: ptr = (const char *)pchar.data16;
86: break;
1.1.1.3 root 87: case FontId::_12x24:
88: ptr = (const char *)pchar.data24;
89: break;
1.1 root 90: default:
1.1.1.3 root 91: PANIC("corrupted fontid=%d", (int)fontid);
1.1 root 92: }
93:
94: int idx = pchar.code * font_bytes;
95: memcpy(&ascii_glyph[idx], ptr, font_bytes);
96: }
97: }
98:
99: // ASCII のグリフを返す
100: const uint8 *
1.1.1.6 ! root 101: FontManager::AsciiGlyph(uint8 code) const
1.1 root 102: {
103: // 変更可能なグリフ
104: if (__predict_false(code == 0x5c)) {
105: if (glyph_5c) {
106: code = 0x80;
107: }
108: } else if (__predict_false(code == 0x7e)) {
109: if (glyph_7e) {
110: code = 0x81;
111: }
112: } else if (__predict_false(code == 0x7c)) {
113: if (glyph_7c) {
114: code = 0x82;
115: }
116: }
117:
1.1.1.6 ! root 118: return &ascii_glyph[code * font_bytes];
1.1 root 119: }
120:
121: // 漢字のグリフを返す
1.1.1.6 ! root 122: const uint8 *
! 123: FontManager::KanjiGlyph(uint16 sjiscode) const
1.1 root 124: {
125: // Shift_JIS を JIS というかコードポイントに変換
126: uint sh = (sjiscode >> 8);
127: uint sl = sjiscode & 0xff;
128: uint jh;
129: uint jl;
130: if (sh < 0xa0) {
131: jh = sh - 0x71;
132: } else {
133: jh = sh - 0xb1;
134: }
135: jh = jh * 2 + 1;
136: jl = sl;
137: if (sl > 0x7f) {
138: jl--;
139: }
140: if (jl < 0x9e) {
141: jl -= 0x1f;
142: } else {
143: jl -= 0x7d;
144: jh++;
145: }
146: // ここで JIS。これを CGROM 格納コードポイントに変換。
147: jh -= 0x21;
148: jl -= 0x21;
149: if (jh >= 15) {
150: jh -= 7;
151: }
152: int code = jh * 94 + jl;
153:
154: // XXX 見付からなかったらゲタ文字にしたい
155: if (code < 0) {
156: code = 0x6b;
157: }
158:
159: // フォント領域
160: const uint8 *base;
161: switch (fontid) {
162: case FontId::_6x12:
163: // 12x12 は内蔵フォントデータ
164: base = builtin_kanji12;
165: break;
166: case FontId::_8x16:
167: // 16x16 は X680x0 CGROM のを使う。
1.1.1.2 root 168: base = Builtin::CGROM16x16();
1.1 root 169: break;
1.1.1.3 root 170: case FontId::_12x24:
171: // 24x24 は X680x0 CGROM のを使う。
172: base = Builtin::CGROM24x24();
173: break;
1.1 root 174: default:
175: // ここより先に必ず半角のほうでエラーが出るはず
1.1.1.3 root 176: PANIC("corrupted fontid=%d", (int)fontid);
1.1 root 177: }
178:
1.1.1.5 root 179: int stride = ((font_width * 2) + 7) / 8;
180: int bytes = stride * font_height;
1.1.1.6 ! root 181: return base + code * bytes;
1.1 root 182: }
183:
184: // フォント種別一覧
185: /*static*/ const std::array<wxSize, FontId::Max>
186: FontManager::fontinfo = {
187: // 順序はヘッダの FontId_* 識別子の順と揃えること
188: FONT_6x12,
189: FONT_8x16,
1.1.1.3 root 190: FONT_12x24,
1.1 root 191: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.