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

1.1       root        1: //
                      2: // CGROM.DAT 生成
                      3: //
1.1.1.4 ! root        4: // Copyright (C) 2012-2022 [email protected]
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.