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

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

unix.superglobalmegacorp.com

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