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

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

unix.superglobalmegacorp.com

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