📄 ttf2pfb.c
字号:
UShort platform, encoding, language, id; char* string; UShort string_len; UShort i, n; n = properties.num_Names; for (i = 0; i < n; i++) { TT_Get_Name_ID(face, i, &platform, &encoding, &language, &id); TT_Get_Name_String(face, i, &string, &string_len); if (id == index) break; } i = (string_len > NAMELEN) ? NAMELEN : string_len; string[i] = '\0'; return string;}/* * Load a glyph's outline and metrics. */intLoadTrueTypeChar(int idx){ TT_Matrix scale = {(1 << 16) / 64, 0, 0, (1 << 16) / 64}; error = TT_Load_Glyph(instance, glyph, idx, TTLOAD_DEFAULT); if (error) fatal_error("Load glyph"); error = TT_Get_Glyph_Outline(glyph, &outline); if (error) fatal_error("Get glyph outlines"); TT_Transform_Outline(&outline, &scale); error = TT_Get_Glyph_Metrics(glyph, &metrics); if (error) fatal_error("Get glyph_metrics"); return TRUE;}/* * Get PS name of a glyph. */char*PS_GlyphName(UShort idx, UShort code){ char *glyphname = ".notdef"; static char CJK_glyphname[8]; if (compact) { sprintf(CJK_glyphname, "cjk%04X", code); glyphname = CJK_glyphname; } else { if (idx) TT_Get_PS_Name(face, idx, &glyphname); } return glyphname;}/* * Header of Type 1 font. */voidPS_Head(FILE *out, int plane, EncVec* planeEV, char* font, int UID){ EVcRange* cRange = planeEV->codeRange; UShort numCR = planeEV->numCodeRanges; int cjk = 0, nGlyph = 0, irange; EVLow* pLow = cRange->low; UShort nLow = cRange->numLowRanges; int ipl, ilow, ich; int idx; UShort code; time_t curtime; struct tm *loctime; char text[NAMELEN]; char fam_name[NAMELEN]; char* version; char fullname[NAMELEN]; char copyright[NAMELEN]; /* Get the current time with local representation */ curtime = time(NULL); loctime = localtime(&curtime); /* Get font infos: family name, version, notice */ strcpy(fullname, LookUp_Name(6)); strcpy(fam_name, LookUp_Name(1)); strcpy(text, LookUp_Name(5)); version = &text[strcspn(text, "1234567890.")]; version[strspn(version, "1234567890.")] = '\0'; strcpy(copyright, LookUp_Name(0)); fprintf(out, "%%!FontType1-1.0: %s %s\n", font, version); fprintf(out, "%%%%Creator: %s, ", prog); fprintf(out, "%s\n", rcsid); fprintf(out, "%%%%CreationDate: %s", asctime(loctime)); Fputs("%%VMusage: 030000 030000"); Fputs("11 dict begin"); Fputs("/FontInfo 8 dict dup begin"); fprintf(out, "/version (%s) readonly def\n", version); fprintf(out, "/Copyright (%s) readonly def\n", copyright); fprintf(out, "/Notice (Plane %d) readonly def\n", plane); fprintf(out, "/FullName (%s) readonly def\n", fullname); fprintf(out, "/FamilyName (%s) readonly def\n", fam_name); Fputs("/Weight (Regular) readonly def"); Fputs("/ItalicAngle 0 def"); Fputs("/isFixedPitch false def"); /* Fputs("/UnderlineThickness 50 def"); */ Fputs("end readonly def"); fprintf(out, "/FontName /%s def\n", font); Fputs("/PaintType 0 def"); Fputs("/FontType 1 def"); if (fontShift == 0) Fputs("/FontMatrix [0.001 0 0 0.001 0 0] readonly def"); else fprintf(out, "/FontMatrix [0.001 0 0 0.001 0 %5.3f] readonly def\n", fontShift); Fputs("/Encoding 256 array"); Fputs("0 1 255 {1 index exch /.notdef put} for"); /* encoding vector */ for (irange = 0; irange < numCR; irange++, cRange++) { pLow = cRange->low; nLow = cRange->numLowRanges; for (ipl = cRange->high.start; ipl <= cRange->high.end; ipl++) { if (nLow == 0) { nGlyph = 0x100; for (ich = 0; ich <= 0xff; ich++) { code = ipl<<8 | ich; idx = TT_Char_Index(cmap, code); fprintf(out, "dup %d /%s put\n", ich, PS_GlyphName(idx, code)); } } else { for (ilow = 0; ilow < nLow; ilow++, pLow++) { if (!compact && !mapping) cjk = pLow->start; nGlyph += pLow->end - pLow->start + 1; for (ich = pLow->start; ich <= pLow->end; ich++, cjk++) { code = ipl<<8 | ich; idx = TT_Char_Index(cmap, code); fprintf(out, "dup %d /%s put\n", cjk, PS_GlyphName(idx, code)); if (mapping && cjk == 0xFF) goto done; } } } } }done: Fputs("readonly def"); Fputs("/FontBBox [0 -300 1000 1000] readonly def"); fprintf(out, "/UniqueID %d def\n",UID); Fputs("currentdict end"); Fputs("currentfile eexec"); Fputs("dup /Private 8 dict dup begin"); Fputs("/-| { string currentfile exch readstring pop } executeonly def"); Fputs("/|- { noaccess def } executeonly def"); Fputs("/| { noaccess put } executeonly def"); Fputs("/BlueValues [ ] |-"); Fputs("/ForceBold true def"); Fputs("/LanguageGroup 1 def"); Fputs("/RndStemUp false def"); Fputs("/MinFeature{16 16} |-"); /* Fputs("/password 5839 def"); */ fprintf(out, "/UniqueID %d def\n",UID); Fputs("/Subrs 4 array"); Fputs("dup 0 { 3 0 callothersubr pop pop setcurrentpoint return } |"); Fputs("dup 1 { 0 1 callothersubr return } |"); Fputs("dup 2 { 0 2 callothersubr return } |"); Fputs("dup 3 { return } |"); Fputs("|-"); fprintf(out, "2 index /CharStrings %d dict dup begin\n", nGlyph + 1);}/* * Tail of Type 1 font. */voidPS_Tail(FILE *out){ Fputs("/.notdef { 0 250 hsbw endchar } |-"); Fputs("end end readonly put noaccess put"); Fputs("dup /FontName get exch definefont pop"); Fputs("mark currentfile closefile");}/* * Use the `rrcurveto' command on more than one `off' points. */voidPS_Curveto(FILE *out, TT_F26Dot6 x, TT_F26Dot6 y, int s, int e){ int N, i; TT_F26Dot6 sx[3], sy[3], cx[4], cy[4]; N = e - s + 1; cx[0] = lastpsx; cy[0] = lastpsy; if (s == e) { cx[1] = (2 * outline.points[s].x + outline.points[s - 1].x) / 3; cy[1] = (2 * outline.points[s].y + outline.points[s - 1].y) / 3; cx[2] = (2 * outline.points[s].x + x) / 3; cy[2] = (2 * outline.points[s].y + y) / 3; cx[3] = x; cy[3] = y; fprintf(out, "%d %d %d %d %d %d rrcurveto\n", Coord(cx[1] - cx[0]), Coord(cy[1] - cy[0]), Coord(cx[2] - cx[1]), Coord(cy[2] - cy[1]), Coord(cx[3] - cx[2]), Coord(cy[3] - cy[2])); } else { for(i = 0; i < N; i++) { sx[0] = (i == 0) ? outline.points[s - 1].x : (outline.points[i + s].x + outline.points[i + s - 1].x) / 2; sy[0] = (i == 0) ? outline.points[s - 1].y : (outline.points[i + s].y + outline.points[i + s - 1].y) / 2; sx[1] = outline.points[s + i].x; sy[1] = outline.points[s + i].y; sx[2] = (i == N - 1) ? x : (outline.points[s + i].x + outline.points[s + i + 1].x) / 2; sy[2] = (i == N - 1) ? y : (outline.points[s + i].y + outline.points[s + i + 1].y) / 2; cx[1] = (2 * sx[1] + sx[0]) / 3; cy[1] = (2 * sy[1] + sy[0]) / 3; cx[2] = (2 * sx[1] + sx[2]) / 3; cy[2] = (2 * sy[1] + sy[2]) / 3; cx[3] = sx[2]; cy[3] = sy[2]; fprintf(out, "%d %d %d %d %d %d rrcurveto\n", Coord(cx[1] - cx[0]), Coord(cy[1] - cy[0]), Coord(cx[2] - cx[1]), Coord(cy[2] - cy[1]), Coord(cx[3] - cx[2]), Coord(cy[3] - cy[2])); cx[0] = cx[3]; cy[0] = cy[3]; } } PS_LastPt(x, y);}#ifdef DEBUGint debug_Char_Code = 0xFFFF;FILE* tmpout;int showlabel = FALSE;int no_glyph = FALSE;int no_control= FALSE;#define Fputps(_msg_) fprintf(tmpout, "%s\n", _msg_)voidtmp_out(FILE* tmpout){ int i, j; Fputps("%!PS"); Fputps("%%% CharString debugging program."); Fputps("%%% Generated by: ttf2pfb $Revision: 1.1.1.1 $"); Fputps("%%% plot char-string (pathes defined in /cjkxxxx)"); Fputps(""); Fputps("%%% user-defined parameter"); Fputps("/scalefactor .6 def"); Fputps("%% 0 black, 1 white"); Fputps("/glyph-outline-gray 0 def"); Fputps("/control-point-gray 0.7 def"); Fputps(""); Fputps("%%% calculate shifts and scale factor"); Fputps("currentpagedevice /PageSize get dup"); Fputps("0 get /pagewidth exch def"); Fputps("1 get /pageheight exch def"); Fputps(""); fprintf(tmpout, "/llx %d.0 def /lly %d.0 def /urx %d.0 def /ury %d.0 def\n", Coord(metrics.bbox.xMin / 64), Coord(metrics.bbox.yMin / 64), Coord(metrics.bbox.xMax / 64), Coord(metrics.bbox.yMax / 64)); Fputps("/olwidth urx llx sub def"); Fputps("/olheight ury lly sub def"); Fputps(""); Fputps("/scale scalefactor pagewidth mul olwidth div def"); Fputps("/xshift pagewidth 1 scalefactor sub mul 2 div def"); Fputps("/yshift pageheight olheight scale mul sub 2 div def"); Fputps(""); Fputps("%% save old gray-scale value"); Fputps("/oldgray currentgray def"); Fputps(""); Fputps("%%% for point sequence label"); Fputps("/TimesRoman 8 selectfont"); Fputps("/i++ {i /i i 1 add def} def"); Fputps("/itos {4 string cvs} def"); Fputps("/point {2 copy i++ 3 1 roll 5 3 roll} def"); Fputps("/drawlabel"); Fputps(" {{moveto dup 0 eq {exit}"); Fputps(" {itos show} ifelse} loop pop} def"); Fputps("/nodrawlabel {clear} def"); Fputps("/i 0 def"); Fputps(""); Fputps("%%% for drawing glyph paths, redefine commands used in CharString"); Fputps("%% scaled to proper size"); Fputps("/addr {scale mul 3 -1 roll add 3 1 roll"); Fputps(" scale mul add exch 2 copy} def"); if (no_glyph) { Fputps("/rmoveto {addr pop pop point} def"); Fputps("/rlineto {addr pop pop point} def"); Fputps("/rrcurveto {8 4 roll addr 8 -2 roll addr 8 -2 roll addr"); Fputps(" 8 2 roll 6 {pop} repeat point} def"); } else { Fputps("/rmoveto {addr moveto point} def"); Fputps("/rlineto {addr lineto point} def"); Fputps("/rrcurveto {8 4 roll addr 8 -2 roll addr 8 -2 roll addr"); Fputps(" 8 2 roll curveto point} def"); } Fputps("/hsbw {pop pop"); Fputps(" xshift llx scale mul sub"); Fputps(" yshift lly scale mul sub} def"); Fputps("/endchar {stroke pop pop} def"); Fputps(""); Fputps("%%% for drawing control paths"); Fputps("/T {pop lly sub scale mul yshift add exch"); Fputps(" llx sub scale mul xshift add exch } def"); Fputps("/mt {T 2 copy moveto} def"); if (no_control) Fputps("/lt {T} def"); else Fputps("/lt {T 2 copy lineto} def"); Fputps(""); Fputps("1 setlinecap 1 setlinejoin"); Fputps("%%% draw control points and paths"); Fputps("control-point-gray setgray"); for (i = 0, j = 0; i < outline.n_contours; i++) { Fputps(""); fprintf(tmpout, "%d %d %d %d mt\n", j, Coord(outline.points[j].x), Coord(outline.points[j].y), outline.flags[j]); j++; for (; j <= outline.contours[i]; j++) fprintf(tmpout, "%d %d %d %d lt\n", j, Coord(outline.points[j].x), Coord(outline.points[j].y), outline.flags[j]); Fputps("closepath"); } Fputps("stroke"); if (showlabel && !no_control) Fputps("drawlabel"); else Fputps("nodrawlabel"); Fputps(""); Fputps("%%% draw glyph outlines"); Fputps("glyph-outline-gray setgray"); Fputps("");}#endif/* * Construct CharString of a glyph. */shortPS_CharString(FILE *out, UShort char_Code){ int idx, i, j; UShort start_offpt, end_offpt = 0, fst;#if DEBUG FILE* oldout = out; int loop = 1;#endif if (force_enc == X) char_Code = JIS_to_SJIS(char_Code); idx = TT_Char_Index(cmap, char_Code); if (idx == 0) return FALSE; if (!LoadTrueTypeChar(idx)) fatal("Couldn't load character with index %d (code %d)", idx, char_Code); if (verbose) printf("0x%04x (%05d): %s\n", char_Code, idx, PS_GlyphName(idx, char_Code)); /* Begin string */ fprintf(out, "/%s {\n", PS_GlyphName(idx, char_Code));#ifdef DEBUG if (char_Code == debug_Char_Code) { tmp_out(tmpout); out = tmpout; loop = 0; } for (; loop < 2; loop++) {#endif /* coordinates are all relative to (0,0) in FreeType */ fprintf(out, "0 %d hsbw\n", (int)(metrics.advance / 64)); /* Initialize ending contour point, relative coordinates */ lastpsx = lastpsy = 0; for (i = 0, j = 0; i < outline.n_contours; i++) { fst = j; PS_Moveto(outline.points[j].x, outline.points[j].y); j++; start_offpt = 0; /* start at least 1 */ /* * data pts for all contours stored in one array. * each round j init at last j + 1 */ /* * start_offpt means start of off points. * 0 means no off points in record. * N means the position of the off point. * end_offpt means the ending off point. * lastx, lasty is the last ON point from which Curve and Line * shall start. */ /* * start with j=0. into loop, j=1. * if pt[1] off, if start_offpt == 0, toggle start_offpt * next j=2. if on, now start_off != 0, run Curveto. * if pt[1] on, start_off == 0, will run Lineto. */ for (; j <= outline.contours[i]; j++) { if (!(outline.flags[j] & TT_Flag_On_Curve)) { if (!start_offpt) start_offpt = end_offpt = j; else end_offpt++; } else { /* On Curve */ if (start_offpt) { /* * start_offpt stuck at j, end_offpt++. * end_offpt - start_offpt gives no of off pts. * start_offpt gives start of sequence. * why need outline.xCoord[j] outline.yCoord[j]? */ PS_Curveto(out, outline.points[j].x, outline.points[j].y, start_offpt, end_offpt); start_offpt = 0; /* * also use start_offpt as indicator to save one variable!! * after curveto, reset condition. */ } else PS_Lineto(outline.points[j].x, outline.points[j].y); } } /* * looks like closepath fst = first, i.e. go back to first */ if (start_offpt) PS_Curveto(out, outline.points[fst].x, outline.points[fst].y, start_offpt, end_offpt); else Fputs("closepath"); } Fputs("endchar");#if DEBUG out = oldout; } if (char_Code == debug_Char_Code) { if (showlabel && !no_glyph) Fputps("drawlabel"); else Fputps("nodrawlabel"); Fputps(""); Fputps("%%% end of drawing"); Fputps("oldgray setgray"); Fputps("showpage"); fclose(tmpout); }#endif Fputs(" } |-"); return TRUE;}/* * Get code ranges of an encoding scheme either from * the eVecMap or a code range file. */EncVec*Get_EncVec(FILE *enc){ EncVec* encVec = NULL; EVcRange* cRange = NULL; EVLow* lByte = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -