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

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: };

unix.superglobalmegacorp.com

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