📄 pfm2afm.java
字号:
if (h_len != in.length() || extlen != 30 || fontname < 75 || fontname > 512) throw new IOException("Not a valid PFM file."); in.seek(psext + 14); capheight = in.readShortLE(); xheight = in.readShortLE(); ascender = in.readShortLE(); descender = in.readShortLE(); } private void putheader() throws IOException { out.print("StartFontMetrics 2.0\n"); if (copyright.length() > 0) out.print("Comment " + copyright + '\n'); out.print("FontName "); in.seek(fontname); String fname = readString(); out.print(fname); out.print("\nEncodingScheme "); if (charset != 0) out.print("FontSpecific\n"); else out.print("AdobeStandardEncoding\n"); /* * The .pfm is missing full name, so construct from font name by * changing the hyphen to a space. This actually works in a lot * of cases. */ out.print("FullName " + fname.replace('-', ' ')); if (face != 0) { in.seek(face); out.print("\nFamilyName " + readString()); } out.print("\nWeight "); if (weight > 475 || fname.toLowerCase().indexOf("bold") >= 0) out.print("Bold"); else if ((weight < 325 && weight != 0) || fname.toLowerCase().indexOf("light") >= 0) out.print("Light"); else if (fname.toLowerCase().indexOf("black") >= 0) out.print("Black"); else out.print("Medium"); out.print("\nItalicAngle "); if (italic != 0 || fname.toLowerCase().indexOf("italic") >= 0) out.print("-12.00"); /* this is a typical value; something else may work better for a specific font */ else out.print("0"); /* * The mono flag in the pfm actually indicates whether there is a * table of font widths, not if they are all the same. */ out.print("\nIsFixedPitch "); if ((kind & 1) == 0 || /* Flag for mono */ avgwidth == maxwidth ) { /* Avg width = max width */ out.print("true"); isMono = true; } else { out.print("false"); isMono = false; } /* * The font bounding box is lost, but try to reconstruct it. * Much of this is just guess work. The bounding box is required in * the .afm, but is not used by the PM font installer. */ out.print("\nFontBBox"); if (isMono) outval(-20); /* Just guess at left bounds */ else outval(-100); outval(-(descender+5)); /* Descender is given as positive value */ outval(maxwidth+10); outval(ascent+5); /* * Give other metrics that were kept */ out.print("\nCapHeight"); outval(capheight); out.print("\nXHeight"); outval(xheight); out.print("\nDescender"); outval(descender); out.print("\nAscender"); outval(ascender); out.print('\n'); } private void putchartab() throws IOException { int count = lastchar - firstchar + 1; int ctabs[] = new int[count]; in.seek(chartab); for (int k = 0; k < count; ++k) ctabs[k] = in.readUnsignedShortLE(); int back[] = new int[256]; if (charset == 0) { for (int i = firstchar; i <= lastchar; ++i) { if (Win2PSStd[i] != 0) back[Win2PSStd[i]] = i; } } /* Put out the header */ out.print("StartCharMetrics"); outval(count); out.print('\n'); /* Put out all encoded chars */ if (charset != 0) { /* * If the charset is not the Windows standard, just put out * unnamed entries. */ for (int i = firstchar; i <= lastchar; i++) { if (ctabs[i - firstchar] != 0) { outchar(i, ctabs[i - firstchar], null); } } } else { for (int i = 0; i < 256; i++) { int j = back[i]; if (j != 0) { outchar(i, ctabs[j - firstchar], WinChars[j]); ctabs[j - firstchar] = 0; } } /* Put out all non-encoded chars */ for (int i = firstchar; i <= lastchar; i++) { if (ctabs[i - firstchar] != 0) { outchar(-1, ctabs[i - firstchar], WinChars[i]); } } } /* Put out the trailer */ out.print("EndCharMetrics\n"); } private void putkerntab() throws IOException { if (kernpairs == 0) return; in.seek(kernpairs); int count = in.readUnsignedShortLE(); int nzero = 0; int kerns[] = new int[count * 3]; for (int k = 0; k < kerns.length;) { kerns[k++] = in.read(); kerns[k++] = in.read(); if ((kerns[k++] = in.readShortLE()) != 0) ++nzero; } if (nzero == 0) return; out.print("StartKernData\nStartKernPairs"); outval(nzero); out.print('\n'); for (int k = 0; k < kerns.length; k += 3) { if (kerns[k + 2] != 0) { out.print("KPX "); out.print(WinChars[kerns[k]]); out.print(' '); out.print(WinChars[kerns[k + 1]]); outval(kerns[k + 2]); out.print('\n'); } } /* Put out trailer */ out.print("EndKernPairs\nEndKernData\n"); } private void puttrailer() { out.print("EndFontMetrics\n"); } private short vers; private int h_len; /* Total length of .pfm file */ private String copyright; /* Copyright string [60]*/ private short type; private short points; private short verres; private short horres; private short ascent; private short intleading; private short extleading; private byte italic; private byte uline; private byte overs; private short weight; private byte charset; /* 0=windows, otherwise nomap */ private short pixwidth; /* Width for mono fonts */ private short pixheight; private byte kind; /* Lower bit off in mono */ private short avgwidth; /* Mono if avg=max width */ private short maxwidth; /* Use to compute bounding box */ private int firstchar; /* First char in table */ private int lastchar; /* Last char in table */ private byte defchar; private byte brkchar; private short widthby; private int device; private int face; /* Face name */ private int bits; private int bitoff; private short extlen; private int psext; /* PostScript extension */ private int chartab; /* Character width tables */ private int res1; private int kernpairs; /* Kerning pairs */ private int res2; private int fontname; /* Font name *//* * Some metrics from the PostScript extension */ private short capheight; /* Cap height */ private short xheight; /* X height */ private short ascender; /* Ascender */ private short descender; /* Descender (positive) */ private boolean isMono;/** * Translate table from 1004 to psstd. 1004 is an extension of the * Windows translate table used in PM. */ private int Win2PSStd[] = { 0, 0, 0, 0, 197, 198, 199, 0, 202, 0, 205, 206, 207, 0, 0, 0, // 00 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10 32, 33, 34, 35, 36, 37, 38, 169, 40, 41, 42, 43, 44, 45, 46, 47, // 20 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 30 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 40 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 50 193, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, // 60 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, // 70 0, 0, 184, 166, 185, 188, 178, 179, 195, 189, 0, 172, 234, 0, 0, 0, // 80 0, 96, 0, 170, 186, 183, 177, 208, 196, 0, 0, 173, 250, 0, 0, 0, // 90 0, 161, 162, 163, 168, 165, 0, 167, 200, 0, 227, 171, 0, 0, 0, 197, // A0 0, 0, 0, 0, 194, 0, 182, 180, 203, 0, 235, 187, 0, 0, 0, 191, // B0 0, 0, 0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C0 0, 0, 0, 0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 251, // D0 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E0 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 0, 0, 0, 0, 0 // F0 }; /** * Character class. This is a minor attempt to overcome the problem that * in the pfm file, all unused characters are given the width of space. * Note that this array isn't used in iText. */ private int WinClass[] = { 0, 0, 0, 0, 2, 2, 2, 0, 2, 0, 2, 2, 2, 0, 0, 0, /* 00 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, /* 70 */ 0, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, /* 80 */ 0, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, /* 90 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* b0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* c0 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -