Annotation of nono/util/mkcgrom/mkcgrom.cpp, revision 1.1.1.5

1.1       root        1: //
                      2: // CGROM.DAT 生成
                      3: //
1.1.1.5 ! root        4: // Copyright (C) 2012-2022 Tetsuya Isaki
1.1       root        5: //
                      6: 
1.1.1.4   root        7: #include "header.h"
1.1       root        8: #include <limits.h>
1.1.1.4   root        9: #include <fcntl.h>
                     10: #include <iconv.h>
                     11: #include <array>
1.1.1.2   root       12: #include <vector>
1.1       root       13: 
1.1.1.4   root       14: #define HOWMANY(x, y)  (((x) + (y - 1)) / (y))
                     15: 
                     16: #define warning(...)   do {    \
                     17:        printf("Warning: ");    \
                     18:        printf(__VA_ARGS__);    \
                     19: } while (0)
                     20: 
                     21: // フォント種別
1.1       root       22: enum fonttype_t {
                     23:        FONT_16x16,
                     24:        FONT_8x8,
                     25:        FONT_8x16,
                     26:        FONT_12x12,
                     27:        FONT_12x24,
                     28:        FONT_24x24,
                     29:        FONT_6x12,
                     30:        FONT_MAX,
                     31: };
                     32: 
1.1.1.4   root       33: // 範囲
                     34: #define R_CTRL         (0x0001)                // 制御文字
                     35: #define R_ASCII                (0x0002)                // ASCII(20-7F)
                     36: #define R_KANA         (0x0004)                // カナ(A0-DF)
                     37: #define R_HIRA         (0x0008)                // ひら(86-BF,E0-FF)
                     38: #define R_80           (0x0010)                // \(0x80)
                     39: #define R_81           (0x0020)                // 〜(0x81)
                     40: #define R_82           (0x0040)                // |(0x82)
1.1       root       41: #define R_SWITCH       (R_80 | R_81 | R_82)
1.1.1.4   root       42: #define R_ALL          (0x007f)                // 全部
1.1       root       43: 
1.1.1.4   root       44: // BDF 形式で使われるバウンディングボックス
                     45: struct BBX {
1.1       root       46:        int w;
                     47:        int h;
                     48:        int x;
                     49:        int y;
                     50: };
                     51: 
1.1.1.4   root       52: // 1文字分のフォントデータ
1.1       root       53: struct font_t {
                     54:        int code;
1.1.1.4   root       55:        std::array<uint8, 3 * 24> pattern;
                     56: };
                     57: 
                     58: // エラーが起きたら即終了する
                     59: class File
                     60: {
                     61:  public:
                     62:        bool Create(const std::string& filename_) {
                     63:                fd = open(filename_.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0644);
                     64:                if (fd < 0) {
                     65:                        err(1, "open: %s", filename_.c_str());
                     66:                }
                     67:                return true;
                     68:        }
                     69: 
                     70:        void Close() {
                     71:                close(fd);
                     72:        }
                     73: 
                     74:        ssize_t Write(const void *buf, size_t len) {
                     75:                auto r = write(fd, buf, len);
                     76:                if (r < 0) {
                     77:                        err(1, "File.Write(%d)", fd);
                     78:                }
                     79:                return r;
                     80:        }
                     81: 
                     82:        off_t Seek(off_t off) {
                     83:                auto r = lseek(fd, off, SEEK_SET);
                     84:                if (r < 0) {
                     85:                        err(1, "File.Seek(%d, %jd)", fd, (intmax_t)off);
                     86:                }
                     87:                return r;
                     88:        }
                     89: 
                     90:  private:
                     91:        int fd {};
1.1       root       92: };
                     93: 
1.1.1.4   root       94: // グローバル変数
                     95: static std::string fontdir;
                     96: static File cgrom;
                     97: 
                     98: // クラス構造
                     99: //
                    100: // Font : すべてのフォントの基底
                    101: //  |
                    102: //  +- BDF : BDF形式ファイルを読み込むすべての基底クラス
                    103: //     |
                    104: //     +- BDF_1byte : 文字コードマッピングが不要な1バイトフォントを出力
                    105: //     |  |
                    106: //     |  +- BDF_1byte_unicode : Unicode から1バイトフォントを出力
                    107: //     |     |
                    108: //     |     +- BDF_1byte_jis0208 : JIS X 0208 から1バイトフォントを出力
                    109: //     |
                    110: //     +- BDF_kanji_jis0208 : JIS X 0208 から漢字フォントを出力する
1.1       root      111: 
1.1.1.4   root      112: //
                    113: // フォント基底クラス
                    114: //
1.1       root      115: class Font
                    116: {
                    117:  public:
1.1.1.4   root      118:        Font(const std::string& filename_, int, int, int);
                    119:        virtual ~Font();
1.1       root      120:        void SetRange(int flag) { range_flag = flag; }
1.1.1.4   root      121: 
                    122:        bool debug {};
1.1       root      123: 
                    124:  protected:
                    125:        bool Open();
                    126:        void Close();
                    127: 
                    128:        static bool IsCtrl(int c) { return (c < 0x20); }
                    129:        static bool IsAscii(int c) { return ((0x20 <= c) && (c < 0x7f)); }
                    130:        static bool IsKana(int c) { return ((0xa0 <= c) && (c < 0xe0)); }
                    131:        static bool IsHira(int c) {
                    132:                if ((0x86 <= c) && (c < 0xa0))
                    133:                        return true;
                    134:                if ((0xe0 <= c) && (c <= 0xff))
                    135:                        return true;
                    136:                return false;
                    137:        }
                    138:        bool IsRange(int code) const;
                    139: 
1.1.1.4   root      140:        int pattern_len {};             // 1文字分のバイト数
                    141:        int offset {};
                    142:        std::string filename {};
                    143:        FILE *fp {};
                    144:        int range_flag {};              // 出力範囲フラグ
1.1       root      145: };
                    146: 
1.1.1.4   root      147: // コンストラクタ
                    148: Font::Font(const std::string& filename_, int font_x, int font_y, int out_offset)
1.1       root      149: {
                    150:        range_flag = R_ALL;
                    151: 
1.1.1.4   root      152:        // 引数
                    153:        filename = filename_;
                    154:        pattern_len = HOWMANY(font_x, 8) * font_y;
1.1       root      155:        offset = out_offset;
                    156: 
1.1.1.4   root      157:        printf("generate %dx%d from %s\n", font_x, font_y, filename.c_str());
1.1       root      158: 
1.1.1.4   root      159:        // ここでもうオープンする
1.1       root      160:        Open();
                    161: }
                    162: 
1.1.1.4   root      163: // デストラクタ
1.1       root      164: Font::~Font()
                    165: {
                    166:        Close();
                    167: }
                    168: 
1.1.1.4   root      169: // オープン
1.1       root      170: bool
                    171: Font::Open()
                    172: {
1.1.1.4   root      173:        std::string pathname = ::fontdir + "/" + filename;
1.1       root      174: 
1.1.1.4   root      175:        fp = fopen(pathname.c_str(), "r");
1.1       root      176:        if (fp == NULL) {
1.1.1.4   root      177:                printf("Cannot open: %s\n", pathname.c_str());
1.1       root      178:                throw 0;
                    179:        }
                    180: 
                    181:        return true;
                    182: }
                    183: 
1.1.1.4   root      184: // クローズ
1.1       root      185: void
                    186: Font::Close()
                    187: {
                    188:        if (fp) {
                    189:                fclose(fp);
                    190:        }
                    191:        fp = NULL;
                    192: }
                    193: 
1.1.1.4   root      194: // 文字コードが今回出力を許可された範囲内か
1.1       root      195: bool
                    196: Font::IsRange(int code) const
                    197: {
                    198:        if ((range_flag & R_CTRL) && IsCtrl(code)) {
                    199:                return true;
                    200:        }
                    201:        if ((range_flag & R_ASCII) && IsAscii(code)) {
                    202:                return true;
                    203:        }
                    204:        if ((range_flag & R_KANA) && IsKana(code)) {
                    205:                return true;
                    206:        }
                    207:        if ((range_flag & R_HIRA) && IsHira(code)) {
                    208:                return true;
                    209:        }
                    210:        if ((range_flag & R_80) && (code == 0x80)) {
                    211:                return true;
                    212:        }
                    213:        if ((range_flag & R_81) && (code == 0x81)) {
                    214:                return true;
                    215:        }
                    216:        if ((range_flag & R_82) && (code == 0x82)) {
                    217:                return true;
                    218:        }
                    219:        return false;
                    220: }
                    221: 
                    222: 
1.1.1.4   root      223: //
                    224: // BDF 基底クラス
                    225: //
1.1       root      226: class BDF : public Font
                    227: {
1.1.1.4   root      228:        using inherited = Font;
1.1       root      229:  public:
1.1.1.4   root      230:        BDF(const std::string& filename_, int, int, int);
                    231:        virtual ~BDF() override;
1.1       root      232: 
                    233:        void Convert();
                    234: 
                    235:  protected:
                    236:        bool ReadProperties();
                    237:        bool ReadNextChar(font_t& data);
1.1.1.4   root      238:        virtual int GetAddr(int code) const;    // CGROM 収録アドレスを求める
                    239:        static int Unicode2JIS(int unicode);
                    240:        static int JIS2Addr(int code);
1.1       root      241: 
1.1.1.4   root      242:        BBX fontbbx {};         // FONTBOUNDINGBOX。.w = 横サイズ、.h = 縦サイズ
                    243:        int font_descent {};
1.1       root      244: };
                    245: 
1.1.1.4   root      246: // コンストラクタ
                    247: BDF::BDF(const std::string& filename_, int font_width, int font_height,
                    248:                int out_offset)
                    249:        : inherited(filename_, font_width, font_height, out_offset)
1.1       root      250: {
1.1.1.4   root      251:        // ここでプロパティを読んでおく
1.1       root      252:        ReadProperties();
                    253: }
                    254: 
1.1.1.4   root      255: // デストラクタ
                    256: BDF::~BDF()
                    257: {
                    258: }
                    259: 
                    260: // BDF のプロパティ (ヘッダみたいなもの) を読み込む
1.1       root      261: bool
                    262: BDF::ReadProperties()
                    263: {
                    264:        char buf[100];
                    265:        char *p;
1.1.1.4   root      266:        int pixel_size;         // 縦サイズ
                    267:        int quad_width;         // 横サイズ
1.1       root      268: 
                    269:        pixel_size = -1;
                    270:        quad_width = -1;
                    271: 
                    272:        while (fgets(buf, sizeof(buf), fp)) {
                    273:                if (strncmp(buf, "FONTBOUNDINGBOX ", 15) == 0) {
1.1.1.4   root      274:                        // フォントの縦横サイズ
1.1       root      275:                        fontbbx.w = strtol(buf + 15, &p, 10);
                    276:                        fontbbx.h = strtol(p, NULL, 10);
                    277: 
                    278:                } else if (strncmp(buf, "PIXEL_SIZE ", 11) == 0) {
1.1.1.4   root      279:                        // フォントの縦サイズ
1.1       root      280:                        pixel_size = strtol(buf + 11, NULL, 10);
                    281: 
                    282:                } else if (strncmp(buf, "QUAD_WIDTH ", 11) == 0) {
1.1.1.4   root      283:                        // フォントの横サイズ
1.1       root      284:                        quad_width = strtol(buf + 11, NULL, 10);
                    285: 
                    286:                } else if (strncmp(buf, "FONT_DESCENT ", 13) == 0) {
                    287:                        font_descent = strtol(buf + 13, NULL, 10);
                    288: 
                    289:                } else if (strncmp(buf, "ENDPROPERTIES", 13) == 0) {
                    290:                        break;
                    291:                }
                    292:        }
                    293: 
1.1.1.4   root      294:        // PIXEL_SIZE, QUAD_WIDTH のほうを優先。
                    295:        // TTF→BDF では FONTBOUNDINGBOX がうまく適切な値にならないため。
                    296:        // 元から BDF なフォントでは大抵同じ値になってるはず。
1.1       root      297:        if (pixel_size != -1) {
                    298:                fontbbx.h = pixel_size;
                    299:        }
                    300:        if (quad_width != -1) {
                    301:                fontbbx.w = quad_width;
                    302:        }
                    303: 
                    304:        return true;
                    305: }
                    306: 
1.1.1.4   root      307: // BDF から次の1文字を読み込んで data に格納する。
                    308: // 取り出せなければ false を返す。
1.1       root      309: bool
                    310: BDF::ReadNextChar(font_t& data)
                    311: {
                    312:        char buf[100];
                    313:        BBX bbx = {0};
                    314:        bool in_bitmap;
                    315:        int y = 0;
                    316:        int dwidth = 0;
                    317: 
                    318:        in_bitmap = false;
                    319:        while (fgets(buf, sizeof(buf), fp)) {
                    320:                if (strncmp(buf, "STARTCHAR ", 10) == 0) {
                    321:                        data.code = strtol(buf + 10, NULL, 16);
                    322:                        dwidth = 0;
1.1.1.4   root      323:                        memset(&data.pattern[0], 0, data.pattern.size());
1.1       root      324: 
                    325:                } else if (strncmp(buf, "ENCODING ", 9) == 0) {
                    326:                        data.code = strtol(buf + 9, NULL, 10);
                    327: 
                    328:                } else if (strncmp(buf, "DWIDTH ", 7) == 0) {
                    329:                        dwidth = strtol(buf + 7, NULL, 10);
                    330:                        if (dwidth > 24) {
                    331:                                printf("unsupported DWIDTH: %d\n", dwidth);
                    332:                                throw 0;
                    333:                        }
                    334: 
                    335:                } else if (strncmp(buf, "BBX ", 4) == 0) {
                    336:                        char *p = buf + 4;
                    337:                        bbx.w = strtol(p, &p, 10);
                    338:                        bbx.h = strtol(p, &p, 10);
                    339:                        bbx.x = strtol(p, &p, 10);
                    340:                        bbx.y = strtol(p, &p, 10);
                    341: 
                    342:                        if (bbx.w > dwidth) {
                    343:                                warning("char %x: BBX.w(%d) > DWIDTH(%d)\n",
                    344:                                        data.code, bbx.w, dwidth);
                    345:                        }
                    346:                        if (bbx.h > fontbbx.h) {
                    347:                                warning("char %x: BBX.h(%d) > FONTBBX.h(%d)\n",
                    348:                                        data.code, bbx.h, fontbbx.h);
                    349:                        }
                    350: 
                    351:                } else if (strncmp(buf, "BITMAP", 6) == 0) {
                    352:                        if (dwidth == 0) {
                    353:                                printf("BITMAP without DWIDTH!\n");
                    354:                                throw 0;
                    355:                        }
                    356:                        in_bitmap = true;
                    357: 
1.1.1.4   root      358:                        // BBX による縦方向の開始行を調整
1.1       root      359:                        y = fontbbx.h - font_descent;   // 上から原点までの行数
                    360:                        y -= bbx.y;                                             // 上から BBX 底辺までの行数
                    361:                        y -= bbx.h;                                             // 上から BBX 上辺までの行数
                    362:                        y *= (dwidth + 7) / 8;                  // バイト数に
                    363: 
                    364:                } else if (strncmp(buf, "ENDCHAR", 7) == 0) {
                    365:                        in_bitmap = false;
                    366:                        return true;
                    367: 
                    368:                } else if (in_bitmap) {
                    369:                        if (y > pattern_len) {
                    370:                                printf("char %x: pattern %d > %d bytes\n",
                    371:                                        data.code, y, pattern_len);
                    372:                                throw 0;
                    373:                        }
                    374:                        int len = strlen(buf) - 1;      // '\n'分を引く
1.1.1.4   root      375:                        uint32 val = strtol(buf, NULL, 16);
                    376:                        // val を左詰めしてから
1.1       root      377:                        val <<= (4 - (len / 2)) * 8;
1.1.1.4   root      378:                        // BBX による横方向の位置調整
1.1       root      379:                        val >>= bbx.x;
                    380: 
1.1.1.4   root      381:                        // 1行を構成するバイト列を出力。等幅フォントを作っているので
                    382:                        // グリフごとの幅(DWIDTH)ではなく出力したいフォントの幅。
1.1       root      383:                        data.pattern[y++] = (val >> 24) & 0xff;
                    384:                        if (fontbbx.w > 8) {
                    385:                                data.pattern[y++] = (val >> 16) & 0xff;
                    386:                        }
                    387:                        if (fontbbx.w > 16) {
                    388:                                data.pattern[y++] = (val >> 8) & 0xff;
                    389:                        }
                    390:                }
                    391:        }
                    392: 
1.1.1.4   root      393:        // EOF なので取り出す文字がない
1.1       root      394:        return false;
                    395: }
                    396: 
1.1.1.4   root      397: // 変換メイン
1.1       root      398: void
                    399: BDF::Convert()
                    400: {
                    401:        font_t data;
                    402: 
1.1.1.4   root      403:        // フォントを1文字ずつ読み込んで
1.1       root      404:        while (ReadNextChar(data)) {
1.1.1.4   root      405:                // CGROM 収録アドレスを求めて書き出す
1.1       root      406:                int addr = GetAddr(data.code);
1.1.1.4   root      407:                if (addr >= 0) {
                    408:                        cgrom.Seek(offset + addr * pattern_len);
                    409:                        cgrom.Write(&data.pattern[0], pattern_len);
1.1       root      410:                }
                    411:        }
                    412: }
                    413: 
1.1.1.4   root      414: // CGROM 収録アドレスを得る
1.1       root      415: int
                    416: BDF::GetAddr(int code) const
                    417: {
1.1.1.4   root      418:        // デフォルトはそのまま返す
1.1       root      419:        return code;
                    420: }
                    421: 
1.1.1.4   root      422: // Unicode を JIS に変換する
                    423: /*static*/ int
                    424: BDF::Unicode2JIS(int unicode)
                    425: {
                    426:        auto cd = iconv_open("iso-2022-jp", "unicode");
                    427:        if (cd == (iconv_t)-1) {
                    428:                printf("iconv_open failed\n");
                    429:                return 0;
                    430:        }
                    431: 
                    432:        // ホストバイトオーダー4バイトのコードポイント
                    433:        const char *src = (const char *)&unicode;
                    434:        size_t srcleft = sizeof(unicode);
                    435:        // JIS は前後のエスケープも含む
                    436:        std::array<char, 16> dstbuf;
                    437:        char *dst = dstbuf.data();
                    438:        size_t dstlen = dstbuf.size();
1.1       root      439: 
1.1.1.4   root      440:        ICONV(cd, &src, &srcleft, &dst, &dstlen);
                    441:        iconv_close(cd);
1.1       root      442: 
1.1.1.4   root      443:        int jiscode = ((unsigned int)dstbuf[3] << 8) + (unsigned int)dstbuf[4];
1.1       root      444:        return jiscode;
                    445: }
                    446: 
1.1.1.4   root      447: // JIS コードから CGROM 収録コードを求めて返す
                    448: /*static*/ int
                    449: BDF::JIS2Addr(int code)
1.1       root      450: {
                    451:        int jh, jl, addr;
                    452: 
1.1.1.4   root      453:        // JIS コード 7425、7426 (区点84-05、84-06) の2文字は
                    454:        // JIS X 0208:1990 で追加されたものなので、CGROM にはない。
1.1       root      455:        if (code > 0x7424) {
                    456:                return -1;
                    457:        }
                    458: 
                    459:        jh = (code >> 8);
                    460:        jl = (code & 0xff);
                    461: 
1.1.1.4   root      462:        // (Unicodeから変換した)コードが JIS の範囲外なら無視
1.1       root      463:        if (jl < 0x21 || jl >= 0x7f) {
                    464:                return -1;
                    465:        }
                    466: 
                    467:        if (jh < 0x30) {
                    468:                addr = (jh - 0x21) * 94 + (jl - 0x21);
                    469:        } else {
                    470:                addr = (jh - 0x28) * 94 + (jl - 0x21);
                    471:        }
                    472:        return addr;
                    473: }
                    474: 
                    475: 
1.1.1.4   root      476: //
                    477: // BDF フォントから1バイトフォントを作るクラス。
                    478: // 文字コードは ASCII/ISO-8859 か JIS X 0201 など
                    479: // そのまま1バイトコードにマップできるもの。
                    480: //
1.1       root      481: class BDF_1byte : public BDF
                    482: {
1.1.1.4   root      483:        using inherited = BDF;
1.1       root      484:  public:
1.1.1.4   root      485:        BDF_1byte(const std::string& filename_, int, int, int);
                    486:        virtual ~BDF_1byte() override;
                    487: 
                    488:        int GetAddr(int code) const override;
1.1       root      489: };
                    490: 
1.1.1.4   root      491: // コンストラクタ
                    492: BDF_1byte::BDF_1byte(const std::string& filename_, int font_x, int font_y,
                    493:                int out_offset)
                    494:        : inherited(filename_, font_x, font_y, out_offset)
                    495: {
                    496: }
                    497: 
                    498: // デストラクタ
                    499: BDF_1byte::~BDF_1byte()
1.1       root      500: {
                    501: }
                    502: 
1.1.1.4   root      503: // CGROM 収録アドレスを返す
1.1       root      504: int
                    505: BDF_1byte::GetAddr(int code) const
                    506: {
1.1.1.4   root      507:        // 指定範囲に入っているかどうかだけ
1.1       root      508:        if (IsRange(code)) {
                    509:                return code;
                    510:        }
                    511:        return -1;
                    512: }
                    513: 
                    514: 
1.1.1.4   root      515: //
                    516: // BDF 日本語フォントから1バイトフォントを作るクラス。
                    517: // 文字コードは Unicode。
                    518: //
1.1       root      519: class BDF_1byte_unicode : public BDF_1byte
                    520: {
1.1.1.4   root      521:        using inherited = BDF_1byte;
1.1       root      522:  public:
1.1.1.4   root      523:        BDF_1byte_unicode(const std::string& filename_, int, int, int);
                    524:        virtual ~BDF_1byte_unicode() override;
                    525: 
                    526:        int GetAddr(int code) const override;
1.1       root      527: 
                    528:  protected:
1.1.1.4   root      529:        static const wchar_t table_uni[];
1.1       root      530: };
                    531: 
1.1.1.4   root      532: // コンストラクタ
                    533: BDF_1byte_unicode::BDF_1byte_unicode(const std::string& filename_,
                    534:                int font_x, int font_y, int out_offset)
                    535:        : inherited(filename_, font_x, font_y, out_offset)
1.1       root      536: {
                    537: }
                    538: 
1.1.1.4   root      539: // デストラクタ
                    540: BDF_1byte_unicode::~BDF_1byte_unicode()
                    541: {
                    542: }
                    543: 
                    544: // CGROM 収録アドレスを返す
1.1       root      545: int
                    546: BDF_1byte_unicode::GetAddr(int code) const
                    547: {
                    548:        for (int i = 0; i < 256; i++) {
                    549:                if (code == table_uni[i]) {
                    550:                        return inherited::GetAddr(i);
                    551:                }
                    552:        }
                    553: 
                    554:        return -1;
                    555: }
                    556: 
1.1.1.4   root      557: // Unicode を1バイト文字コードに変換するテーブル。
                    558: // 制御記号(0x01〜0x1b)、矢印(0x1c〜0x1f)、チルダ(0x81)、パイプ(0x82)は
                    559: // ここでは扱わない。
                    560: const wchar_t BDF_1byte_unicode::table_uni[] =
                    561:        L"                "             // +00
                    562:        L"            →←↑↓"             // +10
                    563:        L" !”#$%&’()*+,−./"             // +20
                    564:        L"0123456789:;<=>?"             // +30
                    565:        L"@ABCDEFGHIJKLMNO"             // +40
                    566:        L"PQRSTUVWXYZ[¥]^_"             // +50
                    567:        L"`abcdefghijklmno"             // +60
                    568:        L"pqrstuvwxyz{|} ̄ "             // +70
                    569:        L"\     をぁぃぅぇぉゃゅょっ"             // +80
                    570:        L" あいうえおかきくけこさしすせそ"             // +90
                    571:        L" 。「」、・ヲァィゥェォャュョッ"             // +a0
                    572:        L"ーアイウエオカキクケコサシスセソ"             // +b0
                    573:        L"タチツテトナニヌネノハヒフヘホマ"             // +c0
                    574:        L"ミムメモヤユヨラリルレロワン゛゜"             // +d0
                    575:        L"たちつてとなにぬねのはひふへほま"             // +e0
                    576:        L"みむめもやゆよらりるれろわん  ";    // +f0
                    577: 
                    578: 
                    579: //
                    580: // BDF 日本語フォントから1バイトフォントを作るクラス。
                    581: // 文字コードは JIS X 0208 (の非漢字部分)。
                    582: //
1.1       root      583: class BDF_1byte_jis0208 : public BDF_1byte_unicode
                    584: {
1.1.1.4   root      585:        using inherited = BDF_1byte_unicode;
1.1       root      586:  public:
1.1.1.4   root      587:        BDF_1byte_jis0208(const std::string& filename_, int, int, int);
                    588:        virtual ~BDF_1byte_jis0208() override;
                    589: 
                    590:        int GetAddr(int code) const override;
1.1       root      591: 
                    592:  protected:
1.1.1.4   root      593:        static std::array<int, 256> table_jis;
1.1       root      594:        static bool table_jis_prepared;
                    595: };
                    596: 
1.1.1.4   root      597: // JIS コードを1バイト文字コードに変換するテーブル
                    598: std::array<int, 256> BDF_1byte_jis0208::table_jis;
1.1       root      599: 
1.1.1.4   root      600: // テーブルが用意できているか
1.1       root      601: bool BDF_1byte_jis0208::table_jis_prepared;
                    602: 
1.1.1.4   root      603: // コンストラクタ
                    604: BDF_1byte_jis0208::BDF_1byte_jis0208(const std::string& filename_,
                    605:                int font_x, int font_y, int out_offset)
                    606:        : inherited(filename_, font_x, font_y, out_offset)
1.1       root      607: {
1.1.1.4   root      608:        // 最初に一度だけ table_uni から table_jis を用意しておく
1.1       root      609:        if (!table_jis_prepared) {
1.1.1.4   root      610:                for (int i = 0, end = table_jis.size(); i < end; i++) {
1.1       root      611:                        int unicode = table_uni[i];
                    612:                        table_jis[i] = Unicode2JIS(unicode);
                    613:                }
                    614:                table_jis_prepared = true;
                    615:        }
                    616: }
                    617: 
1.1.1.4   root      618: // デストラクタ
                    619: BDF_1byte_jis0208::~BDF_1byte_jis0208()
                    620: {
                    621: }
                    622: 
                    623: // CGROM 収録アドレスを求める
1.1       root      624: int
                    625: BDF_1byte_jis0208::GetAddr(int code) const
                    626: {
1.1.1.4   root      627:        for (int i = 0, end = table_jis.size(); i < end; i++) {
1.1       root      628:                if (code == table_jis[i]) {
                    629:                        return i;
                    630:                }
                    631:        }
                    632: 
                    633:        return -1;
                    634: }
                    635: 
                    636: 
1.1.1.4   root      637: //
                    638: // BDF フォントから漢字フォントを作るクラス。
                    639: // 文字コードは JIS X 0208。
                    640: //
1.1       root      641: class BDF_kanji_jis0208 : public BDF
                    642: {
1.1.1.4   root      643:        using inherited = BDF;
1.1       root      644:  public:
1.1.1.4   root      645:        BDF_kanji_jis0208(const std::string& filename_, int, int, int);
                    646:        virtual ~BDF_kanji_jis0208() override;
                    647: 
                    648:        int GetAddr(int code) const override;
1.1       root      649: };
                    650: 
1.1.1.4   root      651: // コンストラクタ
                    652: BDF_kanji_jis0208::BDF_kanji_jis0208(const std::string& filename_,
                    653:                int font_x, int font_y, int out_offset)
                    654:        : inherited(filename_, font_x, font_y, out_offset)
                    655: {
                    656: }
                    657: 
                    658: // デストラクタ
                    659: BDF_kanji_jis0208::~BDF_kanji_jis0208()
1.1       root      660: {
                    661: }
                    662: 
1.1.1.4   root      663: // CGROM 収録コードを求めて返す
1.1       root      664: int
                    665: BDF_kanji_jis0208::GetAddr(int code) const
                    666: {
1.1.1.4   root      667:        // JIS コードを変換するだけ
1.1       root      668:        return JIS2Addr(code);
                    669: }
                    670: 
                    671: 
1.1.1.4   root      672: //
                    673: // アプリケーション
                    674: //
1.1       root      675: 
1.1.1.4   root      676: static void MakeCGROM(const std::string& outfile);
                    677: static void MakeMon(const std::string& outfile);
1.1       root      678: 
1.1.1.4   root      679: int
                    680: main(int ac, char *av[])
1.1       root      681: {
1.1.1.4   root      682:        int c;
                    683:        std::string outfile;
                    684:        bool opt_m;
1.1       root      685: 
1.1.1.4   root      686:        ::fontdir = "./fonts";
                    687:        outfile = "./cgrom.dat";
                    688:        opt_m = false;
1.1       root      689: 
1.1.1.4   root      690:        while ((c = getopt(ac, av, "f:ho:m")) != -1) {
                    691:                switch (c) {
                    692:                 case 'f':
                    693:                        ::fontdir = optarg;
                    694:                        break;
                    695:                 case 'o':
                    696:                        outfile = optarg;
                    697:                        break;
                    698:                 case 'm':
                    699:                        opt_m = true;
                    700:                        break;
1.1       root      701: 
1.1.1.4   root      702:                 case 'h':
                    703:                 default:
                    704:                        errx(1, "usage: [-f ./font] [-o ./cgrom.dat] [-m]");
1.1       root      705:                }
                    706:        }
                    707: 
1.1.1.4   root      708:        if (opt_m) {
                    709:                MakeMon(outfile);
1.1       root      710:        } else {
1.1.1.4   root      711:                MakeCGROM(outfile);
1.1       root      712:        }
1.1.1.4   root      713:        return 0;
1.1       root      714: }
                    715: // X680x0 CGROM を作成する
                    716: void
1.1.1.4   root      717: MakeCGROM(const std::string& outfile)
1.1       root      718: {
1.1.1.4   root      719:        // 出力ファイルを空で作成
                    720:        printf("output file: %s\n", outfile.c_str());
                    721:        cgrom.Create(outfile);
1.1       root      722:        cgrom.Seek(768 * 1024 - 1);
                    723:        cgrom.Write("", 1);
                    724: 
                    725:        try {
                    726:                BDF_1byte_jis0208 r8("misaki_gothic-hikanji.bdf", 8, 8, 0x3a000);
                    727:                r8.Convert();
                    728: 
                    729:                BDF_1byte o8("nono-8x8.bdf", 8, 8, 0x3a000);
                    730:                o8.Convert();
                    731: 
                    732:                BDF_1byte_jis0208 r12("shnmk12min-hikanji.bdf", 12, 12, 0x3b800);
                    733:                r12.Convert();
                    734: 
                    735:                BDF_1byte o12x12("nono-12x12.bdf", 12, 12, 0x3b800);
                    736:                o12x12.Convert();
                    737: 
                    738:                BDF_1byte h8("milkjf_8x16r.bdf", 8, 16, 0x3a800);
                    739:                h8.Convert();
                    740: 
                    741:                BDF_1byte o8x16("nono-8x16.bdf", 8, 16, 0x3a800);
                    742:                o8x16.Convert();
                    743: 
                    744:                BDF_1byte h6("shnm6x12r.bdf", 6, 12, 0xbf400);
                    745:                h6.SetRange(R_ASCII | R_KANA);
                    746:                h6.Convert();
                    747: 
                    748:                BDF_1byte o6("nono-6x12.bdf", 6, 12, 0xbf400);
                    749:                o6.Convert();
                    750: 
                    751:                BDF_1byte_unicode t6("ume-tmo3-6x12-hira.bdf", 6, 12, 0xbf400);
                    752:                t6.SetRange(R_HIRA);
                    753:                t6.Convert();
                    754: 
                    755:                BDF_kanji_jis0208 k16("shnmk16min.bdf", 16, 16, 0);
                    756:                k16.Convert();
                    757: 
1.1.1.4   root      758:                BDF_1byte h12("hibiya-12x24.bdf", 12, 24, 0x3d000);
                    759:                h12.SetRange(R_ASCII);
                    760:                h12.Convert();
1.1       root      761: 
                    762:                BDF_1byte o24("nono-12x24.bdf", 12, 24, 0x3d000);
                    763:                o24.Convert();
                    764: 
1.1.1.4   root      765:                BDF_kanji_jis0208 k24("hibiya-24x24.bdf", 24, 24, 0x40000);
                    766:                k24.Convert();
                    767: 
                    768:                BDF_1byte_unicode t12("ume-tmo3-12x24-kana.bdf", 12, 24, 0x3d000);
                    769:                t12.SetRange(R_HIRA | R_KANA);
1.1       root      770:                t12.Convert();
                    771:        } catch (...) {
                    772:        }
                    773: 
                    774:        cgrom.Close();
                    775: }
                    776: 
                    777: // モニタウィンドウ用 12dot フォントデータ
                    778: void
1.1.1.4   root      779: MakeMon(const std::string& outfile)
1.1       root      780: {
                    781:        // 出力ファイルを空で作成
1.1.1.4   root      782:        printf("output file: %s\n", outfile.c_str());
                    783:        cgrom.Create(outfile);
1.1       root      784:        try {
                    785:                BDF_kanji_jis0208 k12("knmzn12x.bdf", 12, 12, 0);
                    786:                k12.Convert();
                    787:        } catch (...) {
                    788:        }
                    789: 
                    790:        cgrom.Close();
                    791: }

unix.superglobalmegacorp.com

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