|
|
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: bold_glyph.resize(256 * font_bytes);
68:
69: // CGROM に収録されている文字のうち半角ひらがななど使わないものもあるが
70: // 避けるのも手間なので気にせずデータを作っておく。
71: for (int ch = 0; ch < 256; ch++) {
72: int idx = ch * font_bytes;
73: memcpy(&ascii_glyph[idx], base + idx, font_bytes);
74: }
75:
76: // 外字を上書きで割り当てる
77: for (int i = 0; private_chars[i].code != 0; i++) {
78: const auto& pchar = private_chars[i];
79: const char *ptr;
80:
81: switch (fontid) {
82: case FontId::_6x12:
83: ptr = (const char *)pchar.data12;
84: break;
85: case FontId::_8x16:
86: ptr = (const char *)pchar.data16;
87: break;
1.1.1.3 root 88: case FontId::_12x24:
89: ptr = (const char *)pchar.data24;
90: break;
1.1 root 91: default:
1.1.1.3 root 92: PANIC("corrupted fontid=%d", (int)fontid);
1.1 root 93: }
94:
95: int idx = pchar.code * font_bytes;
96: memcpy(&ascii_glyph[idx], ptr, font_bytes);
97: }
98:
99: // 続いてボールドに加工
100: for (int i = 0; i < bold_glyph.size(); i++) {
101: bold_glyph[i] = ascii_glyph[i] | (ascii_glyph[i] >> 1);
102: }
103: }
104:
105: // ASCII のグリフを返す
106: const uint8 *
107: FontManager::AsciiGlyph(uint8 code, uint attr) const
108: {
109: const std::vector<uint8> *glyph;
110:
111: // ボールドかどうかでテーブルが別
1.1.1.4 root 112: if ((attr & TA::Bold)) {
1.1 root 113: glyph = &bold_glyph;
114: } else {
115: glyph = &ascii_glyph;
116: }
117:
118: // 変更可能なグリフ
119: if (__predict_false(code == 0x5c)) {
120: if (glyph_5c) {
121: code = 0x80;
122: }
123: } else if (__predict_false(code == 0x7e)) {
124: if (glyph_7e) {
125: code = 0x81;
126: }
127: } else if (__predict_false(code == 0x7c)) {
128: if (glyph_7c) {
129: code = 0x82;
130: }
131: }
132:
133: return &((*glyph)[code * font_bytes]);
134: }
135:
136: // 漢字のグリフを返す
137: std::vector<uint8>
138: FontManager::KanjiGlyph(uint16 sjiscode, uint attr) const
139: {
140: // Shift_JIS を JIS というかコードポイントに変換
141: uint sh = (sjiscode >> 8);
142: uint sl = sjiscode & 0xff;
143: uint jh;
144: uint jl;
145: if (sh < 0xa0) {
146: jh = sh - 0x71;
147: } else {
148: jh = sh - 0xb1;
149: }
150: jh = jh * 2 + 1;
151: jl = sl;
152: if (sl > 0x7f) {
153: jl--;
154: }
155: if (jl < 0x9e) {
156: jl -= 0x1f;
157: } else {
158: jl -= 0x7d;
159: jh++;
160: }
161: // ここで JIS。これを CGROM 格納コードポイントに変換。
162: jh -= 0x21;
163: jl -= 0x21;
164: if (jh >= 15) {
165: jh -= 7;
166: }
167: int code = jh * 94 + jl;
168:
169: // XXX 見付からなかったらゲタ文字にしたい
170: if (code < 0) {
171: code = 0x6b;
172: }
173:
174: // フォント領域
175: const uint8 *base;
176: switch (fontid) {
177: case FontId::_6x12:
178: // 12x12 は内蔵フォントデータ
179: base = builtin_kanji12;
180: break;
181: case FontId::_8x16:
182: // 16x16 は X680x0 CGROM のを使う。
1.1.1.2 root 183: base = Builtin::CGROM16x16();
1.1 root 184: break;
1.1.1.3 root 185: case FontId::_12x24:
186: // 24x24 は X680x0 CGROM のを使う。
187: base = Builtin::CGROM24x24();
188: break;
1.1 root 189: default:
190: // ここより先に必ず半角のほうでエラーが出るはず
1.1.1.3 root 191: PANIC("corrupted fontid=%d", (int)fontid);
1.1 root 192: }
193:
1.1.1.5 ! root 194: int stride = ((font_width * 2) + 7) / 8;
! 195: int bytes = stride * font_height;
! 196: std::vector<uint8> data(bytes);
1.1 root 197:
1.1.1.5 ! root 198: if (__predict_true((attr & TA::Bold) == 0)) {
! 199: memcpy(&data[0], base + code * bytes, bytes);
! 200: } else {
! 201: // ボールドなら1ラインずつ取り出して重ね合わせる
! 202: const uint8 *s = base + code * bytes;
! 203: int i = 0;
! 204: for (int y = 0; y < font_height; y++) {
! 205: uint64 buf = 0;
! 206: for (int x = 0; x < stride; x++) {
! 207: buf = (buf << 8) | *s++;
! 208: }
! 209: buf |= buf >> 1;
! 210: for (int x = stride - 1; x >= 0; x--) {
! 211: data[i++] = (buf >> (x * 8)) & 0xff;
! 212: }
1.1 root 213: }
214: }
215:
1.1.1.5 ! root 216: return data;
1.1 root 217: }
218:
219: // フォント種別一覧
220: /*static*/ const std::array<wxSize, FontId::Max>
221: FontManager::fontinfo = {
222: // 順序はヘッダの FontId_* 識別子の順と揃えること
223: FONT_6x12,
224: FONT_8x16,
1.1.1.3 root 225: FONT_12x24,
1.1 root 226: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.