⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 otf2bdf.c

📁 将windows 的ttf字库转化成嵌入式开发需要的bdf字库的工具。
💻 C
📖 第 1 页 / 共 4 页
字号:
        if (nocmap) {
            if (code >= face->num_glyphs)

              /*
               * At this point, all the glyphs are done.
               */
              break;
            idx = code;
        } else
          idx = FT_Get_Char_Index(face, code);

        /*
         * If the glyph could not be loaded for some reason, or a subset is
         * being generated and the index is not in the subset bitmap, just
         * continue.
         */

        if (idx <= 0 || FT_Load_Glyph(face, idx, load_flags))
          continue;

        if (FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO))
          continue;

        /*
         * Determine the DWIDTH (device width, or advance width in TT terms)
         * and the SWIDTH (scalable width) values.
         */
        dwidth = face->glyph->metrics.horiAdvance >> 6;
        dw = (double) dwidth;
        swidth = (FT_Short) ((dw * 72000.0) / swscale);

        /*
         * Determine the actual bounding box of the glyph bitmap.  Do not
         * forget that the glyph is rendered upside down!
         */
        sx = sy = 0xffff;
        ex = ey = 0;
        bp = face->glyph->bitmap.buffer;
        for (y = 0; y < face->glyph->bitmap.rows; y++) {
            for (x = 0; x < face->glyph->bitmap.width; x++) {
                if (bp[x >> 3] & (0x80 >> (x & 7))) {
                    if (x < sx) sx = x;
                    if (x > ex) ex = x;
                    if (y < sy) sy = y;
                    if (y > ey) ey = y;
                }
            }
            bp += face->glyph->bitmap.pitch;
        }

        /*
         * If the glyph is actually an empty bitmap, set the size to 0 all
         * around.
         */
        if (sx == 0xffff && sy == 0xffff && ex == 0 && ey == 0)
          sx = ex = sy = ey = 0;
        else {
            /*
             * Adjust the end points.
             */
            ex++;
            ey++;
        }

        /*
         * Increment the number of glyphs generated.
         */
        ng++;

        /*
         * Test to see if the font is going to be monowidth or not by
         * comparing the current glyph width against the last one.
         */
        if (wd != 0xffff && ismono && (ex - sx) + 1 != wd)
          ismono = 0;

        /*
         * Adjust the font bounding box.
         */
        wd = ex - sx;
        ht = ey - sy;
        x_off = sx + face->glyph->bitmap_left;
        y_off = sy + face->glyph->bitmap_top - face->glyph->bitmap.rows;

        bbx.maxas = MAX(bbx.maxas, ht + y_off);
        bbx.maxds = MAX(bbx.maxds, -y_off);
        bbx.rbearing = wd + x_off;
        bbx.maxrb = MAX(bbx.maxrb, bbx.rbearing);
        bbx.minlb = MIN(bbx.minlb, x_off);
        bbx.maxlb = MAX(bbx.maxlb, x_off);

        /*
         * Add to the average width accumulator.
         */
        aw += wd;

        /*
         * Print the bitmap header.
         */
        fprintf(tmp, "STARTCHAR %04lX\nENCODING %ld\n", code,
                (long) remapped_code);
        fprintf(tmp, "SWIDTH %hd 0\n", swidth);
        fprintf(tmp, "DWIDTH %hd 0\n", dwidth);
        fprintf(tmp, "BBX %hd %hd %hd %hd\n", wd, ht, x_off, y_off);

        /*
         * Check for an error return here in case the temporary file system
         * fills up or the file is deleted while it is being used.
         */
        eof = fprintf(tmp, "BITMAP\n");

        bp = face->glyph->bitmap.buffer + (sy * face->glyph->bitmap.pitch);
        for (y = 0; eof != EOF && y < ey - sy; y++) {
            for (idx = 0, x = 0; eof != EOF && x < ex - sx; x++) {
                if (x > sx && (x & 7) == 0) {
                    /*
                     * Print the next byte.
                     */
                    eof = fprintf(tmp, "%02lX", idx & 0xff);
                    idx = 0;
                }
                if (bp[(x+sx) >> 3] & (0x80 >> ((x+sx) & 7)))
                  idx |= (0x80 >> (x & 7));
            }
            bp += face->glyph->bitmap.pitch;
            if (eof != EOF)
              /*
               * Because of the structure of the loop, the last byte should
               * always be printed.
               */
              fprintf(tmp, "%02lX\n", idx & 0xff);
        }
        if (eof != EOF)
          fprintf(tmp, "ENDCHAR\n");
    }

    fclose(tmp);

    /*
     * If a write error occured, delete the temporary file and issue an error
     * message.
     */
    if (eof == EOF) {
        (void) unlink(tmpfile);
        fprintf(stderr, "%s: problem writing to temporary file '%s'.\n",
                prog, tmpfile);
        return -1;
    }

    /*
     * If no characters were generated, just unlink the temp file and issue a
     * warning.
     */
    if (ng == 0) {
        (void) unlink(tmpfile);
        fprintf(stderr, "%s: no glyphs generated from '%s'.\n", prog, iname);
        return -1;
    }

    /*
     * Reopen the temporary file so it can be copied to the actual output
     * file.
     */
    if ((tmp = fopen(tmpfile, "r")) == 0) {
        /*
         * Unable to open the file for read, so attempt to delete it and issue
         * an error message.
         */
        (void) unlink(tmpfile);
        fprintf(stderr, "%s: unable to open temporary file '%s' for read.\n",
                prog, tmpfile);
        return -1;
    }

    /*
     * Calculate the average width.
     */
    aw = (FT_Long) ((((double) aw / (double) ng) + 0.5) * 10.0);

    /*
     * Generate the XLFD font name.
     */
    make_xlfd_name(xlfd, sizeof(xlfd), aw, ismono);

    /*
     * Start writing the font out.
     */
    fprintf(out, "STARTFONT 2.1\n");

    /*
     * Add the vanity comments.
     */
    fprintf(out, "COMMENT\n");
    fprintf(out, "COMMENT Converted from OpenType font \"%s\" by \"%s %s\".\n",
            iname, prog, OTF2BDF_VERSION);
    fprintf(out, "COMMENT\n");

    fprintf(out, "FONT %s\n", xlfd);
    fprintf(out, "SIZE %d %d %d\n", point_size, hres, vres);

    /*
     * Generate the font bounding box.
     */
    fprintf(out, "FONTBOUNDINGBOX %hd %hd %hd %hd\n",
            bbx.maxrb - bbx.minlb, bbx.maxas + bbx.maxds,
            bbx.minlb, -bbx.maxds);

    /*
     * Print the properties.
     */
    fprintf(out, "STARTPROPERTIES %hd\n", 19);

    /*
     * Print the font properties from the XLFD name.
     */
    for (i = 0, xp = xlfd; i < 14; i++) {
        /*
         * Print the XLFD property name.
         */
        fprintf(out, "%s ", xlfd_props[i]);

        /*
         * Make sure the ATOM properties are wrapped in double quotes.
         */
        if (i < 6 || i == 10 || i > 11)
          putc('"', out);

        /*
         * Skip the leading '-' in the XLFD name.
         */
        xp++;

        /*
         * Skip until the next '-' or NULL.
         */
        for (; *xp && *xp != '-'; xp++)
          putc(*xp, out);

        /*
         * Make sure the ATOM properties are wrapped in double quotes.
         */
        if (i < 6 || i == 10 || i > 11)
          putc('"', out);

        putc('\n', out);
    }

    /*
     * Make sure to add the FONT_ASCENT and FONT_DESCENT properties
     * because X11 can not live without them.
     */
    fprintf(out, "FONT_ASCENT %hd\nFONT_DESCENT %hd\n",
            (horizontal->Ascender * imetrics.y_ppem) / upm,
            -((horizontal->Descender * imetrics.y_ppem) / upm));

    /*
     * Get the copyright string from the font.
     */
    (void) otf_get_english_string(face, BDFOTF_COPYRIGHT_STRING, 0, xlfd,
                                  sizeof(xlfd));
    fprintf(out, "COPYRIGHT \"%s\"\n", xlfd);

    /*
     * Last, print the two user-defined properties _OTF_FONTFILE and
     * _OTF_PSNAME.  _OTF_FONTFILE provides a reference to the original OT
     * font file which some systems can take advantage of, and _OTF_PSNAME
     * provides the Postscript name of the font if it exists.
     */
    (void) otf_get_english_string(face, BDFOTF_POSTSCRIPT_STRING, 0, xlfd,
                                  sizeof(xlfd));
    fprintf(out, "_OTF_FONTFILE \"%s\"\n_OTF_PSNAME \"%s\"\n", iname, xlfd);

    fprintf(out, "ENDPROPERTIES\n");

    /*
     * Print the actual number of glyphs to the output file.
     */
    eof = fprintf(out, "CHARS %ld\n", ng);

    /*
     * Copy the temporary file to the output file.
     */
    while (eof != EOF && (ng = fread(iobuf, 1, OTF2BDF_IOBUFSIZ, tmp))) {
        if (fwrite(iobuf, 1, ng, out) == 0)
          eof = EOF;
    }
        
    /*
     * Close the temporary file and delete it.
     */
    fclose(tmp);
    (void) unlink(tmpfile);

    /*
     * If an error occured when writing to the output file, issue a warning
     * and return.
     */
    if (eof == EOF) {
        fprintf(stderr, "%s: problem writing to output file '%s'.\n",
                prog, oname);
        return -1;
    }

    /*
     * End the font and do memory cleanup on the glyph and raster structures.
     */
    eof = fprintf(out, "ENDFONT\n");

    return eof;
}

static int
generate_bdf(FILE *out, char *iname, char *oname)
{
    FT_Long i;

    /*
     * Get the requested cmap.
     */
    for (i = 0; i < face->num_charmaps; i++) {
        if (face->charmaps[i]->platform_id == pid &&
            face->charmaps[i]->encoding_id == eid)
          break;
    }
    if (i == face->num_charmaps && pid == 3 && eid == 1) {
        /*
         * Make a special case when this fails with pid == 3 and eid == 1.
         * Change to eid == 0 and try again.  This captures the two possible
         * cases for MS fonts.  Some other method should be used to cycle
         * through all the alternatives later.
         */
        for (i = 0; i < face->num_charmaps; i++) {
        if (face->charmaps[i]->platform_id == pid &&
            face->charmaps[i]->encoding_id == 0)
              break;
        }
        if (i < face->num_charmaps) {
            pid = 3;
            eid = 1;
            FT_Set_Charmap(face, face->charmaps[i]);
        } else {
            /*
             * No CMAP was found.
             */
            nocmap = 1;
            pid = eid = -1;
        }
    } else {
        FT_Set_Charmap(face, face->charmaps[i]);
        nocmap = 0;
    }

    if (nocmap && verbose) {
        fprintf(stderr,
                    "%s: no character map for platform %d encoding %d.  ",
                    prog, pid, eid);
        fprintf(stderr, "Generating all glyphs.\n");
    }

    /*
     * Now go through and generate the glyph bitmaps themselves.
     */
    return generate_font(out, iname, oname);
}

#define isdig(cc) ((cc) >= '0' && (cc) <= '9')

/*
 * Routine to parse a subset specification supplied on the command line.
 * The syntax for this specification is the same as the syntax used for
 * the XLFD font names (XLFD documentation, page 9).
 *
 * Example:
 *
 *  "60 70 80_90" means the glyphs at codes 60, 70, and between 80 and
 *  90 inclusive.
 */
static void
parse_subset(char *s)
{
    long l, r;

    /*
     * Make sure to clear the flag and bitmap in case more than one subset is
     * specified on the command line.
     */
    maxcode = 0;
    do_subset = 0;
    (void) memset((char *) subset, 0, sizeof(unsigned long) * 2048);

    while (*s) {
        /*
         * Collect the next code value.
         */
        for (l = r = 0; *s && isdig(*s); s++)
          l = (l * 10) + (*s - '0');

        /*
         * If the next character is an '_', advance and collect the end of the
         * specified range.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -