📄 ttf2bdf.c
字号:
/* * Set the pixel size, point size, and resolution. */ sprintf(name, "-%ld-%d-%d-%d", val, point_size * 10, hres, vres); name += strlen(name); switch (spacing) { case 'p': case 'P': spacing = 'P'; break; case 'm': case 'M': spacing = 'M'; break; case 'c': case 'C': spacing = 'C'; break; default: spacing = 0; break; } /* * Set the spacing. */ if (!spacing) spacing = (ismono) ? 'M' : 'P'; *name++ = '-'; *name++ = spacing; /* * Add the average width. */ sprintf(name, "-%ld", awidth); name += strlen(name); /* * Check to see if the remapping table specified a registry and encoding * and use those if they both exist. */ ttf2bdf_remap_charset(&r, &e); if (r != 0 && e != 0) { sprintf(name, "-%s-%s", r, e); return; } /* * If the cmap for the platform and encoding id was not found, or the * platform id is unknown, assume the character set registry and encoding * are the XLFD default. */ if (nocmap || pid > 3) (void) strcpy(name, DEFAULT_XLFD_CSET); else { /* * Finally, determine the character set registry and encoding from the * platform and encoding ID. */ switch (pid) { case 0: /* * Apple Unicode platform, so "Unicode-2.0" is the default. */ (void) strcpy(name, "-Unicode-2.0"); break; case 1: /* * Macintosh platform, so choose from the Macintosh encoding * strings. */ if (eid < 0 || eid >= num_mac_encodings) (void) strcpy(name, DEFAULT_XLFD_CSET); else (void) strcpy(name, mac_encodings[eid]); break; case 2: /* * ISO platform, so choose from the ISO encoding strings. */ if (eid < 0 || eid >= num_iso_encodings) (void) strcpy(name, DEFAULT_XLFD_CSET); else (void) strcpy(name, iso_encodings[eid]); break; case 3: /* * Microsoft platform, so choose from the MS encoding strings. */ if (eid < 0 || eid >= num_ms_encodings) (void) strcpy(name, DEFAULT_XLFD_CSET); else (void) strcpy(name, ms_encodings[eid]); break; } }}static int#ifdef __STDC__generate_font(FILE *out, char *iname, char *oname)#elsegenerate_font(out, iname, oname)FILE *out;char *iname, *oname;#endif{ int eof, ismono, i; FILE *tmp; TT_Short maxx, maxy, minx, miny, xoff, yoff, dwidth, swidth; TT_Short y_off, x_off; TT_UShort sx, sy, ex, ey, wd, ht; TT_Long code, idx, ng, aw; TT_UShort remapped_code; TT_Big_Glyph_Metrics *mp; TT_Raster_Map *rp; unsigned char *bmap; double dw; char *xp, xlfd[256]; char *tmpdir, tmpfile[BUFSIZ]; /* * Open a temporary file to store the bitmaps in until the exact number * of bitmaps are known. */ if ((tmpdir = getenv("TMPDIR")) == 0) tmpdir = "/tmp"; sprintf(tmpfile, "%s/ttf2bdf%ld", tmpdir, (long) getpid()); if ((tmp = fopen(tmpfile, "w")) == 0) { fprintf(stderr, "%s: unable to open temporary file '%s'.\n", prog, tmpfile); return -1; } /* * Initialize the raster structure. */ raster.size = 0; /* * Calculate the scale factor for the SWIDTH field. */ swscale = ((double) vres) * ((double) point_size); /* * Calculate the font bounding box again so enough storage for the largest * bitmap can be allocated. */ minx = (properties.header->xMin * imetrics.x_ppem) / upm; miny = (properties.header->yMin * imetrics.y_ppem) / upm; maxx = (properties.header->xMax * imetrics.x_ppem) / upm; maxy = (properties.header->yMax * imetrics.y_ppem) / upm; maxx = (maxx - minx) + 1; maxy = (maxy - miny) + 1; /* * Initialize the flag that tracks if the font is monowidth or not and * initialize the glyph width variable that is used for testing for a * monowidth font. */ wd = 0xffff; ismono = 1; for (ng = code = 0, eof = 0, aw = 0; eof != EOF && code < 0xffff; code++) { /* * If a remap is indicated, attempt to remap the code. If a remapped * code is not found, then skip generating the glyph. */ remapped_code = (TT_UShort) code; if (do_remap && !ttf2bdf_remap(&remapped_code)) continue; /* * If a subset is being generated and the code is greater than the max * code of the subset, break out of the loop to avoid doing any more * work. */ if (do_subset && remapped_code > maxcode) break; /* * If a subset is being generated and the index is not in the subset * bitmap, just continue. */ if (do_subset && !(subset[remapped_code >> 5] & (1 << (remapped_code & 31)))) continue; if (nocmap) { if (code >= properties.num_Glyphs) /* * At this point, all the glyphs are done. */ break; idx = code; } else idx = TT_Char_Index(cmap, 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 || (have_strike && TT_Load_Glyph_Bitmap(face, instance, idx, sbit)) || (!have_strike && TT_Load_Glyph(instance, glyph, idx, load_flags))) continue; if (have_strike) { /* * Set the pointers to the raster and metrics structures. */ rp = &sbit->map; mp = &sbit->metrics; xoff = (63 - mp->bbox.xMin) & -64; yoff = (63 - mp->bbox.yMin) & -64; } else { if (raster.size == 0) { /* * Set up the raster for getting images from outlines. */ raster.flow = TT_Flow_Down; raster.width = maxx; raster.rows = maxy; raster.cols = (maxx + 7) >> 3; raster.size = raster.cols * raster.rows; raster.bitmap = (void *) malloc(raster.size); } (void) TT_Get_Glyph_Big_Metrics(glyph, &metrics); /* * Clear the raster bitmap. */ (void) memset((char *) raster.bitmap, 0, raster.size); /* * Grid fit to determine the x and y offsets that will force the * bitmap to fit into the storage provided. */ xoff = (63 - metrics.bbox.xMin) & -64; yoff = (63 - metrics.bbox.yMin) & -64; /* * If the bitmap cannot be generated, simply continue. */ if (TT_Get_Glyph_Bitmap(glyph, &raster, xoff, yoff)) continue; /* * Set the pointers to the raster and metrics structures. */ rp = &raster; mp = &metrics; } /* * Determine the DWIDTH (device width, or advance width in TT terms) * and the SWIDTH (scalable width) values. */ dwidth = mp->horiAdvance >> 6; dw = (double) dwidth; swidth = (TT_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; bmap = (unsigned char *) rp->bitmap; for (miny = 0; miny < rp->rows; miny++) { for (minx = 0; minx < rp->width; minx++) { if (bmap[(miny * rp->cols) + (minx >> 3)] & (0x80 >> (minx & 7))) { if (minx < sx) sx = minx; if (minx > ex) ex = minx; if (miny < sy) sy = miny; if (miny > ey) ey = miny; } } } /* * 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 (ismono && ex - sx != wd) ismono = 0; /* * Adjust the font bounding box. */ wd = ex - sx; ht = ey - sy; x_off = sx - (xoff >> 6); y_off = -(yoff >> 6); 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"); /* * Now collect the bits so they can be printed. */ for (miny = sy; eof != EOF && miny < ey; miny++) { for (idx = 0, minx = sx; eof != EOF && minx < ex; minx++) { if (minx > sx && ((minx - sx) & 7) == 0) { /* * Print the next byte. */ eof = fprintf(tmp, "%02lX", idx & 0xff); idx = 0; } if (bmap[(miny * rp->cols) + ((minx - sx) >> 3)] & (0x80 >> ((minx - sx) & 7))) idx |= 0x80 >> ((minx - sx) & 7); } 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); if (raster.size > 0) free((char *) raster.bitmap); 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); if (raster.size > 0) free((char *) raster.bitmap); 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); if (raster.size > 0) free((char *) raster.bitmap); return -1; } /* * Free up the raster storage. */ if (raster.size > 0) free((char *) raster.bitmap); /* * Calculate the average width. */ aw = (TT_Long) ((((double) aw / (double) ng) + 0.5) * 10.0); /* * Generate the XLFD font name. */ make_xlfd_name(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 TrueType font \"%s\" by \"%s %s\".\n", iname, prog, TTF2BDF_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", (properties.horizontal->Ascender * imetrics.y_ppem) / upm, -((properties.horizontal->Descender * imetrics.y_ppem) / upm)); /* * Get the copyright string from the font. */ (void) ttf_get_english_name(xlfd, TTF_COPYRIGHT, 0); fprintf(out, "COPYRIGHT \"%s\"\n", xlfd); /* * Last, print the two user-defined properties _TTF_FONTFILE and * _TTF_PSNAME. _TTF_FONTFILE provides a reference to the original TT * font file which some systems can take advantage of, and _TTF_PSNAME * provides the Postscript name of the font if it exists. */ (void) ttf_get_english_name(xlfd, TTF_PSNAME, 0); fprintf(out, "_TTF_FONTFILE \"%s\"\n_TTF_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, TTF2BDF_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); if (raster.size > 0) free((char *) raster.bitmap); return -1; } /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -