aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/java/org/apache/fop/fonts/type1/AFMParser.java137
-rw-r--r--src/java/org/apache/fop/fonts/type1/AdobeStandardEncoding.java410
-rw-r--r--src/java/org/apache/fop/fonts/type1/CharMetricsHandler.java117
-rw-r--r--src/java/org/apache/fop/fonts/type1/Type1FontLoader.java81
4 files changed, 611 insertions, 134 deletions
diff --git a/src/java/org/apache/fop/fonts/type1/AFMParser.java b/src/java/org/apache/fop/fonts/type1/AFMParser.java
index 0a035238a..3117f3bcb 100644
--- a/src/java/org/apache/fop/fonts/type1/AFMParser.java
+++ b/src/java/org/apache/fop/fonts/type1/AFMParser.java
@@ -22,10 +22,10 @@ package org.apache.fop.fonts.type1;
import java.awt.Rectangle;
import java.beans.Statement;
import java.io.BufferedReader;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
+import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
@@ -97,11 +97,11 @@ public class AFMParser {
private static final int PARSE_NORMAL = 0;
private static final int PARSE_CHAR_METRICS = 1;
- private static final Map VALUE_PARSERS;
- private static final Map PARSE_MODE_CHANGES;
+ private static final Map<String, ValueHandler> VALUE_PARSERS;
+ private static final Map<String, Integer> PARSE_MODE_CHANGES;
static {
- VALUE_PARSERS = new java.util.HashMap();
+ VALUE_PARSERS = new HashMap<String, ValueHandler>();
VALUE_PARSERS.put(START_FONT_METRICS, new StartFontMetrics());
VALUE_PARSERS.put(FONT_NAME, new StringSetter(FONT_NAME));
VALUE_PARSERS.put(FULL_NAME, new StringSetter(FULL_NAME));
@@ -146,7 +146,7 @@ public class AFMParser {
VALUE_PARSERS.put(KPX, new KPXHandler());
VALUE_PARSERS.put(KPY, new NotImplementedYet(KPY));
- PARSE_MODE_CHANGES = new java.util.HashMap();
+ PARSE_MODE_CHANGES = new HashMap<String, Integer>();
PARSE_MODE_CHANGES.put(START_CHAR_METRICS, new Integer(PARSE_CHAR_METRICS));
PARSE_MODE_CHANGES.put(END_CHAR_METRICS, new Integer(PARSE_NORMAL));
}
@@ -155,34 +155,19 @@ public class AFMParser {
* Main constructor.
*/
public AFMParser() {
- //nop
- }
-
- /**
- * Parses an AFM file from a local file.
- * @param afmFile the AFM file
- * @return the parsed AFM file
- * @throws IOException if an I/O error occurs
- */
- public AFMFile parse(File afmFile) throws IOException {
- InputStream in = new java.io.FileInputStream(afmFile);
- try {
- return parse(in);
- } finally {
- IOUtils.closeQuietly(in);
- }
}
/**
* Parses an AFM file from a stream.
* @param in the stream to read from
+ * @param afmFileName the name of the AFM file
* @return the parsed AFM file
* @throws IOException if an I/O error occurs
*/
- public AFMFile parse(InputStream in) throws IOException {
+ public AFMFile parse(InputStream in, String afmFileName) throws IOException {
Reader reader = new java.io.InputStreamReader(in, "US-ASCII");
try {
- return parse(new BufferedReader(reader));
+ return parse(new BufferedReader(reader), afmFileName);
} finally {
IOUtils.closeQuietly(reader);
}
@@ -191,11 +176,12 @@ public class AFMParser {
/**
* Parses an AFM file from a BufferedReader.
* @param reader the BufferedReader instance to read from
+ * @param afmFileName the name of the AFM file
* @return the parsed AFM file
* @throws IOException if an I/O error occurs
*/
- public AFMFile parse(BufferedReader reader) throws IOException {
- Stack stack = new Stack();
+ public AFMFile parse(BufferedReader reader, String afmFileName) throws IOException {
+ Stack<Object> stack = new Stack<Object>();
int parseMode = PARSE_NORMAL;
while (true) {
String line = reader.readLine();
@@ -208,12 +194,12 @@ public class AFMParser {
key = parseLine(line, stack);
break;
case PARSE_CHAR_METRICS:
- key = parseCharMetrics(line, stack);
+ key = parseCharMetrics(line, stack, afmFileName);
break;
default:
throw new IllegalStateException("Invalid parse mode");
}
- Integer newParseMode = (Integer)PARSE_MODE_CHANGES.get(key);
+ Integer newParseMode = PARSE_MODE_CHANGES.get(key);
if (newParseMode != null) {
parseMode = newParseMode.intValue();
}
@@ -221,7 +207,7 @@ public class AFMParser {
return (AFMFile)stack.pop();
}
- private String parseLine(String line, Stack stack) throws IOException {
+ private String parseLine(String line, Stack<Object> stack) throws IOException {
int startpos = 0;
//Find key
startpos = skipToNonWhiteSpace(line, startpos);
@@ -230,47 +216,24 @@ public class AFMParser {
//Parse value
startpos = skipToNonWhiteSpace(line, endpos);
- ValueHandler vp = (ValueHandler)VALUE_PARSERS.get(key);
+ ValueHandler vp = VALUE_PARSERS.get(key);
if (vp != null) {
vp.parse(line, startpos, stack);
}
return key;
}
- private String parseCharMetrics(String line, Stack stack) throws IOException {
- int startpos = 0;
- AFMCharMetrics chm = new AFMCharMetrics();
- stack.push(chm);
- while (true) {
- //Find key
- startpos = skipToNonWhiteSpace(line, startpos);
- int endpos = skipToWhiteSpace(line, startpos);
- String key = line.substring(startpos, endpos);
- if (END_CHAR_METRICS.equals(key)) {
- stack.pop(); //Pop and forget unused AFMCharMetrics instance
- return key;
- } else if (key.length() == 0) {
- //EOL: No more key so break
- break;
- }
-
- //Extract value
- startpos = skipToNonWhiteSpace(line, endpos);
- endpos = skipToSemicolon(line, startpos);
- String value = line.substring(startpos, endpos).trim();
- startpos = endpos + 1;
-
- //Parse value
- ValueHandler vp = (ValueHandler)VALUE_PARSERS.get(key);
- if (vp != null) {
- vp.parse(value, 0, stack);
- }
- if (false) {
- break;
- }
+ private String parseCharMetrics(String line, Stack<Object> stack, String afmFileName)
+ throws IOException {
+ String trimmedLine = line.trim();
+ if (END_CHAR_METRICS.equals(trimmedLine)) {
+ return trimmedLine;
}
- stack.pop();
- AFMFile afm = (AFMFile)stack.peek();
+ AFMFile afm = (AFMFile) stack.peek();
+ String encoding = afm.getEncodingScheme();
+ CharMetricsHandler charMetricsHandler = CharMetricsHandler.getHandler(VALUE_PARSERS,
+ encoding);
+ AFMCharMetrics chm = charMetricsHandler.parse(trimmedLine, stack, afmFileName);
afm.addCharMetrics(chm);
return null;
}
@@ -291,14 +254,6 @@ public class AFMParser {
return pos;
}
- private static int skipToSemicolon(String line, int startpos) {
- int pos = startpos;
- while (pos < line.length() && ';' != line.charAt(pos)) {
- pos++;
- }
- return pos;
- }
-
private static boolean isWhitespace(char ch) {
return ch == ' '
|| ch == '\t';
@@ -306,8 +261,8 @@ public class AFMParser {
// ---------------- Value Handlers ---------------------------
- private interface ValueHandler {
- void parse(String line, int startpos, Stack stack) throws IOException;
+ interface ValueHandler {
+ void parse(String line, int startpos, Stack<Object> stack) throws IOException;
}
private abstract static class AbstractValueHandler implements ValueHandler {
@@ -345,7 +300,7 @@ public class AFMParser {
}
private static class StartFontMetrics extends AbstractValueHandler {
- public void parse(String line, int startpos, Stack stack) throws IOException {
+ public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
int endpos = findValue(line, startpos);
double version = Double.parseDouble(line.substring(startpos, endpos));
if (version < 2) {
@@ -382,7 +337,7 @@ public class AFMParser {
super(variable);
}
- public void parse(String line, int startpos, Stack stack) throws IOException {
+ public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
String s = getStringValue(line, startpos);
Object obj = stack.peek();
setValue(obj, s);
@@ -395,7 +350,7 @@ public class AFMParser {
super(variable);
}
- public void parse(String line, int startpos, Stack stack) throws IOException {
+ public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
NamedCharacter ch = new NamedCharacter(getStringValue(line, startpos));
Object obj = stack.peek();
setValue(obj, ch);
@@ -407,11 +362,11 @@ public class AFMParser {
super(variable);
}
- protected Object getContextObject(Stack stack) {
+ protected Object getContextObject(Stack<Object> stack) {
return stack.peek();
}
- public void parse(String line, int startpos, Stack stack) throws IOException {
+ public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
Number num = getNumberValue(line, startpos);
setValue(getContextObject(stack), num);
}
@@ -422,7 +377,7 @@ public class AFMParser {
super(variable);
}
- public void parse(String line, int startpos, Stack stack) throws IOException {
+ public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
int value = getIntegerValue(line, startpos);
setValue(getContextObject(stack), new Integer(value));
}
@@ -433,7 +388,7 @@ public class AFMParser {
super(variable);
}
- public void parse(String line, int startpos, Stack stack) throws IOException {
+ public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
double value = getDoubleValue(line, startpos);
setValue(getContextObject(stack), new Double(value));
}
@@ -445,7 +400,7 @@ public class AFMParser {
super(variable);
}
- protected Object getContextObject(Stack stack) {
+ protected Object getContextObject(Stack<Object> stack) {
if (stack.peek() instanceof AFMWritingDirectionMetrics) {
return (AFMWritingDirectionMetrics)stack.peek();
} else {
@@ -467,7 +422,7 @@ public class AFMParser {
super(variable);
}
- public void parse(String line, int startpos, Stack stack) throws IOException {
+ public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
double value = getDoubleValue(line, startpos);
setValue(getContextObject(stack), new Double(value));
}
@@ -480,11 +435,11 @@ public class AFMParser {
this.method = "set" + variable.substring(2); //Cut "Is" in front
}
- protected Object getContextObject(Stack stack) {
+ protected Object getContextObject(Stack<Object> stack) {
return (AFMFile)stack.peek();
}
- public void parse(String line, int startpos, Stack stack) throws IOException {
+ public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
Boolean b = getBooleanValue(line, startpos);
//Uses Java Beans API
Statement statement = new Statement(getContextObject(stack),
@@ -504,7 +459,7 @@ public class AFMParser {
super(variable);
}
- protected Object getContextObject(Stack stack) {
+ protected Object getContextObject(Stack<Object> stack) {
if (stack.peek() instanceof AFMWritingDirectionMetrics) {
return (AFMWritingDirectionMetrics)stack.peek();
} else {
@@ -521,7 +476,7 @@ public class AFMParser {
}
private static class FontBBox extends AbstractValueHandler {
- public void parse(String line, int startpos, Stack stack) throws IOException {
+ public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
Rectangle rect = parseBBox(line, startpos);
AFMFile afm = (AFMFile)stack.peek();
@@ -554,7 +509,7 @@ public class AFMParser {
}
private static class CharBBox extends FontBBox {
- public void parse(String line, int startpos, Stack stack) throws IOException {
+ public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
Rectangle rect = parseBBox(line, startpos);
AFMCharMetrics metrics = (AFMCharMetrics)stack.peek();
@@ -563,7 +518,7 @@ public class AFMParser {
}
private static class IsBaseFont extends AbstractValueHandler {
- public void parse(String line, int startpos, Stack stack) throws IOException {
+ public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
if (getBooleanValue(line, startpos).booleanValue()) {
throw new IOException("Only base fonts are currently supported!");
}
@@ -571,7 +526,7 @@ public class AFMParser {
}
private static class IsCIDFont extends AbstractValueHandler {
- public void parse(String line, int startpos, Stack stack) throws IOException {
+ public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
if (getBooleanValue(line, startpos).booleanValue()) {
throw new IOException("CID fonts are currently not supported!");
}
@@ -592,7 +547,7 @@ public class AFMParser {
}
private static class StartDirection extends AbstractValueHandler {
- public void parse(String line, int startpos, Stack stack) throws IOException {
+ public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
int index = getIntegerValue(line, startpos);
AFMWritingDirectionMetrics wdm = new AFMWritingDirectionMetrics();
AFMFile afm = (AFMFile)stack.peek();
@@ -602,7 +557,7 @@ public class AFMParser {
}
private static class EndDirection extends AbstractValueHandler {
- public void parse(String line, int startpos, Stack stack) throws IOException {
+ public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
if (!(stack.pop() instanceof AFMWritingDirectionMetrics)) {
throw new IOException("AFM format error: nesting incorrect");
}
@@ -610,7 +565,7 @@ public class AFMParser {
}
private static class KPXHandler extends AbstractValueHandler {
- public void parse(String line, int startpos, Stack stack) throws IOException {
+ public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
AFMFile afm = (AFMFile)stack.peek();
int endpos;
diff --git a/src/java/org/apache/fop/fonts/type1/AdobeStandardEncoding.java b/src/java/org/apache/fop/fonts/type1/AdobeStandardEncoding.java
new file mode 100644
index 000000000..514d03185
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/type1/AdobeStandardEncoding.java
@@ -0,0 +1,410 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fonts.type1;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Enumerates the {@linkplain http://unicode.org/Public/MAPPINGS/VENDORS/ADOBE/stdenc.txt} for
+ * characters found in a Type1 font.
+ */
+enum AdobeStandardEncoding {
+ /** space character */
+ space(0x0020, 0x20, "SPACE", "space"),
+ /** space character */
+ space_nobreak(0x00A0, 0x20, "NO-BREAK SPACE", "space"),
+ /** exclamation mark */
+ exclam(0x0021, 0x21, "EXCLAMATION MARK", "exclam"),
+ /** quotation mark */
+ quotedbl(0x0022, 0x22, "QUOTATION MARK", "quotedbl"),
+ /** number sign */
+ numersign(0x0023, 0x23, "NUMBER SIGN", "numbersign"),
+ /** dollar character */
+ dollar(0x0024, 0x24, "DOLLAR SIGN", "dollar"),
+ /** percent character */
+ percent(0x0025, 0x25, "PERCENT SIGN", "percent"),
+ /** ampersand character */
+ ampersand(0x0026, 0x26, "AMPERSAND", "ampersand"),
+ /** right single quotation mark */
+ quoteright(0x2019, 0x27, "RIGHT SINGLE QUOTATION MARK", "quoteright"),
+ /** left parenthesis character */
+ parenleft(0x0028, 0x28, "LEFT PARENTHESIS", "parenleft"),
+ /** right parenthesis character */
+ parenright(0x0029, 0x29, "RIGHT PARENTHESIS", "parenright"),
+ /** asterisk character */
+ asterisk(0x002A, 0x2A, "ASTERISK", "asterisk"),
+ /** plus sign */
+ plus(0x002B, 0x2B, "PLUS SIGN", "plus"),
+ /** comma character */
+ comma(0x002C, 0x2C, "COMMA", "comma"),
+ /** hyphen-minus character */
+ hyphen(0x002D, 0x2D, "HYPHEN-MINUS", "hyphen"),
+ /** soft-hyphen character */
+ hyphen_soft(0x00AD, 0x2D, "SOFT HYPHEN", "hyphen"),
+ /** period character */
+ period(0x002E, 0x2E, "FULL STOP", "period"),
+ /** slash character */
+ slash(0x002F, 0x2F, "SOLIDUS", "slash"),
+ /** zero character */
+ zero(0x0030, 0x30, "DIGIT ZERO", "zero"),
+ /** one character */
+ one(0x0031, 0x31, "DIGIT ONE", "one"),
+ /** two character */
+ two(0x0032, 0x32, "DIGIT TWO", "two"),
+ /** three character */
+ three(0x0033, 0x33, "DIGIT THREE", "three"),
+ /** four character */
+ four(0x0034, 0x34, "DIGIT FOUR", "four"),
+ /** five character */
+ five(0x0035, 0x35, "DIGIT FIVE", "five"),
+ /** six character */
+ six(0x0036, 0x36, "DIGIT SIX", "six"),
+ /** seven character */
+ seven(0x0037, 0x37, "DIGIT SEVEN", "seven"),
+ /** eight character */
+ eight(0x0038, 0x38, "DIGIT EIGHT", "eight"),
+ /** nine character */
+ nine(0x0039, 0x39, "DIGIT NINE", "nine"),
+ /** colon character */
+ colon(0x003A, 0x3A, "COLON", "colon"),
+ /** semi-colon character */
+ semicolon(0x003B, 0x3B, "SEMICOLON", "semicolon"),
+ /** less character */
+ less(0x003C, 0x3C, "LESS-THAN SIGN", "less"),
+ /** equal character */
+ equal(0x003D, 0x3D, "EQUALS SIGN", "equal"),
+ /** greater character */
+ greater(0x003E, 0x3E, "GREATER-THAN SIGN", "greater"),
+ /** question character */
+ question(0x003F, 0x3F, "QUESTION MARK", "question"),
+ /** at character */
+ at(0x0040, 0x40, "COMMERCIAL AT", "at"),
+ /** A character */
+ A(0x0041, 0x41, "LATIN CAPITAL LETTER A", "A"),
+ /** B character */
+ B(0x0042, 0x42, "LATIN CAPITAL LETTER B", "B"),
+ /** C character */
+ C(0x0043, 0x43, "LATIN CAPITAL LETTER C", "C"),
+ /** D character */
+ D(0x0044, 0x44, "LATIN CAPITAL LETTER D", "D"),
+ /** E character */
+ E(0x0045, 0x45, "LATIN CAPITAL LETTER E", "E"),
+ /** F character */
+ F(0x0046, 0x46, "LATIN CAPITAL LETTER F", "F"),
+ /** G character */
+ G(0x0047, 0x47, "LATIN CAPITAL LETTER G", "G"),
+ /** H character */
+ H(0x0048, 0x48, "LATIN CAPITAL LETTER H", "H"),
+ /** I character */
+ I(0x0049, 0x49, "LATIN CAPITAL LETTER I", "I"),
+ /** J character */
+ J(0x004A, 0x4A, "LATIN CAPITAL LETTER J", "J"),
+ /** K character */
+ K(0x004B, 0x4B, "LATIN CAPITAL LETTER K", "K"),
+ /** L character */
+ L(0x004C, 0x4C, "LATIN CAPITAL LETTER L", "L"),
+ /** M character */
+ M(0x004D, 0x4D, "LATIN CAPITAL LETTER M", "M"),
+ /** N character */
+ N(0x004E, 0x4E, "LATIN CAPITAL LETTER N", "N"),
+ /** O character */
+ O(0x004F, 0x4F, "LATIN CAPITAL LETTER O", "O"),
+ /** P character */
+ P(0x0050, 0x50, "LATIN CAPITAL LETTER P", "P"),
+ /** Q character */
+ Q(0x0051, 0x51, "LATIN CAPITAL LETTER Q", "Q"),
+ /** R character */
+ R(0x0052, 0x52, "LATIN CAPITAL LETTER R", "R"),
+ /** S character */
+ S(0x0053, 0x53, "LATIN CAPITAL LETTER S", "S"),
+ /** T character */
+ T(0x0054, 0x54, "LATIN CAPITAL LETTER T", "T"),
+ /** U character */
+ U(0x0055, 0x55, "LATIN CAPITAL LETTER U", "U"),
+ /** V character */
+ V(0x0056, 0x56, "LATIN CAPITAL LETTER V", "V"),
+ /** W character */
+ W(0x0057, 0x57, "LATIN CAPITAL LETTER W", "W"),
+ /** X character */
+ X(0x0058, 0x58, "LATIN CAPITAL LETTER X", "X"),
+ /** Y character */
+ Y(0x0059, 0x59, "LATIN CAPITAL LETTER Y", "Y"),
+ /** Z character */
+ Z(0x005A, 0x5A, "LATIN CAPITAL LETTER Z", "Z"),
+ /** left bracket character */
+ bracketleft(0x005B, 0x5B, "LEFT SQUARE BRACKET", "bracketleft"),
+ /** back slash character */
+ backslash(0x005C, 0x5C, "REVERSE SOLIDUS", "backslash"),
+ /** bracket right character */
+ bracketright(0x005D, 0x5D, "RIGHT SQUARE BRACKET", "bracketright"),
+ /** circumflex character */
+ asciicircum(0x005E, 0x5E, "CIRCUMFLEX ACCENT", "asciicircum"),
+ /** under score character */
+ underscore(0x005F, 0x5F, "LOW LINE", "underscore"),
+ /** left single quotation character */
+ quoteleft(0x2018, 0x60, "LEFT SINGLE QUOTATION MARK", "quoteleft"),
+ /** a character */
+ a(0x0061, 0x61, "LATIN SMALL LETTER A", "a"),
+ /** b character */
+ b(0x0062, 0x62, "LATIN SMALL LETTER B", "b"),
+ /** c character */
+ c(0x0063, 0x63, "LATIN SMALL LETTER C", "c"),
+ /** d character */
+ d(0x0064, 0x64, "LATIN SMALL LETTER D", "d"),
+ /** e character */
+ e(0x0065, 0x65, "LATIN SMALL LETTER E", "e"),
+ /** f character */
+ f(0x0066, 0x66, "LATIN SMALL LETTER F", "f"),
+ /** g character */
+ g(0x0067, 0x67, "LATIN SMALL LETTER G", "g"),
+ /** h character */
+ h(0x0068, 0x68, "LATIN SMALL LETTER H", "h"),
+ /** i character */
+ i(0x0069, 0x69, "LATIN SMALL LETTER I", "i"),
+ /** j character */
+ j(0x006A, 0x6A, "LATIN SMALL LETTER J", "j"),
+ /** k character */
+ k(0x006B, 0x6B, "LATIN SMALL LETTER K", "k"),
+ /** l character */
+ l(0x006C, 0x6C, "LATIN SMALL LETTER L", "l"),
+ /** m character */
+ m(0x006D, 0x6D, "LATIN SMALL LETTER M", "m"),
+ /** n character */
+ n(0x006E, 0x6E, "LATIN SMALL LETTER N", "n"),
+ /** o character */
+ o(0x006F, 0x6F, "LATIN SMALL LETTER O", "o"),
+ /** p character */
+ p(0x0070, 0x70, "LATIN SMALL LETTER P", "p"),
+ /** q character */
+ q(0x0071, 0x71, "LATIN SMALL LETTER Q", "q"),
+ /** r character */
+ r(0x0072, 0x72, "LATIN SMALL LETTER R", "r"),
+ /** s character */
+ s(0x0073, 0x73, "LATIN SMALL LETTER S", "s"),
+ /** t character */
+ t(0x0074, 0x74, "LATIN SMALL LETTER T", "t"),
+ /** u character */
+ u(0x0075, 0x75, "LATIN SMALL LETTER U", "u"),
+ /** v character */
+ v(0x0076, 0x76, "LATIN SMALL LETTER V", "v"),
+ /** w character */
+ w(0x0077, 0x77, "LATIN SMALL LETTER W", "w"),
+ /** x character */
+ x(0x0078, 0x78, "LATIN SMALL LETTER X", "x"),
+ /** y character */
+ y(0x0079, 0x79, "LATIN SMALL LETTER Y", "y"),
+ /** z character */
+ z(0x007A, 0x7A, "LATIN SMALL LETTER Z", "z"),
+ /** left curly bracket character */
+ braceleft(0x007B, 0x7B, "LEFT CURLY BRACKET", "braceleft"),
+ /** vertical line character */
+ bar(0x007C, 0x7C, "VERTICAL LINE", "bar"),
+ /** right curly bracket character */
+ braceright(0x007D, 0x7D, "RIGHT CURLY BRACKET", "braceright"),
+ /** tilde character */
+ asciitilde(0x007E, 0x7E, "TILDE", "asciitilde"),
+ /** inverted exclamation mark */
+ exclamdown(0x00A1, 0xA1, "INVERTED EXCLAMATION MARK", "exclamdown"),
+ /** cent character */
+ cent(0x00A2, 0xA2, "CENT SIGN", "cent"),
+ /** sterling character */
+ sterling(0x00A3, 0xA3, "POUND SIGN", "sterling"),
+ /** fraction slash character */
+ fraction(0x2044, 0xA4, "FRACTION SLASH", "fraction"),
+ /** division slash character */
+ fraction_division_slash(0x2215, 0xA4, "DIVISION SLASH", "fraction"),
+ /** yen character */
+ yen(0x00A5, 0xA5, "YEN SIGN", "yen"),
+ /** florin character */
+ florin(0x0192, 0xA6, "LATIN SMALL LETTER F WITH HOOK", "florin"),
+ /** section sign character */
+ section(0x00A7, 0xA7, "SECTION SIGN", "section"),
+ /** currency sign character */
+ currency(0x00A4, 0xA8, "CURRENCY SIGN", "currency"),
+ /** apostrophe character */
+ quotesingle(0x0027, 0xA9, "APOSTROPHE", "quotesingle"),
+ /** double left quotation mark */
+ quotedblleft(0x201C, 0xAA, "LEFT DOUBLE QUOTATION MARK", "quotedblleft"),
+ /** left-pointing double angle quotation mark */
+ guillemotleft(0x00AB, 0xAB, "LEFT-POINTING DOUBLE ANGLE QUOTATION MARK", "guillemotleft"),
+ /** left-pointing single quotation mark */
+ guilsinglleft(0x2039, 0xAC, "SINGLE LEFT-POINTING ANGLE QUOTATION MARK", "guilsinglleft"),
+ /** right-pointing single quotation mark */
+ guilsinglright(0x203A, 0xAD, "SINGLE RIGHT-POINTING ANGLE QUOTATION MARK", "guilsinglright"),
+ /** fi ligature */
+ fi(0xFB01, 0xAE, "LATIN SMALL LIGATURE FI", "fi"),
+ /** fl ligature */
+ fl(0xFB02, 0xAF, "LATIN SMALL LIGATURE FL", "fl"),
+ /** en-dash character */
+ endash(0x2013, 0xB1, "EN DASH", "endash"),
+ /** dagger character */
+ dagger(0x2020, 0xB2, "DAGGER", "dagger"),
+ /** double dagger character */
+ daggerdbl(0x2021, 0xB3, "DOUBLE DAGGER", "daggerdbl"),
+ /** centered period character */
+ periodcentered(0x00B7, 0xB4, "MIDDLE DOT", "periodcentered"),
+ /** centered period character */
+ periodcentered_bullet_operator(0x2219, 0xB4, "BULLET OPERATOR", "periodcentered"),
+ /** paragraph character */
+ paragraph(0x00B6, 0xB6, "PILCROW SIGN", "paragraph"),
+ /** bullet character */
+ bullet(0x2022, 0xB7, "BULLET", "bullet"),
+ /** single low-9 quotation mark */
+ quotesinglbase(0x201A, 0xB8, "SINGLE LOW-9 QUOTATION MARK", "quotesinglbase"),
+ /** double low-9 quotation mark */
+ quotedblbase(0x201E, 0xB9, "DOUBLE LOW-9 QUOTATION MARK", "quotedblbase"),
+ /** right double quotation mark */
+ quotedblright(0x201D, 0xBA, "RIGHT DOUBLE QUOTATION MARK", "quotedblright"),
+ /** right-pointing double angle quotation mark */
+ guillemotright(0x00BB, 0xBB, "RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK", "guillemotright"),
+ /** horizontal ellipsis character */
+ ellipsis(0x2026, 0xBC, "HORIZONTAL ELLIPSIS", "ellipsis"),
+ /** per-mille character */
+ perthousand(0x2030, 0xBD, "PER MILLE SIGN", "perthousand"),
+ /** inverted question mark */
+ questiondown(0x00BF, 0xBF, "INVERTED QUESTION MARK", "questiondown"),
+ /** grave accent character */
+ grave(0x0060, 0xC1, "GRAVE ACCENT", "grave"),
+ /** acute accent character */
+ acute(0x00B4, 0xC2, "ACUTE ACCENT", "acute"),
+ /** modifier letter circumflex accent character */
+ circumflex(0x02C6, 0xC3, "MODIFIER LETTER CIRCUMFLEX ACCENT", "circumflex"),
+ /** small tilde character */
+ tilde(0x02DC, 0xC4, "SMALL TILDE", "tilde"),
+ /** macron character */
+ macron(0x00AF, 0xC5, "MACRON", "macron"),
+ /** modifier letter macron character */
+ macron_modifier_letter(0x02C9, 0xC5, "MODIFIER LETTER MACRON", "macron"),
+ /** breve character */
+ breve(0x02D8, 0xC6, "BREVE", "breve"),
+ /** dot above character */
+ dotaccent(0x02D9, 0xC7, "DOT ABOVE", "dotaccent"),
+ /** diaeresis character */
+ dieresis(0x00A8, 0xC8, "DIAERESIS", "dieresis"),
+ /** ring above character */
+ ring(0x02DA, 0xCA, "RING ABOVE", "ring"),
+ /** cedilla character */
+ cedilla(0x00B8, 0xCB, "CEDILLA", "cedilla"),
+ /** double acute accent character */
+ hungarumlaut(0x02DD, 0xCD, "DOUBLE ACUTE ACCENT", "hungarumlaut"),
+ /** agonek character */
+ ogonek(0x02DB, 0xCE, "OGONEK", "ogonek"),
+ /** caron character */
+ caron(0x02C7, 0xCF, "CARON", "caron"),
+ /** emdash character */
+ emdash(0x2014, 0xD0, "EM DASH", "emdash"),
+ /** AE (capitalised) character */
+ AE(0x00C6, 0xE1, "LATIN CAPITAL LETTER AE", "AE"),
+ /** femenine ordinal indicator character */
+ ordfeminine(0x00AA, 0xE3, "FEMININE ORDINAL INDICATOR", "ordfeminine"),
+ /** capital letter L with stroke character */
+ Lslash(0x0141, 0xE8, "LATIN CAPITAL LETTER L WITH STROKE", "Lslash"),
+ /** capital letter O with stroke character */
+ Oslash(0x00D8, 0xE9, "LATIN CAPITAL LETTER O WITH STROKE", "Oslash"),
+ /** OE (capitalised) character */
+ OE(0x0152, 0xEA, "LATIN CAPITAL LIGATURE OE", "OE"),
+ /** masculine ordinal indicator character */
+ ordmasculine(0x00BA, 0xEB, "MASCULINE ORDINAL INDICATOR", "ordmasculine"),
+ /** ae (small) character */
+ ae(0x00E6, 0xF1, "LATIN SMALL LETTER AE", "ae"),
+ /** dotless i character */
+ dotlessi(0x0131, 0xF5, "LATIN SMALL LETTER DOTLESS I", "dotlessi"),
+ /** small letter l with stroke character */
+ lslash(0x0142, 0xF8, "LATIN SMALL LETTER L WITH STROKE", "lslash"),
+ /** small letter o with stroke character */
+ oslash(0x00F8, 0xF9, "LATIN SMALL LETTER O WITH STROKE", "oslash"),
+ /** oe (small) character */
+ oe(0x0153, 0xFA, "LATIN SMALL LIGATURE OE", "oe"),
+ /** small letter sharp s character */
+ germandbls(0x00DF, 0xFB, "LATIN SMALL LETTER SHARP S", "germandbls");
+
+ private final int unicodeIndex;
+ private final int adobeCodePoint;
+ private final String unicodeName;
+ private final String adobeName;
+
+ /** The name of the Adobe Standard Encoding as seen in an AFM file. */
+ public static final String NAME = "AdobeStandardEncoding";
+
+ private static final Map<String, AdobeStandardEncoding> CACHE
+ = new HashMap<String, AdobeStandardEncoding>();
+ static {
+ for (AdobeStandardEncoding encoding : AdobeStandardEncoding.values()) {
+ CACHE.put(encoding.getAdobeName(), encoding);
+ }
+ }
+
+ private AdobeStandardEncoding(int unicodeIndex, int adobeCodePoint, String unicodeName,
+ String adobeName) {
+ this.unicodeIndex = unicodeIndex;
+ this.adobeCodePoint = adobeCodePoint;
+ this.unicodeName = unicodeName;
+ this.adobeName = adobeName;
+ }
+
+ /**
+ * The Unicode index of this character.
+ *
+ * @return the Unicode index
+ */
+ int getUnicodeIndex() {
+ return unicodeIndex;
+ }
+
+ /**
+ * The Adobe code point of this character.
+ *
+ * @return the Adobe code point
+ */
+ int getAdobeCodePoint() {
+ return adobeCodePoint;
+ }
+
+ /**
+ * The Unicode name for this character.
+ *
+ * @return the Unicode name
+ */
+ String getUnicodeName() {
+ return unicodeName;
+ }
+
+ /**
+ * The Adobe name for this character.
+ *
+ * @return the Adobe name
+ */
+ String getAdobeName() {
+ return adobeName;
+ }
+
+ /**
+ * Returns the code point of a Adobe standard encoded character given its name. If the name
+ * cannot be found, -1 is returned.
+ *
+ * @param adobeName the name of the character
+ * @return the Adobe code point
+ */
+ public static int getAdobeCodePoint(String adobeName) {
+ AdobeStandardEncoding encoding = CACHE.get(adobeName);
+ return encoding != null ? encoding.getAdobeCodePoint() : -1;
+ }
+}
diff --git a/src/java/org/apache/fop/fonts/type1/CharMetricsHandler.java b/src/java/org/apache/fop/fonts/type1/CharMetricsHandler.java
new file mode 100644
index 000000000..8ef172875
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/type1/CharMetricsHandler.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fonts.type1;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Stack;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.fonts.NamedCharacter;
+import org.apache.fop.fonts.type1.AFMParser.ValueHandler;
+
+/**
+ * A handler that parses the various types of character metrics in an AFM file.
+ */
+abstract class CharMetricsHandler {
+
+ private static final Log LOG = LogFactory.getLog(CharMetricsHandler.class);
+
+ private static final String WHITE_SPACE = "\\s*";
+ private static final String OPERATOR = "([A-Z0-9]{1,3})";
+ private static final String OPERANDS = "(.*)";
+
+ private static final Pattern METRICS_REGEX = Pattern.compile(
+ WHITE_SPACE + OPERATOR + WHITE_SPACE + OPERANDS + WHITE_SPACE);
+ private static final Pattern SPLIT_REGEX = Pattern.compile(WHITE_SPACE + ";" + WHITE_SPACE);
+
+ private CharMetricsHandler() {
+ }
+
+ abstract AFMCharMetrics parse(String line, Stack<Object> stack, String afmFileName)
+ throws IOException;
+
+ static CharMetricsHandler getHandler(Map<String, ValueHandler> valueParsers,
+ String line) {
+ if (line != null && line.contains(AdobeStandardEncoding.NAME)) {
+ return new AdobeStandardCharMetricsHandler(valueParsers);
+ } else {
+ return new DefaultCharMetricsHandler(valueParsers);
+ }
+ }
+
+ private static final class DefaultCharMetricsHandler extends CharMetricsHandler {
+ private final Map<String, ValueHandler> valueParsers;
+
+
+ private DefaultCharMetricsHandler(Map<String, ValueHandler> valueParsers) {
+ this.valueParsers = valueParsers;
+ }
+
+ AFMCharMetrics parse(String line, Stack<Object> stack, String afmFileName)
+ throws IOException {
+ AFMCharMetrics chm = new AFMCharMetrics();
+ stack.push(chm);
+ String[] metrics = SPLIT_REGEX.split(line);
+ for (String metric : metrics) {
+ Matcher matcher = METRICS_REGEX.matcher(metric);
+ if (matcher.matches()) {
+ String operator = matcher.group(1);
+ String operands = matcher.group(2);
+ ValueHandler handler = valueParsers.get(operator);
+ if (handler != null) {
+ handler.parse(operands, 0, stack);
+ }
+ }
+ }
+ stack.pop();
+ return chm;
+ }
+ }
+
+ private static final class AdobeStandardCharMetricsHandler extends CharMetricsHandler {
+ private final DefaultCharMetricsHandler defaultHandler;
+
+ private AdobeStandardCharMetricsHandler(Map<String, ValueHandler> valueParsers) {
+ defaultHandler = new DefaultCharMetricsHandler(valueParsers);
+ }
+
+ AFMCharMetrics parse(String line, Stack<Object> stack, String afmFileName)
+ throws IOException {
+ AFMCharMetrics chm = defaultHandler.parse(line, stack, afmFileName);
+ NamedCharacter namedChar = chm.getCharacter();
+ if (namedChar != null) {
+ int codePoint = AdobeStandardEncoding.getAdobeCodePoint(namedChar.getName());
+ if (chm.getCharCode() != codePoint) {
+ LOG.info(afmFileName + ": named character '" + namedChar.getName() + "'"
+ + " has an incorrect code point: " + chm.getCharCode()
+ + ". Changed to " + codePoint);
+ chm.setCharCode(codePoint);
+ }
+ }
+ return chm;
+ }
+ }
+
+}
diff --git a/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java b/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
index 33b4ab0a1..b5b573eca 100644
--- a/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
+++ b/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
@@ -22,7 +22,7 @@ package org.apache.fop.fonts.type1;
import java.awt.geom.RectangularShape;
import java.io.IOException;
import java.io.InputStream;
-import java.util.Iterator;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -62,7 +62,7 @@ public class Type1FontLoader extends FontLoader {
return pfbURI.substring(0, pfbURI.length() - 4) + "." + pfmExt;
}
- private static final String[] AFM_EXTENSIONS = new String[] {".AFM", ".afm", ".Afm"};
+ private static final String[] AFM_EXTENSIONS = new String[] { ".AFM", ".afm", ".Afm" };
/** {@inheritDoc} */
@Override
@@ -71,22 +71,23 @@ public class Type1FontLoader extends FontLoader {
PFMFile pfm = null;
InputStream afmIn = null;
+ String afmUri = null;
for (int i = 0; i < AFM_EXTENSIONS.length; i++) {
try {
- String afmUri = this.fontFileURI.substring(0, this.fontFileURI.length() - 4)
+ afmUri = this.fontFileURI.substring(0, this.fontFileURI.length() - 4)
+ AFM_EXTENSIONS[i];
afmIn = openFontUri(resolver, afmUri);
if (afmIn != null) {
break;
}
} catch (IOException ioe) {
- //Ignore, AFM probably not available under the URI
+ // Ignore, AFM probably not available under the URI
}
}
if (afmIn != null) {
try {
AFMParser afmParser = new AFMParser();
- afm = afmParser.parse(afmIn);
+ afm = afmParser.parse(afmIn, afmUri);
} finally {
IOUtils.closeQuietly(afmIn);
}
@@ -97,7 +98,7 @@ public class Type1FontLoader extends FontLoader {
try {
pfmIn = openFontUri(resolver, pfmUri);
} catch (IOException ioe) {
- //Ignore, PFM probably not available under the URI
+ // Ignore, PFM probably not available under the URI
}
if (pfmIn != null) {
try {
@@ -105,7 +106,7 @@ public class Type1FontLoader extends FontLoader {
pfm.load(pfmIn);
} catch (IOException ioe) {
if (afm == null) {
- //Ignore the exception if we have a valid PFM. PFM is only the fallback.
+ // Ignore the exception if we have a valid PFM. PFM is only the fallback.
throw ioe;
}
} finally {
@@ -139,15 +140,13 @@ public class Type1FontLoader extends FontLoader {
}
private void handleEncoding(AFMFile afm, PFMFile pfm) {
- //Encoding
+ // Encoding
if (afm != null) {
String encoding = afm.getEncodingScheme();
singleFont.setUseNativeEncoding(true);
if ("AdobeStandardEncoding".equals(encoding)) {
singleFont.setEncoding(CodePointMapping.STANDARD_ENCODING);
addUnencodedBasedOnEncoding(afm);
- //char codes in the AFM cannot be relied on in this case, so we override
- afm.overridePrimaryEncoding(singleFont.getEncoding());
} else {
String effEncodingName;
if ("FontSpecific".equals(encoding)) {
@@ -169,7 +168,7 @@ public class Type1FontLoader extends FontLoader {
} else {
log.warn("The PFM reports an unsupported encoding ("
+ pfm.getCharSetName() + "). The font may not work as expected.");
- singleFont.setEncoding("WinAnsiEncoding"); //Try fallback, no guarantees!
+ singleFont.setEncoding("WinAnsiEncoding"); // Try fallback, no guarantees!
}
}
}
@@ -218,26 +217,26 @@ public class Type1FontLoader extends FontLoader {
}
private void handleFontName(AFMFile afm, PFMFile pfm) {
- //Font name
+ // Font name
if (afm != null) {
- returnFont.setFontName(afm.getFontName()); //PostScript font name
+ returnFont.setFontName(afm.getFontName()); // PostScript font name
returnFont.setFullName(afm.getFullName());
- Set names = new java.util.HashSet();
+ Set<String> names = new HashSet<String>();
names.add(afm.getFamilyName());
returnFont.setFamilyNames(names);
} else {
returnFont.setFontName(pfm.getPostscriptName());
String fullName = pfm.getPostscriptName();
- fullName = fullName.replace('-', ' '); //Hack! Try to emulate full name
- returnFont.setFullName(fullName); //emulate afm.getFullName()
- Set names = new java.util.HashSet();
- names.add(pfm.getWindowsName()); //emulate afm.getFamilyName()
+ fullName = fullName.replace('-', ' '); // Hack! Try to emulate full name
+ returnFont.setFullName(fullName); // emulate afm.getFullName()
+ Set<String> names = new HashSet<String>();
+ names.add(pfm.getWindowsName()); // emulate afm.getFamilyName()
returnFont.setFamilyNames(names);
}
}
private void handleMetrics(AFMFile afm, PFMFile pfm) {
- //Basic metrics
+ // Basic metrics
if (afm != null) {
if (afm.getCapHeight() != null) {
returnFont.setCapHeight(afm.getCapHeight().intValue());
@@ -256,16 +255,16 @@ public class Type1FontLoader extends FontLoader {
if (afm.getStdVW() != null) {
returnFont.setStemV(afm.getStdVW().intValue());
} else {
- returnFont.setStemV(80); //Arbitrary value
+ returnFont.setStemV(80); // Arbitrary value
}
- returnFont.setItalicAngle((int)afm.getWritingDirectionMetrics(0).getItalicAngle());
+ returnFont.setItalicAngle((int) afm.getWritingDirectionMetrics(0).getItalicAngle());
} else {
returnFont.setFontBBox(pfm.getFontBBox());
returnFont.setStemV(pfm.getStemV());
returnFont.setItalicAngle(pfm.getItalicAngle());
}
if (pfm != null) {
- //Sometimes the PFM has these metrics while the AFM doesn't (ex. Symbol)
+ // Sometimes the PFM has these metrics while the AFM doesn't (ex. Symbol)
if (returnFont.getCapHeight() == 0) {
returnFont.setCapHeight(pfm.getCapHeight());
}
@@ -280,8 +279,8 @@ public class Type1FontLoader extends FontLoader {
}
}
- //Fallbacks when some crucial font metrics aren't available
- //(the following are all optional in AFM, but FontBBox is always available)
+ // Fallbacks when some crucial font metrics aren't available
+ // (the following are all optional in AFM, but FontBBox is always available)
if (returnFont.getXHeight(1) == 0) {
int xHeight = 0;
if (afm != null) {
@@ -289,7 +288,7 @@ public class Type1FontLoader extends FontLoader {
if (chm != null) {
RectangularShape rect = chm.getBBox();
if (rect != null) {
- xHeight = (int)Math.round(rect.getMinX());
+ xHeight = (int) Math.round(rect.getMinX());
}
}
}
@@ -305,7 +304,7 @@ public class Type1FontLoader extends FontLoader {
if (chm != null) {
RectangularShape rect = chm.getBBox();
if (rect != null) {
- asc = (int)Math.round(rect.getMinX());
+ asc = (int) Math.round(rect.getMinX());
}
}
}
@@ -321,7 +320,7 @@ public class Type1FontLoader extends FontLoader {
if (chm != null) {
RectangularShape rect = chm.getBBox();
if (rect != null) {
- desc = (int)Math.round(rect.getMinX());
+ desc = (int) Math.round(rect.getMinX());
}
}
}
@@ -338,20 +337,20 @@ public class Type1FontLoader extends FontLoader {
String charSet = afm.getCharacterSet();
int flags = 0;
if ("Special".equals(charSet)) {
- flags |= 4; //bit 3: Symbolic
+ flags |= 4; // bit 3: Symbolic
} else {
if (singleFont.getEncoding().mapChar('A') == 'A') {
- //High likelyhood that the font is non-symbolic
- flags |= 32; //bit 6: Nonsymbolic
+ // High likelyhood that the font is non-symbolic
+ flags |= 32; // bit 6: Nonsymbolic
} else {
- flags |= 4; //bit 3: Symbolic
+ flags |= 4; // bit 3: Symbolic
}
}
if (afm.getWritingDirectionMetrics(0).isFixedPitch()) {
- flags |= 1; //bit 1: FixedPitch
+ flags |= 1; // bit 1: FixedPitch
}
if (afm.getWritingDirectionMetrics(0).getItalicAngle() != 0.0) {
- flags |= 64; //bit 7: Italic
+ flags |= 64; // bit 7: Italic
}
returnFont.setFlags(flags);
@@ -359,7 +358,7 @@ public class Type1FontLoader extends FontLoader {
returnFont.setLastChar(afm.getLastChar());
for (AFMCharMetrics chm : afm.getCharMetrics()) {
if (chm.hasCharCode()) {
- singleFont.setWidth(chm.getCharCode(), (int)Math.round(chm.getWidthX()));
+ singleFont.setWidth(chm.getCharCode(), (int) Math.round(chm.getWidthX()));
}
}
if (useKerning) {
@@ -379,12 +378,10 @@ public class Type1FontLoader extends FontLoader {
}
private CodePointMapping buildCustomEncoding(String encodingName, AFMFile afm) {
- List chars = afm.getCharMetrics();
int mappingCount = 0;
- //Just count the first time...
- Iterator iter = chars.iterator();
- while (iter.hasNext()) {
- AFMCharMetrics charMetrics = (AFMCharMetrics)iter.next();
+ // Just count the first time...
+ List<AFMCharMetrics> chars = afm.getCharMetrics();
+ for (AFMCharMetrics charMetrics : chars) {
if (charMetrics.getCharCode() >= 0) {
String u = charMetrics.getUnicodeSequence();
if (u != null && u.length() == 1) {
@@ -392,13 +389,11 @@ public class Type1FontLoader extends FontLoader {
}
}
}
- //...and now build the table.
+ // ...and now build the table.
int[] table = new int[mappingCount * 2];
String[] charNameMap = new String[256];
- iter = chars.iterator();
int idx = 0;
- while (iter.hasNext()) {
- AFMCharMetrics charMetrics = (AFMCharMetrics)iter.next();
+ for (AFMCharMetrics charMetrics : chars) {
if (charMetrics.getCharCode() >= 0) {
charNameMap[charMetrics.getCharCode()] = charMetrics.getCharName();
String unicodes = charMetrics.getUnicodeSequence();