📄 type1font.java
字号:
}
else
throw new DocumentException(afmFile + " is not an AFM or PFM font file.");
EncodingScheme = EncodingScheme.trim();
if (EncodingScheme.equals("AdobeStandardEncoding") || EncodingScheme.equals("StandardEncoding")) {
fontSpecific = false;
}
if (!encoding.startsWith("#"))
PdfEncodings.convertToBytes(" ", enc); // check if the encoding exists
createEncoding();
}
/** Gets the width from the font according to the <CODE>name</CODE> or,
* if the <CODE>name</CODE> is null, meaning it is a symbolic font,
* the char <CODE>c</CODE>.
* @param c the char if the font is symbolic
* @param name the glyph name
* @return the width of the char
*/
int getRawWidth(int c, String name) {
Object metrics[];
if (name == null) { // font specific
metrics = (Object[])CharMetrics.get(new Integer(c));
}
else {
if (name.equals(".notdef"))
return 0;
metrics = (Object[])CharMetrics.get(name);
}
if (metrics != null)
return ((Integer)(metrics[1])).intValue();
return 0;
}
/** Gets the kerning between two Unicode characters. The characters
* are converted to names and this names are used to find the kerning
* pairs in the <CODE>HashMap</CODE> <CODE>KernPairs</CODE>.
* @param char1 the first char
* @param char2 the second char
* @return the kerning to be applied
*/
public int getKerning(char char1, char char2)
{
String first = GlyphList.unicodeToName((int)char1);
if (first == null)
return 0;
String second = GlyphList.unicodeToName((int)char2);
if (second == null)
return 0;
Object obj[] = (Object[])KernPairs.get(first);
if (obj == null)
return 0;
for (int k = 0; k < obj.length; k += 2) {
if (second.equals(obj[k]))
return ((Integer)obj[k + 1]).intValue();
}
return 0;
}
/** Reads the font metrics
* @param rf the AFM file
* @throws DocumentException the AFM file is invalid
* @throws IOException the AFM file could not be read
*/
public void process(RandomAccessFileOrArray rf) throws DocumentException, IOException
{
String line;
boolean isMetrics = false;
while ((line = rf.readLine()) != null)
{
StringTokenizer tok = new StringTokenizer(line, " ,\n\r\t\f");
if (!tok.hasMoreTokens())
continue;
String ident = tok.nextToken();
if (ident.equals("FontName"))
FontName = tok.nextToken("\u00ff").substring(1);
else if (ident.equals("FullName"))
FullName = tok.nextToken("\u00ff").substring(1);
else if (ident.equals("FamilyName"))
FamilyName = tok.nextToken("\u00ff").substring(1);
else if (ident.equals("Weight"))
Weight = tok.nextToken("\u00ff").substring(1);
else if (ident.equals("ItalicAngle"))
ItalicAngle = Float.parseFloat(tok.nextToken());
else if (ident.equals("IsFixedPitch"))
IsFixedPitch = tok.nextToken().equals("true");
else if (ident.equals("CharacterSet"))
CharacterSet = tok.nextToken("\u00ff").substring(1);
else if (ident.equals("FontBBox"))
{
llx = (int)Float.parseFloat(tok.nextToken());
lly = (int)Float.parseFloat(tok.nextToken());
urx = (int)Float.parseFloat(tok.nextToken());
ury = (int)Float.parseFloat(tok.nextToken());
}
else if (ident.equals("UnderlinePosition"))
UnderlinePosition = (int)Float.parseFloat(tok.nextToken());
else if (ident.equals("UnderlineThickness"))
UnderlineThickness = (int)Float.parseFloat(tok.nextToken());
else if (ident.equals("EncodingScheme"))
EncodingScheme = tok.nextToken("\u00ff").substring(1);
else if (ident.equals("CapHeight"))
CapHeight = (int)Float.parseFloat(tok.nextToken());
else if (ident.equals("XHeight"))
XHeight = (int)Float.parseFloat(tok.nextToken());
else if (ident.equals("Ascender"))
Ascender = (int)Float.parseFloat(tok.nextToken());
else if (ident.equals("Descender"))
Descender = (int)Float.parseFloat(tok.nextToken());
else if (ident.equals("StdHW"))
StdHW = (int)Float.parseFloat(tok.nextToken());
else if (ident.equals("StdVW"))
StdVW = (int)Float.parseFloat(tok.nextToken());
else if (ident.equals("StartCharMetrics"))
{
isMetrics = true;
break;
}
}
if (!isMetrics)
throw new DocumentException("Missing StartCharMetrics in " + fileName);
while ((line = rf.readLine()) != null)
{
StringTokenizer tok = new StringTokenizer(line);
if (!tok.hasMoreTokens())
continue;
String ident = tok.nextToken();
if (ident.equals("EndCharMetrics"))
{
isMetrics = false;
break;
}
Integer C = new Integer(-1);
Integer WX = new Integer(250);
String N = "";
int B[] = null;
tok = new StringTokenizer(line, ";");
while (tok.hasMoreTokens())
{
StringTokenizer tokc = new StringTokenizer(tok.nextToken());
if (!tokc.hasMoreTokens())
continue;
ident = tokc.nextToken();
if (ident.equals("C"))
C = Integer.valueOf(tokc.nextToken());
else if (ident.equals("WX"))
WX = new Integer((int)Float.parseFloat(tokc.nextToken()));
else if (ident.equals("N"))
N = tokc.nextToken();
else if (ident.equals("B")) {
B = new int[]{Integer.parseInt(tokc.nextToken()),
Integer.parseInt(tokc.nextToken()),
Integer.parseInt(tokc.nextToken()),
Integer.parseInt(tokc.nextToken())};
}
}
Object metrics[] = new Object[]{C, WX, N, B};
if (C.intValue() >= 0)
CharMetrics.put(C, metrics);
CharMetrics.put(N, metrics);
}
if (isMetrics)
throw new DocumentException("Missing EndCharMetrics in " + fileName);
if (!CharMetrics.containsKey("nonbreakingspace")) {
Object[] space = (Object[])CharMetrics.get("space");
if (space != null)
CharMetrics.put("nonbreakingspace", space);
}
while ((line = rf.readLine()) != null)
{
StringTokenizer tok = new StringTokenizer(line);
if (!tok.hasMoreTokens())
continue;
String ident = tok.nextToken();
if (ident.equals("EndFontMetrics"))
return;
if (ident.equals("StartKernPairs"))
{
isMetrics = true;
break;
}
}
if (!isMetrics)
throw new DocumentException("Missing EndFontMetrics in " + fileName);
while ((line = rf.readLine()) != null)
{
StringTokenizer tok = new StringTokenizer(line);
if (!tok.hasMoreTokens())
continue;
String ident = tok.nextToken();
if (ident.equals("KPX"))
{
String first = tok.nextToken();
String second = tok.nextToken();
Integer width = new Integer((int)Float.parseFloat(tok.nextToken()));
Object relates[] = (Object[])KernPairs.get(first);
if (relates == null)
KernPairs.put(first, new Object[]{second, width});
else
{
int n = relates.length;
Object relates2[] = new Object[n + 2];
System.arraycopy(relates, 0, relates2, 0, n);
relates2[n] = second;
relates2[n + 1] = width;
KernPairs.put(first, relates2);
}
}
else if (ident.equals("EndKernPairs"))
{
isMetrics = false;
break;
}
}
if (isMetrics)
throw new DocumentException("Missing EndKernPairs in " + fileName);
rf.close();
}
/** If the embedded flag is <CODE>false</CODE> or if the font is
* one of the 14 built in types, it returns <CODE>null</CODE>,
* otherwise the font is read and output in a PdfStream object.
* @return the PdfStream containing the font or <CODE>null</CODE>
* @throws DocumentException if there is an error reading the font
*/
private PdfStream getFontStream() throws DocumentException
{
if (builtinFont || !embedded)
return null;
RandomAccessFileOrArray rf = null;
try {
String filePfb = fileName.substring(0, fileName.length() - 3) + "pfb";
if (pfb == null)
rf = new RandomAccessFileOrArray(filePfb);
else
rf = new RandomAccessFileOrArray(pfb);
int fileLength = rf.length();
byte st[] = new byte[fileLength - 18];
int lengths[] = new int[3];
int bytePtr = 0;
for (int k = 0; k < 3; ++k) {
if (rf.read() != 0x80)
throw new DocumentException("Start marker missing in " + filePfb);
if (rf.read() != PFB_TYPES[k])
throw new DocumentException("Incorrect segment type in " + filePfb);
int size = rf.read();
size += rf.read() << 8;
size += rf.read() << 16;
size += rf.read() << 24;
lengths[k] = size;
while (size != 0) {
int got = rf.read(st, bytePtr, size);
if (got < 0)
throw new DocumentException("Premature end in " + filePfb);
bytePtr += got;
size -= got;
}
}
return new StreamFont(st, lengths);
}
catch (Exception e) {
throw new DocumentException(e);
}
finally {
if (rf != null) {
try {
rf.close();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -