git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1204488 13f79535-47bb-0310-9956-ffa450edef68pull/18/head
<copy todir="${build.unit.tests.dir}"> | <copy todir="${build.unit.tests.dir}"> | ||||
<fileset dir="${test.dir}/java"> | <fileset dir="${test.dir}/java"> | ||||
<include name="**/*.xsl"/> | <include name="**/*.xsl"/> | ||||
<include name="**/*.txt"/> | |||||
<include name="**/*.afm"/> | |||||
<include name="**/*.fo"/> | |||||
</fileset> | </fileset> | ||||
</copy> | </copy> | ||||
</target> | </target> |
import java.awt.Rectangle; | import java.awt.Rectangle; | ||||
import java.beans.Statement; | import java.beans.Statement; | ||||
import java.io.BufferedReader; | import java.io.BufferedReader; | ||||
import java.io.File; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.InputStream; | import java.io.InputStream; | ||||
import java.io.Reader; | import java.io.Reader; | ||||
import java.util.HashMap; | |||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Stack; | import java.util.Stack; | ||||
private static final int PARSE_NORMAL = 0; | private static final int PARSE_NORMAL = 0; | ||||
private static final int PARSE_CHAR_METRICS = 1; | 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 { | static { | ||||
VALUE_PARSERS = new java.util.HashMap(); | |||||
VALUE_PARSERS = new HashMap<String, ValueHandler>(); | |||||
VALUE_PARSERS.put(START_FONT_METRICS, new StartFontMetrics()); | VALUE_PARSERS.put(START_FONT_METRICS, new StartFontMetrics()); | ||||
VALUE_PARSERS.put(FONT_NAME, new StringSetter(FONT_NAME)); | VALUE_PARSERS.put(FONT_NAME, new StringSetter(FONT_NAME)); | ||||
VALUE_PARSERS.put(FULL_NAME, new StringSetter(FULL_NAME)); | VALUE_PARSERS.put(FULL_NAME, new StringSetter(FULL_NAME)); | ||||
VALUE_PARSERS.put(KPX, new KPXHandler()); | VALUE_PARSERS.put(KPX, new KPXHandler()); | ||||
VALUE_PARSERS.put(KPY, new NotImplementedYet(KPY)); | 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(START_CHAR_METRICS, new Integer(PARSE_CHAR_METRICS)); | ||||
PARSE_MODE_CHANGES.put(END_CHAR_METRICS, new Integer(PARSE_NORMAL)); | PARSE_MODE_CHANGES.put(END_CHAR_METRICS, new Integer(PARSE_NORMAL)); | ||||
} | } | ||||
* Main constructor. | * Main constructor. | ||||
*/ | */ | ||||
public AFMParser() { | 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. | * Parses an AFM file from a stream. | ||||
* @param in the stream to read from | * @param in the stream to read from | ||||
* @param afmFileName the name of the AFM file | |||||
* @return the parsed AFM file | * @return the parsed AFM file | ||||
* @throws IOException if an I/O error occurs | * @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"); | Reader reader = new java.io.InputStreamReader(in, "US-ASCII"); | ||||
try { | try { | ||||
return parse(new BufferedReader(reader)); | |||||
return parse(new BufferedReader(reader), afmFileName); | |||||
} finally { | } finally { | ||||
IOUtils.closeQuietly(reader); | IOUtils.closeQuietly(reader); | ||||
} | } | ||||
/** | /** | ||||
* Parses an AFM file from a BufferedReader. | * Parses an AFM file from a BufferedReader. | ||||
* @param reader the BufferedReader instance to read from | * @param reader the BufferedReader instance to read from | ||||
* @param afmFileName the name of the AFM file | |||||
* @return the parsed AFM file | * @return the parsed AFM file | ||||
* @throws IOException if an I/O error occurs | * @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; | int parseMode = PARSE_NORMAL; | ||||
while (true) { | while (true) { | ||||
String line = reader.readLine(); | String line = reader.readLine(); | ||||
key = parseLine(line, stack); | key = parseLine(line, stack); | ||||
break; | break; | ||||
case PARSE_CHAR_METRICS: | case PARSE_CHAR_METRICS: | ||||
key = parseCharMetrics(line, stack); | |||||
key = parseCharMetrics(line, stack, afmFileName); | |||||
break; | break; | ||||
default: | default: | ||||
throw new IllegalStateException("Invalid parse mode"); | throw new IllegalStateException("Invalid parse mode"); | ||||
} | } | ||||
Integer newParseMode = (Integer)PARSE_MODE_CHANGES.get(key); | |||||
Integer newParseMode = PARSE_MODE_CHANGES.get(key); | |||||
if (newParseMode != null) { | if (newParseMode != null) { | ||||
parseMode = newParseMode.intValue(); | parseMode = newParseMode.intValue(); | ||||
} | } | ||||
return (AFMFile)stack.pop(); | 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; | int startpos = 0; | ||||
//Find key | //Find key | ||||
startpos = skipToNonWhiteSpace(line, startpos); | startpos = skipToNonWhiteSpace(line, startpos); | ||||
//Parse value | //Parse value | ||||
startpos = skipToNonWhiteSpace(line, endpos); | startpos = skipToNonWhiteSpace(line, endpos); | ||||
ValueHandler vp = (ValueHandler)VALUE_PARSERS.get(key); | |||||
ValueHandler vp = VALUE_PARSERS.get(key); | |||||
if (vp != null) { | if (vp != null) { | ||||
vp.parse(line, startpos, stack); | vp.parse(line, startpos, stack); | ||||
} | } | ||||
return key; | 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); | afm.addCharMetrics(chm); | ||||
return null; | return null; | ||||
} | } | ||||
return pos; | 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) { | private static boolean isWhitespace(char ch) { | ||||
return ch == ' ' | return ch == ' ' | ||||
|| ch == '\t'; | || ch == '\t'; | ||||
// ---------------- Value Handlers --------------------------- | // ---------------- 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 { | private abstract static class AbstractValueHandler implements ValueHandler { | ||||
} | } | ||||
private static class StartFontMetrics extends AbstractValueHandler { | 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); | int endpos = findValue(line, startpos); | ||||
double version = Double.parseDouble(line.substring(startpos, endpos)); | double version = Double.parseDouble(line.substring(startpos, endpos)); | ||||
if (version < 2) { | if (version < 2) { | ||||
super(variable); | 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); | String s = getStringValue(line, startpos); | ||||
Object obj = stack.peek(); | Object obj = stack.peek(); | ||||
setValue(obj, s); | setValue(obj, s); | ||||
super(variable); | 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)); | NamedCharacter ch = new NamedCharacter(getStringValue(line, startpos)); | ||||
Object obj = stack.peek(); | Object obj = stack.peek(); | ||||
setValue(obj, ch); | setValue(obj, ch); | ||||
super(variable); | super(variable); | ||||
} | } | ||||
protected Object getContextObject(Stack stack) { | |||||
protected Object getContextObject(Stack<Object> stack) { | |||||
return stack.peek(); | 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); | Number num = getNumberValue(line, startpos); | ||||
setValue(getContextObject(stack), num); | setValue(getContextObject(stack), num); | ||||
} | } | ||||
super(variable); | 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); | int value = getIntegerValue(line, startpos); | ||||
setValue(getContextObject(stack), new Integer(value)); | setValue(getContextObject(stack), new Integer(value)); | ||||
} | } | ||||
super(variable); | 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); | double value = getDoubleValue(line, startpos); | ||||
setValue(getContextObject(stack), new Double(value)); | setValue(getContextObject(stack), new Double(value)); | ||||
} | } | ||||
super(variable); | super(variable); | ||||
} | } | ||||
protected Object getContextObject(Stack stack) { | |||||
protected Object getContextObject(Stack<Object> stack) { | |||||
if (stack.peek() instanceof AFMWritingDirectionMetrics) { | if (stack.peek() instanceof AFMWritingDirectionMetrics) { | ||||
return (AFMWritingDirectionMetrics)stack.peek(); | return (AFMWritingDirectionMetrics)stack.peek(); | ||||
} else { | } else { | ||||
super(variable); | 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); | double value = getDoubleValue(line, startpos); | ||||
setValue(getContextObject(stack), new Double(value)); | setValue(getContextObject(stack), new Double(value)); | ||||
} | } | ||||
this.method = "set" + variable.substring(2); //Cut "Is" in front | 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(); | 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); | Boolean b = getBooleanValue(line, startpos); | ||||
//Uses Java Beans API | //Uses Java Beans API | ||||
Statement statement = new Statement(getContextObject(stack), | Statement statement = new Statement(getContextObject(stack), | ||||
super(variable); | super(variable); | ||||
} | } | ||||
protected Object getContextObject(Stack stack) { | |||||
protected Object getContextObject(Stack<Object> stack) { | |||||
if (stack.peek() instanceof AFMWritingDirectionMetrics) { | if (stack.peek() instanceof AFMWritingDirectionMetrics) { | ||||
return (AFMWritingDirectionMetrics)stack.peek(); | return (AFMWritingDirectionMetrics)stack.peek(); | ||||
} else { | } else { | ||||
} | } | ||||
private static class FontBBox extends AbstractValueHandler { | 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); | Rectangle rect = parseBBox(line, startpos); | ||||
AFMFile afm = (AFMFile)stack.peek(); | AFMFile afm = (AFMFile)stack.peek(); | ||||
} | } | ||||
private static class CharBBox extends FontBBox { | 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); | Rectangle rect = parseBBox(line, startpos); | ||||
AFMCharMetrics metrics = (AFMCharMetrics)stack.peek(); | AFMCharMetrics metrics = (AFMCharMetrics)stack.peek(); | ||||
} | } | ||||
private static class IsBaseFont extends AbstractValueHandler { | 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()) { | if (getBooleanValue(line, startpos).booleanValue()) { | ||||
throw new IOException("Only base fonts are currently supported!"); | throw new IOException("Only base fonts are currently supported!"); | ||||
} | } | ||||
} | } | ||||
private static class IsCIDFont extends AbstractValueHandler { | 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()) { | if (getBooleanValue(line, startpos).booleanValue()) { | ||||
throw new IOException("CID fonts are currently not supported!"); | throw new IOException("CID fonts are currently not supported!"); | ||||
} | } | ||||
} | } | ||||
private static class StartDirection extends AbstractValueHandler { | 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); | int index = getIntegerValue(line, startpos); | ||||
AFMWritingDirectionMetrics wdm = new AFMWritingDirectionMetrics(); | AFMWritingDirectionMetrics wdm = new AFMWritingDirectionMetrics(); | ||||
AFMFile afm = (AFMFile)stack.peek(); | AFMFile afm = (AFMFile)stack.peek(); | ||||
} | } | ||||
private static class EndDirection extends AbstractValueHandler { | 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)) { | if (!(stack.pop() instanceof AFMWritingDirectionMetrics)) { | ||||
throw new IOException("AFM format error: nesting incorrect"); | throw new IOException("AFM format error: nesting incorrect"); | ||||
} | } | ||||
} | } | ||||
private static class KPXHandler extends AbstractValueHandler { | 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(); | AFMFile afm = (AFMFile)stack.peek(); | ||||
int endpos; | int endpos; | ||||
/* | |||||
* 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; | |||||
} | |||||
} |
/* | |||||
* 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; | |||||
} | |||||
} | |||||
} |
import java.awt.geom.RectangularShape; | import java.awt.geom.RectangularShape; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.InputStream; | import java.io.InputStream; | ||||
import java.util.Iterator; | |||||
import java.util.HashSet; | |||||
import java.util.List; | import java.util.List; | ||||
import java.util.Set; | import java.util.Set; | ||||
return pfbURI.substring(0, pfbURI.length() - 4) + "." + pfmExt; | 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} */ | /** {@inheritDoc} */ | ||||
@Override | @Override | ||||
PFMFile pfm = null; | PFMFile pfm = null; | ||||
InputStream afmIn = null; | InputStream afmIn = null; | ||||
String afmUri = null; | |||||
for (int i = 0; i < AFM_EXTENSIONS.length; i++) { | for (int i = 0; i < AFM_EXTENSIONS.length; i++) { | ||||
try { | try { | ||||
String afmUri = this.fontFileURI.substring(0, this.fontFileURI.length() - 4) | |||||
afmUri = this.fontFileURI.substring(0, this.fontFileURI.length() - 4) | |||||
+ AFM_EXTENSIONS[i]; | + AFM_EXTENSIONS[i]; | ||||
afmIn = openFontUri(resolver, afmUri); | afmIn = openFontUri(resolver, afmUri); | ||||
if (afmIn != null) { | if (afmIn != null) { | ||||
break; | break; | ||||
} | } | ||||
} catch (IOException ioe) { | } catch (IOException ioe) { | ||||
//Ignore, AFM probably not available under the URI | |||||
// Ignore, AFM probably not available under the URI | |||||
} | } | ||||
} | } | ||||
if (afmIn != null) { | if (afmIn != null) { | ||||
try { | try { | ||||
AFMParser afmParser = new AFMParser(); | AFMParser afmParser = new AFMParser(); | ||||
afm = afmParser.parse(afmIn); | |||||
afm = afmParser.parse(afmIn, afmUri); | |||||
} finally { | } finally { | ||||
IOUtils.closeQuietly(afmIn); | IOUtils.closeQuietly(afmIn); | ||||
} | } | ||||
try { | try { | ||||
pfmIn = openFontUri(resolver, pfmUri); | pfmIn = openFontUri(resolver, pfmUri); | ||||
} catch (IOException ioe) { | } catch (IOException ioe) { | ||||
//Ignore, PFM probably not available under the URI | |||||
// Ignore, PFM probably not available under the URI | |||||
} | } | ||||
if (pfmIn != null) { | if (pfmIn != null) { | ||||
try { | try { | ||||
pfm.load(pfmIn); | pfm.load(pfmIn); | ||||
} catch (IOException ioe) { | } catch (IOException ioe) { | ||||
if (afm == null) { | 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; | throw ioe; | ||||
} | } | ||||
} finally { | } finally { | ||||
} | } | ||||
private void handleEncoding(AFMFile afm, PFMFile pfm) { | private void handleEncoding(AFMFile afm, PFMFile pfm) { | ||||
//Encoding | |||||
// Encoding | |||||
if (afm != null) { | if (afm != null) { | ||||
String encoding = afm.getEncodingScheme(); | String encoding = afm.getEncodingScheme(); | ||||
singleFont.setUseNativeEncoding(true); | singleFont.setUseNativeEncoding(true); | ||||
if ("AdobeStandardEncoding".equals(encoding)) { | if ("AdobeStandardEncoding".equals(encoding)) { | ||||
singleFont.setEncoding(CodePointMapping.STANDARD_ENCODING); | singleFont.setEncoding(CodePointMapping.STANDARD_ENCODING); | ||||
addUnencodedBasedOnEncoding(afm); | addUnencodedBasedOnEncoding(afm); | ||||
//char codes in the AFM cannot be relied on in this case, so we override | |||||
afm.overridePrimaryEncoding(singleFont.getEncoding()); | |||||
} else { | } else { | ||||
String effEncodingName; | String effEncodingName; | ||||
if ("FontSpecific".equals(encoding)) { | if ("FontSpecific".equals(encoding)) { | ||||
} else { | } else { | ||||
log.warn("The PFM reports an unsupported encoding (" | log.warn("The PFM reports an unsupported encoding (" | ||||
+ pfm.getCharSetName() + "). The font may not work as expected."); | + pfm.getCharSetName() + "). The font may not work as expected."); | ||||
singleFont.setEncoding("WinAnsiEncoding"); //Try fallback, no guarantees! | |||||
singleFont.setEncoding("WinAnsiEncoding"); // Try fallback, no guarantees! | |||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
private void handleFontName(AFMFile afm, PFMFile pfm) { | private void handleFontName(AFMFile afm, PFMFile pfm) { | ||||
//Font name | |||||
// Font name | |||||
if (afm != null) { | if (afm != null) { | ||||
returnFont.setFontName(afm.getFontName()); //PostScript font name | |||||
returnFont.setFontName(afm.getFontName()); // PostScript font name | |||||
returnFont.setFullName(afm.getFullName()); | returnFont.setFullName(afm.getFullName()); | ||||
Set names = new java.util.HashSet(); | |||||
Set<String> names = new HashSet<String>(); | |||||
names.add(afm.getFamilyName()); | names.add(afm.getFamilyName()); | ||||
returnFont.setFamilyNames(names); | returnFont.setFamilyNames(names); | ||||
} else { | } else { | ||||
returnFont.setFontName(pfm.getPostscriptName()); | returnFont.setFontName(pfm.getPostscriptName()); | ||||
String fullName = 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); | returnFont.setFamilyNames(names); | ||||
} | } | ||||
} | } | ||||
private void handleMetrics(AFMFile afm, PFMFile pfm) { | private void handleMetrics(AFMFile afm, PFMFile pfm) { | ||||
//Basic metrics | |||||
// Basic metrics | |||||
if (afm != null) { | if (afm != null) { | ||||
if (afm.getCapHeight() != null) { | if (afm.getCapHeight() != null) { | ||||
returnFont.setCapHeight(afm.getCapHeight().intValue()); | returnFont.setCapHeight(afm.getCapHeight().intValue()); | ||||
if (afm.getStdVW() != null) { | if (afm.getStdVW() != null) { | ||||
returnFont.setStemV(afm.getStdVW().intValue()); | returnFont.setStemV(afm.getStdVW().intValue()); | ||||
} else { | } 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 { | } else { | ||||
returnFont.setFontBBox(pfm.getFontBBox()); | returnFont.setFontBBox(pfm.getFontBBox()); | ||||
returnFont.setStemV(pfm.getStemV()); | returnFont.setStemV(pfm.getStemV()); | ||||
returnFont.setItalicAngle(pfm.getItalicAngle()); | returnFont.setItalicAngle(pfm.getItalicAngle()); | ||||
} | } | ||||
if (pfm != null) { | 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) { | if (returnFont.getCapHeight() == 0) { | ||||
returnFont.setCapHeight(pfm.getCapHeight()); | returnFont.setCapHeight(pfm.getCapHeight()); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
//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) { | if (returnFont.getXHeight(1) == 0) { | ||||
int xHeight = 0; | int xHeight = 0; | ||||
if (afm != null) { | if (afm != null) { | ||||
if (chm != null) { | if (chm != null) { | ||||
RectangularShape rect = chm.getBBox(); | RectangularShape rect = chm.getBBox(); | ||||
if (rect != null) { | if (rect != null) { | ||||
xHeight = (int)Math.round(rect.getMinX()); | |||||
xHeight = (int) Math.round(rect.getMinX()); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
if (chm != null) { | if (chm != null) { | ||||
RectangularShape rect = chm.getBBox(); | RectangularShape rect = chm.getBBox(); | ||||
if (rect != null) { | if (rect != null) { | ||||
asc = (int)Math.round(rect.getMinX()); | |||||
asc = (int) Math.round(rect.getMinX()); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
if (chm != null) { | if (chm != null) { | ||||
RectangularShape rect = chm.getBBox(); | RectangularShape rect = chm.getBBox(); | ||||
if (rect != null) { | if (rect != null) { | ||||
desc = (int)Math.round(rect.getMinX()); | |||||
desc = (int) Math.round(rect.getMinX()); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
String charSet = afm.getCharacterSet(); | String charSet = afm.getCharacterSet(); | ||||
int flags = 0; | int flags = 0; | ||||
if ("Special".equals(charSet)) { | if ("Special".equals(charSet)) { | ||||
flags |= 4; //bit 3: Symbolic | |||||
flags |= 4; // bit 3: Symbolic | |||||
} else { | } else { | ||||
if (singleFont.getEncoding().mapChar('A') == 'A') { | 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 { | } else { | ||||
flags |= 4; //bit 3: Symbolic | |||||
flags |= 4; // bit 3: Symbolic | |||||
} | } | ||||
} | } | ||||
if (afm.getWritingDirectionMetrics(0).isFixedPitch()) { | if (afm.getWritingDirectionMetrics(0).isFixedPitch()) { | ||||
flags |= 1; //bit 1: FixedPitch | |||||
flags |= 1; // bit 1: FixedPitch | |||||
} | } | ||||
if (afm.getWritingDirectionMetrics(0).getItalicAngle() != 0.0) { | if (afm.getWritingDirectionMetrics(0).getItalicAngle() != 0.0) { | ||||
flags |= 64; //bit 7: Italic | |||||
flags |= 64; // bit 7: Italic | |||||
} | } | ||||
returnFont.setFlags(flags); | returnFont.setFlags(flags); | ||||
returnFont.setLastChar(afm.getLastChar()); | returnFont.setLastChar(afm.getLastChar()); | ||||
for (AFMCharMetrics chm : afm.getCharMetrics()) { | for (AFMCharMetrics chm : afm.getCharMetrics()) { | ||||
if (chm.hasCharCode()) { | if (chm.hasCharCode()) { | ||||
singleFont.setWidth(chm.getCharCode(), (int)Math.round(chm.getWidthX())); | |||||
singleFont.setWidth(chm.getCharCode(), (int) Math.round(chm.getWidthX())); | |||||
} | } | ||||
} | } | ||||
if (useKerning) { | if (useKerning) { | ||||
} | } | ||||
private CodePointMapping buildCustomEncoding(String encodingName, AFMFile afm) { | private CodePointMapping buildCustomEncoding(String encodingName, AFMFile afm) { | ||||
List chars = afm.getCharMetrics(); | |||||
int mappingCount = 0; | 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) { | if (charMetrics.getCharCode() >= 0) { | ||||
String u = charMetrics.getUnicodeSequence(); | String u = charMetrics.getUnicodeSequence(); | ||||
if (u != null && u.length() == 1) { | if (u != null && u.length() == 1) { | ||||
} | } | ||||
} | } | ||||
} | } | ||||
//...and now build the table. | |||||
// ...and now build the table. | |||||
int[] table = new int[mappingCount * 2]; | int[] table = new int[mappingCount * 2]; | ||||
String[] charNameMap = new String[256]; | String[] charNameMap = new String[256]; | ||||
iter = chars.iterator(); | |||||
int idx = 0; | int idx = 0; | ||||
while (iter.hasNext()) { | |||||
AFMCharMetrics charMetrics = (AFMCharMetrics)iter.next(); | |||||
for (AFMCharMetrics charMetrics : chars) { | |||||
if (charMetrics.getCharCode() >= 0) { | if (charMetrics.getCharCode() >= 0) { | ||||
charNameMap[charMetrics.getCharCode()] = charMetrics.getCharName(); | charNameMap[charMetrics.getCharCode()] = charMetrics.getCharName(); | ||||
String unicodes = charMetrics.getUnicodeSequence(); | String unicodes = charMetrics.getUnicodeSequence(); |
<person name="Manuel Mall" email="manuel@apache.org" id="MM"/> | <person name="Manuel Mall" email="manuel@apache.org" id="MM"/> | ||||
<person name="Jeremias Märki" email="jeremias@apache.org" id="JM"/> | <person name="Jeremias Märki" email="jeremias@apache.org" id="JM"/> | ||||
<person name="Simon Pepping" email="spepping@apache.org" id="SP"/> | <person name="Simon Pepping" email="spepping@apache.org" id="SP"/> | ||||
<person name="Mehdi Houshmand" email="mehdi@apache.org" id="MH"/> | |||||
<person name="the FOP committers" email="fop-dev@xmlgraphics.apache.org" id="all"/> | <person name="the FOP committers" email="fop-dev@xmlgraphics.apache.org" id="all"/> | ||||
<person name="Volunteer needed" email="general@xmlgraphics.apache.org" id="open"/> | <person name="Volunteer needed" email="general@xmlgraphics.apache.org" id="open"/> | ||||
<!-- See also src/documentation/content/xdocs/team.xml --> | <!-- See also src/documentation/content/xdocs/team.xml --> | ||||
documents. Example: the fix of marks layering will be such a case when it's done. | documents. Example: the fix of marks layering will be such a case when it's done. | ||||
--> | --> | ||||
<release version="FOP Trunk" date="TBD"> | <release version="FOP Trunk" date="TBD"> | ||||
<action context="Code" dev="MH" type="add" fixes-bug="52197"> | |||||
Improved AdobeStandardEncoding support in AFM files for type1 fonts | |||||
</action> | |||||
<action context="Code" dev="VH" type="add" fixes-bug="52151" due-to="Mehdi Houshmand"> | <action context="Code" dev="VH" type="add" fixes-bug="52151" due-to="Mehdi Houshmand"> | ||||
Added ant script to get JaCoCo code coverage. | Added ant script to get JaCoCo code coverage. | ||||
</action> | </action> |
<renderer mime="application/pdf"> | <renderer mime="application/pdf"> | ||||
<fonts> | <fonts> | ||||
<!-- this font has an embed-url that does not exist on filesystem --> | <!-- this font has an embed-url that does not exist on filesystem --> | ||||
<font metrics-url="test/resources/fonts/glb12.ttf.xml" embed-url="test/resources/fonts/doesnotexist.ttf"> | |||||
<font metrics-url="test/resources/fonts/ttf/glb12.ttf.xml" embed-url="test/resources/fonts/ttf/doesnotexist.ttf"> | |||||
<font-triplet name="Gladiator-Ansi" style="normal" weight="normal"/> | <font-triplet name="Gladiator-Ansi" style="normal" weight="normal"/> | ||||
</font> | </font> | ||||
</fonts> | </fonts> |
<renderer mime="application/pdf"> | <renderer mime="application/pdf"> | ||||
<fonts> | <fonts> | ||||
<!-- this font has a malformed embed-url --> | <!-- this font has a malformed embed-url --> | ||||
<font metrics-url="test/resources/fonts/glb12.ttf.xml" embed-url="badprotocol:test/resources/fonts/glb12.ttf"> | |||||
<font metrics-url="test/resources/fonts/ttf/glb12.ttf.xml" embed-url="badprotocol:test/resources/fonts/ttf/glb12.ttf"> | |||||
<font-triplet name="Gladiator-Ansi" style="normal" weight="normal"/> | <font-triplet name="Gladiator-Ansi" style="normal" weight="normal"/> | ||||
</font> | </font> | ||||
</fonts> | </fonts> |
<renderer mime="application/pdf"> | <renderer mime="application/pdf"> | ||||
<fonts> | <fonts> | ||||
<!-- this font has a metrics-url that does not exist on filesystem --> | <!-- this font has a metrics-url that does not exist on filesystem --> | ||||
<font metrics-url="test/resources/fonts/doesnotexist.ttf.ansi.xml"> | |||||
<font metrics-url="test/resources/fonts/ttf/doesnotexist.ttf.ansi.xml"> | |||||
<font-triplet name="Gladiator-Ansi" style="normal" weight="normal"/> | <font-triplet name="Gladiator-Ansi" style="normal" weight="normal"/> | ||||
</font> | </font> | ||||
</fonts> | </fonts> |
<renderer mime="application/pdf"> | <renderer mime="application/pdf"> | ||||
<fonts> | <fonts> | ||||
<!-- this font has a malformed metrics-url --> | <!-- this font has a malformed metrics-url --> | ||||
<font metrics-url="badprotocol:test/resources/fonts/glb12.ttf.xml"> | |||||
<font metrics-url="badprotocol:test/resources/fonts/ttf/glb12.ttf.xml"> | |||||
<font-triplet name="Gladiator" style="normal" weight="normal"/> | <font-triplet name="Gladiator" style="normal" weight="normal"/> | ||||
</font> | </font> | ||||
</fonts> | </fonts> |
<renderers> | <renderers> | ||||
<renderer mime="application/pdf"> | <renderer mime="application/pdf"> | ||||
<fonts> | <fonts> | ||||
<font metrics-url="test/resources/fonts/glb12.ttf.xml"> | |||||
<font metrics-url="test/resources/fonts/ttf/glb12.ttf.xml"> | |||||
<!-- this font-triplet has a missing style attribute --> | <!-- this font-triplet has a missing style attribute --> | ||||
<font-triplet name="Gladiator" weight="normal"/> | <font-triplet name="Gladiator" weight="normal"/> | ||||
</font> | </font> |
<fonts> | <fonts> | ||||
<!-- this font is with a relative metrics-url | <!-- this font is with a relative metrics-url | ||||
so should call upon the bad font-base --> | so should call upon the bad font-base --> | ||||
<font metrics-url="test/resources/fonts/glb12.ttf.xml" embed-url="test/resources/fonts/glb12.ttf"> | |||||
<font metrics-url="test/resources/fonts/ttf/glb12.ttf.xml" embed-url="test/resources/fonts/ttf/glb12.ttf"> | |||||
<font-triplet name="Gladiator" style="normal" weight="normal"/> | <font-triplet name="Gladiator" style="normal" weight="normal"/> | ||||
</font> | </font> | ||||
</fonts> | </fonts> |
<renderers> | <renderers> | ||||
<renderer mime="application/pdf"> | <renderer mime="application/pdf"> | ||||
<fonts> | <fonts> | ||||
<font metrics-url="test/resources/fonts/glb12.ttf.xml" embed-url="test/resources/fonts/glb12.ttf"> | |||||
<font metrics-url="test/resources/fonts/ttf/glb12.ttf.xml" embed-url="test/resources/fonts/ttf/glb12.ttf"> | |||||
<font-triplet name="Gladiator" style="normal" weight="bold"/> | <font-triplet name="Gladiator" style="normal" weight="bold"/> | ||||
</font> | </font> | ||||
</fonts> | </fonts> |
<?xml version="1.0" standalone="no"?> | |||||
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> | |||||
<fo:layout-master-set> | |||||
<fo:simple-page-master master-name="page" | |||||
page-height="420pt" page-width="320pt" margin="10pt"> | |||||
<fo:region-body background-color="#F0F0F0"/> | |||||
</fo:simple-page-master> | |||||
</fo:layout-master-set> | |||||
<fo:page-sequence master-reference="page"> | |||||
<fo:flow flow-name="xsl-region-body"> | |||||
<fo:block font-family="blah">This block uses an unknown font.</fo:block> | |||||
</fo:flow> | |||||
</fo:page-sequence> | |||||
</fo:root> |
import org.apache.fop.afp.parser.MODCAParserTestCase; | import org.apache.fop.afp.parser.MODCAParserTestCase; | ||||
import org.apache.fop.area.ViewportTestSuite; | import org.apache.fop.area.ViewportTestSuite; | ||||
import org.apache.fop.fonts.DejaVuLGCSerifTestCase; | import org.apache.fop.fonts.DejaVuLGCSerifTestCase; | ||||
import org.apache.fop.fonts.FontEventProcessingTestCase; | |||||
import org.apache.fop.fonts.truetype.GlyfTableTestCase; | import org.apache.fop.fonts.truetype.GlyfTableTestCase; | ||||
import org.apache.fop.fonts.type1.AFMParserTestCase; | |||||
import org.apache.fop.fonts.type1.AdobeStandardEncodingTestCase; | |||||
import org.apache.fop.image.loader.batik.ImageLoaderTestCase; | import org.apache.fop.image.loader.batik.ImageLoaderTestCase; | ||||
import org.apache.fop.image.loader.batik.ImagePreloaderTestCase; | import org.apache.fop.image.loader.batik.ImagePreloaderTestCase; | ||||
import org.apache.fop.intermediate.IFMimickingTestCase; | import org.apache.fop.intermediate.IFMimickingTestCase; | ||||
*/ | */ | ||||
@RunWith(Suite.class) | @RunWith(Suite.class) | ||||
@SuiteClasses({ | @SuiteClasses({ | ||||
BasicDriverTestSuite.class, | |||||
UtilityCodeTestSuite.class, | |||||
PDFAConformanceTestCase.class, | |||||
PDFEncodingTestCase.class, | |||||
PDFCMapTestCase.class, | |||||
PDFsRGBSettingsTestCase.class, | |||||
DejaVuLGCSerifTestCase.class, | |||||
RichTextFormatTestSuite.class, | |||||
ImageLoaderTestCase.class, | |||||
ImagePreloaderTestCase.class, | |||||
IFMimickingTestCase.class, | |||||
PageBoundariesTestCase.class, | |||||
PageScaleTestCase.class, | |||||
org.apache.fop.afp.AFPTestSuite.class, | |||||
GlyfTableTestCase.class, | |||||
ViewportTestSuite.class, | |||||
RenderPDFTestSuite.class, | |||||
MODCAParserTestCase.class, | |||||
CharactersetEncoderTestCase.class, | |||||
org.apache.fop.render.afp.AFPTestSuite.class, | |||||
PSTestSuite.class, | |||||
MinOptMaxTestCase.class | |||||
BasicDriverTestSuite.class, | |||||
UtilityCodeTestSuite.class, | |||||
PDFAConformanceTestCase.class, | |||||
PDFEncodingTestCase.class, | |||||
PDFCMapTestCase.class, | |||||
PDFsRGBSettingsTestCase.class, | |||||
DejaVuLGCSerifTestCase.class, | |||||
RichTextFormatTestSuite.class, | |||||
ImageLoaderTestCase.class, | |||||
ImagePreloaderTestCase.class, | |||||
IFMimickingTestCase.class, | |||||
PageBoundariesTestCase.class, | |||||
PageScaleTestCase.class, | |||||
org.apache.fop.afp.AFPTestSuite.class, | |||||
GlyfTableTestCase.class, | |||||
ViewportTestSuite.class, | |||||
RenderPDFTestSuite.class, | |||||
MODCAParserTestCase.class, | |||||
CharactersetEncoderTestCase.class, | |||||
org.apache.fop.render.afp.AFPTestSuite.class, | |||||
PSTestSuite.class, | |||||
MinOptMaxTestCase.class, | |||||
AdobeStandardEncodingTestCase.class, | |||||
AFMParserTestCase.class, | |||||
FontEventProcessingTestCase.class | |||||
}) | }) | ||||
public class StandardTestSuite { | public class StandardTestSuite { | ||||
} | } |
package org.apache.fop.events; | package org.apache.fop.events; | ||||
import java.io.File; | |||||
import java.io.FileInputStream; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.InputStream; | |||||
import javax.xml.transform.Result; | import javax.xml.transform.Result; | ||||
import javax.xml.transform.Source; | import javax.xml.transform.Source; | ||||
import org.apache.fop.area.AreaEventProducer; | import org.apache.fop.area.AreaEventProducer; | ||||
import org.apache.fop.fo.FOValidationEventProducer; | import org.apache.fop.fo.FOValidationEventProducer; | ||||
import org.apache.fop.fo.flow.table.TableEventProducer; | import org.apache.fop.fo.flow.table.TableEventProducer; | ||||
import org.apache.fop.fonts.FontEventProducer; | |||||
import org.apache.fop.layoutmgr.BlockLevelEventProducer; | import org.apache.fop.layoutmgr.BlockLevelEventProducer; | ||||
import org.apache.fop.layoutmgr.inline.InlineLevelEventProducer; | import org.apache.fop.layoutmgr.inline.InlineLevelEventProducer; | ||||
private final TransformerFactory tFactory = TransformerFactory.newInstance(); | private final TransformerFactory tFactory = TransformerFactory.newInstance(); | ||||
private void doTest(String filename, String fopConf, String expectedEventID) | |||||
private static final String BASE_DIR = "test/events/"; | |||||
public void doTest(InputStream inStream, String fopConf, String expectedEventID) | |||||
throws FOPException, TransformerException, IOException, SAXException { | throws FOPException, TransformerException, IOException, SAXException { | ||||
EventChecker eventChecker = new EventChecker(expectedEventID); | EventChecker eventChecker = new EventChecker(expectedEventID); | ||||
if (fopConf != null) { | if (fopConf != null) { | ||||
userAgent.getEventBroadcaster().addEventListener(eventChecker); | userAgent.getEventBroadcaster().addEventListener(eventChecker); | ||||
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent, new NullOutputStream()); | Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent, new NullOutputStream()); | ||||
Transformer transformer = tFactory.newTransformer(); | Transformer transformer = tFactory.newTransformer(); | ||||
Source src = new StreamSource(new File("test/events/" + filename)); | |||||
Source src = new StreamSource(inStream); | |||||
Result res = new SAXResult(fop.getDefaultHandler()); | Result res = new SAXResult(fop.getDefaultHandler()); | ||||
transformer.transform(src, res); | transformer.transform(src, res); | ||||
eventChecker.end(); | eventChecker.end(); | ||||
} | } | ||||
private void doTest(String filename, String expectedEventID) throws | |||||
public void doTest(String filename, String expectedEventID) throws | |||||
FOPException, TransformerException, IOException, SAXException { | FOPException, TransformerException, IOException, SAXException { | ||||
doTest(filename, null, expectedEventID); | doTest(filename, null, expectedEventID); | ||||
} | } | ||||
public void doTest(String filename, String fopConf, String expectedEventID) throws | |||||
FOPException, TransformerException, IOException, SAXException { | |||||
doTest(new FileInputStream(BASE_DIR + filename), fopConf, expectedEventID); | |||||
} | |||||
@Test | @Test | ||||
public void testArea() throws TransformerException, IOException, SAXException { | public void testArea() throws TransformerException, IOException, SAXException { | ||||
doTest("area.fo", | doTest("area.fo", | ||||
doTest("inline-level.fo", | doTest("inline-level.fo", | ||||
InlineLevelEventProducer.class.getName() + ".lineOverflows"); | InlineLevelEventProducer.class.getName() + ".lineOverflows"); | ||||
} | } | ||||
@Test | |||||
public void testFont() throws FOPException, TransformerException, IOException, SAXException { | |||||
doTest("font.fo", | |||||
FontEventProducer.class.getName() + ".fontSubstituted"); | |||||
} | |||||
@Test | |||||
public void testFontWithBadDirectory() throws FOPException, TransformerException, IOException, | |||||
SAXException { | |||||
doTest("font.fo", "test/config/test_fonts_directory_bad.xconf", | |||||
FontEventProducer.class.getName() + ".fontDirectoryNotFound"); | |||||
} | |||||
} | } |
*/ | */ | ||||
@Before | @Before | ||||
public void setUp() throws Exception { | public void setUp() throws Exception { | ||||
File file = new File("test/resources/fonts/DejaVuLGCSerif.ttf"); | |||||
font = FontLoader.loadFont(file, "", true, EncodingMode.AUTO, | |||||
fontResolver); | |||||
File file = new File("test/resources/fonts/ttf/DejaVuLGCSerif.ttf"); | |||||
font = FontLoader.loadFont(file, "", true, EncodingMode.AUTO, fontResolver); | |||||
} | } | ||||
/** | /** |
/* | |||||
* 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; | |||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import javax.xml.transform.TransformerException; | |||||
import org.junit.Test; | |||||
import org.xml.sax.SAXException; | |||||
import org.apache.fop.apps.FOPException; | |||||
import org.apache.fop.events.EventProcessingTestCase; | |||||
/** | |||||
* Testing font events. | |||||
*/ | |||||
public class FontEventProcessingTestCase { | |||||
private EventProcessingTestCase eventsTests = new EventProcessingTestCase(); | |||||
@Test | |||||
public void testFont() throws FOPException, TransformerException, IOException, SAXException { | |||||
InputStream inStream = getClass().getResourceAsStream("substituted-font.fo"); | |||||
eventsTests.doTest(inStream, null, FontEventProducer.class.getName() + ".fontSubstituted"); | |||||
} | |||||
@Test | |||||
public void testFontWithBadDirectory() throws FOPException, TransformerException, IOException, | |||||
SAXException { | |||||
InputStream inStream = getClass().getResourceAsStream("substituted-font.fo"); | |||||
eventsTests.doTest(inStream, "test/config/test_fonts_directory_bad.xconf", | |||||
FontEventProducer.class.getName() + ".fontDirectoryNotFound"); | |||||
} | |||||
} |
<?xml version="1.0" standalone="no"?> | |||||
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> | |||||
<fo:layout-master-set> | |||||
<fo:simple-page-master master-name="page" | |||||
page-height="420pt" page-width="320pt" margin="10pt"> | |||||
<fo:region-body background-color="#F0F0F0"/> | |||||
</fo:simple-page-master> | |||||
</fo:layout-master-set> | |||||
<fo:page-sequence master-reference="page"> | |||||
<fo:flow flow-name="xsl-region-body"> | |||||
<fo:block font-family="blah">This block uses an unknown font.</fo:block> | |||||
</fo:flow> | |||||
</fo:page-sequence> | |||||
</fo:root> |
@Before | @Before | ||||
public void setUp() throws IOException { | public void setUp() throws IOException { | ||||
originalFontReader = new FontFileReader("test/resources/fonts/DejaVuLGCSerif.ttf"); | |||||
originalFontReader = new FontFileReader("test/resources/fonts/ttf/DejaVuLGCSerif.ttf"); | |||||
} | } | ||||
/** | /** |
@Test | @Test | ||||
public void testUseKerning() throws IOException { | public void testUseKerning() throws IOException { | ||||
File file = new File("test/resources/fonts/DejaVuLGCSerif.ttf"); | |||||
File file = new File("test/resources/fonts/ttf/DejaVuLGCSerif.ttf"); | |||||
String absoluteFilePath = file.toURL().toExternalForm(); | String absoluteFilePath = file.toURL().toExternalForm(); | ||||
FontResolver resolver = FontManager.createMinimalFontResolver(); | FontResolver resolver = FontManager.createMinimalFontResolver(); | ||||
String fontName = "Deja Vu"; | String fontName = "Deja Vu"; | ||||
useKerning, resolver); | useKerning, resolver); | ||||
assertFalse(fontLoader.getFont().hasKerningInfo()); | assertFalse(fontLoader.getFont().hasKerningInfo()); | ||||
} | } | ||||
} | |||||
} |
/* | |||||
* 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 static org.junit.Assert.assertEquals; | |||||
import static org.junit.Assert.assertTrue; | |||||
import java.awt.Rectangle; | |||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import java.util.List; | |||||
import org.junit.Test; | |||||
/** | |||||
* Test case for {@link AFMParser}. | |||||
*/ | |||||
public class AFMParserTestCase { | |||||
private AFMParser sut = new AFMParser(); | |||||
/** | |||||
* We're testing with two identical files except one has: | |||||
* EncodingScheme AdobeStandardEncoding | |||||
* the other has: | |||||
* EncodingScheme ExpectedEncoding | |||||
* Both files have the correct character metrics data, and we're checking that both are handled | |||||
* consistently with both encoding settings. | |||||
* | |||||
* @throws IOException if an I/O error occurs | |||||
*/ | |||||
@Test | |||||
public void testMappingAgainstAdobeStandardEncoding() throws IOException { | |||||
InputStream expectedStream = getClass().getResourceAsStream( | |||||
"adobe-charset_unknown-encoding.afm"); | |||||
InputStream adobeStandardStream = getClass().getResourceAsStream( | |||||
"adobe-charset_adobe-encoding.afm"); | |||||
AFMFile expectedParser = sut.parse(expectedStream, null); | |||||
AFMFile adobeStandard = sut.parse(adobeStandardStream, null); | |||||
List<AFMCharMetrics> adobeMetrics = adobeStandard.getCharMetrics(); | |||||
checkCharMtrxList(true, expectedParser.getCharMetrics(), adobeMetrics); | |||||
compareMetrics(adobeMetrics); | |||||
nonAdobeCharsetUnknownEncoding(adobeMetrics); | |||||
nonAdobeCharsetAdobeEncoding(adobeMetrics); | |||||
} | |||||
private void compareMetrics(List<AFMCharMetrics> charMetrics) { | |||||
// in order to ensure that every character is parsed properly, we're going to check them | |||||
// against the AFM file (bboxes were created with a counter) | |||||
AdobeStandardEncoding[] standardEncoding = AdobeStandardEncoding.values(); | |||||
for (int i = 0; i < charMetrics.size(); i++) { | |||||
Rectangle expectedBbox = new Rectangle(i + 1, i + 1, 0, 0); | |||||
AFMCharMetrics thisMetric = charMetrics.get(i); | |||||
assertTrue(thisMetric.getBBox().equals(expectedBbox)); | |||||
assertEquals(thisMetric.getCharName(), standardEncoding[i].getAdobeName()); | |||||
} | |||||
} | |||||
/** | |||||
* A non-adobe encoded file is tested, all the character codes are not AdobeStandardEncoding and | |||||
* the encoding is not AdobeStandardEncoding, we are checking a failure case here. Checking that | |||||
* the AdobeStandardEncoding isn't forced on other encodings. | |||||
* | |||||
* @param expected the AdobeStandardEncoding encoded character metrics list | |||||
* @throws IOException if an IO error occurs | |||||
*/ | |||||
private void nonAdobeCharsetUnknownEncoding(List<AFMCharMetrics> expected) | |||||
throws IOException { | |||||
InputStream inStream = getClass().getResourceAsStream( | |||||
"notadobe-charset_unknown-encoding.afm"); | |||||
AFMFile afmFile = sut.parse(inStream, null); | |||||
List<AFMCharMetrics> unknownEncodingMetrics = afmFile.getCharMetrics(); | |||||
checkCharMtrxList(false, expected, unknownEncodingMetrics); | |||||
} | |||||
/** | |||||
* This tests a poorly encoded file, it has AdobeStandardEncoding. We are checking that the | |||||
* metrics are correctly analysed against properly encoded char metrics. | |||||
* | |||||
* @param expected | |||||
* @throws IOException | |||||
*/ | |||||
private void nonAdobeCharsetAdobeEncoding(List<AFMCharMetrics> expected) | |||||
throws IOException { | |||||
InputStream inStream = getClass().getResourceAsStream( | |||||
"notadobe-charset_adobe-encoding.afm"); | |||||
AFMFile afmFile = sut.parse(inStream, null); | |||||
List<AFMCharMetrics> correctedCharMetrics = afmFile.getCharMetrics(); | |||||
checkCharMtrxList(true, expected, correctedCharMetrics); | |||||
} | |||||
private boolean charMetricsEqual(AFMCharMetrics o1, AFMCharMetrics o2) { | |||||
return o1.getCharCode() == o2.getCharCode() | |||||
&& objectEquals(o1.getCharacter(), o2.getCharacter()) | |||||
&& o1.getWidthX() == o2.getWidthX() | |||||
&& o1.getWidthY() == o2.getWidthY() | |||||
&& objectEquals(o1.getBBox(), o2.getBBox()); | |||||
} | |||||
private void checkCharMtrxList(boolean expectedResult, List<AFMCharMetrics> expectedList, | |||||
List<AFMCharMetrics> actualList) { | |||||
assertEquals(expectedList.size(), actualList.size()); | |||||
for (int i = 0; i < expectedList.size(); i++) { | |||||
assertEquals(expectedResult, charMetricsEqual(expectedList.get(i), actualList.get(i))); | |||||
} | |||||
} | |||||
private boolean objectEquals(Object o1, Object o2) { | |||||
return o1 == null ? o2 == null : (o1 == o2 || o1.equals(o2)); | |||||
} | |||||
} |
# | |||||
# Name: Adobe Standard Encoding to Unicode | |||||
# Unicode version: 2.0 | |||||
# Table version: 1.0 | |||||
# Date: 2011 July 12 | |||||
# | |||||
# Copyright (c) 1991-2011 Unicode, Inc. All Rights reserved. | |||||
# | |||||
# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). No | |||||
# claims are made as to fitness for any particular purpose. No warranties of | |||||
# any kind are expressed or implied. The recipient agrees to determine | |||||
# applicability of information provided. If this file has been provided on | |||||
# magnetic media by Unicode, Inc., the sole remedy for any claim will be | |||||
# exchange of defective media within 90 days of receipt. | |||||
# | |||||
# Unicode, Inc. hereby grants the right to freely use the information | |||||
# supplied in this file in the creation of products supporting the | |||||
# Unicode Standard, and to make copies of this file in any form for | |||||
# internal or external distribution as long as this notice remains | |||||
# attached. | |||||
# | |||||
# Format: 4 tab-delimited fields: | |||||
# | |||||
# (1) The Unicode value (in hexadecimal) | |||||
# (2) The Adobe Standard Encoding code point (in hexadecimal) | |||||
# (3) # Unicode name | |||||
# (4) # PostScript character name | |||||
# | |||||
# General Notes: | |||||
# | |||||
# The Unicode values in this table were produced as the result of applying | |||||
# the algorithm described in the section "Populating a Unicode space" in the | |||||
# document "Unicode and Glyph Names," at | |||||
# http://partners.adobe.com/asn/developer/typeforum/unicodegn.html | |||||
# to the characters encoded in Adobe Standard Encoding. Note that some | |||||
# Standard Encoding characters, such as "space", are mapped to 2 Unicode | |||||
# values. Refer to the above document for more details. | |||||
# | |||||
# 2011 July 12: The above link is no longer valid. For comparable, | |||||
# more current information, see the document, "Glyph", at: | |||||
# <http://www.adobe.com/devnet/opentype/archives/glyph.html> | |||||
# | |||||
# Revision History: | |||||
# | |||||
# [v1.0, 2011 July 12] | |||||
# Updated terms of use to current wording. | |||||
# Updated contact information and document link. | |||||
# No changes to the mapping data. | |||||
# | |||||
# [v0.2, 30 March 1999] | |||||
# Different algorithm to produce Unicode values (see notes above) results in | |||||
# some character codes being mapped to 2 Unicode values. Updated Unicode | |||||
# names to Unicode 2.0 names. | |||||
# | |||||
# [v0.1, 5 May 1995] First release. | |||||
# | |||||
# Use the Unicode reporting form <http://www.unicode.org/reporting.html> | |||||
# for any questions or comments or to report errors in the data. | |||||
# | |||||
0020 20 # SPACE # space | |||||
00A0 20 # NO-BREAK SPACE # space | |||||
0021 21 # EXCLAMATION MARK # exclam | |||||
0022 22 # QUOTATION MARK # quotedbl | |||||
0023 23 # NUMBER SIGN # numbersign | |||||
0024 24 # DOLLAR SIGN # dollar | |||||
0025 25 # PERCENT SIGN # percent | |||||
0026 26 # AMPERSAND # ampersand | |||||
2019 27 # RIGHT SINGLE QUOTATION MARK # quoteright | |||||
0028 28 # LEFT PARENTHESIS # parenleft | |||||
0029 29 # RIGHT PARENTHESIS # parenright | |||||
002A 2A # ASTERISK # asterisk | |||||
002B 2B # PLUS SIGN # plus | |||||
002C 2C # COMMA # comma | |||||
002D 2D # HYPHEN-MINUS # hyphen | |||||
00AD 2D # SOFT HYPHEN # hyphen | |||||
002E 2E # FULL STOP # period | |||||
002F 2F # SOLIDUS # slash | |||||
0030 30 # DIGIT ZERO # zero | |||||
0031 31 # DIGIT ONE # one | |||||
0032 32 # DIGIT TWO # two | |||||
0033 33 # DIGIT THREE # three | |||||
0034 34 # DIGIT FOUR # four | |||||
0035 35 # DIGIT FIVE # five | |||||
0036 36 # DIGIT SIX # six | |||||
0037 37 # DIGIT SEVEN # seven | |||||
0038 38 # DIGIT EIGHT # eight | |||||
0039 39 # DIGIT NINE # nine | |||||
003A 3A # COLON # colon | |||||
003B 3B # SEMICOLON # semicolon | |||||
003C 3C # LESS-THAN SIGN # less | |||||
003D 3D # EQUALS SIGN # equal | |||||
003E 3E # GREATER-THAN SIGN # greater | |||||
003F 3F # QUESTION MARK # question | |||||
0040 40 # COMMERCIAL AT # at | |||||
0041 41 # LATIN CAPITAL LETTER A # A | |||||
0042 42 # LATIN CAPITAL LETTER B # B | |||||
0043 43 # LATIN CAPITAL LETTER C # C | |||||
0044 44 # LATIN CAPITAL LETTER D # D | |||||
0045 45 # LATIN CAPITAL LETTER E # E | |||||
0046 46 # LATIN CAPITAL LETTER F # F | |||||
0047 47 # LATIN CAPITAL LETTER G # G | |||||
0048 48 # LATIN CAPITAL LETTER H # H | |||||
0049 49 # LATIN CAPITAL LETTER I # I | |||||
004A 4A # LATIN CAPITAL LETTER J # J | |||||
004B 4B # LATIN CAPITAL LETTER K # K | |||||
004C 4C # LATIN CAPITAL LETTER L # L | |||||
004D 4D # LATIN CAPITAL LETTER M # M | |||||
004E 4E # LATIN CAPITAL LETTER N # N | |||||
004F 4F # LATIN CAPITAL LETTER O # O | |||||
0050 50 # LATIN CAPITAL LETTER P # P | |||||
0051 51 # LATIN CAPITAL LETTER Q # Q | |||||
0052 52 # LATIN CAPITAL LETTER R # R | |||||
0053 53 # LATIN CAPITAL LETTER S # S | |||||
0054 54 # LATIN CAPITAL LETTER T # T | |||||
0055 55 # LATIN CAPITAL LETTER U # U | |||||
0056 56 # LATIN CAPITAL LETTER V # V | |||||
0057 57 # LATIN CAPITAL LETTER W # W | |||||
0058 58 # LATIN CAPITAL LETTER X # X | |||||
0059 59 # LATIN CAPITAL LETTER Y # Y | |||||
005A 5A # LATIN CAPITAL LETTER Z # Z | |||||
005B 5B # LEFT SQUARE BRACKET # bracketleft | |||||
005C 5C # REVERSE SOLIDUS # backslash | |||||
005D 5D # RIGHT SQUARE BRACKET # bracketright | |||||
005E 5E # CIRCUMFLEX ACCENT # asciicircum | |||||
005F 5F # LOW LINE # underscore | |||||
2018 60 # LEFT SINGLE QUOTATION MARK # quoteleft | |||||
0061 61 # LATIN SMALL LETTER A # a | |||||
0062 62 # LATIN SMALL LETTER B # b | |||||
0063 63 # LATIN SMALL LETTER C # c | |||||
0064 64 # LATIN SMALL LETTER D # d | |||||
0065 65 # LATIN SMALL LETTER E # e | |||||
0066 66 # LATIN SMALL LETTER F # f | |||||
0067 67 # LATIN SMALL LETTER G # g | |||||
0068 68 # LATIN SMALL LETTER H # h | |||||
0069 69 # LATIN SMALL LETTER I # i | |||||
006A 6A # LATIN SMALL LETTER J # j | |||||
006B 6B # LATIN SMALL LETTER K # k | |||||
006C 6C # LATIN SMALL LETTER L # l | |||||
006D 6D # LATIN SMALL LETTER M # m | |||||
006E 6E # LATIN SMALL LETTER N # n | |||||
006F 6F # LATIN SMALL LETTER O # o | |||||
0070 70 # LATIN SMALL LETTER P # p | |||||
0071 71 # LATIN SMALL LETTER Q # q | |||||
0072 72 # LATIN SMALL LETTER R # r | |||||
0073 73 # LATIN SMALL LETTER S # s | |||||
0074 74 # LATIN SMALL LETTER T # t | |||||
0075 75 # LATIN SMALL LETTER U # u | |||||
0076 76 # LATIN SMALL LETTER V # v | |||||
0077 77 # LATIN SMALL LETTER W # w | |||||
0078 78 # LATIN SMALL LETTER X # x | |||||
0079 79 # LATIN SMALL LETTER Y # y | |||||
007A 7A # LATIN SMALL LETTER Z # z | |||||
007B 7B # LEFT CURLY BRACKET # braceleft | |||||
007C 7C # VERTICAL LINE # bar | |||||
007D 7D # RIGHT CURLY BRACKET # braceright | |||||
007E 7E # TILDE # asciitilde | |||||
00A1 A1 # INVERTED EXCLAMATION MARK # exclamdown | |||||
00A2 A2 # CENT SIGN # cent | |||||
00A3 A3 # POUND SIGN # sterling | |||||
2044 A4 # FRACTION SLASH # fraction | |||||
2215 A4 # DIVISION SLASH # fraction | |||||
00A5 A5 # YEN SIGN # yen | |||||
0192 A6 # LATIN SMALL LETTER F WITH HOOK # florin | |||||
00A7 A7 # SECTION SIGN # section | |||||
00A4 A8 # CURRENCY SIGN # currency | |||||
0027 A9 # APOSTROPHE # quotesingle | |||||
201C AA # LEFT DOUBLE QUOTATION MARK # quotedblleft | |||||
00AB AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK # guillemotleft | |||||
2039 AC # SINGLE LEFT-POINTING ANGLE QUOTATION MARK # guilsinglleft | |||||
203A AD # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK # guilsinglright | |||||
FB01 AE # LATIN SMALL LIGATURE FI # fi | |||||
FB02 AF # LATIN SMALL LIGATURE FL # fl | |||||
2013 B1 # EN DASH # endash | |||||
2020 B2 # DAGGER # dagger | |||||
2021 B3 # DOUBLE DAGGER # daggerdbl | |||||
00B7 B4 # MIDDLE DOT # periodcentered | |||||
2219 B4 # BULLET OPERATOR # periodcentered | |||||
00B6 B6 # PILCROW SIGN # paragraph | |||||
2022 B7 # BULLET # bullet | |||||
201A B8 # SINGLE LOW-9 QUOTATION MARK # quotesinglbase | |||||
201E B9 # DOUBLE LOW-9 QUOTATION MARK # quotedblbase | |||||
201D BA # RIGHT DOUBLE QUOTATION MARK # quotedblright | |||||
00BB BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK # guillemotright | |||||
2026 BC # HORIZONTAL ELLIPSIS # ellipsis | |||||
2030 BD # PER MILLE SIGN # perthousand | |||||
00BF BF # INVERTED QUESTION MARK # questiondown | |||||
0060 C1 # GRAVE ACCENT # grave | |||||
00B4 C2 # ACUTE ACCENT # acute | |||||
02C6 C3 # MODIFIER LETTER CIRCUMFLEX ACCENT # circumflex | |||||
02DC C4 # SMALL TILDE # tilde | |||||
00AF C5 # MACRON # macron | |||||
02C9 C5 # MODIFIER LETTER MACRON # macron | |||||
02D8 C6 # BREVE # breve | |||||
02D9 C7 # DOT ABOVE # dotaccent | |||||
00A8 C8 # DIAERESIS # dieresis | |||||
02DA CA # RING ABOVE # ring | |||||
00B8 CB # CEDILLA # cedilla | |||||
02DD CD # DOUBLE ACUTE ACCENT # hungarumlaut | |||||
02DB CE # OGONEK # ogonek | |||||
02C7 CF # CARON # caron | |||||
2014 D0 # EM DASH # emdash | |||||
00C6 E1 # LATIN CAPITAL LETTER AE # AE | |||||
00AA E3 # FEMININE ORDINAL INDICATOR # ordfeminine | |||||
0141 E8 # LATIN CAPITAL LETTER L WITH STROKE # Lslash | |||||
00D8 E9 # LATIN CAPITAL LETTER O WITH STROKE # Oslash | |||||
0152 EA # LATIN CAPITAL LIGATURE OE # OE | |||||
00BA EB # MASCULINE ORDINAL INDICATOR # ordmasculine | |||||
00E6 F1 # LATIN SMALL LETTER AE # ae | |||||
0131 F5 # LATIN SMALL LETTER DOTLESS I # dotlessi | |||||
0142 F8 # LATIN SMALL LETTER L WITH STROKE # lslash | |||||
00F8 F9 # LATIN SMALL LETTER O WITH STROKE # oslash | |||||
0153 FA # LATIN SMALL LIGATURE OE # oe | |||||
00DF FB # LATIN SMALL LETTER SHARP S # germandbls |
/* | |||||
* 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 static org.junit.Assert.assertEquals; | |||||
import java.io.BufferedReader; | |||||
import java.io.FileNotFoundException; | |||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import java.io.InputStreamReader; | |||||
import org.junit.BeforeClass; | |||||
import org.junit.Test; | |||||
/** | |||||
* Test case for {@link AdobeStandardEncoding}. | |||||
*/ | |||||
public class AdobeStandardEncodingTestCase { | |||||
private static BufferedReader adobeStandardEncoding; | |||||
/** | |||||
* Sets up the file reader, this file was retrieved from the url below. | |||||
* http://unicode.org/Public/MAPPINGS/VENDORS/ADOBE/stdenc.txt | |||||
* | |||||
* @throws FileNotFoundException if the file was not found | |||||
*/ | |||||
@BeforeClass | |||||
public static void setupReader() throws FileNotFoundException { | |||||
InputStream inStream = AdobeStandardEncodingTestCase.class.getResourceAsStream( | |||||
"AdobeStandardEncoding.txt"); | |||||
adobeStandardEncoding = new BufferedReader(new InputStreamReader(inStream)); | |||||
} | |||||
/** | |||||
* Probably the best way to test the encoding is by converting it back to format specified in | |||||
* the file, that way we can ensure data has been migrated properly. | |||||
* | |||||
* @throws IOException if an I/O error occurs | |||||
*/ | |||||
@Test | |||||
public void testCorrectEncoding() throws IOException { | |||||
for (AdobeStandardEncoding encoding : AdobeStandardEncoding.values()) { | |||||
String expectedLine = getLine(); | |||||
String hexUnicode = toHexString(encoding.getUnicodeIndex(), 4); | |||||
String hexAdobe = toHexString(encoding.getAdobeCodePoint(), 2); | |||||
String actualLine = hexUnicode + "\t" | |||||
+ hexAdobe + "\t# " | |||||
+ encoding.getUnicodeName() + "\t# " | |||||
+ encoding.getAdobeName(); | |||||
assertEquals(expectedLine, actualLine); | |||||
} | |||||
} | |||||
private String getLine() throws IOException { | |||||
String line = "# The first few lines are comments, these should be ignored"; | |||||
while (line.startsWith("#")) { | |||||
line = adobeStandardEncoding.readLine(); | |||||
} | |||||
return line; | |||||
} | |||||
private String toHexString(int number, int length) { | |||||
return String.format("%0" + length + "X", number); | |||||
} | |||||
} |
/* | |||||
* 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 static org.mockito.Mockito.mock; | |||||
import static org.mockito.Mockito.verify; | |||||
import static org.mockito.Mockito.when; | |||||
import java.awt.Rectangle; | |||||
import java.io.IOException; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
import java.util.Stack; | |||||
import org.junit.Test; | |||||
import org.apache.fop.fonts.NamedCharacter; | |||||
import org.apache.fop.fonts.type1.AFMParser.ValueHandler; | |||||
/** | |||||
* Test case for {@link CharMetricsHandler}. | |||||
*/ | |||||
public class CharMetricsHandlerTestCase { | |||||
private static final String GOOD_LINE = "C 32 ; WX 32 ; N space ; B 1 1 1 1"; | |||||
private static final AFMCharMetrics EXPECTED_CHM; | |||||
static { | |||||
EXPECTED_CHM = new AFMCharMetrics(); | |||||
EXPECTED_CHM.setCharCode(32); | |||||
EXPECTED_CHM.setWidthX(32.0); | |||||
EXPECTED_CHM.setCharacter(new NamedCharacter("space")); | |||||
EXPECTED_CHM.setBBox(new Rectangle(1, 1, 0, 0)); | |||||
} | |||||
@Test | |||||
public void testHandlers() throws IOException { | |||||
testEncodingWithMetricsLine("", GOOD_LINE); | |||||
testEncodingWithMetricsLine("WrongEncoding", GOOD_LINE); | |||||
testEncodingWithMetricsLine("AdobeStandardEncoding", GOOD_LINE); | |||||
} | |||||
private void testEncodingWithMetricsLine(String encoding, String line) throws IOException { | |||||
Map<String, ValueHandler> valueParsers = mock(HashMap.class); | |||||
ValueHandler cHandler = mock(ValueHandler.class); | |||||
ValueHandler wxHandler = mock(ValueHandler.class); | |||||
ValueHandler nHandler = mock(ValueHandler.class); | |||||
ValueHandler bHandler = mock(ValueHandler.class); | |||||
when(valueParsers.get("C")).thenReturn(cHandler); | |||||
when(valueParsers.get("WX")).thenReturn(wxHandler); | |||||
when(valueParsers.get("N")).thenReturn(nHandler); | |||||
when(valueParsers.get("B")).thenReturn(bHandler); | |||||
CharMetricsHandler handler = CharMetricsHandler.getHandler(valueParsers, encoding); | |||||
Stack<Object> stack = new Stack<Object>(); | |||||
handler.parse(line, stack, null); | |||||
verify(valueParsers).get("C"); | |||||
verify(valueParsers).get("WX"); | |||||
verify(valueParsers).get("N"); | |||||
verify(valueParsers).get("B"); | |||||
verify(cHandler).parse("32", 0, new Stack<Object>()); | |||||
verify(wxHandler).parse("32", 0, new Stack<Object>()); | |||||
verify(nHandler).parse("space", 0, new Stack<Object>()); | |||||
verify(bHandler).parse("1 1 1 1", 0, new Stack<Object>()); | |||||
} | |||||
} |
StartFontMetrics 2.0 | |||||
EncodingScheme AdobeStandardEncoding | |||||
StartCharMetrics 154 | |||||
C 32 ; WX 32 ; N space ; B 1 1 1 1 | |||||
C 32 ; WX 32 ; N space ; B 2 2 2 2 | |||||
C 33 ; WX 33 ; N exclam ; B 3 3 3 3 | |||||
C 34 ; WX 34 ; N quotedbl ; B 4 4 4 4 | |||||
C 35 ; WX 35 ; N numbersign ; B 5 5 5 5 | |||||
C 36 ; WX 36 ; N dollar ; B 6 6 6 6 | |||||
C 37 ; WX 37 ; N percent ; B 7 7 7 7 | |||||
C 38 ; WX 38 ; N ampersand ; B 8 8 8 8 | |||||
C 39 ; WX 39 ; N quoteright ; B 9 9 9 9 | |||||
C 40 ; WX 40 ; N parenleft ; B 10 10 10 10 | |||||
C 41 ; WX 41 ; N parenright ; B 11 11 11 11 | |||||
C 42 ; WX 42 ; N asterisk ; B 12 12 12 12 | |||||
C 43 ; WX 43 ; N plus ; B 13 13 13 13 | |||||
C 44 ; WX 44 ; N comma ; B 14 14 14 14 | |||||
C 45 ; WX 45 ; N hyphen ; B 15 15 15 15 | |||||
C 45 ; WX 45 ; N hyphen ; B 16 16 16 16 | |||||
C 46 ; WX 46 ; N period ; B 17 17 17 17 | |||||
C 47 ; WX 47 ; N slash ; B 18 18 18 18 | |||||
C 48 ; WX 48 ; N zero ; B 19 19 19 19 | |||||
C 49 ; WX 49 ; N one ; B 20 20 20 20 | |||||
C 50 ; WX 50 ; N two ; B 21 21 21 21 | |||||
C 51 ; WX 51 ; N three ; B 22 22 22 22 | |||||
C 52 ; WX 52 ; N four ; B 23 23 23 23 | |||||
C 53 ; WX 53 ; N five ; B 24 24 24 24 | |||||
C 54 ; WX 54 ; N six ; B 25 25 25 25 | |||||
C 55 ; WX 55 ; N seven ; B 26 26 26 26 | |||||
C 56 ; WX 56 ; N eight ; B 27 27 27 27 | |||||
C 57 ; WX 57 ; N nine ; B 28 28 28 28 | |||||
C 58 ; WX 58 ; N colon ; B 29 29 29 29 | |||||
C 59 ; WX 59 ; N semicolon ; B 30 30 30 30 | |||||
C 60 ; WX 60 ; N less ; B 31 31 31 31 | |||||
C 61 ; WX 61 ; N equal ; B 32 32 32 32 | |||||
C 62 ; WX 62 ; N greater ; B 33 33 33 33 | |||||
C 63 ; WX 63 ; N question ; B 34 34 34 34 | |||||
C 64 ; WX 64 ; N at ; B 35 35 35 35 | |||||
C 65 ; WX 65 ; N A ; B 36 36 36 36 | |||||
C 66 ; WX 66 ; N B ; B 37 37 37 37 | |||||
C 67 ; WX 67 ; N C ; B 38 38 38 38 | |||||
C 68 ; WX 68 ; N D ; B 39 39 39 39 | |||||
C 69 ; WX 69 ; N E ; B 40 40 40 40 | |||||
C 70 ; WX 70 ; N F ; B 41 41 41 41 | |||||
C 71 ; WX 71 ; N G ; B 42 42 42 42 | |||||
C 72 ; WX 72 ; N H ; B 43 43 43 43 | |||||
C 73 ; WX 73 ; N I ; B 44 44 44 44 | |||||
C 74 ; WX 74 ; N J ; B 45 45 45 45 | |||||
C 75 ; WX 75 ; N K ; B 46 46 46 46 | |||||
C 76 ; WX 76 ; N L ; B 47 47 47 47 | |||||
C 77 ; WX 77 ; N M ; B 48 48 48 48 | |||||
C 78 ; WX 78 ; N N ; B 49 49 49 49 | |||||
C 79 ; WX 79 ; N O ; B 50 50 50 50 | |||||
C 80 ; WX 80 ; N P ; B 51 51 51 51 | |||||
C 81 ; WX 81 ; N Q ; B 52 52 52 52 | |||||
C 82 ; WX 82 ; N R ; B 53 53 53 53 | |||||
C 83 ; WX 83 ; N S ; B 54 54 54 54 | |||||
C 84 ; WX 84 ; N T ; B 55 55 55 55 | |||||
C 85 ; WX 85 ; N U ; B 56 56 56 56 | |||||
C 86 ; WX 86 ; N V ; B 57 57 57 57 | |||||
C 87 ; WX 87 ; N W ; B 58 58 58 58 | |||||
C 88 ; WX 88 ; N X ; B 59 59 59 59 | |||||
C 89 ; WX 89 ; N Y ; B 60 60 60 60 | |||||
C 90 ; WX 90 ; N Z ; B 61 61 61 61 | |||||
C 91 ; WX 91 ; N bracketleft ; B 62 62 62 62 | |||||
C 92 ; WX 92 ; N backslash ; B 63 63 63 63 | |||||
C 93 ; WX 93 ; N bracketright ; B 64 64 64 64 | |||||
C 94 ; WX 94 ; N asciicircum ; B 65 65 65 65 | |||||
C 95 ; WX 95 ; N underscore ; B 66 66 66 66 | |||||
C 96 ; WX 96 ; N quoteleft ; B 67 67 67 67 | |||||
C 97 ; WX 97 ; N a ; B 68 68 68 68 | |||||
C 98 ; WX 98 ; N b ; B 69 69 69 69 | |||||
C 99 ; WX 99 ; N c ; B 70 70 70 70 | |||||
C 100 ; WX 100 ; N d ; B 71 71 71 71 | |||||
C 101 ; WX 101 ; N e ; B 72 72 72 72 | |||||
C 102 ; WX 102 ; N f ; B 73 73 73 73 | |||||
C 103 ; WX 103 ; N g ; B 74 74 74 74 | |||||
C 104 ; WX 104 ; N h ; B 75 75 75 75 | |||||
C 105 ; WX 105 ; N i ; B 76 76 76 76 | |||||
C 106 ; WX 106 ; N j ; B 77 77 77 77 | |||||
C 107 ; WX 107 ; N k ; B 78 78 78 78 | |||||
C 108 ; WX 108 ; N l ; B 79 79 79 79 | |||||
C 109 ; WX 109 ; N m ; B 80 80 80 80 | |||||
C 110 ; WX 110 ; N n ; B 81 81 81 81 | |||||
C 111 ; WX 111 ; N o ; B 82 82 82 82 | |||||
C 112 ; WX 112 ; N p ; B 83 83 83 83 | |||||
C 113 ; WX 113 ; N q ; B 84 84 84 84 | |||||
C 114 ; WX 114 ; N r ; B 85 85 85 85 | |||||
C 115 ; WX 115 ; N s ; B 86 86 86 86 | |||||
C 116 ; WX 116 ; N t ; B 87 87 87 87 | |||||
C 117 ; WX 117 ; N u ; B 88 88 88 88 | |||||
C 118 ; WX 118 ; N v ; B 89 89 89 89 | |||||
C 119 ; WX 119 ; N w ; B 90 90 90 90 | |||||
C 120 ; WX 120 ; N x ; B 91 91 91 91 | |||||
C 121 ; WX 121 ; N y ; B 92 92 92 92 | |||||
C 122 ; WX 122 ; N z ; B 93 93 93 93 | |||||
C 123 ; WX 123 ; N braceleft ; B 94 94 94 94 | |||||
C 124 ; WX 124 ; N bar ; B 95 95 95 95 | |||||
C 125 ; WX 125 ; N braceright ; B 96 96 96 96 | |||||
C 126 ; WX 126 ; N asciitilde ; B 97 97 97 97 | |||||
C 161 ; WX 161 ; N exclamdown ; B 98 98 98 98 | |||||
C 162 ; WX 162 ; N cent ; B 99 99 99 99 | |||||
C 163 ; WX 163 ; N sterling ; B 100 100 100 100 | |||||
C 164 ; WX 164 ; N fraction ; B 101 101 101 101 | |||||
C 164 ; WX 164 ; N fraction ; B 102 102 102 102 | |||||
C 165 ; WX 165 ; N yen ; B 103 103 103 103 | |||||
C 166 ; WX 166 ; N florin ; B 104 104 104 104 | |||||
C 167 ; WX 167 ; N section ; B 105 105 105 105 | |||||
C 168 ; WX 168 ; N currency ; B 106 106 106 106 | |||||
C 169 ; WX 169 ; N quotesingle ; B 107 107 107 107 | |||||
C 170 ; WX 170 ; N quotedblleft ; B 108 108 108 108 | |||||
C 171 ; WX 171 ; N guillemotleft ; B 109 109 109 109 | |||||
C 172 ; WX 172 ; N guilsinglleft ; B 110 110 110 110 | |||||
C 173 ; WX 173 ; N guilsinglright ; B 111 111 111 111 | |||||
C 174 ; WX 174 ; N fi ; B 112 112 112 112 | |||||
C 175 ; WX 175 ; N fl ; B 113 113 113 113 | |||||
C 177 ; WX 177 ; N endash ; B 114 114 114 114 | |||||
C 178 ; WX 178 ; N dagger ; B 115 115 115 115 | |||||
C 179 ; WX 179 ; N daggerdbl ; B 116 116 116 116 | |||||
C 180 ; WX 180 ; N periodcentered ; B 117 117 117 117 | |||||
C 180 ; WX 180 ; N periodcentered ; B 118 118 118 118 | |||||
C 182 ; WX 182 ; N paragraph ; B 119 119 119 119 | |||||
C 183 ; WX 183 ; N bullet ; B 120 120 120 120 | |||||
C 184 ; WX 184 ; N quotesinglbase ; B 121 121 121 121 | |||||
C 185 ; WX 185 ; N quotedblbase ; B 122 122 122 122 | |||||
C 186 ; WX 186 ; N quotedblright ; B 123 123 123 123 | |||||
C 187 ; WX 187 ; N guillemotright ; B 124 124 124 124 | |||||
C 188 ; WX 188 ; N ellipsis ; B 125 125 125 125 | |||||
C 189 ; WX 189 ; N perthousand ; B 126 126 126 126 | |||||
C 191 ; WX 191 ; N questiondown ; B 127 127 127 127 | |||||
C 193 ; WX 193 ; N grave ; B 128 128 128 128 | |||||
C 194 ; WX 194 ; N acute ; B 129 129 129 129 | |||||
C 195 ; WX 195 ; N circumflex ; B 130 130 130 130 | |||||
C 196 ; WX 196 ; N tilde ; B 131 131 131 131 | |||||
C 197 ; WX 197 ; N macron ; B 132 132 132 132 | |||||
C 197 ; WX 197 ; N macron ; B 133 133 133 133 | |||||
C 198 ; WX 198 ; N breve ; B 134 134 134 134 | |||||
C 199 ; WX 199 ; N dotaccent ; B 135 135 135 135 | |||||
C 200 ; WX 200 ; N dieresis ; B 136 136 136 136 | |||||
C 202 ; WX 202 ; N ring ; B 137 137 137 137 | |||||
C 203 ; WX 203 ; N cedilla ; B 138 138 138 138 | |||||
C 205 ; WX 205 ; N hungarumlaut ; B 139 139 139 139 | |||||
C 206 ; WX 206 ; N ogonek ; B 140 140 140 140 | |||||
C 207 ; WX 207 ; N caron ; B 141 141 141 141 | |||||
C 208 ; WX 208 ; N emdash ; B 142 142 142 142 | |||||
C 225 ; WX 225 ; N AE ; B 143 143 143 143 | |||||
C 227 ; WX 227 ; N ordfeminine ; B 144 144 144 144 | |||||
C 232 ; WX 232 ; N Lslash ; B 145 145 145 145 | |||||
C 233 ; WX 233 ; N Oslash ; B 146 146 146 146 | |||||
C 234 ; WX 234 ; N OE ; B 147 147 147 147 | |||||
C 235 ; WX 235 ; N ordmasculine ; B 148 148 148 148 | |||||
C 241 ; WX 241 ; N ae ; B 149 149 149 149 | |||||
C 245 ; WX 245 ; N dotlessi ; B 150 150 150 150 | |||||
C 248 ; WX 248 ; N lslash ; B 151 151 151 151 | |||||
C 249 ; WX 249 ; N oslash ; B 152 152 152 152 | |||||
C 250 ; WX 250 ; N oe ; B 153 153 153 153 | |||||
C 251 ; WX 251 ; N germandbls ; B 154 154 154 154 | |||||
EndCharMetrics |
StartFontMetrics 2.0 | |||||
EncodingScheme FontSpecific | |||||
StartCharMetrics 154 | |||||
C 32 ; WX 32 ; N space ; B 1 1 1 1 | |||||
C 32 ; WX 32 ; N space ; B 2 2 2 2 | |||||
C 33 ; WX 33 ; N exclam ; B 3 3 3 3 | |||||
C 34 ; WX 34 ; N quotedbl ; B 4 4 4 4 | |||||
C 35 ; WX 35 ; N numbersign ; B 5 5 5 5 | |||||
C 36 ; WX 36 ; N dollar ; B 6 6 6 6 | |||||
C 37 ; WX 37 ; N percent ; B 7 7 7 7 | |||||
C 38 ; WX 38 ; N ampersand ; B 8 8 8 8 | |||||
C 39 ; WX 39 ; N quoteright ; B 9 9 9 9 | |||||
C 40 ; WX 40 ; N parenleft ; B 10 10 10 10 | |||||
C 41 ; WX 41 ; N parenright ; B 11 11 11 11 | |||||
C 42 ; WX 42 ; N asterisk ; B 12 12 12 12 | |||||
C 43 ; WX 43 ; N plus ; B 13 13 13 13 | |||||
C 44 ; WX 44 ; N comma ; B 14 14 14 14 | |||||
C 45 ; WX 45 ; N hyphen ; B 15 15 15 15 | |||||
C 45 ; WX 45 ; N hyphen ; B 16 16 16 16 | |||||
C 46 ; WX 46 ; N period ; B 17 17 17 17 | |||||
C 47 ; WX 47 ; N slash ; B 18 18 18 18 | |||||
C 48 ; WX 48 ; N zero ; B 19 19 19 19 | |||||
C 49 ; WX 49 ; N one ; B 20 20 20 20 | |||||
C 50 ; WX 50 ; N two ; B 21 21 21 21 | |||||
C 51 ; WX 51 ; N three ; B 22 22 22 22 | |||||
C 52 ; WX 52 ; N four ; B 23 23 23 23 | |||||
C 53 ; WX 53 ; N five ; B 24 24 24 24 | |||||
C 54 ; WX 54 ; N six ; B 25 25 25 25 | |||||
C 55 ; WX 55 ; N seven ; B 26 26 26 26 | |||||
C 56 ; WX 56 ; N eight ; B 27 27 27 27 | |||||
C 57 ; WX 57 ; N nine ; B 28 28 28 28 | |||||
C 58 ; WX 58 ; N colon ; B 29 29 29 29 | |||||
C 59 ; WX 59 ; N semicolon ; B 30 30 30 30 | |||||
C 60 ; WX 60 ; N less ; B 31 31 31 31 | |||||
C 61 ; WX 61 ; N equal ; B 32 32 32 32 | |||||
C 62 ; WX 62 ; N greater ; B 33 33 33 33 | |||||
C 63 ; WX 63 ; N question ; B 34 34 34 34 | |||||
C 64 ; WX 64 ; N at ; B 35 35 35 35 | |||||
C 65 ; WX 65 ; N A ; B 36 36 36 36 | |||||
C 66 ; WX 66 ; N B ; B 37 37 37 37 | |||||
C 67 ; WX 67 ; N C ; B 38 38 38 38 | |||||
C 68 ; WX 68 ; N D ; B 39 39 39 39 | |||||
C 69 ; WX 69 ; N E ; B 40 40 40 40 | |||||
C 70 ; WX 70 ; N F ; B 41 41 41 41 | |||||
C 71 ; WX 71 ; N G ; B 42 42 42 42 | |||||
C 72 ; WX 72 ; N H ; B 43 43 43 43 | |||||
C 73 ; WX 73 ; N I ; B 44 44 44 44 | |||||
C 74 ; WX 74 ; N J ; B 45 45 45 45 | |||||
C 75 ; WX 75 ; N K ; B 46 46 46 46 | |||||
C 76 ; WX 76 ; N L ; B 47 47 47 47 | |||||
C 77 ; WX 77 ; N M ; B 48 48 48 48 | |||||
C 78 ; WX 78 ; N N ; B 49 49 49 49 | |||||
C 79 ; WX 79 ; N O ; B 50 50 50 50 | |||||
C 80 ; WX 80 ; N P ; B 51 51 51 51 | |||||
C 81 ; WX 81 ; N Q ; B 52 52 52 52 | |||||
C 82 ; WX 82 ; N R ; B 53 53 53 53 | |||||
C 83 ; WX 83 ; N S ; B 54 54 54 54 | |||||
C 84 ; WX 84 ; N T ; B 55 55 55 55 | |||||
C 85 ; WX 85 ; N U ; B 56 56 56 56 | |||||
C 86 ; WX 86 ; N V ; B 57 57 57 57 | |||||
C 87 ; WX 87 ; N W ; B 58 58 58 58 | |||||
C 88 ; WX 88 ; N X ; B 59 59 59 59 | |||||
C 89 ; WX 89 ; N Y ; B 60 60 60 60 | |||||
C 90 ; WX 90 ; N Z ; B 61 61 61 61 | |||||
C 91 ; WX 91 ; N bracketleft ; B 62 62 62 62 | |||||
C 92 ; WX 92 ; N backslash ; B 63 63 63 63 | |||||
C 93 ; WX 93 ; N bracketright ; B 64 64 64 64 | |||||
C 94 ; WX 94 ; N asciicircum ; B 65 65 65 65 | |||||
C 95 ; WX 95 ; N underscore ; B 66 66 66 66 | |||||
C 96 ; WX 96 ; N quoteleft ; B 67 67 67 67 | |||||
C 97 ; WX 97 ; N a ; B 68 68 68 68 | |||||
C 98 ; WX 98 ; N b ; B 69 69 69 69 | |||||
C 99 ; WX 99 ; N c ; B 70 70 70 70 | |||||
C 100 ; WX 100 ; N d ; B 71 71 71 71 | |||||
C 101 ; WX 101 ; N e ; B 72 72 72 72 | |||||
C 102 ; WX 102 ; N f ; B 73 73 73 73 | |||||
C 103 ; WX 103 ; N g ; B 74 74 74 74 | |||||
C 104 ; WX 104 ; N h ; B 75 75 75 75 | |||||
C 105 ; WX 105 ; N i ; B 76 76 76 76 | |||||
C 106 ; WX 106 ; N j ; B 77 77 77 77 | |||||
C 107 ; WX 107 ; N k ; B 78 78 78 78 | |||||
C 108 ; WX 108 ; N l ; B 79 79 79 79 | |||||
C 109 ; WX 109 ; N m ; B 80 80 80 80 | |||||
C 110 ; WX 110 ; N n ; B 81 81 81 81 | |||||
C 111 ; WX 111 ; N o ; B 82 82 82 82 | |||||
C 112 ; WX 112 ; N p ; B 83 83 83 83 | |||||
C 113 ; WX 113 ; N q ; B 84 84 84 84 | |||||
C 114 ; WX 114 ; N r ; B 85 85 85 85 | |||||
C 115 ; WX 115 ; N s ; B 86 86 86 86 | |||||
C 116 ; WX 116 ; N t ; B 87 87 87 87 | |||||
C 117 ; WX 117 ; N u ; B 88 88 88 88 | |||||
C 118 ; WX 118 ; N v ; B 89 89 89 89 | |||||
C 119 ; WX 119 ; N w ; B 90 90 90 90 | |||||
C 120 ; WX 120 ; N x ; B 91 91 91 91 | |||||
C 121 ; WX 121 ; N y ; B 92 92 92 92 | |||||
C 122 ; WX 122 ; N z ; B 93 93 93 93 | |||||
C 123 ; WX 123 ; N braceleft ; B 94 94 94 94 | |||||
C 124 ; WX 124 ; N bar ; B 95 95 95 95 | |||||
C 125 ; WX 125 ; N braceright ; B 96 96 96 96 | |||||
C 126 ; WX 126 ; N asciitilde ; B 97 97 97 97 | |||||
C 161 ; WX 161 ; N exclamdown ; B 98 98 98 98 | |||||
C 162 ; WX 162 ; N cent ; B 99 99 99 99 | |||||
C 163 ; WX 163 ; N sterling ; B 100 100 100 100 | |||||
C 164 ; WX 164 ; N fraction ; B 101 101 101 101 | |||||
C 164 ; WX 164 ; N fraction ; B 102 102 102 102 | |||||
C 165 ; WX 165 ; N yen ; B 103 103 103 103 | |||||
C 166 ; WX 166 ; N florin ; B 104 104 104 104 | |||||
C 167 ; WX 167 ; N section ; B 105 105 105 105 | |||||
C 168 ; WX 168 ; N currency ; B 106 106 106 106 | |||||
C 169 ; WX 169 ; N quotesingle ; B 107 107 107 107 | |||||
C 170 ; WX 170 ; N quotedblleft ; B 108 108 108 108 | |||||
C 171 ; WX 171 ; N guillemotleft ; B 109 109 109 109 | |||||
C 172 ; WX 172 ; N guilsinglleft ; B 110 110 110 110 | |||||
C 173 ; WX 173 ; N guilsinglright ; B 111 111 111 111 | |||||
C 174 ; WX 174 ; N fi ; B 112 112 112 112 | |||||
C 175 ; WX 175 ; N fl ; B 113 113 113 113 | |||||
C 177 ; WX 177 ; N endash ; B 114 114 114 114 | |||||
C 178 ; WX 178 ; N dagger ; B 115 115 115 115 | |||||
C 179 ; WX 179 ; N daggerdbl ; B 116 116 116 116 | |||||
C 180 ; WX 180 ; N periodcentered ; B 117 117 117 117 | |||||
C 180 ; WX 180 ; N periodcentered ; B 118 118 118 118 | |||||
C 182 ; WX 182 ; N paragraph ; B 119 119 119 119 | |||||
C 183 ; WX 183 ; N bullet ; B 120 120 120 120 | |||||
C 184 ; WX 184 ; N quotesinglbase ; B 121 121 121 121 | |||||
C 185 ; WX 185 ; N quotedblbase ; B 122 122 122 122 | |||||
C 186 ; WX 186 ; N quotedblright ; B 123 123 123 123 | |||||
C 187 ; WX 187 ; N guillemotright ; B 124 124 124 124 | |||||
C 188 ; WX 188 ; N ellipsis ; B 125 125 125 125 | |||||
C 189 ; WX 189 ; N perthousand ; B 126 126 126 126 | |||||
C 191 ; WX 191 ; N questiondown ; B 127 127 127 127 | |||||
C 193 ; WX 193 ; N grave ; B 128 128 128 128 | |||||
C 194 ; WX 194 ; N acute ; B 129 129 129 129 | |||||
C 195 ; WX 195 ; N circumflex ; B 130 130 130 130 | |||||
C 196 ; WX 196 ; N tilde ; B 131 131 131 131 | |||||
C 197 ; WX 197 ; N macron ; B 132 132 132 132 | |||||
C 197 ; WX 197 ; N macron ; B 133 133 133 133 | |||||
C 198 ; WX 198 ; N breve ; B 134 134 134 134 | |||||
C 199 ; WX 199 ; N dotaccent ; B 135 135 135 135 | |||||
C 200 ; WX 200 ; N dieresis ; B 136 136 136 136 | |||||
C 202 ; WX 202 ; N ring ; B 137 137 137 137 | |||||
C 203 ; WX 203 ; N cedilla ; B 138 138 138 138 | |||||
C 205 ; WX 205 ; N hungarumlaut ; B 139 139 139 139 | |||||
C 206 ; WX 206 ; N ogonek ; B 140 140 140 140 | |||||
C 207 ; WX 207 ; N caron ; B 141 141 141 141 | |||||
C 208 ; WX 208 ; N emdash ; B 142 142 142 142 | |||||
C 225 ; WX 225 ; N AE ; B 143 143 143 143 | |||||
C 227 ; WX 227 ; N ordfeminine ; B 144 144 144 144 | |||||
C 232 ; WX 232 ; N Lslash ; B 145 145 145 145 | |||||
C 233 ; WX 233 ; N Oslash ; B 146 146 146 146 | |||||
C 234 ; WX 234 ; N OE ; B 147 147 147 147 | |||||
C 235 ; WX 235 ; N ordmasculine ; B 148 148 148 148 | |||||
C 241 ; WX 241 ; N ae ; B 149 149 149 149 | |||||
C 245 ; WX 245 ; N dotlessi ; B 150 150 150 150 | |||||
C 248 ; WX 248 ; N lslash ; B 151 151 151 151 | |||||
C 249 ; WX 249 ; N oslash ; B 152 152 152 152 | |||||
C 250 ; WX 250 ; N oe ; B 153 153 153 153 | |||||
C 251 ; WX 251 ; N germandbls ; B 154 154 154 154 | |||||
EndCharMetrics |
StartFontMetrics 2.0 | |||||
EncodingScheme AdobeStandardEncoding | |||||
StartCharMetrics 154 | |||||
C 33 ; WX 32 ; N space ; B 1 1 1 1 | |||||
C 33 ; WX 32 ; N space ; B 2 2 2 2 | |||||
C 34 ; WX 33 ; N exclam ; B 3 3 3 3 | |||||
C 35 ; WX 34 ; N quotedbl ; B 4 4 4 4 | |||||
C 36 ; WX 35 ; N numbersign ; B 5 5 5 5 | |||||
C 37 ; WX 36 ; N dollar ; B 6 6 6 6 | |||||
C 38 ; WX 37 ; N percent ; B 7 7 7 7 | |||||
C 39 ; WX 38 ; N ampersand ; B 8 8 8 8 | |||||
C 40 ; WX 39 ; N quoteright ; B 9 9 9 9 | |||||
C 41 ; WX 40 ; N parenleft ; B 10 10 10 10 | |||||
C 42 ; WX 41 ; N parenright ; B 11 11 11 11 | |||||
C 43 ; WX 42 ; N asterisk ; B 12 12 12 12 | |||||
C 44 ; WX 43 ; N plus ; B 13 13 13 13 | |||||
C 45 ; WX 44 ; N comma ; B 14 14 14 14 | |||||
C 46 ; WX 45 ; N hyphen ; B 15 15 15 15 | |||||
C 46 ; WX 45 ; N hyphen ; B 16 16 16 16 | |||||
C 47 ; WX 46 ; N period ; B 17 17 17 17 | |||||
C 48 ; WX 47 ; N slash ; B 18 18 18 18 | |||||
C 49 ; WX 48 ; N zero ; B 19 19 19 19 | |||||
C 50 ; WX 49 ; N one ; B 20 20 20 20 | |||||
C 51 ; WX 50 ; N two ; B 21 21 21 21 | |||||
C 52 ; WX 51 ; N three ; B 22 22 22 22 | |||||
C 53 ; WX 52 ; N four ; B 23 23 23 23 | |||||
C 54 ; WX 53 ; N five ; B 24 24 24 24 | |||||
C 55 ; WX 54 ; N six ; B 25 25 25 25 | |||||
C 56 ; WX 55 ; N seven ; B 26 26 26 26 | |||||
C 57 ; WX 56 ; N eight ; B 27 27 27 27 | |||||
C 58 ; WX 57 ; N nine ; B 28 28 28 28 | |||||
C 59 ; WX 58 ; N colon ; B 29 29 29 29 | |||||
C 60 ; WX 59 ; N semicolon ; B 30 30 30 30 | |||||
C 61 ; WX 60 ; N less ; B 31 31 31 31 | |||||
C 62 ; WX 61 ; N equal ; B 32 32 32 32 | |||||
C 63 ; WX 62 ; N greater ; B 33 33 33 33 | |||||
C 64 ; WX 63 ; N question ; B 34 34 34 34 | |||||
C 65 ; WX 64 ; N at ; B 35 35 35 35 | |||||
C 66 ; WX 65 ; N A ; B 36 36 36 36 | |||||
C 67 ; WX 66 ; N B ; B 37 37 37 37 | |||||
C 68 ; WX 67 ; N C ; B 38 38 38 38 | |||||
C 69 ; WX 68 ; N D ; B 39 39 39 39 | |||||
C 70 ; WX 69 ; N E ; B 40 40 40 40 | |||||
C 71 ; WX 70 ; N F ; B 41 41 41 41 | |||||
C 72 ; WX 71 ; N G ; B 42 42 42 42 | |||||
C 73 ; WX 72 ; N H ; B 43 43 43 43 | |||||
C 74 ; WX 73 ; N I ; B 44 44 44 44 | |||||
C 75 ; WX 74 ; N J ; B 45 45 45 45 | |||||
C 76 ; WX 75 ; N K ; B 46 46 46 46 | |||||
C 77 ; WX 76 ; N L ; B 47 47 47 47 | |||||
C 78 ; WX 77 ; N M ; B 48 48 48 48 | |||||
C 79 ; WX 78 ; N N ; B 49 49 49 49 | |||||
C 80 ; WX 79 ; N O ; B 50 50 50 50 | |||||
C 81 ; WX 80 ; N P ; B 51 51 51 51 | |||||
C 82 ; WX 81 ; N Q ; B 52 52 52 52 | |||||
C 83 ; WX 82 ; N R ; B 53 53 53 53 | |||||
C 84 ; WX 83 ; N S ; B 54 54 54 54 | |||||
C 85 ; WX 84 ; N T ; B 55 55 55 55 | |||||
C 86 ; WX 85 ; N U ; B 56 56 56 56 | |||||
C 87 ; WX 86 ; N V ; B 57 57 57 57 | |||||
C 88 ; WX 87 ; N W ; B 58 58 58 58 | |||||
C 89 ; WX 88 ; N X ; B 59 59 59 59 | |||||
C 90 ; WX 89 ; N Y ; B 60 60 60 60 | |||||
C 91 ; WX 90 ; N Z ; B 61 61 61 61 | |||||
C 92 ; WX 91 ; N bracketleft ; B 62 62 62 62 | |||||
C 93 ; WX 92 ; N backslash ; B 63 63 63 63 | |||||
C 94 ; WX 93 ; N bracketright ; B 64 64 64 64 | |||||
C 95 ; WX 94 ; N asciicircum ; B 65 65 65 65 | |||||
C 96 ; WX 95 ; N underscore ; B 66 66 66 66 | |||||
C 97 ; WX 96 ; N quoteleft ; B 67 67 67 67 | |||||
C 98 ; WX 97 ; N a ; B 68 68 68 68 | |||||
C 99 ; WX 98 ; N b ; B 69 69 69 69 | |||||
C 100 ; WX 99 ; N c ; B 70 70 70 70 | |||||
C 101 ; WX 100 ; N d ; B 71 71 71 71 | |||||
C 102 ; WX 101 ; N e ; B 72 72 72 72 | |||||
C 103 ; WX 102 ; N f ; B 73 73 73 73 | |||||
C 104 ; WX 103 ; N g ; B 74 74 74 74 | |||||
C 105 ; WX 104 ; N h ; B 75 75 75 75 | |||||
C 106 ; WX 105 ; N i ; B 76 76 76 76 | |||||
C 107 ; WX 106 ; N j ; B 77 77 77 77 | |||||
C 108 ; WX 107 ; N k ; B 78 78 78 78 | |||||
C 109 ; WX 108 ; N l ; B 79 79 79 79 | |||||
C 110 ; WX 109 ; N m ; B 80 80 80 80 | |||||
C 111 ; WX 110 ; N n ; B 81 81 81 81 | |||||
C 112 ; WX 111 ; N o ; B 82 82 82 82 | |||||
C 113 ; WX 112 ; N p ; B 83 83 83 83 | |||||
C 114 ; WX 113 ; N q ; B 84 84 84 84 | |||||
C 115 ; WX 114 ; N r ; B 85 85 85 85 | |||||
C 116 ; WX 115 ; N s ; B 86 86 86 86 | |||||
C 117 ; WX 116 ; N t ; B 87 87 87 87 | |||||
C 118 ; WX 117 ; N u ; B 88 88 88 88 | |||||
C 119 ; WX 118 ; N v ; B 89 89 89 89 | |||||
C 120 ; WX 119 ; N w ; B 90 90 90 90 | |||||
C 121 ; WX 120 ; N x ; B 91 91 91 91 | |||||
C 122 ; WX 121 ; N y ; B 92 92 92 92 | |||||
C 123 ; WX 122 ; N z ; B 93 93 93 93 | |||||
C 124 ; WX 123 ; N braceleft ; B 94 94 94 94 | |||||
C 125 ; WX 124 ; N bar ; B 95 95 95 95 | |||||
C 126 ; WX 125 ; N braceright ; B 96 96 96 96 | |||||
C 127 ; WX 126 ; N asciitilde ; B 97 97 97 97 | |||||
C 162 ; WX 161 ; N exclamdown ; B 98 98 98 98 | |||||
C 163 ; WX 162 ; N cent ; B 99 99 99 99 | |||||
C 164 ; WX 163 ; N sterling ; B 100 100 100 100 | |||||
C 165 ; WX 164 ; N fraction ; B 101 101 101 101 | |||||
C 165 ; WX 164 ; N fraction ; B 102 102 102 102 | |||||
C 166 ; WX 165 ; N yen ; B 103 103 103 103 | |||||
C 167 ; WX 166 ; N florin ; B 104 104 104 104 | |||||
C 168 ; WX 167 ; N section ; B 105 105 105 105 | |||||
C 169 ; WX 168 ; N currency ; B 106 106 106 106 | |||||
C 170 ; WX 169 ; N quotesingle ; B 107 107 107 107 | |||||
C 171 ; WX 170 ; N quotedblleft ; B 108 108 108 108 | |||||
C 172 ; WX 171 ; N guillemotleft ; B 109 109 109 109 | |||||
C 173 ; WX 172 ; N guilsinglleft ; B 110 110 110 110 | |||||
C 174 ; WX 173 ; N guilsinglright ; B 111 111 111 111 | |||||
C 175 ; WX 174 ; N fi ; B 112 112 112 112 | |||||
C 176 ; WX 175 ; N fl ; B 113 113 113 113 | |||||
C 178 ; WX 177 ; N endash ; B 114 114 114 114 | |||||
C 179 ; WX 178 ; N dagger ; B 115 115 115 115 | |||||
C 180 ; WX 179 ; N daggerdbl ; B 116 116 116 116 | |||||
C 181 ; WX 180 ; N periodcentered ; B 117 117 117 117 | |||||
C 181 ; WX 180 ; N periodcentered ; B 118 118 118 118 | |||||
C 183 ; WX 182 ; N paragraph ; B 119 119 119 119 | |||||
C 184 ; WX 183 ; N bullet ; B 120 120 120 120 | |||||
C 185 ; WX 184 ; N quotesinglbase ; B 121 121 121 121 | |||||
C 186 ; WX 185 ; N quotedblbase ; B 122 122 122 122 | |||||
C 187 ; WX 186 ; N quotedblright ; B 123 123 123 123 | |||||
C 188 ; WX 187 ; N guillemotright ; B 124 124 124 124 | |||||
C 189 ; WX 188 ; N ellipsis ; B 125 125 125 125 | |||||
C 190 ; WX 189 ; N perthousand ; B 126 126 126 126 | |||||
C 192 ; WX 191 ; N questiondown ; B 127 127 127 127 | |||||
C 194 ; WX 193 ; N grave ; B 128 128 128 128 | |||||
C 195 ; WX 194 ; N acute ; B 129 129 129 129 | |||||
C 196 ; WX 195 ; N circumflex ; B 130 130 130 130 | |||||
C 197 ; WX 196 ; N tilde ; B 131 131 131 131 | |||||
C 198 ; WX 197 ; N macron ; B 132 132 132 132 | |||||
C 198 ; WX 197 ; N macron ; B 133 133 133 133 | |||||
C 199 ; WX 198 ; N breve ; B 134 134 134 134 | |||||
C 200 ; WX 199 ; N dotaccent ; B 135 135 135 135 | |||||
C 201 ; WX 200 ; N dieresis ; B 136 136 136 136 | |||||
C 203 ; WX 202 ; N ring ; B 137 137 137 137 | |||||
C 204 ; WX 203 ; N cedilla ; B 138 138 138 138 | |||||
C 206 ; WX 205 ; N hungarumlaut ; B 139 139 139 139 | |||||
C 207 ; WX 206 ; N ogonek ; B 140 140 140 140 | |||||
C 208 ; WX 207 ; N caron ; B 141 141 141 141 | |||||
C 209 ; WX 208 ; N emdash ; B 142 142 142 142 | |||||
C 226 ; WX 225 ; N AE ; B 143 143 143 143 | |||||
C 228 ; WX 227 ; N ordfeminine ; B 144 144 144 144 | |||||
C 233 ; WX 232 ; N Lslash ; B 145 145 145 145 | |||||
C 234 ; WX 233 ; N Oslash ; B 146 146 146 146 | |||||
C 235 ; WX 234 ; N OE ; B 147 147 147 147 | |||||
C 236 ; WX 235 ; N ordmasculine ; B 148 148 148 148 | |||||
C 242 ; WX 241 ; N ae ; B 149 149 149 149 | |||||
C 246 ; WX 245 ; N dotlessi ; B 150 150 150 150 | |||||
C 249 ; WX 248 ; N lslash ; B 151 151 151 151 | |||||
C 250 ; WX 249 ; N oslash ; B 152 152 152 152 | |||||
C 251 ; WX 250 ; N oe ; B 153 153 153 153 | |||||
C 252 ; WX 251 ; N germandbls ; B 154 154 154 154 | |||||
EndCharMetrics |
StartFontMetrics 2.0 | |||||
EncodingScheme FontSpecific | |||||
StartCharMetrics 154 | |||||
C 33 ; WX 32 ; N space ; B 1 1 1 1 | |||||
C 33 ; WX 32 ; N space ; B 2 2 2 2 | |||||
C 34 ; WX 33 ; N exclam ; B 3 3 3 3 | |||||
C 35 ; WX 34 ; N quotedbl ; B 4 4 4 4 | |||||
C 36 ; WX 35 ; N numbersign ; B 5 5 5 5 | |||||
C 37 ; WX 36 ; N dollar ; B 6 6 6 6 | |||||
C 38 ; WX 37 ; N percent ; B 7 7 7 7 | |||||
C 39 ; WX 38 ; N ampersand ; B 8 8 8 8 | |||||
C 40 ; WX 39 ; N quoteright ; B 9 9 9 9 | |||||
C 41 ; WX 40 ; N parenleft ; B 10 10 10 10 | |||||
C 42 ; WX 41 ; N parenright ; B 11 11 11 11 | |||||
C 43 ; WX 42 ; N asterisk ; B 12 12 12 12 | |||||
C 44 ; WX 43 ; N plus ; B 13 13 13 13 | |||||
C 45 ; WX 44 ; N comma ; B 14 14 14 14 | |||||
C 46 ; WX 45 ; N hyphen ; B 15 15 15 15 | |||||
C 46 ; WX 45 ; N hyphen ; B 16 16 16 16 | |||||
C 47 ; WX 46 ; N period ; B 17 17 17 17 | |||||
C 48 ; WX 47 ; N slash ; B 18 18 18 18 | |||||
C 49 ; WX 48 ; N zero ; B 19 19 19 19 | |||||
C 50 ; WX 49 ; N one ; B 20 20 20 20 | |||||
C 51 ; WX 50 ; N two ; B 21 21 21 21 | |||||
C 52 ; WX 51 ; N three ; B 22 22 22 22 | |||||
C 53 ; WX 52 ; N four ; B 23 23 23 23 | |||||
C 54 ; WX 53 ; N five ; B 24 24 24 24 | |||||
C 55 ; WX 54 ; N six ; B 25 25 25 25 | |||||
C 56 ; WX 55 ; N seven ; B 26 26 26 26 | |||||
C 57 ; WX 56 ; N eight ; B 27 27 27 27 | |||||
C 58 ; WX 57 ; N nine ; B 28 28 28 28 | |||||
C 59 ; WX 58 ; N colon ; B 29 29 29 29 | |||||
C 60 ; WX 59 ; N semicolon ; B 30 30 30 30 | |||||
C 61 ; WX 60 ; N less ; B 31 31 31 31 | |||||
C 62 ; WX 61 ; N equal ; B 32 32 32 32 | |||||
C 63 ; WX 62 ; N greater ; B 33 33 33 33 | |||||
C 64 ; WX 63 ; N question ; B 34 34 34 34 | |||||
C 65 ; WX 64 ; N at ; B 35 35 35 35 | |||||
C 66 ; WX 65 ; N A ; B 36 36 36 36 | |||||
C 67 ; WX 66 ; N B ; B 37 37 37 37 | |||||
C 68 ; WX 67 ; N C ; B 38 38 38 38 | |||||
C 69 ; WX 68 ; N D ; B 39 39 39 39 | |||||
C 70 ; WX 69 ; N E ; B 40 40 40 40 | |||||
C 71 ; WX 70 ; N F ; B 41 41 41 41 | |||||
C 72 ; WX 71 ; N G ; B 42 42 42 42 | |||||
C 73 ; WX 72 ; N H ; B 43 43 43 43 | |||||
C 74 ; WX 73 ; N I ; B 44 44 44 44 | |||||
C 75 ; WX 74 ; N J ; B 45 45 45 45 | |||||
C 76 ; WX 75 ; N K ; B 46 46 46 46 | |||||
C 77 ; WX 76 ; N L ; B 47 47 47 47 | |||||
C 78 ; WX 77 ; N M ; B 48 48 48 48 | |||||
C 79 ; WX 78 ; N N ; B 49 49 49 49 | |||||
C 80 ; WX 79 ; N O ; B 50 50 50 50 | |||||
C 81 ; WX 80 ; N P ; B 51 51 51 51 | |||||
C 82 ; WX 81 ; N Q ; B 52 52 52 52 | |||||
C 83 ; WX 82 ; N R ; B 53 53 53 53 | |||||
C 84 ; WX 83 ; N S ; B 54 54 54 54 | |||||
C 85 ; WX 84 ; N T ; B 55 55 55 55 | |||||
C 86 ; WX 85 ; N U ; B 56 56 56 56 | |||||
C 87 ; WX 86 ; N V ; B 57 57 57 57 | |||||
C 88 ; WX 87 ; N W ; B 58 58 58 58 | |||||
C 89 ; WX 88 ; N X ; B 59 59 59 59 | |||||
C 90 ; WX 89 ; N Y ; B 60 60 60 60 | |||||
C 91 ; WX 90 ; N Z ; B 61 61 61 61 | |||||
C 92 ; WX 91 ; N bracketleft ; B 62 62 62 62 | |||||
C 93 ; WX 92 ; N backslash ; B 63 63 63 63 | |||||
C 94 ; WX 93 ; N bracketright ; B 64 64 64 64 | |||||
C 95 ; WX 94 ; N asciicircum ; B 65 65 65 65 | |||||
C 96 ; WX 95 ; N underscore ; B 66 66 66 66 | |||||
C 97 ; WX 96 ; N quoteleft ; B 67 67 67 67 | |||||
C 98 ; WX 97 ; N a ; B 68 68 68 68 | |||||
C 99 ; WX 98 ; N b ; B 69 69 69 69 | |||||
C 100 ; WX 99 ; N c ; B 70 70 70 70 | |||||
C 101 ; WX 100 ; N d ; B 71 71 71 71 | |||||
C 102 ; WX 101 ; N e ; B 72 72 72 72 | |||||
C 103 ; WX 102 ; N f ; B 73 73 73 73 | |||||
C 104 ; WX 103 ; N g ; B 74 74 74 74 | |||||
C 105 ; WX 104 ; N h ; B 75 75 75 75 | |||||
C 106 ; WX 105 ; N i ; B 76 76 76 76 | |||||
C 107 ; WX 106 ; N j ; B 77 77 77 77 | |||||
C 108 ; WX 107 ; N k ; B 78 78 78 78 | |||||
C 109 ; WX 108 ; N l ; B 79 79 79 79 | |||||
C 110 ; WX 109 ; N m ; B 80 80 80 80 | |||||
C 111 ; WX 110 ; N n ; B 81 81 81 81 | |||||
C 112 ; WX 111 ; N o ; B 82 82 82 82 | |||||
C 113 ; WX 112 ; N p ; B 83 83 83 83 | |||||
C 114 ; WX 113 ; N q ; B 84 84 84 84 | |||||
C 115 ; WX 114 ; N r ; B 85 85 85 85 | |||||
C 116 ; WX 115 ; N s ; B 86 86 86 86 | |||||
C 117 ; WX 116 ; N t ; B 87 87 87 87 | |||||
C 118 ; WX 117 ; N u ; B 88 88 88 88 | |||||
C 119 ; WX 118 ; N v ; B 89 89 89 89 | |||||
C 120 ; WX 119 ; N w ; B 90 90 90 90 | |||||
C 121 ; WX 120 ; N x ; B 91 91 91 91 | |||||
C 122 ; WX 121 ; N y ; B 92 92 92 92 | |||||
C 123 ; WX 122 ; N z ; B 93 93 93 93 | |||||
C 124 ; WX 123 ; N braceleft ; B 94 94 94 94 | |||||
C 125 ; WX 124 ; N bar ; B 95 95 95 95 | |||||
C 126 ; WX 125 ; N braceright ; B 96 96 96 96 | |||||
C 127 ; WX 126 ; N asciitilde ; B 97 97 97 97 | |||||
C 162 ; WX 161 ; N exclamdown ; B 98 98 98 98 | |||||
C 163 ; WX 162 ; N cent ; B 99 99 99 99 | |||||
C 164 ; WX 163 ; N sterling ; B 100 100 100 100 | |||||
C 165 ; WX 164 ; N fraction ; B 101 101 101 101 | |||||
C 165 ; WX 164 ; N fraction ; B 102 102 102 102 | |||||
C 166 ; WX 165 ; N yen ; B 103 103 103 103 | |||||
C 167 ; WX 166 ; N florin ; B 104 104 104 104 | |||||
C 168 ; WX 167 ; N section ; B 105 105 105 105 | |||||
C 169 ; WX 168 ; N currency ; B 106 106 106 106 | |||||
C 170 ; WX 169 ; N quotesingle ; B 107 107 107 107 | |||||
C 171 ; WX 170 ; N quotedblleft ; B 108 108 108 108 | |||||
C 172 ; WX 171 ; N guillemotleft ; B 109 109 109 109 | |||||
C 173 ; WX 172 ; N guilsinglleft ; B 110 110 110 110 | |||||
C 174 ; WX 173 ; N guilsinglright ; B 111 111 111 111 | |||||
C 175 ; WX 174 ; N fi ; B 112 112 112 112 | |||||
C 176 ; WX 175 ; N fl ; B 113 113 113 113 | |||||
C 178 ; WX 177 ; N endash ; B 114 114 114 114 | |||||
C 179 ; WX 178 ; N dagger ; B 115 115 115 115 | |||||
C 180 ; WX 179 ; N daggerdbl ; B 116 116 116 116 | |||||
C 181 ; WX 180 ; N periodcentered ; B 117 117 117 117 | |||||
C 181 ; WX 180 ; N periodcentered ; B 118 118 118 118 | |||||
C 183 ; WX 182 ; N paragraph ; B 119 119 119 119 | |||||
C 184 ; WX 183 ; N bullet ; B 120 120 120 120 | |||||
C 185 ; WX 184 ; N quotesinglbase ; B 121 121 121 121 | |||||
C 186 ; WX 185 ; N quotedblbase ; B 122 122 122 122 | |||||
C 187 ; WX 186 ; N quotedblright ; B 123 123 123 123 | |||||
C 188 ; WX 187 ; N guillemotright ; B 124 124 124 124 | |||||
C 189 ; WX 188 ; N ellipsis ; B 125 125 125 125 | |||||
C 190 ; WX 189 ; N perthousand ; B 126 126 126 126 | |||||
C 192 ; WX 191 ; N questiondown ; B 127 127 127 127 | |||||
C 194 ; WX 193 ; N grave ; B 128 128 128 128 | |||||
C 195 ; WX 194 ; N acute ; B 129 129 129 129 | |||||
C 196 ; WX 195 ; N circumflex ; B 130 130 130 130 | |||||
C 197 ; WX 196 ; N tilde ; B 131 131 131 131 | |||||
C 198 ; WX 197 ; N macron ; B 132 132 132 132 | |||||
C 198 ; WX 197 ; N macron ; B 133 133 133 133 | |||||
C 199 ; WX 198 ; N breve ; B 134 134 134 134 | |||||
C 200 ; WX 199 ; N dotaccent ; B 135 135 135 135 | |||||
C 201 ; WX 200 ; N dieresis ; B 136 136 136 136 | |||||
C 203 ; WX 202 ; N ring ; B 137 137 137 137 | |||||
C 204 ; WX 203 ; N cedilla ; B 138 138 138 138 | |||||
C 206 ; WX 205 ; N hungarumlaut ; B 139 139 139 139 | |||||
C 207 ; WX 206 ; N ogonek ; B 140 140 140 140 | |||||
C 208 ; WX 207 ; N caron ; B 141 141 141 141 | |||||
C 209 ; WX 208 ; N emdash ; B 142 142 142 142 | |||||
C 226 ; WX 225 ; N AE ; B 143 143 143 143 | |||||
C 228 ; WX 227 ; N ordfeminine ; B 144 144 144 144 | |||||
C 233 ; WX 232 ; N Lslash ; B 145 145 145 145 | |||||
C 234 ; WX 233 ; N Oslash ; B 146 146 146 146 | |||||
C 235 ; WX 234 ; N OE ; B 147 147 147 147 | |||||
C 236 ; WX 235 ; N ordmasculine ; B 148 148 148 148 | |||||
C 242 ; WX 241 ; N ae ; B 149 149 149 149 | |||||
C 246 ; WX 245 ; N dotlessi ; B 150 150 150 150 | |||||
C 249 ; WX 248 ; N lslash ; B 151 151 151 151 | |||||
C 250 ; WX 249 ; N oslash ; B 152 152 152 152 | |||||
C 251 ; WX 250 ; N oe ; B 153 153 153 153 | |||||
C 252 ; WX 251 ; N germandbls ; B 154 154 154 154 | |||||
EndCharMetrics |
<base>./</base> | <base>./</base> | ||||
<!-- Font Base URL for resolving relative font URLs --> | <!-- Font Base URL for resolving relative font URLs --> | ||||
<font-base>./resources/fonts</font-base> | |||||
<font-base>./resources/fonts/ttf/</font-base> | |||||
<renderers> | <renderers> | ||||
<renderer mime="application/pdf"> | <renderer mime="application/pdf"> |
<value>null</value> | <value>null</value> | ||||
</filterList> | </filterList> | ||||
<fonts> | <fonts> | ||||
<font metrics-url="test/resources/fonts/glb12.ttf.xml" embed-url="test/resources/fonts/glb12.ttf"> | |||||
<font metrics-url="test/resources/fonts/ttf/glb12.ttf.xml" embed-url="test/resources/fonts/ttf/glb12.ttf"> | |||||
<font-triplet name="Gladiator" style="normal" weight="normal"/> | <font-triplet name="Gladiator" style="normal" weight="normal"/> | ||||
<font-triplet name="Gladiator" style="normal" weight="bold"/> | <font-triplet name="Gladiator" style="normal" weight="bold"/> | ||||
</font> | </font> | ||||
<font metrics-url="test/resources/fonts/glb12.ttf.ansi.xml" embed-url="test/resources/fonts/glb12.ttf"> | |||||
<font metrics-url="test/resources/fonts/ttf/glb12.ttf.ansi.xml" embed-url="test/resources/fonts/ttf/glb12.ttf"> | |||||
<font-triplet name="Gladiator-Ansi" style="normal" weight="normal"/> | <font-triplet name="Gladiator-Ansi" style="normal" weight="normal"/> | ||||
<font-triplet name="Gladiator-Ansi" style="normal" weight="bold"/> | <font-triplet name="Gladiator-Ansi" style="normal" weight="bold"/> | ||||
</font> | </font> | ||||
<font metrics-url="test/resources/fonts/glb12.ttf.ansi.xml"> | |||||
<font metrics-url="test/resources/fonts/ttf/glb12.ttf.ansi.xml"> | |||||
<font-triplet name="Gladiator-Non-Embedded" style="normal" weight="normal"/> | <font-triplet name="Gladiator-Non-Embedded" style="normal" weight="normal"/> | ||||
<font-triplet name="Gladiator-Non-Embedded" style="normal" weight="bold"/> | <font-triplet name="Gladiator-Non-Embedded" style="normal" weight="bold"/> | ||||
</font> | </font> |
<!-- use a custom font to show encoding problems --> | <!-- use a custom font to show encoding problems --> | ||||
<fonts> | <fonts> | ||||
<font metrics-url="test/resources/fonts/glb12.ttf.xml" embed-url="test/resources/fonts/glb12.ttf"> | |||||
<font metrics-url="test/resources/fonts/ttf/glb12.ttf.xml" embed-url="test/resources/fonts/ttf/glb12.ttf"> | |||||
<font-triplet name="Gladiator" style="normal" weight="normal"/> | <font-triplet name="Gladiator" style="normal" weight="normal"/> | ||||
</font> | </font> | ||||
</fonts> | </fonts> |