Annotation of nono/wx/fontmanager.cpp, revision 1.1.1.2

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:        // フォントデータを更新。
                     38:        // 6x12, 8x16 半角は X68030 CGROM にあるのでそれを使う。
                     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;
                     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 のを使う。
1.1.1.2 ! root      177:                base = Builtin::CGROM16x16();
1.1       root      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: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.