aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop/fonts
diff options
context:
space:
mode:
authorGlenn Adams <gadams@apache.org>2016-03-03 09:49:26 +0000
committerGlenn Adams <gadams@apache.org>2016-03-03 09:49:26 +0000
commitc8cde713f54ca731f4a7f3bfaef8af9e8a1b9262 (patch)
treef553e13b28bd90fd2067bf390509f9290260d330 /src/java/org/apache/fop/fonts
parent82804d6ffcb68841cd7adf9740469f3a79c372c8 (diff)
downloadxmlgraphics-fop-c8cde713f54ca731f4a7f3bfaef8af9e8a1b9262.tar.gz
xmlgraphics-fop-c8cde713f54ca731f4a7f3bfaef8af9e8a1b9262.zip
Transition source to standard maven hierarchy (initial).
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/maven@1733433 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop/fonts')
-rw-r--r--src/java/org/apache/fop/fonts/AbstractCodePointMapping.java216
-rw-r--r--src/java/org/apache/fop/fonts/Base14Font.java39
-rw-r--r--src/java/org/apache/fop/fonts/CIDFont.java88
-rw-r--r--src/java/org/apache/fop/fonts/CIDFontType.java82
-rw-r--r--src/java/org/apache/fop/fonts/CIDFull.java124
-rw-r--r--src/java/org/apache/fop/fonts/CIDSet.java104
-rw-r--r--src/java/org/apache/fop/fonts/CIDSubset.java160
-rw-r--r--src/java/org/apache/fop/fonts/CMapSegment.java106
-rw-r--r--src/java/org/apache/fop/fonts/CustomFont.java583
-rw-r--r--src/java/org/apache/fop/fonts/CustomFontCollection.java73
-rw-r--r--src/java/org/apache/fop/fonts/DefaultFontConfig.java359
-rw-r--r--src/java/org/apache/fop/fonts/DefaultFontConfigurator.java191
-rw-r--r--src/java/org/apache/fop/fonts/EmbedFontInfo.java217
-rw-r--r--src/java/org/apache/fop/fonts/EmbeddingMode.java58
-rw-r--r--src/java/org/apache/fop/fonts/EncodingMode.java69
-rw-r--r--src/java/org/apache/fop/fonts/Font.java465
-rw-r--r--src/java/org/apache/fop/fonts/FontAdder.java75
-rw-r--r--src/java/org/apache/fop/fonts/FontCache.java549
-rw-r--r--src/java/org/apache/fop/fonts/FontCacheManager.java55
-rw-r--r--src/java/org/apache/fop/fonts/FontCacheManagerFactory.java111
-rw-r--r--src/java/org/apache/fop/fonts/FontCollection.java39
-rw-r--r--src/java/org/apache/fop/fonts/FontConfig.java50
-rw-r--r--src/java/org/apache/fop/fonts/FontConfigurator.java39
-rw-r--r--src/java/org/apache/fop/fonts/FontDescriptor.java95
-rw-r--r--src/java/org/apache/fop/fonts/FontDetector.java34
-rw-r--r--src/java/org/apache/fop/fonts/FontDetectorFactory.java119
-rw-r--r--src/java/org/apache/fop/fonts/FontEventAdapter.java74
-rw-r--r--src/java/org/apache/fop/fonts/FontEventListener.java64
-rw-r--r--src/java/org/apache/fop/fonts/FontEventProducer.java89
-rw-r--r--src/java/org/apache/fop/fonts/FontEventProducer.xml25
-rw-r--r--src/java/org/apache/fop/fonts/FontInfo.java659
-rw-r--r--src/java/org/apache/fop/fonts/FontLoader.java128
-rw-r--r--src/java/org/apache/fop/fonts/FontManager.java232
-rw-r--r--src/java/org/apache/fop/fonts/FontManagerConfigurator.java217
-rw-r--r--src/java/org/apache/fop/fonts/FontMetrics.java200
-rw-r--r--src/java/org/apache/fop/fonts/FontReader.java309
-rw-r--r--src/java/org/apache/fop/fonts/FontSelector.java143
-rw-r--r--src/java/org/apache/fop/fonts/FontSetup.java217
-rw-r--r--src/java/org/apache/fop/fonts/FontTriplet.java152
-rw-r--r--src/java/org/apache/fop/fonts/FontType.java142
-rw-r--r--src/java/org/apache/fop/fonts/FontUris.java65
-rw-r--r--src/java/org/apache/fop/fonts/FontUtil.java159
-rw-r--r--src/java/org/apache/fop/fonts/GlyphMapping.java340
-rw-r--r--src/java/org/apache/fop/fonts/Glyphs.java1318
-rw-r--r--src/java/org/apache/fop/fonts/LazyFont.java502
-rw-r--r--src/java/org/apache/fop/fonts/MultiByteFont.java807
-rw-r--r--src/java/org/apache/fop/fonts/MutableFont.java161
-rw-r--r--src/java/org/apache/fop/fonts/NamedCharacter.java142
-rw-r--r--src/java/org/apache/fop/fonts/SimpleSingleByteEncoding.java160
-rw-r--r--src/java/org/apache/fop/fonts/SingleByteEncoding.java58
-rw-r--r--src/java/org/apache/fop/fonts/SingleByteFont.java552
-rw-r--r--src/java/org/apache/fop/fonts/TextFragment.java71
-rw-r--r--src/java/org/apache/fop/fonts/Typeface.java158
-rw-r--r--src/java/org/apache/fop/fonts/apps/AbstractFontReader.java142
-rw-r--r--src/java/org/apache/fop/fonts/apps/PFMReader.java328
-rw-r--r--src/java/org/apache/fop/fonts/apps/TTFReader.java514
-rw-r--r--src/java/org/apache/fop/fonts/apps/package.html23
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/FontDirFinder.java41
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java179
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/FontFinder.java41
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java279
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/MacFontDirFinder.java39
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/NativeFontDirFinder.java55
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/UnixFontDirFinder.java40
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/WindowsFontDirFinder.java120
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/package.html23
-rw-r--r--src/java/org/apache/fop/fonts/base14/Base14FontCollection.java149
-rw-r--r--src/java/org/apache/fop/fonts/base14/package.html6
-rw-r--r--src/java/org/apache/fop/fonts/cff/CFFDataReader.java929
-rw-r--r--src/java/org/apache/fop/fonts/package.html23
-rw-r--r--src/java/org/apache/fop/fonts/substitute/AttributeValue.java65
-rw-r--r--src/java/org/apache/fop/fonts/substitute/FontQualifier.java306
-rw-r--r--src/java/org/apache/fop/fonts/substitute/FontSubstitution.java61
-rw-r--r--src/java/org/apache/fop/fonts/substitute/FontSubstitutions.java67
-rw-r--r--src/java/org/apache/fop/fonts/substitute/FontSubstitutionsConfigurator.java84
-rw-r--r--src/java/org/apache/fop/fonts/substitute/FontWeightRange.java114
-rw-r--r--src/java/org/apache/fop/fonts/substitute/package.html23
-rw-r--r--src/java/org/apache/fop/fonts/truetype/FontFileReader.java325
-rw-r--r--src/java/org/apache/fop/fonts/truetype/GlyfTable.java231
-rw-r--r--src/java/org/apache/fop/fonts/truetype/OFDirTabEntry.java117
-rw-r--r--src/java/org/apache/fop/fonts/truetype/OFFontLoader.java271
-rw-r--r--src/java/org/apache/fop/fonts/truetype/OFMtxEntry.java195
-rw-r--r--src/java/org/apache/fop/fonts/truetype/OFTableName.java169
-rw-r--r--src/java/org/apache/fop/fonts/truetype/OTFFile.java175
-rw-r--r--src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java1129
-rw-r--r--src/java/org/apache/fop/fonts/truetype/OpenFont.java2006
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFFile.java203
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFGlyphOutputStream.java48
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFOutputStream.java49
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java714
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFTableOutputStream.java37
-rw-r--r--src/java/org/apache/fop/fonts/truetype/package.html6
-rw-r--r--src/java/org/apache/fop/fonts/type1/AFMCharMetrics.java167
-rw-r--r--src/java/org/apache/fop/fonts/type1/AFMFile.java505
-rw-r--r--src/java/org/apache/fop/fonts/type1/AFMParser.java597
-rw-r--r--src/java/org/apache/fop/fonts/type1/AFMWritingDirectionMetrics.java96
-rw-r--r--src/java/org/apache/fop/fonts/type1/AdobeStandardEncoding.java419
-rw-r--r--src/java/org/apache/fop/fonts/type1/CharMetricsHandler.java120
-rw-r--r--src/java/org/apache/fop/fonts/type1/PFBData.java185
-rw-r--r--src/java/org/apache/fop/fonts/type1/PFBParser.java202
-rw-r--r--src/java/org/apache/fop/fonts/type1/PFMFile.java521
-rw-r--r--src/java/org/apache/fop/fonts/type1/PFMInputStream.java113
-rw-r--r--src/java/org/apache/fop/fonts/type1/PostscriptParser.java655
-rw-r--r--src/java/org/apache/fop/fonts/type1/Type1FontLoader.java463
-rw-r--r--src/java/org/apache/fop/fonts/type1/Type1SubsetFile.java756
-rw-r--r--src/java/org/apache/fop/fonts/type1/package.html6
106 files changed, 0 insertions, 25375 deletions
diff --git a/src/java/org/apache/fop/fonts/AbstractCodePointMapping.java b/src/java/org/apache/fop/fonts/AbstractCodePointMapping.java
deleted file mode 100644
index ca0c52d5e..000000000
--- a/src/java/org/apache/fop/fonts/AbstractCodePointMapping.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * 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.util.Arrays;
-
-import org.apache.xmlgraphics.fonts.Glyphs;
-
-import org.apache.fop.util.CharUtilities;
-
-/**
- * Abstract base class for code point mapping classes (1-byte character encodings).
- */
-public class AbstractCodePointMapping implements SingleByteEncoding {
-
- private final String name;
- private char[] latin1Map;
- private char[] characters;
- private char[] codepoints;
- private char[] unicodeMap; //code point to Unicode char
- private String[] charNameMap; //all character names in the encoding
-
- /**
- * Main constructor.
- * @param name the name of the encoding
- * @param table the table ([code point, unicode scalar value]+) with the mapping
- */
- public AbstractCodePointMapping(String name, int[] table) {
- this(name, table, null);
- }
-
- /**
- * Extended constructor.
- * @param name the name of the encoding
- * @param table the table ([code point, unicode scalar value]+) with the mapping
- * @param charNameMap all character names in the encoding (a value of null will be converted
- * to ".notdef")
- */
- public AbstractCodePointMapping(String name, int[] table, String[] charNameMap) {
- this.name = name;
- buildFromTable(table);
- if (charNameMap != null) {
- this.charNameMap = new String[256];
- for (int i = 0; i < 256; i++) {
- String charName = charNameMap[i];
- if (charName == null) {
- this.charNameMap[i] = Glyphs.NOTDEF;
- } else {
- this.charNameMap[i] = charName;
- }
- }
- }
- }
-
- /**
- * Builds the internal lookup structures based on a given table.
- * @param table the table ([code point, unicode scalar value]+) with the mapping
- */
- protected void buildFromTable(int[] table) {
- int nonLatin1 = 0;
- latin1Map = new char[256];
- unicodeMap = new char[256];
- Arrays.fill(unicodeMap, CharUtilities.NOT_A_CHARACTER);
- for (int i = 0; i < table.length; i += 2) {
- char unicode = (char)table[i + 1];
- if (unicode < 256) {
- if (latin1Map[unicode] == 0) {
- latin1Map[unicode] = (char) table[i];
- }
- } else {
- ++nonLatin1;
- }
- if (unicodeMap[table[i]] == CharUtilities.NOT_A_CHARACTER) {
- unicodeMap[table[i]] = unicode;
- }
- }
- characters = new char[nonLatin1];
- codepoints = new char[nonLatin1];
- int top = 0;
- for (int i = 0; i < table.length; i += 2) {
- char c = (char) table[i + 1];
- if (c >= 256) {
- ++top;
- for (int j = top - 1; j >= 0; --j) {
- if (j > 0 && characters[j - 1] >= c) {
- characters[j] = characters[j - 1];
- codepoints[j] = codepoints[j - 1];
- } else {
- characters[j] = c;
- codepoints[j] = (char) table[i];
- break;
- }
- }
- }
- }
- }
-
- /** {@inheritDoc} */
- public String getName() {
- return this.name;
- }
-
- /** {@inheritDoc} */
- public final char mapChar(char c) {
- if (c < 256) {
- char latin1 = latin1Map[c];
- if (latin1 > 0) {
- return latin1;
- }
- }
- int bot = 0;
- int top = characters.length - 1;
- while (top >= bot) {
- assert bot < 65536;
- assert top < 65536;
- int mid = (bot + top) >>> 1;
- char mc = characters[mid];
-
- if (c == mc) {
- return codepoints[mid];
- } else if (c < mc) {
- top = mid - 1;
- } else {
- bot = mid + 1;
- }
- }
- return NOT_FOUND_CODE_POINT;
- }
-
- /**
- * Returns the main Unicode value that is associated with the given code point in the encoding.
- * Note that multiple Unicode values can theoretically be mapped to one code point in the
- * encoding.
- * @param idx the code point in the encoding
- * @return the Unicode value (or \uFFFF (NOT A CHARACTER) if no Unicode value is at that point)
- */
- public final char getUnicodeForIndex(int idx) {
- return this.unicodeMap[idx];
- }
-
- /** {@inheritDoc} */
- public final char[] getUnicodeCharMap() {
- char[] copy = new char[this.unicodeMap.length];
- System.arraycopy(this.unicodeMap, 0, copy, 0, this.unicodeMap.length);
- return copy;
- }
-
- /**
- * Returns the index of a character/glyph with the given name. Note that this
- * method is relatively slow and should only be used for fallback operations.
- * @param charName the character name
- * @return the index of the character in the encoding or -1 if it doesn't exist
- */
- public short getCodePointForGlyph(String charName) {
- String[] names = this.charNameMap;
- if (names == null) {
- names = getCharNameMap();
- }
- for (short i = 0, c = (short)names.length; i < c; i++) {
- if (names[i].equals(charName)) {
- return i;
- }
- }
- return -1;
- }
-
- public String getNameFromCodePoint(int idx) {
- return getCharNameMap()[idx];
- }
-
- /** {@inheritDoc} */
- public String[] getCharNameMap() {
- if (this.charNameMap != null) {
- String[] copy = new String[this.charNameMap.length];
- System.arraycopy(this.charNameMap, 0, copy, 0, this.charNameMap.length);
- return copy;
- } else {
- //Note: this is suboptimal but will probably never be used.
- String[] derived = new String[256];
- Arrays.fill(derived, Glyphs.NOTDEF);
- for (int i = 0; i < 256; i++) {
- char c = getUnicodeForIndex(i);
- if (c != CharUtilities.NOT_A_CHARACTER) {
- String charName = Glyphs.charToGlyphName(c);
- if (charName.length() > 0) {
- derived[i] = charName;
- }
- }
- }
- return derived;
- }
- }
-
- /** {@inheritDoc} */
- @Override
- public String toString() {
- return getName();
- }
-}
diff --git a/src/java/org/apache/fop/fonts/Base14Font.java b/src/java/org/apache/fop/fonts/Base14Font.java
deleted file mode 100644
index fdefd0cdd..000000000
--- a/src/java/org/apache/fop/fonts/Base14Font.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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;
-
-
-/**
- * Base class for all Base 14 fonts.
- */
-public abstract class Base14Font extends Typeface {
-
- /** Thickness for underline and strikeout. */
- private static final int LINE_THICKNESS = 50;
-
- public int getStrikeoutPosition(int size) {
- return getXHeight(size) / 2;
- }
-
- public int getStrikeoutThickness(int size) {
- return size * LINE_THICKNESS;
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/CIDFont.java b/src/java/org/apache/fop/fonts/CIDFont.java
deleted file mode 100644
index dc398263e..000000000
--- a/src/java/org/apache/fop/fonts/CIDFont.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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 org.apache.fop.apps.io.InternalResourceResolver;
-
-//Java
-
-/**
- * Abstract base class for CID fonts.
- */
-public abstract class CIDFont extends CustomFont {
-
- /** Contains the character widths for all characters in the font */
- protected int[] width;
-
- /**
- * @param resourceResolver the URI resolver for controlling file access
- */
- public CIDFont(InternalResourceResolver resourceResolver) {
- super(resourceResolver);
- }
-
- // ---- Required ----
- /**
- * Returns the type of the CID font.
- * @return the type of the CID font
- */
- public abstract CIDFontType getCIDType();
-
- /**
- * Returns the name of the issuer of the font.
- * @return a String identifying an issuer of character collections -
- * for example, Adobe
- */
- public abstract String getRegistry();
-
- /**
- * Returns a font name for use within a registry.
- * @return a String that uniquely names a character collection issued by
- * a specific registry - for example, Japan1.
- */
- public abstract String getOrdering();
-
- /**
- * Returns the supplement number of the character collection.
- * @return the supplement number
- */
- public abstract int getSupplement();
-
- /**
- * Returns the subset information for this font.
- * @return the subset information
- */
- public abstract CIDSet getCIDSet();
-
- // ---- Optional ----
- /**
- * Returns the default width for this font.
- * @return the default width
- */
- public int getDefaultWidth() {
- return 0;
- }
-
- /** {@inheritDoc} */
- public boolean isMultiByte() {
- return true;
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/CIDFontType.java b/src/java/org/apache/fop/fonts/CIDFontType.java
deleted file mode 100644
index 20a94b9dd..000000000
--- a/src/java/org/apache/fop/fonts/CIDFontType.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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 org.apache.avalon.framework.ValuedEnum;
-
-/**
- * This class enumerates all supported CID font types.
- */
-public class CIDFontType extends ValuedEnum {
-
- /**
- * CID Font Type 0 (based on Type 1 format)
- */
- public static final CIDFontType CIDTYPE0 = new CIDFontType("CIDFontType0", 0);
-
- /**
- * CID Font Type 2 (based on TrueType format)
- */
- public static final CIDFontType CIDTYPE2 = new CIDFontType("CIDFontType2", 2);
-
-
- /**
- * Construct a CID font type.
- * @param name a type name
- * @param value a type value
- * @see org.apache.avalon.framework.Enum#Enum(String)
- */
- protected CIDFontType(String name, int value) {
- super(name, value);
- }
-
-
- /**
- * Returns the CIDFontType by name.
- * @param name Name of the CID font type to look up
- * @return FontType the CID font type
- */
- public static CIDFontType byName(String name) {
- if (name.equalsIgnoreCase(CIDFontType.CIDTYPE0.getName())) {
- return CIDFontType.CIDTYPE0;
- } else if (name.equalsIgnoreCase(CIDFontType.CIDTYPE2.getName())) {
- return CIDFontType.CIDTYPE2;
- } else {
- throw new IllegalArgumentException("Invalid CID font type: " + name);
- }
- }
-
-
- /**
- * Returns the CID FontType by value.
- * @param value Value of the CID font type to look up
- * @return FontType the CID font type
- */
- public static CIDFontType byValue(int value) {
- if (value == CIDFontType.CIDTYPE0.getValue()) {
- return CIDFontType.CIDTYPE0;
- } else if (value == CIDFontType.CIDTYPE2.getValue()) {
- return CIDFontType.CIDTYPE2;
- } else {
- throw new IllegalArgumentException("Invalid CID font type: " + value);
- }
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/CIDFull.java b/src/java/org/apache/fop/fonts/CIDFull.java
deleted file mode 100644
index 1130459b7..000000000
--- a/src/java/org/apache/fop/fonts/CIDFull.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * 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.util.BitSet;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.fop.util.CharUtilities;
-
-/**
- * Provides methods to get font information.
- * Naming:
- * glyph index: original index of the glyph in the non-subset font (!= unicode index)
- * character selector: index into a set of glyphs. For subset CID fonts, this starts at 0. For non-subset
- * fonts, this is the same as the glyph index.
- * Unicode index: The Unicode codepoint of a character.
- * Glyph name: the Adobe glyph name (as found in Glyphs.java)
- */
-public class CIDFull implements CIDSet {
-
- private BitSet glyphIndices;
- private final MultiByteFont font;
-
- public CIDFull(MultiByteFont mbf) {
- font = mbf;
- }
-
- private void initGlyphIndices() {
- // this cannot be called in the constructor since the font is not ready...
- if (glyphIndices == null) {
- glyphIndices = font.getGlyphIndices();
- }
- }
-
- /** {@inheritDoc} */
- public int getOriginalGlyphIndex(int index) {
- return index;
- }
-
- /** {@inheritDoc} */
- @Override
- public char getUnicodeFromGID(int glyphIndex) {
- return ' ';
- }
-
- /** {@inheritDoc} */
- @Override
- public int getGIDFromChar(char ch) {
- return ch;
- }
-
- /** {@inheritDoc} */
- public char getUnicode(int index) {
- initGlyphIndices();
- if (glyphIndices.get(index)) {
- return (char) index;
- } else {
- return CharUtilities.NOT_A_CHARACTER;
- }
- }
-
- /** {@inheritDoc} */
- public int mapChar(int glyphIndex, char unicode) {
- return (char) glyphIndex;
- }
-
- /** {@inheritDoc} */
- public Map<Integer, Integer> getGlyphs() {
- // this is never really called for full embedded fonts but the equivalent map would be the identity
- initGlyphIndices();
- Map<Integer, Integer> glyphs = new HashMap<Integer, Integer>();
- int nextBitSet = 0;
- for (int j = 0; j < glyphIndices.cardinality(); j++) {
- nextBitSet = glyphIndices.nextSetBit(nextBitSet);
- glyphs.put(Integer.valueOf(nextBitSet), Integer.valueOf(nextBitSet));
- nextBitSet++;
- }
- return Collections.unmodifiableMap(glyphs);
- }
-
- /** {@inheritDoc} */
- public char[] getChars() {
- return font.getChars();
- }
-
- /** {@inheritDoc} */
- public int getNumberOfGlyphs() {
- initGlyphIndices();
- // note: the real number of glyphs is given by the cardinality() method (not the length()) but since
- // we will pad gaps in the indices with zeros we really want the length() here. this method is only
- // called when embedding a font in PostScript and this will be the value of the CIDCount entry
- return glyphIndices.length();
- }
-
- /** {@inheritDoc} */
- public BitSet getGlyphIndices() {
- initGlyphIndices();
- return glyphIndices;
- }
-
- /** {@inheritDoc} */
- public int[] getWidths() {
- return font.getWidths();
- }
-}
diff --git a/src/java/org/apache/fop/fonts/CIDSet.java b/src/java/org/apache/fop/fonts/CIDSet.java
deleted file mode 100644
index acfc705c8..000000000
--- a/src/java/org/apache/fop/fonts/CIDSet.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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.util.BitSet;
-import java.util.Map;
-
-/**
- * Declares methods to retrieve font information (glyph indices, widths, unicode values) from a CID font.
- */
-public interface CIDSet {
-
- /**
- * Returns the original index of the glyph inside the (non-subset) font's glyph list. This
- * index can be used to access the character width information, for example.
- * @param index the subset index (character selector) to access the glyph
- * @return the original index (or -1 if no glyph index is available for the subset index)
- */
- int getOriginalGlyphIndex(int index);
-
- /**
- * Returns the Unicode value for a subset index (character selector). If there's no such
- * Unicode value, the "NOT A CHARACTER" (0xFFFF) is returned.
- * @param index the subset index (character selector)
- * @return the Unicode value or "NOT A CHARACTER" (0xFFFF)
- */
- char getUnicode(int index);
-
- /**
- * Gets the unicode character from the original font glyph index
- * @param glyphIndex The original glyph index of the character in the font
- * @return The character represented by the passed GID
- */
- char getUnicodeFromGID(int glyphIndex);
-
- /**
- * Returns the glyph index from the original font from a character
- * @param ch The character
- * @return The glyph index in the original font.
- */
- int getGIDFromChar(char ch);
-
- /**
- * Maps a character to a character selector for a font subset. If the character isn't in the
- * subset, yet, it is added and a new character selector returned. Otherwise, the already
- * allocated character selector is returned from the existing map/subset.
- * @param glyphIndex the glyph index of the character
- * @param unicode the Unicode index of the character
- * @return the subset index
- */
- int mapChar(int glyphIndex, char unicode);
-
- /**
- * Returns an unmodifiable Map of the font subset. It maps from glyph index to
- * character selector (i.e. the subset index in this case).
- * @return Map Map&lt;Integer, Integer&gt; of the font subset
- */
- Map<Integer, Integer> getGlyphs();
-
- /**
- * Returns a char array containing all Unicode characters that are in the subset.
- * @return a char array with all used Unicode characters
- */
- char[] getChars();
-
- /**
- * Returns the number of glyphs in the subset.
- * @return the number of glyphs in the subset
- */
- int getNumberOfGlyphs();
-
- /**
- * Returns a BitSet with bits set for each available glyph index in the subset.
- * @return a BitSet indicating available glyph indices
- */
- BitSet getGlyphIndices();
-
- /**
- * Return the array of widths.
- * <p>
- * This is used to get an array for inserting in an output format.
- * It should not be used for lookup.
- * @return an array of widths
- */
- int[] getWidths();
-
-}
diff --git a/src/java/org/apache/fop/fonts/CIDSubset.java b/src/java/org/apache/fop/fonts/CIDSubset.java
deleted file mode 100644
index 01b8495f8..000000000
--- a/src/java/org/apache/fop/fonts/CIDSubset.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * 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.util.BitSet;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.fop.util.CharUtilities;
-
-/**
- * Provides methods to get font information.
- * Naming:
- * glyph index: original index of the glyph in the non-subset font (!= unicode index)
- * character selector: index into a set of glyphs. For subset CID fonts, this starts at 0. For non-subset
- * fonts, this is the same as the glyph index.
- * Unicode index: The Unicode codepoint of a character.
- * Glyph name: the Adobe glyph name (as found in Glyphs.java)
- */
-public class CIDSubset implements CIDSet {
-
- /**
- * usedGlyphs contains orginal, new glyph index (glyph index -> char selector)
- */
- private Map<Integer, Integer> usedGlyphs = new HashMap<Integer, Integer>();
-
- /**
- * usedGlyphsIndex contains new glyph, original index (char selector -> glyph index)
- */
- private Map<Integer, Integer> usedGlyphsIndex = new HashMap<Integer, Integer>();
- private int usedGlyphsCount;
-
- /**
- * usedCharsIndex contains new glyph, original char (char selector -> Unicode)
- */
- private Map<Integer, Character> usedCharsIndex = new HashMap<Integer, Character>();
-
- /**
- * A map between the original character and it's GID in the original font.
- */
- private Map<Character, Integer> charToGIDs = new HashMap<Character, Integer>();
-
-
- private final MultiByteFont font;
-
- public CIDSubset(MultiByteFont mbf) {
- font = mbf;
- // The zeroth value is reserved for .notdef
- usedGlyphs.put(0, 0);
- usedGlyphsIndex.put(0, 0);
- usedGlyphsCount++;
- }
-
- /** {@inheritDoc} */
- public int getOriginalGlyphIndex(int index) {
- Integer glyphIndex = usedGlyphsIndex.get(index);
- if (glyphIndex != null) {
- return glyphIndex;
- } else {
- return -1;
- }
- }
-
- /** {@inheritDoc} */
- public char getUnicode(int index) {
- Character mapValue = usedCharsIndex.get(index);
- if (mapValue != null) {
- return mapValue.charValue();
- } else {
- return CharUtilities.NOT_A_CHARACTER;
- }
- }
-
- /** {@inheritDoc} */
- public int mapChar(int glyphIndex, char unicode) {
- // Reencode to a new subset font or get the reencoded value
- // IOW, accumulate the accessed characters and build a character map for them
- Integer subsetCharSelector = usedGlyphs.get(glyphIndex);
- if (subsetCharSelector == null) {
- int selector = usedGlyphsCount;
- usedGlyphs.put(glyphIndex, selector);
- usedGlyphsIndex.put(selector, glyphIndex);
- usedCharsIndex.put(selector, unicode);
- charToGIDs.put(unicode, glyphIndex);
- usedGlyphsCount++;
- return selector;
- } else {
- return subsetCharSelector;
- }
- }
-
- /** {@inheritDoc} */
- public Map<Integer, Integer> getGlyphs() {
- return Collections.unmodifiableMap(this.usedGlyphs);
- }
-
- /** {@inheritDoc} */
- public char getUnicodeFromGID(int glyphIndex) {
- int selector = usedGlyphs.get(glyphIndex);
- return usedCharsIndex.get(selector);
- }
-
- /** {@inheritDoc} */
- public int getGIDFromChar(char ch) {
- return charToGIDs.get(ch);
- }
-
- /** {@inheritDoc} */
- public char[] getChars() {
- char[] charArray = new char[usedGlyphsCount];
- for (int i = 0; i < usedGlyphsCount; i++) {
- charArray[i] = getUnicode(i);
- }
- return charArray;
- }
-
- /** {@inheritDoc} */
- public int getNumberOfGlyphs() {
- return this.usedGlyphsCount;
- }
-
- /** {@inheritDoc} */
- public BitSet getGlyphIndices() {
- BitSet bitset = new BitSet();
- for (Integer cid : usedGlyphs.keySet()) {
- bitset.set(cid);
- }
- return bitset;
- }
-
- /** {@inheritDoc} */
- public int[] getWidths() {
- int[] widths = font.getWidths();
- int[] tmpWidth = new int[getNumberOfGlyphs()];
- for (int i = 0, c = getNumberOfGlyphs(); i < c; i++) {
- int nwx = Math.max(0, getOriginalGlyphIndex(i));
- tmpWidth[i] = widths[nwx];
- }
- return tmpWidth;
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/CMapSegment.java b/src/java/org/apache/fop/fonts/CMapSegment.java
deleted file mode 100644
index 664ae727f..000000000
--- a/src/java/org/apache/fop/fonts/CMapSegment.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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;
-
-/**
- * A segment in a cmap table of format 4. Unicode code points between
- * {@link #getUnicodeStart()} and {@link #getUnicodeEnd()} map to contiguous glyph indices
- * starting from {@link #getGlyphStartIndex()}.
- */
-public final class CMapSegment {
-
- private final int unicodeStart;
- private final int unicodeEnd;
- private final int glyphStartIndex;
-
- /**
- * Creates a new segment.
- *
- * @param unicodeStart Unicode start index
- * @param unicodeEnd Unicode end index
- * @param glyphStartIndex glyph start index
- */
- public CMapSegment(int unicodeStart, int unicodeEnd, int glyphStartIndex) {
- this.unicodeStart = unicodeStart;
- this.unicodeEnd = unicodeEnd;
- this.glyphStartIndex = glyphStartIndex;
- }
-
- @Override
- public int hashCode() {
- int hc = 17;
- hc = 31 * hc + unicodeStart;
- hc = 31 * hc + unicodeEnd;
- hc = 31 * hc + glyphStartIndex;
- return hc;
- }
-
- @Override
- public boolean equals(Object o) {
- if (o instanceof CMapSegment) {
- CMapSegment ce = (CMapSegment) o;
- return ce.unicodeStart == this.unicodeStart
- && ce.unicodeEnd == this.unicodeEnd
- && ce.glyphStartIndex == this.glyphStartIndex;
- }
- return false;
- }
-
- /**
- * Returns the unicodeStart.
- * @return the Unicode start index
- */
- public int getUnicodeStart() {
- return unicodeStart;
- }
-
- /**
- * Returns the unicodeEnd.
- * @return the Unicode end index
- */
- public int getUnicodeEnd() {
- return unicodeEnd;
- }
-
- /**
- * Returns the glyphStartIndex.
- * @return the glyph start index
- */
- public int getGlyphStartIndex() {
- return glyphStartIndex;
- }
-
- /** {@inheritDoc} */
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("CMapSegment: ");
- sb.append("{ UC[");
- sb.append(unicodeStart);
- sb.append(',');
- sb.append(unicodeEnd);
- sb.append("]: GC[");
- sb.append(glyphStartIndex);
- sb.append(',');
- sb.append(glyphStartIndex + (unicodeEnd - unicodeStart));
- sb.append("] }");
- return sb.toString();
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/CustomFont.java b/src/java/org/apache/fop/fonts/CustomFont.java
deleted file mode 100644
index 6f325d96d..000000000
--- a/src/java/org/apache/fop/fonts/CustomFont.java
+++ /dev/null
@@ -1,583 +0,0 @@
-/*
- * 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 java.net.URI;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.fop.apps.io.InternalResourceResolver;
-
-
-/**
- * Abstract base class for custom fonts loaded from files, for example.
- */
-public abstract class CustomFont extends Typeface
- implements FontDescriptor, MutableFont {
-
- /** Fallback thickness for underline and strikeout when not provided by the font. */
- private static final int DEFAULT_LINE_THICKNESS = 50;
-
- private URI fontFileURI;
- private String fontName;
- private String fullName;
- private Set<String> familyNames;
- private String fontSubName;
- private URI embedFileURI;
- private String embedResourceName;
- private final InternalResourceResolver resourceResolver;
- private EmbeddingMode embeddingMode = EmbeddingMode.AUTO;
-
- private int capHeight;
- private int xHeight;
- private int ascender;
- private int descender;
- private int[] fontBBox = {0, 0, 0, 0};
- private int flags = 4;
- private int weight; //0 means unknown weight
- private int stemV;
- private int italicAngle;
- private int missingWidth;
- private FontType fontType = FontType.TYPE1;
- private int firstChar;
- private int lastChar = 255;
-
- private int underlinePosition;
-
- private int underlineThickness;
-
- private int strikeoutPosition;
-
- private int strikeoutThickness;
-
- private Map<Integer, Map<Integer, Integer>> kerning;
-
- private boolean useKerning = true;
- /** the character map, mapping Unicode ranges to glyph indices. */
- protected List<CMapSegment> cmap = new ArrayList<CMapSegment>();
- private boolean useAdvanced = true;
-
- /**
- * @param resourceResolver the URI resource resolver for controlling file access
- */
- public CustomFont(InternalResourceResolver resourceResolver) {
- this.resourceResolver = resourceResolver;
- }
-
-
- /** {@inheritDoc} */
- public URI getFontURI() {
- return fontFileURI;
- }
-
- /** {@inheritDoc} */
- public String getFontName() {
- return fontName;
- }
-
- /** {@inheritDoc} */
- public String getEmbedFontName() {
- return getFontName();
- }
-
- /** {@inheritDoc} */
- public String getFullName() {
- return fullName;
- }
-
- /**
- * Returns the font family names.
- * @return the font family names (a Set of Strings)
- */
- public Set<String> getFamilyNames() {
- return Collections.unmodifiableSet(this.familyNames);
- }
-
- /**
- * Returns the font family name stripped of whitespace.
- * @return the stripped font family
- * @see FontUtil#stripWhiteSpace(String)
- */
- public String getStrippedFontName() {
- return FontUtil.stripWhiteSpace(getFontName());
- }
-
- /**
- * Returns font's subfamily name.
- * @return the font's subfamily name
- */
- public String getFontSubName() {
- return fontSubName;
- }
-
- /**
- * Returns an URI representing an embeddable font file.
- *
- * @return URI to an embeddable font file or null if not available.
- */
- public URI getEmbedFileURI() {
- return embedFileURI;
- }
-
- /**
-
- * Returns the embedding mode for this font.
- * @return embedding mode
- */
- public EmbeddingMode getEmbeddingMode() {
- return embeddingMode;
- }
-
- /**
- * Returns an {@link InputStream} representing an embeddable font file.
- *
- * @return {@link InputStream} for an embeddable font file
- * @throws IOException if embedFileName is not null but Source is not found
- */
- public InputStream getInputStream() throws IOException {
- return resourceResolver.getResource(embedFileURI);
- }
-
- /**
- * Returns the lookup name to an embeddable font file available as a
- * resource.
- * (todo) Remove this method, this should be done using a resource: URI.
- * @return the lookup name
- */
- public String getEmbedResourceName() {
- return embedResourceName;
- }
-
- /**
- * {@inheritDoc}
- */
- public int getAscender() {
- return ascender;
- }
-
- /**
- * {@inheritDoc}
- */
- public int getDescender() {
- return descender;
- }
-
- /**
- * {@inheritDoc}
- */
- public int getCapHeight() {
- return capHeight;
- }
-
- /**
- * {@inheritDoc}
- */
- public int getAscender(int size) {
- return size * ascender;
- }
-
- /**
- * {@inheritDoc}
- */
- public int getDescender(int size) {
- return size * descender;
- }
-
- /**
- * {@inheritDoc}
- */
- public int getCapHeight(int size) {
- return size * capHeight;
- }
-
- /**
- * {@inheritDoc}
- */
- public int getXHeight(int size) {
- return size * xHeight;
- }
-
- /**
- * {@inheritDoc}
- */
- public int[] getFontBBox() {
- return fontBBox;
- }
-
- /** {@inheritDoc} */
- public int getFlags() {
- return flags;
- }
-
- /** {@inheritDoc} */
- public boolean isSymbolicFont() {
- return ((getFlags() & 4) != 0) || "ZapfDingbatsEncoding".equals(getEncodingName());
- //Note: The check for ZapfDingbats is necessary as the PFM does not reliably indicate
- //if a font is symbolic.
- }
-
- /**
- * Returns the font weight (100, 200...800, 900). This value may be different from the
- * one that was actually used to register the font.
- * @return the font weight (or 0 if the font weight is unknown)
- */
- public int getWeight() {
- return this.weight;
- }
-
- /**
- * {@inheritDoc}
- */
- public int getStemV() {
- return stemV;
- }
-
- /**
- * {@inheritDoc}
- */
- public int getItalicAngle() {
- return italicAngle;
- }
-
- /**
- * Returns the width to be used when no width is available.
- * @return a character width
- */
- public int getMissingWidth() {
- return missingWidth;
- }
-
- /**
- * {@inheritDoc}
- */
- public FontType getFontType() {
- return fontType;
- }
-
- /**
- * Returns the index of the first character defined in this font.
- * @return the index of the first character
- */
- public int getFirstChar() {
- return firstChar;
- }
-
- /**
- * Returns the index of the last character defined in this font.
- * @return the index of the last character
- */
- public int getLastChar() {
- return lastChar;
- }
-
- /**
- * Used to determine if kerning is enabled.
- * @return True if kerning is enabled.
- */
- public boolean isKerningEnabled() {
- return useKerning;
- }
-
- /**
- * {@inheritDoc}
- */
- public final boolean hasKerningInfo() {
- return (isKerningEnabled() && (kerning != null) && !kerning.isEmpty());
- }
-
- /**
- * {@inheritDoc}
- */
- public final Map<Integer, Map<Integer, Integer>> getKerningInfo() {
- if (hasKerningInfo()) {
- return kerning;
- } else {
- return Collections.emptyMap();
- }
- }
-
- /**
- * Used to determine if advanced typographic features are enabled.
- * By default, this is false, but may be overridden by subclasses.
- * @return true if enabled.
- */
- public boolean isAdvancedEnabled() {
- return useAdvanced;
- }
-
- /* ---- MutableFont interface ---- */
-
- /** {@inheritDoc} */
- public void setFontURI(URI uri) {
- this.fontFileURI = uri;
- }
-
- /** {@inheritDoc} */
- public void setFontName(String name) {
- this.fontName = name;
- }
-
- /** {@inheritDoc} */
- public void setFullName(String name) {
- this.fullName = name;
- }
-
- /** {@inheritDoc} */
- public void setFamilyNames(Set<String> names) {
- this.familyNames = new HashSet<String>(names);
- }
-
- /**
- * Sets the font's subfamily name.
- * @param subFamilyName the subfamily name of the font
- */
- public void setFontSubFamilyName(String subFamilyName) {
- this.fontSubName = subFamilyName;
- }
-
- /**
- * {@inheritDoc}
- */
- public void setEmbedURI(URI path) {
- this.embedFileURI = path;
- }
-
- /**
- * {@inheritDoc}
- */
- public void setEmbedResourceName(String name) {
- this.embedResourceName = name;
- }
-
- /**
- * {@inheritDoc}
- */
- public void setEmbeddingMode(EmbeddingMode embeddingMode) {
- this.embeddingMode = embeddingMode;
- }
-
- /**
- * {@inheritDoc}
- */
- public void setCapHeight(int capHeight) {
- this.capHeight = capHeight;
- }
-
- /**
- * Returns the XHeight value of the font.
- * @param xHeight the XHeight value
- */
- public void setXHeight(int xHeight) {
- this.xHeight = xHeight;
- }
-
- /**
- * {@inheritDoc}
- */
- public void setAscender(int ascender) {
- this.ascender = ascender;
- }
-
- /**
- * {@inheritDoc}
- */
- public void setDescender(int descender) {
- this.descender = descender;
- }
-
- /**
- * {@inheritDoc}
- */
- public void setFontBBox(int[] bbox) {
- this.fontBBox = bbox;
- }
-
- /**
- * {@inheritDoc}
- */
- public void setFlags(int flags) {
- this.flags = flags;
- }
-
- /**
- * Sets the font weight. Valid values are 100, 200...800, 900.
- * @param weight the font weight
- */
- public void setWeight(int weight) {
- weight = (weight / 100) * 100;
- weight = Math.max(100, weight);
- weight = Math.min(900, weight);
- this.weight = weight;
- }
-
- /**
- * {@inheritDoc}
- */
- public void setStemV(int stemV) {
- this.stemV = stemV;
- }
-
- /**
- * {@inheritDoc}
- */
- public void setItalicAngle(int italicAngle) {
- this.italicAngle = italicAngle;
- }
-
- /**
- * {@inheritDoc}
- */
- public void setMissingWidth(int width) {
- this.missingWidth = width;
- }
-
- /**
- * {@inheritDoc}
- */
- public void setFontType(FontType fontType) {
- this.fontType = fontType;
- }
-
- /**
- * {@inheritDoc}
- */
- public void setFirstChar(int index) {
- this.firstChar = index;
- }
-
- /**
- * {@inheritDoc}
- */
- public void setLastChar(int index) {
- this.lastChar = index;
- }
-
- /**
- * {@inheritDoc}
- */
- public void setKerningEnabled(boolean enabled) {
- this.useKerning = enabled;
- }
-
- /**
- * {@inheritDoc}
- */
- public void setAdvancedEnabled(boolean enabled) {
- this.useAdvanced = enabled;
- }
-
- /** {@inheritDoc} */
- public void putKerningEntry(Integer key, Map<Integer, Integer> value) {
- if (kerning == null) {
- kerning = new HashMap<Integer, Map<Integer, Integer>>();
- }
- this.kerning.put(key, value);
- }
-
- /**
- * Replaces the existing kerning map with a new one.
- * @param kerningMap the kerning map (Map<Integer, Map<Integer, Integer>, the integers are
- * character codes)
- */
- public void replaceKerningMap(Map<Integer, Map<Integer, Integer>> kerningMap) {
- if (kerningMap == null) {
- this.kerning = Collections.emptyMap();
- } else {
- this.kerning = kerningMap;
- }
- }
-
- /**
- * Sets the character map for this font. It maps all available Unicode characters
- * to their glyph indices inside the font.
- * @param cmap the character map
- */
- public void setCMap(CMapSegment[] cmap) {
- this.cmap.clear();
- for (CMapSegment c : cmap) {
- this.cmap.add(c);
- }
- }
-
- /**
- * Returns the character map for this font. It maps all available Unicode characters
- * to their glyph indices inside the font.
- * @return the character map
- */
- public CMapSegment[] getCMap() {
- return cmap.toArray(new CMapSegment[cmap.size()]);
- }
-
- public int getUnderlinePosition(int size) {
- return (underlinePosition == 0)
- ? getDescender(size) / 2
- : size * underlinePosition;
- }
-
- public void setUnderlinePosition(int underlinePosition) {
- this.underlinePosition = underlinePosition;
- }
-
- public int getUnderlineThickness(int size) {
- return size * ((underlineThickness == 0) ? DEFAULT_LINE_THICKNESS : underlineThickness);
- }
-
- public void setUnderlineThickness(int underlineThickness) {
- this.underlineThickness = underlineThickness;
- }
-
- public int getStrikeoutPosition(int size) {
- return (strikeoutPosition == 0)
- ? getXHeight(size) / 2
- : size * strikeoutPosition;
- }
-
- public void setStrikeoutPosition(int strikeoutPosition) {
- this.strikeoutPosition = strikeoutPosition;
- }
-
- public int getStrikeoutThickness(int size) {
- return (strikeoutThickness == 0) ? getUnderlineThickness(size) : size * strikeoutThickness;
- }
-
- public void setStrikeoutThickness(int strikeoutThickness) {
- this.strikeoutThickness = strikeoutThickness;
- }
-
- /**
- * Returns a Map of used Glyphs.
- * @return Map Map of used Glyphs
- */
- public abstract Map<Integer, Integer> getUsedGlyphs();
-
- /**
- * Returns the character from it's original glyph index in the font
- * @param glyphIndex The original index of the character
- * @return The character
- */
- public abstract char getUnicodeFromGID(int glyphIndex);
-}
diff --git a/src/java/org/apache/fop/fonts/CustomFontCollection.java b/src/java/org/apache/fop/fonts/CustomFontCollection.java
deleted file mode 100644
index 35231e224..000000000
--- a/src/java/org/apache/fop/fonts/CustomFontCollection.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.util.List;
-
-import org.apache.fop.apps.io.InternalResourceResolver;
-
-/**
- * Sets up a set of custom (embedded) fonts
- */
-public class CustomFontCollection implements FontCollection {
-
- private final List<EmbedFontInfo> embedFontInfoList;
- private final InternalResourceResolver uriResolver;
- private final boolean useComplexScripts;
-
- /**
- * Main constructor.
- * @param fontResolver a font resolver
- * @param customFonts the list of custom fonts
- * @param useComplexScriptFeatures true if complex script features enabled
- */
- public CustomFontCollection(InternalResourceResolver fontResolver,
- List<EmbedFontInfo> customFonts, boolean useComplexScriptFeatures) {
- this.uriResolver = fontResolver;
- this.embedFontInfoList = customFonts;
- this.useComplexScripts = useComplexScriptFeatures;
- }
-
- /** {@inheritDoc} */
- public int setup(int num, FontInfo fontInfo) {
- if (embedFontInfoList == null) {
- return num; //No fonts to process
- }
-
- String internalName = null;
-
- for (int i = 0; i < embedFontInfoList.size(); i++) {
- EmbedFontInfo embedFontInfo = embedFontInfoList.get(i);
-
- internalName = "F" + num;
- num++;
-
- LazyFont font = new LazyFont(embedFontInfo, this.uriResolver, useComplexScripts);
- fontInfo.addMetrics(internalName, font);
-
- List<FontTriplet> triplets = embedFontInfo.getFontTriplets();
- for (int tripletIndex = 0; tripletIndex < triplets.size(); tripletIndex++) {
- FontTriplet triplet = triplets.get(tripletIndex);
- fontInfo.addFontProperties(internalName, triplet);
- }
- }
- return num;
- }
-}
diff --git a/src/java/org/apache/fop/fonts/DefaultFontConfig.java b/src/java/org/apache/fop/fonts/DefaultFontConfig.java
deleted file mode 100644
index 72d2280a8..000000000
--- a/src/java/org/apache/fop/fonts/DefaultFontConfig.java
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * 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.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.events.EventProducer;
-import org.apache.fop.util.LogUtil;
-
-/**
- * The font configuration data for the more generic fonts such as TTF and Type1, that are used by
- * most the renderers.
- */
-public final class DefaultFontConfig implements FontConfig {
-
- private static final Log log = LogFactory.getLog(DefaultFontConfig.class);
-
- private final List<Directory> directories = new ArrayList<Directory>();
-
- private final List<Font> fonts = new ArrayList<Font>();
-
- private final List<String> referencedFontFamilies = new ArrayList<String>();
-
- private final boolean autoDetectFonts;
-
- private DefaultFontConfig(boolean autoDetectFonts) {
- this.autoDetectFonts = autoDetectFonts;
- }
-
- /**
- * Parses the morge generic font information.
- */
- public static final class DefaultFontConfigParser implements FontConfig.FontConfigParser {
- /**
- * Parses the font configuration and return the configuration object.
- *
- * @param cfg the configuration data
- * @param strict whether or not to enforce strict validation
- * @return the font configuration object
- * @throws FOPException if an error occurs when creating the configuration object
- */
- public DefaultFontConfig parse(Configuration cfg, boolean strict) throws FOPException {
- return new ParserHelper(cfg, strict).instance;
- }
-
- /** {@inheritDoc} */
- public FontConfig parse(Configuration cfg, FontManager fontManager, boolean strict,
- EventProducer eventProducer) throws FOPException {
- return parse(cfg, strict);
- }
- }
-
- private static final class ParserHelper {
-
- private boolean strict;
-
- private Configuration fontInfoCfg;
-
- private DefaultFontConfig instance;
-
- private ParserHelper(Configuration cfg, boolean strict) throws FOPException {
- if (cfg == null || cfg.getChild("fonts", false) == null) {
- instance = null;
- } else {
- this.strict = strict;
- this.fontInfoCfg = cfg.getChild("fonts", false);
- instance = new DefaultFontConfig(fontInfoCfg.getChild("auto-detect", false) != null);
- parse();
- }
- }
-
- private void parse() throws FOPException {
- parseFonts();
- parseReferencedFonts();
- parseDirectories();
- }
-
- private void parseFonts() throws FOPException {
- for (Configuration fontCfg : fontInfoCfg.getChildren("font")) {
- String embed = fontCfg.getAttribute("embed-url", null);
- if (embed == null) {
- LogUtil.handleError(log, "Font configuration without embed-url attribute",
- strict);
- continue;
- }
- Font font = new Font(fontCfg.getAttribute("metrics-url", null), embed, fontCfg.getAttribute(
- "embed-url-afm", null), fontCfg.getAttribute("embed-url-pfm", null),
- fontCfg.getAttribute("sub-font", null),
- fontCfg.getAttributeAsBoolean("kerning", true), fontCfg.getAttributeAsBoolean(
- "advanced", true), fontCfg.getAttribute("encoding-mode",
- EncodingMode.AUTO.getName()), fontCfg.getAttribute("embedding-mode",
- EncodingMode.AUTO.getName()));
- instance.fonts.add(font);
- boolean hasTriplets = false;
- for (Configuration tripletCfg : fontCfg.getChildren("font-triplet")) {
- FontTriplet fontTriplet = getFontTriplet(tripletCfg, strict);
- font.tripletList.add(fontTriplet);
- hasTriplets = true;
- }
- // no font triplet info
- if (!hasTriplets) {
- LogUtil.handleError(log, "font without font-triplet", strict);
- }
- }
- }
-
- private void parseReferencedFonts() throws FOPException {
- Configuration referencedFontsCfg = fontInfoCfg.getChild("referenced-fonts", false);
- if (referencedFontsCfg != null) {
- for (Configuration match : referencedFontsCfg.getChildren("match")) {
- try {
- instance.referencedFontFamilies.add(match.getAttribute("font-family"));
- } catch (ConfigurationException ce) {
- LogUtil.handleException(log, ce, strict);
- continue;
- }
- }
- }
- }
-
- private void parseDirectories() throws FOPException {
- for (Configuration directoriesCfg : fontInfoCfg.getChildren("directory")) {
- boolean recursive = directoriesCfg.getAttributeAsBoolean("recursive", false);
- String directory;
- try {
- directory = directoriesCfg.getValue();
- } catch (ConfigurationException e) {
- LogUtil.handleException(log, e, strict);
- continue;
- }
- if (directory == null) {
- LogUtil.handleException(log,
- new FOPException("directory defined without value"), strict);
- continue;
- }
- instance.directories.add(new Directory(directory, recursive));
- }
- }
-
- /**
- * Creates a new FontTriplet given a triple Configuration
- *
- * @param tripletCfg a triplet configuration
- * @return a font triplet font key
- * @throws FOPException thrown if a FOP exception occurs
- */
- private FontTriplet getFontTriplet(Configuration tripletCfg, boolean strict)
- throws FOPException {
- try {
- String name = tripletCfg.getAttribute("name");
- if (name == null) {
- LogUtil.handleError(log, "font-triplet without name", strict);
- return null;
- }
- String weightStr = tripletCfg.getAttribute("weight");
- if (weightStr == null) {
- LogUtil.handleError(log, "font-triplet without weight", strict);
- return null;
- }
- int weight = FontUtil.parseCSS2FontWeight(FontUtil.stripWhiteSpace(weightStr));
- String style = tripletCfg.getAttribute("style");
- if (style == null) {
- LogUtil.handleError(log, "font-triplet without style", strict);
- return null;
- } else {
- style = FontUtil.stripWhiteSpace(style);
- }
- return FontInfo.createFontKey(name, style, weight);
- } catch (ConfigurationException e) {
- LogUtil.handleException(log, e, strict);
- }
- return null;
- }
-
- }
-
- /**
- * Returns the list of fonts that were parsed.
- * @return a list of fonts
- */
- public List<Font> getFonts() {
- return Collections.unmodifiableList(fonts);
- }
-
- /**
- * Returns a list of directories that were parsed.
- * @return a list of directories
- */
- public List<Directory> getDirectories() {
- return Collections.unmodifiableList(directories);
- }
-
- /**
- * Returns a list of referenced font families.
- * @return the referenced font families
- */
- public List<String> getReferencedFontFamily() {
- return Collections.unmodifiableList(referencedFontFamilies);
- }
-
- /**
- * Whether or not to enable auto-detecting of fonts in the system.
- * @return true to enable auto-detect
- */
- public boolean isAutoDetectFonts() {
- return autoDetectFonts;
- }
-
- /**
- * The directory to find fonts within.
- */
- public static final class Directory {
-
- private final String directory;
-
- private final boolean recursive;
-
- private Directory(String directory, boolean recurse) {
- this.directory = directory;
- this.recursive = recurse;
- }
-
- /**
- * Returns a String representing the directory to find fonts within.
- * @return the directory
- */
- public String getDirectory() {
- return directory;
- }
-
- /**
- * Returns whether or not to recurse through the directory when finding fonts.
- * @return true to recurse through the directory and sub-directories
- */
- public boolean isRecursive() {
- return recursive;
- }
- }
-
- /**
- * Represents a font object within the FOP conf.
- */
- public static final class Font {
-
- private final String metrics;
-
- private final String embedUri;
-
- private String afm;
-
- private String pfm;
-
- private final String subFont;
-
- private final boolean kerning;
-
- private final boolean advanced;
-
- private final String encodingMode;
-
- private final String embeddingMode;
-
- public String getEncodingMode() {
- return encodingMode;
- }
-
- private final List<FontTriplet> tripletList = new ArrayList<FontTriplet>();
-
- public List<FontTriplet> getTripletList() {
- return Collections.unmodifiableList(tripletList);
- }
-
- private Font(String metrics, String embed, String afm, String pfm, String subFont, boolean kerning,
- boolean advanced, String encodingMode, String embeddingMode) {
- this.metrics = metrics;
- this.embedUri = embed;
- this.afm = afm;
- this.pfm = pfm;
- this.subFont = subFont;
- this.kerning = kerning;
- this.advanced = advanced;
- this.encodingMode = encodingMode;
- this.embeddingMode = embeddingMode;
- }
-
- /**
- * Whether or not to allow kerning of glyphs.
- * @return true to allow glyph kerning
- */
- public boolean isKerning() {
- return kerning;
- }
-
- public boolean isAdvanced() {
- return advanced;
- }
-
- /**
- * Gets the String representing the metrics file.
- * @return the metrics file
- */
- public String getMetrics() {
- return metrics;
- }
-
- /**
- * Gets the URI of the font to embed.
- * @return the font URI
- */
- public String getEmbedURI() {
- return embedUri;
- }
-
- /**
- * Gets the sub font within, for example, a TTC.
- * @return the sub font name
- */
- public String getSubFont() {
- return subFont;
- }
-
- public String getEmbeddingMode() {
- return embeddingMode;
- }
-
- public String getAfm() {
- return afm;
- }
-
- public String getPfm() {
- return pfm;
- }
- }
-}
diff --git a/src/java/org/apache/fop/fonts/DefaultFontConfigurator.java b/src/java/org/apache/fop/fonts/DefaultFontConfigurator.java
deleted file mode 100644
index 4a8b11f74..000000000
--- a/src/java/org/apache/fop/fonts/DefaultFontConfigurator.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * 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.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.apps.io.InternalResourceResolver;
-import org.apache.fop.fonts.DefaultFontConfig.Directory;
-import org.apache.fop.fonts.autodetect.FontFileFinder;
-import org.apache.fop.fonts.autodetect.FontInfoFinder;
-import org.apache.fop.util.LogUtil;
-
-/**
- * The default configurator for fonts. This configurator can configure the more generic fonts used
- * by the renderers i.e. TTF, Type1 etc...
- */
-public class DefaultFontConfigurator implements FontConfigurator<EmbedFontInfo> {
- /** logger instance */
- protected static final Log log = LogFactory.getLog(DefaultFontConfigurator.class);
-
- private final FontManager fontManager;
- private final InternalResourceResolver resourceResolver;
- private final FontEventListener listener;
- private final boolean strict;
-
- /**
- * Main constructor
- * @param fontManager the font manager
- * @param listener the font event listener
- * @param strict true if an Exception should be thrown if an error is found.
- */
- public DefaultFontConfigurator(FontManager fontManager, FontEventListener listener, boolean strict) {
- this.fontManager = fontManager;
- this.resourceResolver = fontManager.getResourceResolver();
- this.listener = listener;
- this.strict = strict;
- }
-
- /**
- * Initializes font info settings from the user configuration
- * @throws FOPException if an exception occurs while processing the configuration
- */
- public List<EmbedFontInfo> configure(FontConfig fontInfoConfig) throws FOPException {
- List<EmbedFontInfo> fontInfoList = new ArrayList<EmbedFontInfo>();
- if (fontInfoConfig != null) {
- assert fontInfoConfig instanceof DefaultFontConfig;
- DefaultFontConfig adobeFontInfoConfig = (DefaultFontConfig) fontInfoConfig;
- long start = 0;
- if (log.isDebugEnabled()) {
- log.debug("Starting font configuration...");
- start = System.currentTimeMillis();
- }
- FontAdder fontAdder = new FontAdder(fontManager, resourceResolver, listener);
- // native o/s search (autodetect) configuration
- fontManager.autoDetectFonts(adobeFontInfoConfig.isAutoDetectFonts(), fontAdder, strict,
- listener, fontInfoList);
- // Add configured directories to FontInfo list
- addDirectories(adobeFontInfoConfig, fontAdder, fontInfoList);
- // Add configured fonts to FontInfo
- FontCache fontCache = fontManager.getFontCache();
- try {
- addFonts(adobeFontInfoConfig, fontCache, fontInfoList);
- } catch (URISyntaxException use) {
- LogUtil.handleException(log, use, strict);
- }
- // Update referenced fonts (fonts which are not to be embedded)
- fontManager.updateReferencedFonts(fontInfoList);
- // Renderer-specific referenced fonts
- List<String> referencedFonts = adobeFontInfoConfig.getReferencedFontFamily();
- if (referencedFonts.size() > 0) {
- FontTriplet.Matcher matcher = FontManagerConfigurator.createFontsMatcher(
- referencedFonts, strict);
- fontManager.updateReferencedFonts(fontInfoList, matcher);
- }
- // Update font cache if it has changed
- fontManager.saveCache();
- if (log.isDebugEnabled()) {
- log.debug("Finished font configuration in "
- + (System.currentTimeMillis() - start) + "ms");
- }
- }
- return Collections.unmodifiableList(fontInfoList);
- }
-
- private void addDirectories(DefaultFontConfig fontInfoConfig, FontAdder fontAdder,
- List<EmbedFontInfo> fontInfoList) throws FOPException {
- // directory (multiple font) configuration
- List<Directory> directories = fontInfoConfig.getDirectories();
- for (Directory directory : directories) {
- // add fonts found in directory
- FontFileFinder fontFileFinder = new FontFileFinder(directory.isRecursive() ? -1 : 1, listener);
- List<URL> fontURLList;
- try {
- fontURLList = fontFileFinder.find(directory.getDirectory());
- fontAdder.add(fontURLList, fontInfoList);
- } catch (IOException e) {
- LogUtil.handleException(log, e, strict);
- } catch (URISyntaxException use) {
- LogUtil.handleException(log, use, strict);
- }
- }
- }
-
- private void addFonts(DefaultFontConfig fontInfoConfig, FontCache fontCache,
- List<EmbedFontInfo> fontInfoList) throws FOPException, URISyntaxException {
- // font file (singular) configuration
- List<DefaultFontConfig.Font> fonts = fontInfoConfig.getFonts();
- for (DefaultFontConfig.Font font : fonts) {
- EmbedFontInfo embedFontInfo = getFontInfo(font, fontCache);
- if (embedFontInfo != null) {
- fontInfoList.add(embedFontInfo);
- }
- }
- }
-
- private EmbedFontInfo getFontInfo(DefaultFontConfig.Font font, FontCache fontCache)
- throws FOPException, URISyntaxException {
- String embed = font.getEmbedURI();
- String metrics = font.getMetrics();
- String afm = font.getAfm();
- String pfm = font.getPfm();
- URI embedUri = InternalResourceResolver.cleanURI(embed);
- URI metricsUri = metrics == null ? null : InternalResourceResolver.cleanURI(metrics);
- URI afmUri = (afm == null) ? null : InternalResourceResolver.cleanURI(afm);
- URI pfmUri = (pfm == null) ? null : InternalResourceResolver.cleanURI(pfm);
- FontUris fontUris = (afmUri != null || pfmUri != null) ? new FontUris(embedUri, metricsUri, afmUri,
- pfmUri) : new FontUris(embedUri, metricsUri);
-
- String subFont = font.getSubFont();
- List<FontTriplet> tripletList = font.getTripletList();
-
- // no font triplet info
- if (tripletList.size() == 0) {
- URI fontUri = resourceResolver.resolveFromBase(embedUri);
- FontInfoFinder finder = new FontInfoFinder();
- finder.setEventListener(listener);
- EmbedFontInfo[] infos = finder.find(fontUri, resourceResolver, fontCache);
- return infos[0]; //When subFont is set, only one font is returned
- }
- EncodingMode encodingMode = EncodingMode.getValue(font.getEncodingMode());
- EmbeddingMode embeddingMode = EmbeddingMode.getValue(font.getEmbeddingMode());
- EmbedFontInfo embedFontInfo = new EmbedFontInfo(fontUris, font.isKerning(), font.isAdvanced(),
- tripletList, subFont, encodingMode, embeddingMode);
- if (fontCache != null) {
- if (!fontCache.containsFont(embedFontInfo)) {
- fontCache.addFont(embedFontInfo, resourceResolver);
- }
- }
-
- if (log.isDebugEnabled()) {
- URI embedFile = embedFontInfo.getEmbedURI();
- log.debug("Adding font " + (embedFile != null ? embedFile + ", " : "")
- + "metrics URI " + embedFontInfo.getMetricsURI());
- for (int j = 0; j < tripletList.size(); ++j) {
- FontTriplet triplet = tripletList.get(j);
- log.debug(" Font triplet "
- + triplet.getName() + ", "
- + triplet.getStyle() + ", "
- + triplet.getWeight());
- }
- }
- return embedFontInfo;
- }
-}
diff --git a/src/java/org/apache/fop/fonts/EmbedFontInfo.java b/src/java/org/apache/fop/fonts/EmbedFontInfo.java
deleted file mode 100644
index cc96469f1..000000000
--- a/src/java/org/apache/fop/fonts/EmbedFontInfo.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * 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.Serializable;
-import java.net.URI;
-import java.util.List;
-
-/**
- * FontInfo contains meta information on fonts (where is the metrics file etc.)
- * TODO: We need to remove this class and think about more intelligent design patterns
- * (Data classes => Procedural code)
- */
-public class EmbedFontInfo implements Serializable {
-
- /** Serialization Version UID */
- private static final long serialVersionUID = 8755432068669997369L;
-
- /** false, to disable kerning */
- protected final boolean kerning;
- /** false, to disable advanced typographic features */
- protected final boolean advanced;
- /** the requested encoding mode for the font */
- private final EncodingMode encodingMode;
- /** the requested embedding mode for this font */
- private final EmbeddingMode embeddingMode;
-
- /** the PostScript name of the font */
- protected String postScriptName;
- /** the sub-fontname of the font (used for TrueType Collections, null otherwise) */
- protected String subFontName;
-
- /** the list of associated font triplets */
- private List<FontTriplet> fontTriplets;
-
- private transient boolean embedded = true;
-
- private FontUris fontUris;
-
- /**
- * Main constructor
- * @param metricsURI the URI of the XML resource containing font metrics
- * @param kerning True if kerning should be enabled
- * @param advanced true if advanced typography features should be enabled
- * @param fontTriplets List of font triplets to associate with this font
- * @param embedURI Path to the embeddable font file (may be null)
- * @param subFontName the sub-fontname used for TrueType Collections (null otherwise)
- * @param encodingMode the encoding mode to use for this font
- */
- public EmbedFontInfo(FontUris fontUris, boolean kerning, boolean advanced,
- List<FontTriplet> fontTriplets, String subFontName,
- EncodingMode encodingMode, EmbeddingMode embeddingMode) {
- this.kerning = kerning;
- this.advanced = advanced;
- this.fontTriplets = fontTriplets;
- this.subFontName = subFontName;
- this.encodingMode = encodingMode;
- this.embeddingMode = embeddingMode;
- this.fontUris = fontUris;
- }
-
- /**
- * Main constructor
- * @param metricsURI the URI of the XML resource containing font metrics
- * @param kerning True if kerning should be enabled
- * @param fontTriplets List of font triplets to associate with this font
- * @param embedURI Path to the embeddable font file (may be null)
- * @param subFontName the sub-fontname used for TrueType Collections (null otherwise)
- */
- public EmbedFontInfo(FontUris fontUris, boolean kerning, boolean advanced,
- List<FontTriplet> fontTriplets, String subFontName) {
- this(fontUris, kerning, advanced, fontTriplets, subFontName, EncodingMode.AUTO,
- EmbeddingMode.AUTO);
- }
-
- /**
- * Returns the URI of the metrics XML resource
- *
- * @return the metrics file path
- */
- public URI getMetricsURI() {
- return fontUris.getMetrics();
- }
-
- /**
- * Returns the URI to the embeddable font resource
- *
- * @return the font resource URI
- */
- public URI getEmbedURI() {
- return fontUris.getEmbed();
- }
-
- /**
- * Determines if kerning is enabled
- * @return true if enabled
- */
- public boolean getKerning() {
- return kerning;
- }
-
- /**
- * Determines if advanced typographic features are enabled
- * @return true if enabled
- */
- public boolean getAdvanced() {
- return advanced;
- }
-
- /**
- * Returns the sub-font name of the font. This is primarily used for TrueType Collections
- * to select one of the sub-fonts. For all other fonts, this is always null.
- * @return the sub-font name (or null)
- */
- public String getSubFontName() {
- return this.subFontName;
- }
-
- /**
- * Returns the PostScript name of the font.
- * @return the PostScript name
- */
- public String getPostScriptName() {
- return postScriptName;
- }
-
- /**
- * Sets the PostScript name of the font
- * @param postScriptName the PostScript name
- */
- public void setPostScriptName(String postScriptName) {
- this.postScriptName = postScriptName;
- }
-
- /**
- * Returns the list of font triplets associated with this font.
- * @return List of font triplets
- */
- public List<FontTriplet> getFontTriplets() {
- return fontTriplets;
- }
-
- /**
- * Indicates whether the font is only referenced rather than embedded.
- * @return true if the font is embedded, false if it is referenced.
- */
- public boolean isEmbedded() {
- if (fontUris.getEmbed() == null) {
- return false;
- } else {
- return this.embedded;
- }
- }
-
- /**
- * Returns the embedding mode for this font.
- * @return the embedding mode.
- */
- public EmbeddingMode getEmbeddingMode() {
- return embeddingMode;
- }
-
- /**
- * Defines whether the font is embedded or not.
- * @param value true to embed the font, false to reference it
- */
- public void setEmbedded(boolean value) {
- this.embedded = value;
- }
-
- /**
- * Returns the requested encoding mode for this font.
- * @return the encoding mode
- */
- public EncodingMode getEncodingMode() {
- return this.encodingMode;
- }
-
- private void readObject(java.io.ObjectInputStream in)
- throws IOException, ClassNotFoundException {
- in.defaultReadObject();
- this.embedded = true;
- }
-
- /** {@inheritDoc} */
- public String toString() {
- return "metrics-uri=" + fontUris.getMetrics() + ", embed-uri=" + fontUris.getEmbed()
- + ", kerning=" + kerning
- + ", advanced=" + advanced
- + ", enc-mode=" + encodingMode
- + ", font-triplet=" + fontTriplets
- + (getSubFontName() != null ? ", sub-font=" + getSubFontName() : "")
- + (isEmbedded() ? "" : ", NOT embedded");
- }
-
- public FontUris getFontUris() {
- return fontUris;
- }
-}
diff --git a/src/java/org/apache/fop/fonts/EmbeddingMode.java b/src/java/org/apache/fop/fonts/EmbeddingMode.java
deleted file mode 100644
index 5a3e905c9..000000000
--- a/src/java/org/apache/fop/fonts/EmbeddingMode.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.util.Locale;
-
-/**
- * This enumerates the embedding mode of fonts; full; subset; auto (auto defaults to full for
- * Type 1 fonts and subset for TrueType fonts.
- */
-public enum EmbeddingMode {
- /** Default option: assumes FULL for Type 1 fonts and SUBSET for TrueType fonts. */
- AUTO,
- /** Full font embedding: This means the whole of the font is written to file. */
- FULL,
- /** Subset font embedding: Only the mandatory tables and a subset of glyphs are written
- * to file.*/
- SUBSET;
-
- /**
- * Returns the name of this embedding mode.
- * @return the name of this embedding mode in lower case.
- */
- public String getName() {
- return this.toString().toLowerCase(Locale.ENGLISH);
- }
-
- /**
- * Returns the embedding mode corresponding to the given name.
- * @param value the name of an embedding mode (not case sensitive)
- * @return the corresponding embedding mode
- */
- public static EmbeddingMode getValue(String value) {
- for (EmbeddingMode mode : EmbeddingMode.values()) {
- if (mode.toString().equalsIgnoreCase(value)) {
- return mode;
- }
- }
- throw new IllegalArgumentException("Invalid embedding-mode: " + value);
- }
-}
diff --git a/src/java/org/apache/fop/fonts/EncodingMode.java b/src/java/org/apache/fop/fonts/EncodingMode.java
deleted file mode 100644
index 78ffb7ac6..000000000
--- a/src/java/org/apache/fop/fonts/EncodingMode.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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;
-
-/**
- * This class enumerates all supported encoding modes for fonts: auto, single-byte and CID.
- */
-public enum EncodingMode {
-
- /** Automatic selection of encoding mode. */
- AUTO("auto"),
-
- /** Single-byte encoding */
- SINGLE_BYTE("single-byte"),
-
- /** CID encoding */
- CID("cid");
-
- private String name;
-
- private EncodingMode(String name) {
- this.name = name;
- }
-
- /**
- * Returns the encoding mode name.
- * @return the encoding mode name
- */
- public String getName() {
- return this.name;
- }
-
- /**
- * Returns the {@link EncodingMode} by name.
- * @param name the name of the encoding mode to look up
- * @return the encoding mode constant
- */
- public static EncodingMode getValue(String name) {
- for (EncodingMode em : EncodingMode.values()) {
- if (name.equalsIgnoreCase(em.getName())) {
- return em;
- }
- }
- throw new IllegalArgumentException("Invalid encoding mode: " + name);
- }
-
- /** {@inheritDoc} */
- public String toString() {
- return "EncodingMode: " + getName();
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/Font.java b/src/java/org/apache/fop/fonts/Font.java
deleted file mode 100644
index b3cea0d6f..000000000
--- a/src/java/org/apache/fop/fonts/Font.java
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * 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.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.complexscripts.fonts.Positionable;
-import org.apache.fop.complexscripts.fonts.Substitutable;
-
-/**
- * This class holds font state information and provides access to the font
- * metrics.
- */
-public class Font implements Substitutable, Positionable {
-
- /** Extra Bold font weight */
- public static final int WEIGHT_EXTRA_BOLD = 800;
-
- /** Bold font weight */
- public static final int WEIGHT_BOLD = 700;
-
- /** Normal font weight */
- public static final int WEIGHT_NORMAL = 400;
-
- /** Light font weight */
- public static final int WEIGHT_LIGHT = 200;
-
- /** Normal font style */
- public static final String STYLE_NORMAL = "normal";
-
- /** Italic font style */
- public static final String STYLE_ITALIC = "italic";
-
- /** Oblique font style */
- public static final String STYLE_OBLIQUE = "oblique";
-
- /** Inclined font style */
- public static final String STYLE_INCLINED = "inclined";
-
- /** Default selection priority */
- public static final int PRIORITY_DEFAULT = 0;
-
- /** Default fallback key */
- public static final FontTriplet DEFAULT_FONT = new FontTriplet(
- "any", STYLE_NORMAL, WEIGHT_NORMAL, PRIORITY_DEFAULT);
-
- /** logger */
- private static Log log = LogFactory.getLog(Font.class);
-
- private final String fontName;
- private final FontTriplet triplet;
- private final int fontSize;
-
- /**
- * normal or small-caps font
- */
- //private int fontVariant;
-
- private final FontMetrics metric;
-
- /**
- * Main constructor
- * @param key key of the font
- * @param triplet the font triplet that was used to lookup this font (may be null)
- * @param met font metrics
- * @param fontSize font size
- */
- public Font(String key, FontTriplet triplet, FontMetrics met, int fontSize) {
- this.fontName = key;
- this.triplet = triplet;
- this.metric = met;
- this.fontSize = fontSize;
- }
-
- /**
- * Returns the associated font metrics object.
- * @return the font metrics
- */
- public FontMetrics getFontMetrics() {
- return this.metric;
- }
-
- /**
- * Determines whether the font is a multibyte font.
- * @return True if it is multibyte
- */
- public boolean isMultiByte() {
- return getFontMetrics().isMultiByte();
- }
-
- /**
- * Returns the font's ascender.
- * @return the ascender
- */
- public int getAscender() {
- return metric.getAscender(fontSize) / 1000;
- }
-
- /**
- * Returns the font's CapHeight.
- * @return the capital height
- */
- public int getCapHeight() {
- return metric.getCapHeight(fontSize) / 1000;
- }
-
- /**
- * Returns the font's Descender.
- * @return the descender
- */
- public int getDescender() {
- return metric.getDescender(fontSize) / 1000;
- }
-
- /**
- * Returns the font's name.
- * @return the font name
- */
- public String getFontName() {
- return fontName;
- }
-
- /** @return the font triplet that selected this font */
- public FontTriplet getFontTriplet() {
- return this.triplet;
- }
-
- /**
- * Returns the font size
- * @return the font size
- */
- public int getFontSize() {
- return fontSize;
- }
-
- /**
- * Returns the XHeight
- * @return the XHeight
- */
- public int getXHeight() {
- return metric.getXHeight(fontSize) / 1000;
- }
-
- /** @return true if the font has kerning info */
- public boolean hasKerning() {
- return metric.hasKerningInfo();
- }
-
- /** @return true if the font has feature (i.e., at least one lookup matches) */
- public boolean hasFeature(int tableType, String script, String language, String feature) {
- return metric.hasFeature(tableType, script, language, feature);
- }
-
- /**
- * Returns the font's kerning table
- * @return the kerning table
- */
- public Map<Integer, Map<Integer, Integer>> getKerning() {
- if (metric.hasKerningInfo()) {
- return metric.getKerningInfo();
- } else {
- return Collections.emptyMap();
- }
- }
-
- /**
- * Returns the amount of kerning between two characters.
- *
- * The value returned measures in pt. So it is already adjusted for font size.
- *
- * @param ch1 first character
- * @param ch2 second character
- * @return the distance to adjust for kerning, 0 if there's no kerning
- */
- public int getKernValue(char ch1, char ch2) {
- Map<Integer, Integer> kernPair = getKerning().get((int) ch1);
- if (kernPair != null) {
- Integer width = kernPair.get((int) ch2);
- if (width != null) {
- return width.intValue() * getFontSize() / 1000;
- }
- }
- return 0;
- }
-
- /**
- * Returns the amount of kerning between two characters.
- *
- * The value returned measures in pt. So it is already adjusted for font size.
- *
- * @param ch1 first character
- * @param ch2 second character
- * @return the distance to adjust for kerning, 0 if there's no kerning
- */
- public int getKernValue(int ch1, int ch2) {
- // TODO !BMP
- if (ch1 > 0x10000) {
- return 0;
- } else if ((ch1 >= 0xD800) && (ch1 <= 0xE000)) {
- return 0;
- } else if (ch2 > 0x10000) {
- return 0;
- } else if ((ch2 >= 0xD800) && (ch2 <= 0xE000)) {
- return 0;
- } else {
- return getKernValue((char) ch1, (char) ch2);
- }
- }
-
- /**
- * Returns the width of a character
- * @param charnum character to look up
- * @return width of the character
- */
- public int getWidth(int charnum) {
- // returns width of given character number in millipoints
- return (metric.getWidth(charnum, fontSize) / 1000);
- }
-
- /**
- * Map a java character (unicode) to a font character.
- * Default uses CodePointMapping.
- * @param c character to map
- * @return the mapped character
- */
- public char mapChar(char c) {
-
- if (metric instanceof org.apache.fop.fonts.Typeface) {
- return ((org.apache.fop.fonts.Typeface)metric).mapChar(c);
- }
-
- // Use default CodePointMapping
- char d = CodePointMapping.getMapping("WinAnsiEncoding").mapChar(c);
- if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) {
- c = d;
- } else {
- log.warn("Glyph " + (int) c + " not available in font " + fontName);
- c = Typeface.NOT_FOUND;
- }
-
- return c;
- }
-
- /**
- * Determines whether this font contains a particular character/glyph.
- * @param c character to check
- * @return True if the character is supported, Falso otherwise
- */
- public boolean hasChar(char c) {
- if (metric instanceof org.apache.fop.fonts.Typeface) {
- return ((org.apache.fop.fonts.Typeface)metric).hasChar(c);
- } else {
- // Use default CodePointMapping
- return (CodePointMapping.getMapping("WinAnsiEncoding").mapChar(c) > 0);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- StringBuffer sbuf = new StringBuffer(super.toString());
- sbuf.append('{');
- /*
- sbuf.append(fontFamily);
- sbuf.append(',');*/
- sbuf.append(fontName);
- sbuf.append(',');
- sbuf.append(fontSize);
- /*
- sbuf.append(',');
- sbuf.append(fontStyle);
- sbuf.append(',');
- sbuf.append(fontWeight);*/
- sbuf.append('}');
- return sbuf.toString();
- }
-
- /**
- * Helper method for getting the width of a unicode char
- * from the current fontstate.
- * This also performs some guessing on widths on various
- * versions of space that might not exists in the font.
- * @param c character to inspect
- * @return the width of the character or -1 if no width available
- */
- public int getCharWidth(char c) {
- int width;
-
- if ((c == '\n') || (c == '\r') || (c == '\t') || (c == '\u00A0')) {
- width = getCharWidth(' ');
- } else {
- if (hasChar(c)) {
- int mappedChar = mapChar(c);
- width = getWidth(mappedChar);
- } else {
- width = -1;
- }
- if (width <= 0) {
- // Estimate the width of spaces not represented in
- // the font
- int em = getFontSize(); //http://en.wikipedia.org/wiki/Em_(typography)
- int en = em / 2; //http://en.wikipedia.org/wiki/En_(typography)
-
- if (c == ' ') {
- width = em;
- } else if (c == '\u2000') {
- width = en;
- } else if (c == '\u2001') {
- width = em;
- } else if (c == '\u2002') {
- width = em / 2;
- } else if (c == '\u2003') {
- width = getFontSize();
- } else if (c == '\u2004') {
- width = em / 3;
- } else if (c == '\u2005') {
- width = em / 4;
- } else if (c == '\u2006') {
- width = em / 6;
- } else if (c == '\u2007') {
- width = getCharWidth('0');
- } else if (c == '\u2008') {
- width = getCharWidth('.');
- } else if (c == '\u2009') {
- width = em / 5;
- } else if (c == '\u200A') {
- width = em / 10;
- } else if (c == '\u200B') {
- width = 0;
- } else if (c == '\u202F') {
- width = getCharWidth(' ') / 2;
- } else if (c == '\u2060') {
- width = 0;
- } else if (c == '\u3000') {
- width = getCharWidth(' ') * 2;
- } else if (c == '\ufeff') {
- width = 0;
- } else {
- //Will be internally replaced by "#" if not found
- width = getWidth(mapChar(c));
- }
- }
- }
-
- return width;
- }
-
- /**
- * Helper method for getting the width of a unicode char
- * from the current fontstate.
- * This also performs some guessing on widths on various
- * versions of space that might not exists in the font.
- * @param c character to inspect
- * @return the width of the character or -1 if no width available
- */
- public int getCharWidth(int c) {
- if (c < 0x10000) {
- return getCharWidth((char) c);
- } else {
- // TODO !BMP
- return -1;
- }
- }
-
- /**
- * Calculates the word width.
- * @param word text to get width for
- * @return the width of the text
- */
- public int getWordWidth(String word) {
- if (word == null) {
- return 0;
- }
- int wordLength = word.length();
- int width = 0;
- char[] characters = new char[wordLength];
- word.getChars(0, wordLength, characters, 0);
- for (int i = 0; i < wordLength; i++) {
- width += getCharWidth(characters[i]);
- }
- return width;
- }
-
- /** {@inheritDoc} */
- public boolean performsSubstitution() {
- if (metric instanceof Substitutable) {
- Substitutable s = (Substitutable) metric;
- return s.performsSubstitution();
- } else {
- return false;
- }
- }
-
- /** {@inheritDoc} */
- public CharSequence performSubstitution(CharSequence cs,
- String script, String language, List associations, boolean retainControls) {
- if (metric instanceof Substitutable) {
- Substitutable s = (Substitutable) metric;
- return s.performSubstitution(cs, script, language, associations, retainControls);
- } else {
- throw new UnsupportedOperationException();
- }
- }
-
- /** {@inheritDoc} */
- public CharSequence reorderCombiningMarks(CharSequence cs, int[][] gpa,
- String script, String language, List associations) {
- if (metric instanceof Substitutable) {
- Substitutable s = (Substitutable) metric;
- return s.reorderCombiningMarks(cs, gpa, script, language, associations);
- } else {
- throw new UnsupportedOperationException();
- }
- }
-
- /** {@inheritDoc} */
- public boolean performsPositioning() {
- if (metric instanceof Positionable) {
- Positionable p = (Positionable) metric;
- return p.performsPositioning();
- } else {
- return false;
- }
- }
-
- /** {@inheritDoc} */
- public int[][] performPositioning(CharSequence cs, String script, String language, int fontSize) {
- if (metric instanceof Positionable) {
- Positionable p = (Positionable) metric;
- return p.performPositioning(cs, script, language, fontSize);
- } else {
- throw new UnsupportedOperationException();
- }
- }
-
- /** {@inheritDoc} */
- public int[][] performPositioning(CharSequence cs, String script, String language) {
- return performPositioning(cs, script, language, fontSize);
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/FontAdder.java b/src/java/org/apache/fop/fonts/FontAdder.java
deleted file mode 100644
index f585dbfa5..000000000
--- a/src/java/org/apache/fop/fonts/FontAdder.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.net.URISyntaxException;
-import java.net.URL;
-import java.util.List;
-
-import org.apache.fop.apps.io.InternalResourceResolver;
-import org.apache.fop.fonts.autodetect.FontInfoFinder;
-
-/**
- * Adds a list of fonts to a given font info list
- */
-public class FontAdder {
- private final FontEventListener listener;
- private final InternalResourceResolver resourceResolver;
- private final FontManager manager;
-
- /**
- * Main constructor
- * @param manager a font manager
- * @param resourceResolver a font resolver
- * @param listener a font event handler
- */
- public FontAdder(FontManager manager, InternalResourceResolver resourceResolver,
- FontEventListener listener) {
- this.manager = manager;
- this.resourceResolver = resourceResolver;
- this.listener = listener;
- }
-
- /**
- * Iterates over font url list adding to font info list
- * @param fontURLList font file list
- * @param fontInfoList a configured font info list
- * @throws URISyntaxException if a URI syntax error is found
- */
- public void add(List<URL> fontURLList, List<EmbedFontInfo> fontInfoList)
- throws URISyntaxException {
- FontCache cache = manager.getFontCache();
- FontInfoFinder finder = new FontInfoFinder();
- finder.setEventListener(listener);
-
- for (URL fontURL : fontURLList) {
- EmbedFontInfo[] embedFontInfos = finder.find(fontURL.toURI(), resourceResolver, cache);
- if (embedFontInfos == null) {
- continue;
- }
- for (int i = 0, c = embedFontInfos.length; i < c; i++) {
- EmbedFontInfo fontInfo = embedFontInfos[i];
- if (fontInfo != null) {
- fontInfoList.add(fontInfo);
- }
- }
- }
- }
-}
diff --git a/src/java/org/apache/fop/fonts/FontCache.java b/src/java/org/apache/fop/fonts/FontCache.java
deleted file mode 100644
index 1f5b96b80..000000000
--- a/src/java/org/apache/fop/fonts/FontCache.java
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- * 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.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.apps.io.InternalResourceResolver;
-import org.apache.fop.util.LogUtil;
-
-/**
- * Fop cache (currently only used for font info caching)
- */
-public final class FontCache implements Serializable {
-
- /**
- * Serialization Version UID. Change this value if you want to make sure the
- * user's cache file is purged after an update.
- */
- private static final long serialVersionUID = 9129238336422194339L;
-
- /** logging instance */
- private static Log log = LogFactory.getLog(FontCache.class);
-
- /** FOP's user directory name */
- private static final String FOP_USER_DIR = ".fop";
-
- /** font cache file path */
- private static final String DEFAULT_CACHE_FILENAME = "fop-fonts.cache";
-
- /** has this cache been changed since it was last read? */
- private transient boolean changed;
-
- /** change lock */
- private final boolean[] changeLock = new boolean[1];
-
- /**
- * master mapping of font url -> font info. This needs to be a list, since a
- * TTC file may contain more than 1 font.
- * @serial
- */
- private Map<String, CachedFontFile> fontfileMap;
-
- /**
- * mapping of font url -> file modified date (for all fonts that have failed
- * to load)
- * @serial
- */
- private Map<String, Long> failedFontMap;
-
- private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
- ois.defaultReadObject();
- }
-
- private static File getUserHome() {
- return toDirectory(System.getProperty("user.home"));
- }
-
- private static File getTempDirectory() {
- return toDirectory(System.getProperty("java.io.tmpdir"));
- }
-
- private static File toDirectory(String path) {
- if (path != null) {
- File dir = new File(path);
- if (dir.exists()) {
- return dir;
- }
- }
- return null;
- }
-
- /**
- * Returns the default font cache file.
- *
- * @param forWriting
- * true if the user directory should be created
- * @return the default font cache file
- */
- public static File getDefaultCacheFile(boolean forWriting) {
- File userHome = getUserHome();
- if (userHome != null) {
- File fopUserDir = new File(userHome, FOP_USER_DIR);
- if (forWriting) {
- boolean writable = fopUserDir.canWrite();
- if (!fopUserDir.exists()) {
- writable = fopUserDir.mkdir();
- }
- if (!writable) {
- userHome = getTempDirectory();
- fopUserDir = new File(userHome, FOP_USER_DIR);
- fopUserDir.mkdir();
- }
- }
- return new File(fopUserDir, DEFAULT_CACHE_FILENAME);
- }
- return new File(FOP_USER_DIR);
- }
-
- /**
- * Reads the default font cache file and returns its contents.
- *
- * @return the font cache deserialized from the file (or null if no cache
- * file exists or if it could not be read)
- * @deprecated use {@link #loadFrom(File)} instead
- */
- public static FontCache load() {
- return loadFrom(getDefaultCacheFile(false));
- }
-
- /**
- * Reads a font cache file and returns its contents.
- *
- * @param cacheFile
- * the cache file
- * @return the font cache deserialized from the file (or null if no cache
- * file exists or if it could not be read)
- */
- public static FontCache loadFrom(File cacheFile) {
- if (cacheFile.exists()) {
- try {
- if (log.isTraceEnabled()) {
- log.trace("Loading font cache from "
- + cacheFile.getCanonicalPath());
- }
- InputStream in = new BufferedInputStream(new FileInputStream(cacheFile));
- ObjectInputStream oin = new ObjectInputStream(in);
- try {
- return (FontCache) oin.readObject();
- } finally {
- IOUtils.closeQuietly(oin);
- }
- } catch (ClassNotFoundException e) {
- // We don't really care about the exception since it's just a
- // cache file
- log.warn("Could not read font cache. Discarding font cache file. Reason: "
- + e.getMessage());
- } catch (IOException ioe) {
- // We don't really care about the exception since it's just a
- // cache file
- log.warn("I/O exception while reading font cache ("
- + ioe.getMessage() + "). Discarding font cache file.");
- try {
- cacheFile.delete();
- } catch (SecurityException ex) {
- log.warn("Failed to delete font cache file: "
- + cacheFile.getAbsolutePath());
- }
- }
- }
- return null;
- }
-
- /**
- * Writes the font cache to disk.
- *
- * @throws FOPException fop exception
- * @deprecated use {@link #saveTo(File)} instead
- */
- public void save() throws FOPException {
- saveTo(getDefaultCacheFile(true));
- }
-
- /**
- * Writes the font cache to disk.
- *
- * @param cacheFile
- * the file to write to
- * @throws FOPException
- * fop exception
- */
- public void saveTo(File cacheFile) throws FOPException {
- synchronized (changeLock) {
- if (changed) {
- try {
- log.trace("Writing font cache to " + cacheFile.getCanonicalPath());
- OutputStream out = new java.io.FileOutputStream(cacheFile);
- out = new java.io.BufferedOutputStream(out);
- ObjectOutputStream oout = new ObjectOutputStream(out);
- try {
- oout.writeObject(this);
- } finally {
- IOUtils.closeQuietly(oout);
- }
- } catch (IOException ioe) {
- LogUtil.handleException(log, ioe, true);
- }
- changed = false;
- log.trace("Cache file written.");
- }
- }
- }
-
- /**
- * creates a key given a font info for the font mapping
- *
- * @param fontInfo
- * font info
- * @return font cache key
- */
- protected static String getCacheKey(EmbedFontInfo fontInfo) {
- if (fontInfo != null) {
- URI embedFile = fontInfo.getEmbedURI();
- URI metricsFile = fontInfo.getMetricsURI();
- return (embedFile != null) ? embedFile.toASCIIString() : metricsFile.toASCIIString();
- }
- return null;
- }
-
- /**
- * cache has been updated since it was read
- *
- * @return if this cache has changed
- */
- public boolean hasChanged() {
- return this.changed;
- }
-
- /**
- * is this font in the cache?
- *
- * @param embedUrl
- * font info
- * @return boolean
- */
- public boolean containsFont(String embedUrl) {
- return (embedUrl != null && getFontFileMap().containsKey(embedUrl));
- }
-
- /**
- * is this font info in the cache?
- *
- * @param fontInfo
- * font info
- * @return font
- */
- public boolean containsFont(EmbedFontInfo fontInfo) {
- return (fontInfo != null && getFontFileMap().containsKey(
- getCacheKey(fontInfo)));
- }
-
- /**
- * Tries to identify a File instance from an array of URLs. If there's no
- * file URL in the array, the method returns null.
- *
- * @param urls
- * array of possible font urls
- * @return file font file
- */
- public static File getFileFromUrls(String[] urls) {
- for (int i = 0; i < urls.length; i++) {
- String urlStr = urls[i];
- if (urlStr != null) {
- File fontFile = null;
- if (urlStr.startsWith("file:")) {
- try {
- URL url = new URL(urlStr);
- fontFile = FileUtils.toFile(url);
- } catch (MalformedURLException mfue) {
- // do nothing
- }
- }
- if (fontFile == null) {
- fontFile = new File(urlStr);
- }
- if (fontFile.exists() && fontFile.canRead()) {
- return fontFile;
- }
- }
- }
- return null;
- }
-
- private Map<String, CachedFontFile> getFontFileMap() {
- if (fontfileMap == null) {
- fontfileMap = new HashMap<String, CachedFontFile>();
- }
- return fontfileMap;
- }
-
- /**
- * Adds a font info to cache
- *
- * @param fontInfo
- * font info
- */
- public void addFont(EmbedFontInfo fontInfo, InternalResourceResolver resourceResolver) {
- String cacheKey = getCacheKey(fontInfo);
- synchronized (changeLock) {
- CachedFontFile cachedFontFile;
- if (containsFont(cacheKey)) {
- cachedFontFile = getFontFileMap().get(cacheKey);
- if (!cachedFontFile.containsFont(fontInfo)) {
- cachedFontFile.put(fontInfo);
- }
- } else {
- // try and determine modified date
- URI fontUri = resourceResolver.resolveFromBase(fontInfo.getEmbedURI());
- File fontFile = new File(fontUri);
- long lastModified = fontFile.lastModified();
- cachedFontFile = new CachedFontFile(lastModified);
- if (log.isTraceEnabled()) {
- log.trace("Font added to cache: " + cacheKey);
- }
- cachedFontFile.put(fontInfo);
- getFontFileMap().put(cacheKey, cachedFontFile);
- changed = true;
- }
- }
- }
-
- /**
- * Returns a font from the cache.
- *
- * @param embedUrl
- * font info
- * @return CachedFontFile object
- */
- public CachedFontFile getFontFile(String embedUrl) {
- return containsFont(embedUrl) ? getFontFileMap().get(embedUrl) : null;
- }
-
- /**
- * Returns the EmbedFontInfo instances belonging to a font file. If the font
- * file was modified since it was cached the entry is removed and null is
- * returned.
- *
- * @param embedUrl
- * the font URL
- * @param lastModified
- * the last modified date/time of the font file
- * @return the EmbedFontInfo instances or null if there's no cached entry or
- * if it is outdated
- */
- public EmbedFontInfo[] getFontInfos(String embedUrl, long lastModified) {
- CachedFontFile cff = getFontFile(embedUrl);
- if (cff.lastModified() == lastModified) {
- return cff.getEmbedFontInfos();
- } else {
- removeFont(embedUrl);
- return null;
- }
- }
-
- /**
- * removes font from cache
- *
- * @param embedUrl
- * embed url
- */
- public void removeFont(String embedUrl) {
- synchronized (changeLock) {
- if (containsFont(embedUrl)) {
- if (log.isTraceEnabled()) {
- log.trace("Font removed from cache: " + embedUrl);
- }
- getFontFileMap().remove(embedUrl);
- changed = true;
- }
- }
- }
-
- /**
- * has this font previously failed to load?
- *
- * @param embedUrl
- * embed url
- * @param lastModified
- * last modified
- * @return whether this is a failed font
- */
- public boolean isFailedFont(String embedUrl, long lastModified) {
- synchronized (changeLock) {
- if (getFailedFontMap().containsKey(embedUrl)) {
- long failedLastModified = getFailedFontMap().get(
- embedUrl).longValue();
- if (lastModified != failedLastModified) {
- // this font has been changed so lets remove it
- // from failed font map for now
- getFailedFontMap().remove(embedUrl);
- changed = true;
- }
- return true;
- } else {
- return false;
- }
- }
- }
-
- /**
- * Registers a failed font with the cache
- *
- * @param embedUrl
- * embed url
- * @param lastModified
- * time last modified
- */
- public void registerFailedFont(String embedUrl, long lastModified) {
- synchronized (changeLock) {
- if (!getFailedFontMap().containsKey(embedUrl)) {
- getFailedFontMap().put(embedUrl, new Long(lastModified));
- changed = true;
- }
- }
- }
-
- private Map<String, Long> getFailedFontMap() {
- if (failedFontMap == null) {
- failedFontMap = new HashMap<String, Long>();
- }
- return failedFontMap;
- }
-
- /**
- * Clears font cache
- */
- public void clear() {
- synchronized (changeLock) {
- if (log.isTraceEnabled()) {
- log.trace("Font cache cleared.");
- }
- fontfileMap = null;
- failedFontMap = null;
- changed = true;
- }
- }
-
- /**
- * Retrieve the last modified date/time of a URI.
- *
- * @param uri the URI
- * @return the last modified date/time
- */
- public static long getLastModified(URI uri) {
- try {
- URL url = uri.toURL();
- URLConnection conn = url.openConnection();
- try {
- return conn.getLastModified();
- } finally {
- // An InputStream is created even if it's not accessed, but we
- // need to close it.
- IOUtils.closeQuietly(conn.getInputStream());
- }
- } catch (IOException e) {
- // Should never happen, because URL must be local
- log.debug("IOError: " + e.getMessage());
- return 0;
- }
- }
-
- private static class CachedFontFile implements Serializable {
- private static final long serialVersionUID = 4524237324330578883L;
-
- /** file modify date (if available) */
- private long lastModified = -1;
-
- private Map<String, EmbedFontInfo> filefontsMap;
-
- public CachedFontFile(long lastModified) {
- setLastModified(lastModified);
- }
-
- private Map<String, EmbedFontInfo> getFileFontsMap() {
- if (filefontsMap == null) {
- filefontsMap = new HashMap<String, EmbedFontInfo>();
- }
- return filefontsMap;
- }
-
- void put(EmbedFontInfo efi) {
- getFileFontsMap().put(efi.getPostScriptName(), efi);
- }
-
- public boolean containsFont(EmbedFontInfo efi) {
- return efi.getPostScriptName() != null
- && getFileFontsMap().containsKey(efi.getPostScriptName());
- }
-
- public EmbedFontInfo[] getEmbedFontInfos() {
- return getFileFontsMap().values().toArray(
- new EmbedFontInfo[getFileFontsMap().size()]);
- }
-
- /**
- * Gets the modified timestamp for font file (not always available)
- *
- * @return modified timestamp
- */
- public long lastModified() {
- return this.lastModified;
- }
-
- /**
- * Gets the modified timestamp for font file (used for the purposes of
- * font info caching)
- *
- * @param lastModified
- * modified font file timestamp
- */
- public void setLastModified(long lastModified) {
- this.lastModified = lastModified;
- }
-
- /**
- * @return string representation of this object {@inheritDoc}
- */
- public String toString() {
- return super.toString() + ", lastModified=" + lastModified;
- }
-
- }
-}
diff --git a/src/java/org/apache/fop/fonts/FontCacheManager.java b/src/java/org/apache/fop/fonts/FontCacheManager.java
deleted file mode 100644
index a4acd43a4..000000000
--- a/src/java/org/apache/fop/fonts/FontCacheManager.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.net.URI;
-
-import org.apache.fop.apps.FOPException;
-
-
-/**
- * Fop cache (currently only used for font info caching)
- */
-public interface FontCacheManager {
-
- /**
- * Sets the font cache file given the URI pointing to the file.
- * @param fontCacheURI the font cache URI
- */
- void setCacheFile(URI fontCacheURI);
-
- /**
- * Loads the font cache into memory from the given file.
- * @return the de-serialized font cache
- */
- FontCache load();
-
- /**
- * Serializes the font cache to file.
- * @throws FOPException if an error occurs serializing the font cache
- */
- void save() throws FOPException;
-
- /**
- * Deletes the font cache from the file-system.
- * @throws FOPException if an error occurs deleting the font cache
- */
- void delete() throws FOPException;
-}
diff --git a/src/java/org/apache/fop/fonts/FontCacheManagerFactory.java b/src/java/org/apache/fop/fonts/FontCacheManagerFactory.java
deleted file mode 100644
index c1d736b0d..000000000
--- a/src/java/org/apache/fop/fonts/FontCacheManagerFactory.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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.File;
-import java.net.URI;
-
-import org.apache.fop.apps.FOPException;
-
-/**
- * A factory that provides the font caching manager mechanism.
- *
- */
-public final class FontCacheManagerFactory {
-
- private FontCacheManagerFactory() {
- }
-
- /**
- * Create the default font caching mechanism.
- * @return the font cache manager
- */
- public static FontCacheManager createDefault() {
- return new FontCacheManagerImpl();
- }
-
- /**
- * Create a disabled font caching mechanism which by definition does nothing to cache fonts.
- * @return a completely restricted font cache manager
- */
- public static FontCacheManager createDisabled() {
- return new DisabledFontCacheManager();
- }
-
- private static final class FontCacheManagerImpl implements FontCacheManager {
-
- /** Provides a font cache file path **/
- private File cacheFile;
-
- private FontCache fontCache;
-
- public FontCache load() {
- if (fontCache == null) {
- fontCache = FontCache.loadFrom(getCacheFile(false));
- if (fontCache == null) {
- fontCache = new FontCache();
- }
- }
- return fontCache;
- }
-
- public void save() throws FOPException {
- if (fontCache != null && fontCache.hasChanged()) {
- fontCache.saveTo(getCacheFile(true));
- }
- }
-
- public void delete() throws FOPException {
- if (!getCacheFile(true).delete()) {
- throw new FOPException("Failed to flush the font cache file '" + cacheFile + "'.");
- }
- }
-
- private File getCacheFile(boolean forWriting) {
- if (cacheFile != null) {
- return cacheFile;
- }
- return FontCache.getDefaultCacheFile(forWriting);
- }
-
- public void setCacheFile(URI fontCacheURI) {
- cacheFile = new File(fontCacheURI);
- }
- }
-
- private static final class DisabledFontCacheManager implements FontCacheManager {
-
- public FontCache load() {
- return null;
- }
-
- public void save() throws FOPException {
- // nop
- }
-
- public void delete() throws FOPException {
- throw new FOPException("Font Cache disabled");
- }
-
- public void setCacheFile(URI fontCacheURI) {
- // nop
- }
- }
-}
diff --git a/src/java/org/apache/fop/fonts/FontCollection.java b/src/java/org/apache/fop/fonts/FontCollection.java
deleted file mode 100644
index d481ae2f9..000000000
--- a/src/java/org/apache/fop/fonts/FontCollection.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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;
-
-
-/**
- * Sets up a set of fonts
- */
-public interface FontCollection {
-
- /**
- * Sets up fonts in a font info object.
- *
- * Adds metrics for basic fonts and useful family-style-weight
- * triplets for lookup.
- *
- * @param start the font starting number
- * @param fontInfo the font info to set up
- * @return the starting font number for the next font to be added
- */
- int setup(int start, FontInfo fontInfo);
-}
diff --git a/src/java/org/apache/fop/fonts/FontConfig.java b/src/java/org/apache/fop/fonts/FontConfig.java
deleted file mode 100644
index 167baf09e..000000000
--- a/src/java/org/apache/fop/fonts/FontConfig.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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 org.apache.avalon.framework.configuration.Configuration;
-
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.events.EventProducer;
-
-/**
- * An interface for font configuration information.
- */
-public interface FontConfig {
-
- /**
- * An interface for parsing font configuration information.
- */
- public interface FontConfigParser {
-
- /**
- * Parse the font configuration and return an object containing all the necessary data.
- *
- * @param cfg the configuration object
- * @param fontManager the font manager
- * @param strict whether or not to enforce strict validation
- * @param eventProducer the event producer for handling font events
- * @return the configuration object
- * @throws FOPException if an error occurs creating the font configuration object
- */
- FontConfig parse(Configuration cfg, FontManager fontManager, boolean strict,
- EventProducer eventProducer) throws FOPException;
- }
-}
diff --git a/src/java/org/apache/fop/fonts/FontConfigurator.java b/src/java/org/apache/fop/fonts/FontConfigurator.java
deleted file mode 100644
index c1ddb4296..000000000
--- a/src/java/org/apache/fop/fonts/FontConfigurator.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.util.List;
-
-import org.apache.fop.apps.FOPException;
-
-/**
- * An abstract FontInfo configurator
- */
-// TODO: Make T extends some interface to make the font info type explicit
-public interface FontConfigurator<T> {
-
- /**
- * Initializes font info settings from the user configuration
- * @return a font info list
- * @throws FOPException if an exception occurs while processing the configuration
- */
- List<T> configure(FontConfig fontInfoConfig) throws FOPException;
-
-}
diff --git a/src/java/org/apache/fop/fonts/FontDescriptor.java b/src/java/org/apache/fop/fonts/FontDescriptor.java
deleted file mode 100644
index 8aea105be..000000000
--- a/src/java/org/apache/fop/fonts/FontDescriptor.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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;
-
-
-/**
- * This interface enhances the font metrics interface with access methods to
- * value needed to register fonts in various target formats like PDF or
- * PostScript.
- */
-public interface FontDescriptor extends FontMetrics {
-
- /**
- * Returns the ascender value of the font. (Ascent in pdf spec)
- * @return the ascender
- */
- int getAscender();
-
-
- /**
- * Returns the capital height of the font.
- * @return the capital height
- */
- int getCapHeight();
-
-
- /**
- * Returns the descender value of the font. (Descent in pdf spec)
- * @return the descender value
- */
- int getDescender();
-
-
- /**
- * Returns the flags for the font. (See pdf spec)
- * @return the flags
- */
- int getFlags();
-
- /**
- * Indicates whether the font is a symbolic font.
- * @return true if the font is a symbolic font (i.e. Symbol or ZapfDingbats)
- */
- boolean isSymbolicFont();
- /**
- * Returns the font's bounding box.
- * @return the bounding box
- */
- int[] getFontBBox();
-
-
- /**
- * Returns the italic angle for the font.
- * @return the italic angle
- */
- int getItalicAngle();
-
-
- /**
- * Returns the vertical stem width for the font.
- * @return the vertical stem width
- */
- int getStemV();
-
-
- /**
- * Indicates if this font may be embedded.
- * @return True, if embedding is possible/permitted
- */
- boolean isEmbeddable();
-
- /**
- * Indicates whether this font is subset embedded.
- * @return true if this font is subset embedded
- */
- boolean isSubsetEmbedded();
-
-}
diff --git a/src/java/org/apache/fop/fonts/FontDetector.java b/src/java/org/apache/fop/fonts/FontDetector.java
deleted file mode 100644
index 71965f4a4..000000000
--- a/src/java/org/apache/fop/fonts/FontDetector.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.util.List;
-
-import org.apache.fop.apps.FOPException;
-
-/**
- * An interface for the font detecting mechanism.
- */
-
-public interface FontDetector {
- void detect(FontManager fontManager, FontAdder fontAdder, boolean strict,
- FontEventListener eventListener, List<EmbedFontInfo> fontInfoList) throws FOPException;
-}
diff --git a/src/java/org/apache/fop/fonts/FontDetectorFactory.java b/src/java/org/apache/fop/fonts/FontDetectorFactory.java
deleted file mode 100644
index dd96e4a1a..000000000
--- a/src/java/org/apache/fop/fonts/FontDetectorFactory.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.List;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.xmlgraphics.util.ClasspathResource;
-
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.fonts.autodetect.FontFileFinder;
-import org.apache.fop.util.LogUtil;
-
-/**
- * A factory that provides the font detecting machanism.
- */
-public final class FontDetectorFactory {
- private FontDetectorFactory() {
- }
-
- /**
- * Creates the default font detector
- * @return the default font detector
- */
- public static FontDetector createDefault() {
- return new DefaultFontDetector();
- }
-
- /**
- * Creates a disabled font detector which, by definition, does nothing to detect fonts.
- * @return the completely restricted font detector
- */
- public static FontDetector createDisabled() {
- return new DisabledFontDetector();
- }
-
-
- private static class DisabledFontDetector implements FontDetector {
- public void detect(FontManager fontManager, FontAdder fontAdder, boolean strict,
- FontEventListener eventListener, List<EmbedFontInfo> fontInfoList)
- throws FOPException {
- // nop
- }
- }
-
- /**
- * Detector of operating system and classpath fonts
- */
- private static class DefaultFontDetector implements FontDetector {
- private static Log log = LogFactory.getLog(DefaultFontDetector.class);
-
- private static final String[] FONT_MIMETYPES = {
- "application/x-font", "application/x-font-truetype"
- };
-
- /**
- * Detect installed fonts on the system
- * @param fontInfoList a list of fontinfo to populate
- * @throws FOPException thrown if a problem occurred during detection
- */
- public void detect(FontManager fontManager, FontAdder fontAdder, boolean strict,
- FontEventListener eventListener, List<EmbedFontInfo> fontInfoList)
- throws FOPException {
- try {
- // search in font base if it is defined and
- // is a directory but don't recurse
- FontFileFinder fontFileFinder = new FontFileFinder(eventListener);
- URI fontBaseURI = fontManager.getResourceResolver().getBaseURI();
- File fontBase = FileUtils.toFile(fontBaseURI.toURL());
- if (fontBase != null) {
- List<URL> fontURLList = fontFileFinder.find(fontBase.getAbsolutePath());
- fontAdder.add(fontURLList, fontInfoList);
-
- //Can only use the font base URL if it's a file URL
- }
-
- // native o/s font directory finding
- List<URL> systemFontList;
- systemFontList = fontFileFinder.find();
- fontAdder.add(systemFontList, fontInfoList);
-
- // classpath font finding
- ClasspathResource resource = ClasspathResource.getInstance();
- for (String mimeTypes : FONT_MIMETYPES) {
- fontAdder.add(resource.listResourcesOfMimeType(mimeTypes), fontInfoList);
- }
- } catch (IOException e) {
- LogUtil.handleException(log, e, strict);
- } catch (URISyntaxException use) {
- LogUtil.handleException(log, use, strict);
- }
- }
- }
-}
diff --git a/src/java/org/apache/fop/fonts/FontEventAdapter.java b/src/java/org/apache/fop/fonts/FontEventAdapter.java
deleted file mode 100644
index e8078a796..000000000
--- a/src/java/org/apache/fop/fonts/FontEventAdapter.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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 org.apache.fop.events.EventBroadcaster;
-
-/**
- * Event listener interface for font-related events. This interface extends FontEventListener
- * and EventProducer for integration into FOP's event subsystem.
- */
-public class FontEventAdapter implements FontEventListener {
-
- private final EventBroadcaster eventBroadcaster;
-
- private FontEventProducer eventProducer;
-
- /**
- * Creates a new FontEventAdapter.
- * @param broadcaster the event broadcaster to send the generated events to
- */
- public FontEventAdapter(EventBroadcaster broadcaster) {
- this.eventBroadcaster = broadcaster;
- }
-
- private FontEventProducer getEventProducer() {
- if (eventProducer == null) {
- eventProducer = FontEventProducer.Provider.get(eventBroadcaster);
- }
- return eventProducer;
- }
-
- /** {@inheritDoc} */
- public void fontSubstituted(Object source, FontTriplet requested, FontTriplet effective) {
- getEventProducer().fontSubstituted(source, requested, effective);
- }
-
- /** {@inheritDoc} */
- public void fontLoadingErrorAtAutoDetection(Object source, String fontURL, Exception e) {
- getEventProducer().fontLoadingErrorAtAutoDetection(source, fontURL, e);
- }
-
- /** {@inheritDoc} */
- public void glyphNotAvailable(Object source, char ch, String fontName) {
- getEventProducer().glyphNotAvailable(source, ch, fontName);
- }
-
- /** {@inheritDoc} */
- public void fontDirectoryNotFound(Object source, String dir) {
- getEventProducer().fontDirectoryNotFound(source, dir);
- }
-
- /** {@inheritDoc} */
- public void svgTextStrokedAsShapes(Object source, String fontFamily) {
- getEventProducer().svgTextStrokedAsShapes(source, fontFamily);
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/FontEventListener.java b/src/java/org/apache/fop/fonts/FontEventListener.java
deleted file mode 100644
index 419a3fcd2..000000000
--- a/src/java/org/apache/fop/fonts/FontEventListener.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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;
-
-/**
- * Event listener interface for font-related events.
- */
-public interface FontEventListener {
-
- /**
- * Notifies about a font being substituted as the requested one isn't available.
- * @param source the event source
- * @param requested the requested font triplet
- * @param effective the effective font triplet
- */
- void fontSubstituted(Object source, FontTriplet requested, FontTriplet effective);
-
- /**
- * An error occurred while loading a font for auto-detection.
- * @param source the event source
- * @param fontURL the font URL
- * @param e the original exception
- */
- void fontLoadingErrorAtAutoDetection(Object source, String fontURL, Exception e);
-
- /**
- * A glyph has been requested that is not available in the font.
- * @param source the event source
- * @param ch the character for which the glyph isn't available
- * @param fontName the name of the font
- */
- void glyphNotAvailable(Object source, char ch, String fontName);
-
- /**
- * An error occurred trying to find the font directory specified in the config file.
- * @param source the event source
- * @param dir the directory in the config file
- */
- void fontDirectoryNotFound(Object source, String dir);
-
- /**
- * The SVG text will be stroked as shapes.
- * @param source the event source
- * @param fontFamily the family name of the font that is being stroked
- */
- void svgTextStrokedAsShapes(Object source, String fontFamily);
-}
diff --git a/src/java/org/apache/fop/fonts/FontEventProducer.java b/src/java/org/apache/fop/fonts/FontEventProducer.java
deleted file mode 100644
index c6aaef662..000000000
--- a/src/java/org/apache/fop/fonts/FontEventProducer.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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 org.apache.fop.events.EventBroadcaster;
-import org.apache.fop.events.EventProducer;
-
-/**
- * Event producer for fonts-related events.
- */
-public interface FontEventProducer extends EventProducer {
-
- /**
- * Provider class for the event producer.
- */
- final class Provider {
-
- private Provider() { }
-
- /**
- * Returns an event producer.
- * @param broadcaster the event broadcaster to use
- * @return the event producer
- */
- public static FontEventProducer get(EventBroadcaster broadcaster) {
- return broadcaster.getEventProducerFor(FontEventProducer.class);
- }
- }
-
- /**
- * Notifies about a font being substituted as the requested one isn't available.
- * @param source the event source
- * @param requested the requested font triplet
- * @param effective the effective font triplet
- * @event.severity WARN
- */
- void fontSubstituted(Object source, FontTriplet requested, FontTriplet effective);
-
- /**
- * An error occurred while loading a font for auto-detection.
- * @param source the event source
- * @param fontURL the font URL
- * @param e the original exception
- * @event.severity WARN
- */
- void fontLoadingErrorAtAutoDetection(Object source, String fontURL, Exception e);
-
- /**
- * A glyph has been requested that is not available in the font.
- * @param source the event source
- * @param ch the character for which the glyph isn't available
- * @param fontName the name of the font
- * @event.severity WARN
- */
- void glyphNotAvailable(Object source, char ch, String fontName);
-
- /**
- * An error occurred trying to find the font directory specified in the config file.
- * @param source the event source
- * @param dir the directory in the config file
- * @event.severity WARN
- */
- void fontDirectoryNotFound(Object source, String dir);
-
- /**
- * The SVG text will be stroked as shapes.
- * @param source the event source
- * @param fontFamily the family name of the font that is being stroked
- * @event.severity WARN
- */
- void svgTextStrokedAsShapes(Object source, String fontFamily);
-}
diff --git a/src/java/org/apache/fop/fonts/FontEventProducer.xml b/src/java/org/apache/fop/fonts/FontEventProducer.xml
deleted file mode 100644
index d7ce27e7a..000000000
--- a/src/java/org/apache/fop/fonts/FontEventProducer.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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$ -->
-<catalogue xml:lang="en">
- <message key="fontSubstituted">Font "{requested}" not found. Substituting with "{effective}".</message>
- <message key="fontLoadingErrorAtAutoDetection">Unable to load font file: {fontURL}.[ Reason: {e}]</message>
- <message key="glyphNotAvailable">Glyph "{ch}" (0x{ch,hex}[, {ch,glyph-name}]) not available in font "{fontName}".</message>
- <message key="fontDirectoryNotFound">The font directory {dir} could not be found.</message>
- <message key="svgTextStrokedAsShapes">The SVG text for font {fontFamily} will be stroked as shapes.</message>
-</catalogue>
diff --git a/src/java/org/apache/fop/fonts/FontInfo.java b/src/java/org/apache/fop/fonts/FontInfo.java
deleted file mode 100644
index 617b5a4a7..000000000
--- a/src/java/org/apache/fop/fonts/FontInfo.java
+++ /dev/null
@@ -1,659 +0,0 @@
-/*
- * 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.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-
-/**
- * The FontInfo holds font information for the layout and rendering of a fo document.
- * This stores the list of available fonts that are setup by
- * the renderer. The font name can be retrieved for the
- * family style and weight.
- * <br>
- * Currently font supported font-variant small-caps is not
- * implemented.
- */
-public class FontInfo {
-
- /** logging instance */
- protected static final Log log = LogFactory.getLog(FontInfo.class);
-
- /** Map containing fonts that have been used */
- private Map<String, Typeface> usedFonts; //(String = font key)
-
- /** look up a font-triplet to find a font-name */
- private Map<FontTriplet, String> triplets; //(String = font key)
-
- /** look up a font-triplet to find its priority
- * (only used inside addFontProperties()) */
- private Map<FontTriplet, Integer> tripletPriorities; //Map<FontTriplet,Integer>
-
- /** look up a font-name to get a font (that implements FontMetrics at least) */
- private Map<String, Typeface> fonts; //(String = font key)
-
- /** Cache for Font instances. */
- private Map<FontTriplet, Map<Integer, Font>> fontInstanceCache;
-
- /** Event listener for font events */
- private FontEventListener eventListener;
-
- /**
- * Main constructor
- */
- public FontInfo() {
- this.triplets = new HashMap<FontTriplet, String>();
- this.tripletPriorities = new HashMap<FontTriplet, Integer>();
- this.fonts = new HashMap<String, Typeface>();
- this.usedFonts = new HashMap<String, Typeface>();
- }
-
- /**
- * Sets the font event listener that can be used to receive events about particular events
- * in this class.
- * @param listener the font event listener
- */
- public void setEventListener(FontEventListener listener) {
- this.eventListener = listener;
- }
-
- /**
- * Checks if the font setup is valid (At least the ultimate fallback font
- * must be registered.)
- * @return True if valid
- */
- public boolean isSetupValid() {
- //We're only called when font setup is done:
- tripletPriorities = null; // candidate for garbage collection
- return triplets.containsKey(Font.DEFAULT_FONT);
- }
-
- /**
- * Adds a new font triplet.
- * @param name internal key
- * @param family font family name
- * @param style font style (normal, italic, oblique...)
- * @param weight font weight
- */
- public void addFontProperties(String name, String family, String style, int weight) {
- addFontProperties(name, createFontKey(family, style, weight));
- }
-
- /**
- * Adds a series of new font triplets given an array of font family names.
- * @param name internal key
- * @param families an array of font family names
- * @param style font style (normal, italic, oblique...)
- * @param weight font weight
- */
- public void addFontProperties(String name, String[] families, String style, int weight) {
- for (int i = 0; i < families.length; i++) {
- addFontProperties(name, families[i], style, weight);
- }
- }
-
- /**
- * Adds a new font triplet.
- * @param internalFontKey internal font key
- * @param triplet the font triplet to associate with the internal key
- */
- public void addFontProperties(String internalFontKey, FontTriplet triplet) {
- /*
- * add the given family, style and weight as a lookup for the font
- * with the given name
- */
- if (log.isDebugEnabled()) {
- log.debug("Registering: " + triplet + " under " + internalFontKey);
- }
- String oldName = triplets.get(triplet);
- int newPriority = triplet.getPriority();
- if (oldName != null) {
- int oldPriority = tripletPriorities.get(triplet).intValue();
- if (oldPriority < newPriority) {
- logDuplicateFont(triplet, false, oldName, oldPriority, internalFontKey, newPriority);
- return;
- } else {
- logDuplicateFont(triplet, true, oldName, oldPriority, internalFontKey, newPriority);
- }
- }
- this.triplets.put(triplet, internalFontKey);
- this.tripletPriorities.put(triplet, Integer.valueOf(newPriority));
- }
-
- /**
- * Log warning about duplicate font triplets.
- *
- * @param triplet the duplicate font triplet
- * @param replacing true iff the new font will replace the old one
- * @param oldKey the old internal font name
- * @param oldPriority the priority of the existing font mapping
- * @param newKey the new internal font name
- * @param newPriority the priority of the duplicate font mapping
- */
- private void logDuplicateFont(FontTriplet triplet, boolean replacing, String oldKey, int oldPriority,
- String newKey, int newPriority) {
- if (log.isDebugEnabled()) {
- log.debug(triplet
- + (replacing ? ": Replacing " : ": Not replacing ")
- + fonts.get(triplets.get(triplet)).getFullName()
- + " (priority=" + oldPriority + ") by "
- + fonts.get(newKey).getFullName()
- + " (priority=" + newPriority + ")");
- }
- }
-
- /**
- * Adds font metrics for a specific font.
- * @param internalFontKey internal key
- * @param metrics metrics to register
- */
- public void addMetrics(String internalFontKey, FontMetrics metrics) {
- // add the given metrics as a font with the given name
-
- if (metrics instanceof Typeface) {
- ((Typeface)metrics).setEventListener(this.eventListener);
- }
- this.fonts.put(internalFontKey, (Typeface)metrics);
- }
-
- /**
- * Lookup a font.
- * <br>
- * Locate the font name for a given family, style and weight.
- * The font name can then be used as a key as it is unique for
- * the associated document.
- * This also adds the font to the list of used fonts.
- * @param family font family
- * @param style font style
- * @param weight font weight
- * @param substitutable true if the font may be substituted with the
- * default font if not found
- * @return internal font triplet key
- */
- private FontTriplet fontLookup(String family, String style, int weight, boolean substitutable) {
- if (log.isTraceEnabled()) {
- log.trace("Font lookup: " + family + " " + style + " " + weight
- + (substitutable ? " substitutable" : ""));
- }
-
- FontTriplet startKey = createFontKey(family, style, weight);
- FontTriplet fontTriplet = startKey;
- // first try given parameters
- String internalFontKey = getInternalFontKey(fontTriplet);
- if (internalFontKey == null) {
- fontTriplet = fuzzyFontLookup(family, style, weight, startKey, substitutable);
- }
-
- if (fontTriplet != null) {
- if (fontTriplet != startKey) {
- notifyFontReplacement(startKey, fontTriplet);
- }
- return fontTriplet;
- } else {
- return null;
- }
- }
-
- private FontTriplet fuzzyFontLookup(String family, String style,
- int weight, FontTriplet startKey, boolean substitutable) {
- FontTriplet key;
- String internalFontKey = null;
- if (!family.equals(startKey.getName())) {
- key = createFontKey(family, style, weight);
- internalFontKey = getInternalFontKey(key);
- if (internalFontKey != null) {
- return key;
- }
- }
-
- // adjust weight, favouring normal or bold
- key = findAdjustWeight(family, style, weight);
- if (key != null) {
- internalFontKey = getInternalFontKey(key);
- }
-
- // return null if not found and not substitutable
- if (!substitutable && internalFontKey == null) {
- return null;
- }
-
- // only if the font may be substituted
- // fallback 1: try the same font-family and weight with default style
- if (internalFontKey == null && !style.equals(Font.STYLE_NORMAL)) {
- key = createFontKey(family, Font.STYLE_NORMAL, weight);
- internalFontKey = getInternalFontKey(key);
- }
-
- // fallback 2: try the same font-family with default style and try to adjust weight
- if (internalFontKey == null && !style.equals(Font.STYLE_NORMAL)) {
- key = findAdjustWeight(family, Font.STYLE_NORMAL, weight);
- if (key != null) {
- internalFontKey = getInternalFontKey(key);
- }
- }
-
- // fallback 3: try any family with original style/weight
- if (internalFontKey == null) {
- return fuzzyFontLookup("any", style, weight, startKey, false);
- }
-
- // last resort: use default
- if (key == null && internalFontKey == null) {
- key = Font.DEFAULT_FONT;
- internalFontKey = getInternalFontKey(key);
- }
-
- if (internalFontKey != null) {
- return key;
- } else {
- return null;
- }
- }
-
- /**
- * Tells this class that the font with the given internal name has been used.
- * @param internalName the internal font name (F1, F2 etc.)
- */
- public void useFont(String internalName) {
- usedFonts.put(internalName, fonts.get(internalName));
- }
-
- private Map<FontTriplet, Map<Integer, Font>> getFontInstanceCache() {
- if (fontInstanceCache == null) {
- fontInstanceCache = new HashMap<FontTriplet, Map<Integer, Font>>();
- }
- return fontInstanceCache;
- }
-
- /**
- * Retrieves a (possibly cached) Font instance based on a FontTriplet and a font size.
- *
- * @param triplet the font triplet designating the requested font
- * @param fontSize the font size
- * @return the requested Font instance
- */
- public Font getFontInstance(FontTriplet triplet, int fontSize) {
- Map<Integer, Font> sizes = getFontInstanceCache().get(triplet);
- if (sizes == null) {
- sizes = new HashMap<Integer, Font>();
- getFontInstanceCache().put(triplet, sizes);
- }
- Integer size = Integer.valueOf(fontSize);
- Font font = sizes.get(size);
- if (font == null) {
- String fontKey = getInternalFontKey(triplet);
- useFont(fontKey);
- FontMetrics metrics = getMetricsFor(fontKey);
- font = new Font(fontKey, triplet, metrics, fontSize);
- sizes.put(size, font);
- }
- return font;
- }
-
- private List<FontTriplet> getTripletsForName(String fontName) {
- List<FontTriplet> matchedTriplets = new ArrayList<FontTriplet>();
- for (FontTriplet triplet : triplets.keySet()) {
- String tripletName = triplet.getName();
- if (tripletName.toLowerCase().equals(fontName.toLowerCase())) {
- matchedTriplets.add(triplet);
- }
- }
- return matchedTriplets;
- }
-
- /**
- * Returns a suitable internal font given an AWT Font instance.
- *
- * @param awtFont the AWT font
- * @return a best matching internal Font
- */
- public Font getFontInstanceForAWTFont(java.awt.Font awtFont) {
- String awtFontName = awtFont.getName();
- String awtFontFamily = awtFont.getFamily();
- String awtFontStyle = awtFont.isItalic() ? Font.STYLE_ITALIC : Font.STYLE_NORMAL;
- int awtFontWeight = awtFont.isBold() ? Font.WEIGHT_BOLD : Font.WEIGHT_NORMAL;
-
- FontTriplet matchedTriplet = null;
- List<FontTriplet> triplets = getTripletsForName(awtFontName);
- if (!triplets.isEmpty()) {
- for (FontTriplet triplet : triplets) {
- boolean styleMatched = triplet.getStyle().equals(awtFontStyle);
- boolean weightMatched = triplet.getWeight() == awtFontWeight;
- if (styleMatched && weightMatched) {
- matchedTriplet = triplet;
- break;
- }
- }
- }
-
- // not matched on font name so do a lookup using family
- if (matchedTriplet == null) {
- if (awtFontFamily.equals("sanserif")) {
- awtFontFamily = "sans-serif";
- }
- matchedTriplet = fontLookup(awtFontFamily, awtFontStyle, awtFontWeight);
- }
- int fontSize = Math.round(awtFont.getSize2D() * 1000);
- return getFontInstance(matchedTriplet, fontSize);
- }
-
- /**
- * Lookup a font.
- * <br>
- * Locate the font name for a given family, style and weight.
- * The font name can then be used as a key as it is unique for
- * the associated document.
- * This also adds the font to the list of used fonts.
- * @param family font family
- * @param style font style
- * @param weight font weight
- * @return the font triplet of the font chosen
- */
- public FontTriplet fontLookup(String family, String style, int weight) {
- return fontLookup(family, style, weight, true);
- }
-
- private List<FontTriplet> fontLookup(String[] families, String style, int weight, boolean substitutable) {
- List<FontTriplet> matchingTriplets = new ArrayList<FontTriplet>();
- FontTriplet triplet = null;
- for (int i = 0; i < families.length; i++) {
- triplet = fontLookup(families[i], style, weight, substitutable);
- if (triplet != null) {
- matchingTriplets.add(triplet);
- }
- }
- return matchingTriplets;
- }
-
- /**
- * Looks up a set of fonts.
- * <br>
- * Locate the font name(s) for the given families, style and weight.
- * The font name(s) can then be used as a key as they are unique for
- * the associated document.
- * This also adds the fonts to the list of used fonts.
- * @param families font families (priority list)
- * @param style font style
- * @param weight font weight
- * @return the set of font triplets of all supported and chosen font-families
- * in the specified style and weight.
- */
- public FontTriplet[] fontLookup(String[] families, String style, int weight) {
- if (families.length == 0) {
- throw new IllegalArgumentException("Specify at least one font family");
- }
-
- // try matching without substitutions
- List<FontTriplet> matchedTriplets = fontLookup(families, style, weight, false);
-
- // if there are no matching font triplets found try with substitutions
- if (matchedTriplets.size() == 0) {
- matchedTriplets = fontLookup(families, style, weight, true);
- }
-
- // no matching font triplets found!
- if (matchedTriplets.size() == 0) {
- StringBuffer sb = new StringBuffer();
- for (int i = 0, c = families.length; i < c; i++) {
- if (i > 0) {
- sb.append(", ");
- }
- sb.append(families[i]);
- }
- throw new IllegalStateException(
- "fontLookup must return an array with at least one "
- + "FontTriplet on the last call. Lookup: " + sb.toString());
-
- }
- FontTriplet[] fontTriplets = new FontTriplet[matchedTriplets.size()];
- matchedTriplets.toArray(fontTriplets);
-
- // found some matching fonts so return them
- return fontTriplets;
- }
-
- private void notifyFontReplacement(FontTriplet replacedKey, FontTriplet newKey) {
- if (this.eventListener != null) {
- this.eventListener.fontSubstituted(this, replacedKey, newKey);
- }
- }
-
- /**
- * Notify listeners that the SVG text for the given font will be stroked as shapes.
- * @param fontFamily a SVG font family
- */
- public void notifyStrokingSVGTextAsShapes(String fontFamily) {
- if (this.eventListener != null) {
- this.eventListener.svgTextStrokedAsShapes(this, fontFamily);
- }
- }
-
- /**
- * Find a font with a given family and style by trying
- * different font weights according to the spec.
- * @param family font family
- * @param style font style
- * @param weight font weight
- * @return internal key
- */
- public FontTriplet findAdjustWeight(String family, String style, int weight) {
- FontTriplet key = null;
- String f = null;
- int newWeight = weight;
- if (newWeight < 400) {
- while (f == null && newWeight > 100) {
- newWeight -= 100;
- key = createFontKey(family, style, newWeight);
- f = getInternalFontKey(key);
- }
- newWeight = weight;
- while (f == null && newWeight < 400) {
- newWeight += 100;
- key = createFontKey(family, style, newWeight);
- f = getInternalFontKey(key);
- }
- } else if (newWeight == 400 || newWeight == 500) {
- key = createFontKey(family, style, 400);
- f = getInternalFontKey(key);
- } else if (newWeight > 500) {
- while (f == null && newWeight < 1000) {
- newWeight += 100;
- key = createFontKey(family, style, newWeight);
- f = getInternalFontKey(key);
- }
- newWeight = weight;
- while (f == null && newWeight > 400) {
- newWeight -= 100;
- key = createFontKey(family, style, newWeight);
- f = getInternalFontKey(key);
- }
- }
- if (f == null && weight != 400) {
- key = createFontKey(family, style, 400);
- f = getInternalFontKey(key);
- }
-
- if (f != null) {
- return key;
- } else {
- return null;
- }
- }
-
- /**
- * Determines if a particular font is available.
- * @param family font family
- * @param style font style
- * @param weight font weight
- * @return True if available
- */
- public boolean hasFont(String family, String style, int weight) {
- FontTriplet key = createFontKey(family, style, weight);
- return this.triplets.containsKey(key);
- }
-
- /**
- * Returns the internal font key (F1, F2, F3 etc.) for a given triplet.
- * @param triplet the font triplet
- * @return the associated internal key or null, if not found
- */
- public String getInternalFontKey(FontTriplet triplet) {
- return triplets.get(triplet);
- }
-
- /**
- * Creates a key from the given strings.
- * @param family font family
- * @param style font style
- * @param weight font weight
- * @return internal key
- */
- public static FontTriplet createFontKey(String family, String style, int weight) {
- return new FontTriplet(family, style, weight);
- }
-
- /**
- * Gets a Map of all registered fonts.
- * @return a read-only Map with font key/FontMetrics pairs
- */
- public Map<String, Typeface> getFonts() {
- return Collections.unmodifiableMap(this.fonts);
- }
-
- /**
- * Gets a Map of all registered font triplets.
- * @return a Map with FontTriplet/font key pairs
- */
- public Map<FontTriplet, String> getFontTriplets() {
- return this.triplets;
- }
-
- /**
- * This is used by the renderers to retrieve all the
- * fonts used in the document.
- * This is for embedded font or creating a list of used fonts.
- * @return a read-only Map with font key/FontMetrics pairs
- */
- public Map<String, Typeface> getUsedFonts() {
- return this.usedFonts;
- }
-
- /**
- * Returns the FontMetrics for a particular font
- * @param fontName internal key
- * @return font metrics
- */
- public FontMetrics getMetricsFor(String fontName) {
- Typeface metrics = fonts.get(fontName);
- usedFonts.put(fontName, metrics);
- return metrics;
- }
-
- /**
- * Returns all font triplet matching the given font name.
- * @param fontName The font name we are looking for
- * @return A list of matching font triplets
- */
- public List<FontTriplet> getTripletsFor(String fontName) {
- List<FontTriplet> foundTriplets = new ArrayList<FontTriplet>();
- for (Map.Entry<FontTriplet, String> tripletEntry : triplets.entrySet()) {
- if (fontName.equals((tripletEntry.getValue()))) {
- foundTriplets.add(tripletEntry.getKey());
- }
- }
- return foundTriplets;
- }
-
- /**
- * Returns the first triplet matching the given font name.
- * As there may be multiple triplets matching the font name
- * the result set is sorted first to guarantee consistent results.
- * @param fontName The font name we are looking for
- * @return The first triplet for the given font name
- */
- public FontTriplet getTripletFor(String fontName) {
- List<FontTriplet> foundTriplets = getTripletsFor(fontName);
- if (foundTriplets.size() > 0) {
- Collections.sort(foundTriplets);
- return foundTriplets.get(0);
- }
- return null;
- }
-
- /**
- * Returns the font style for a particular font.
- * There may be multiple font styles matching this font. Only the first
- * found is returned. Searching is done on a sorted list to guarantee consistent
- * results.
- * @param fontName internal key
- * @return font style
- */
- public String getFontStyleFor(String fontName) {
- FontTriplet triplet = getTripletFor(fontName);
- if (triplet != null) {
- return triplet.getStyle();
- } else {
- return "";
- }
- }
-
- /**
- * Returns the font weight for a particular font.
- * There may be multiple font weights matching this font. Only the first
- * found is returned. Searching is done on a sorted list to guarantee consistent
- * results.
- * @param fontName internal key
- * @return font weight
- */
- public int getFontWeightFor(String fontName) {
- FontTriplet triplet = getTripletFor(fontName);
- if (triplet != null) {
- return triplet.getWeight();
- } else {
- return 0;
- }
- }
-
- /**
- * Diagnostic method for logging all registered fonts to System.out.
- */
- public void dumpAllTripletsToSystemOut() {
- SortedSet<String> entries = new TreeSet<String>();
- for (FontTriplet triplet : this.triplets.keySet()) {
- String key = getInternalFontKey(triplet);
- FontMetrics metrics = getMetricsFor(key);
- entries.add(triplet.toString() + " -> " + key + " -> " + metrics.getFontName() + "\n");
- }
- StringBuffer stringBuffer = new StringBuffer();
- for (String str : entries) {
- stringBuffer.append(str);
- }
- System.out.println(stringBuffer.toString());
- }
-}
diff --git a/src/java/org/apache/fop/fonts/FontLoader.java b/src/java/org/apache/fop/fonts/FontLoader.java
deleted file mode 100644
index 92656ca2d..000000000
--- a/src/java/org/apache/fop/fonts/FontLoader.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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.net.URI;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.apps.io.InternalResourceResolver;
-import org.apache.fop.fonts.truetype.OFFontLoader;
-import org.apache.fop.fonts.type1.Type1FontLoader;
-
-/**
- * Base class for font loaders.
- */
-public abstract class FontLoader {
-
- /** logging instance */
- protected static final Log log = LogFactory.getLog(FontLoader.class);
-
- /** URI representing the font file */
- protected final URI fontFileURI;
- /** the resource resolver to use for font URI resolution */
- protected final InternalResourceResolver resourceResolver;
- /** the loaded font */
- protected CustomFont returnFont;
-
- /** true if the font has been loaded */
- protected boolean loaded;
- /** true if the font will be embedded, false if it will be referenced only. */
- protected boolean embedded;
- /** true if kerning information false be loaded if available. */
- protected boolean useKerning;
- /** true if advanced typographic information shall be loaded if available. */
- protected boolean useAdvanced;
-
- /**
- * Default constructor.
- * @param fontFileURI the URI to the PFB file of a Type 1 font
- * @param embedded indicates whether the font is embedded or referenced
- * @param useKerning indicates whether kerning information shall be loaded if available
- * @param useAdvanced indicates whether advanced typographic information shall be loaded if
- * available
- * @param resourceResolver the font resolver used to resolve URIs
- */
- public FontLoader(URI fontFileURI, boolean embedded, boolean useKerning,
- boolean useAdvanced, InternalResourceResolver resourceResolver) {
- this.fontFileURI = fontFileURI;
- this.embedded = embedded;
- this.useKerning = useKerning;
- this.useAdvanced = useAdvanced;
- this.resourceResolver = resourceResolver;
- }
-
- private static boolean isType1(URI fontURI) {
- return fontURI.toASCIIString().toLowerCase().endsWith(".pfb");
- }
-
- /**
- * Loads a custom font from a URI. In the case of Type 1 fonts, the PFB file must be specified.
- * @param fontFileURI the URI to the font
- * @param subFontName the sub-fontname of a font (for TrueType Collections, null otherwise)
- * @param embedded indicates whether the font is embedded or referenced
- * @param embeddingMode the embedding mode of the font
- * @param encodingMode the requested encoding mode
- * @param useKerning indicates whether kerning information should be loaded if available
- * @param useAdvanced indicates whether advanced typographic information shall be loaded if
- * available
- * @param resourceResolver the font resolver to use when resolving URIs
- * @return the newly loaded font
- * @throws IOException In case of an I/O error
- */
- public static CustomFont loadFont(FontUris fontUris, String subFontName,
- boolean embedded, EmbeddingMode embeddingMode, EncodingMode encodingMode,
- boolean useKerning, boolean useAdvanced, InternalResourceResolver resourceResolver) throws IOException {
- boolean type1 = isType1(fontUris.getEmbed());
- FontLoader loader;
- if (type1) {
- if (encodingMode == EncodingMode.CID) {
- throw new IllegalArgumentException(
- "CID encoding mode not supported for Type 1 fonts");
- }
- loader = new Type1FontLoader(fontUris, embedded, embeddingMode, useKerning,
- resourceResolver);
- } else {
- loader = new OFFontLoader(fontUris.getEmbed(), subFontName, embedded, embeddingMode,
- encodingMode, useKerning, useAdvanced, resourceResolver);
- }
- return loader.getFont();
- }
-
- /**
- * Reads/parses the font data.
- * @throws IOException In case of an I/O error
- */
- protected abstract void read() throws IOException;
-
- /**
- * Returns the custom font that was read using this instance of FontLoader.
- * @return the newly loaded font
- * @throws IOException if an I/O error occurs
- */
- public CustomFont getFont() throws IOException {
- if (!loaded) {
- read();
- }
- return this.returnFont;
- }
-}
diff --git a/src/java/org/apache/fop/fonts/FontManager.java b/src/java/org/apache/fop/fonts/FontManager.java
deleted file mode 100644
index 266220d14..000000000
--- a/src/java/org/apache/fop/fonts/FontManager.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * 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.net.URI;
-import java.util.List;
-
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.apps.io.InternalResourceResolver;
-import org.apache.fop.fonts.FontTriplet.Matcher;
-import org.apache.fop.fonts.substitute.FontSubstitutions;
-
-// TODO: Refactor fonts package so major font activities (autodetection etc)
-// are all centrally managed and delegated from this class
-
-/**
- * The manager of fonts. The class holds a reference to the font cache and information about
- * font substitution, referenced fonts and similar.
- */
-public class FontManager {
-
- /** The resource resolver */
- private InternalResourceResolver resourceResolver;
-
- private final FontDetector fontDetector;
-
- private FontCacheManager fontCacheManager;
-
- /** Font substitutions */
- private FontSubstitutions fontSubstitutions;
-
- /** Allows enabling kerning on the base 14 fonts, default is false */
- private boolean enableBase14Kerning;
-
- /** FontTriplet matcher for fonts that shall be referenced rather than embedded. */
- private FontTriplet.Matcher referencedFontsMatcher;
-
- /**
- * Main constructor
- *
- * @param resourceResolver the URI resolver
- * @param fontDetector the font detector
- * @param fontCacheManager the font cache manager
- */
- public FontManager(InternalResourceResolver resourceResolver, FontDetector fontDetector,
- FontCacheManager fontCacheManager) {
- this.resourceResolver = resourceResolver;
- this.fontDetector = fontDetector;
- this.fontCacheManager = fontCacheManager;
- }
-
- /**
- * Sets the font resource resolver
- * @param resourceResolver resource resolver
- */
- public void setResourceResolver(InternalResourceResolver resourceResolver) {
- this.resourceResolver = resourceResolver;
- }
-
- public InternalResourceResolver getResourceResolver() {
- return this.resourceResolver;
- }
-
- /** @return true if kerning on base 14 fonts is enabled */
- public boolean isBase14KerningEnabled() {
- return this.enableBase14Kerning;
- }
-
- /**
- * Controls whether kerning is activated on base 14 fonts.
- * @param value true if kerning should be activated
- */
- public void setBase14KerningEnabled(boolean value) {
- this.enableBase14Kerning = value;
- }
-
- /**
- * Sets the font substitutions
- * @param substitutions font substitutions
- */
- public void setFontSubstitutions(FontSubstitutions substitutions) {
- this.fontSubstitutions = substitutions;
- }
-
- /**
- * Returns the font substitution catalog
- * @return the font substitution catalog
- */
- protected FontSubstitutions getFontSubstitutions() {
- if (fontSubstitutions == null) {
- this.fontSubstitutions = new FontSubstitutions();
- }
- return fontSubstitutions;
- }
-
- /**
- * Sets the font cache file
- * @param cacheFileURI the URI of the font cache file
- */
- public void setCacheFile(URI cacheFileURI) {
- fontCacheManager.setCacheFile(resourceResolver.resolveFromBase(cacheFileURI));
- }
-
- /**
- * Whether or not to cache results of font triplet detection/auto-config
- */
- public void disableFontCache() {
- fontCacheManager = FontCacheManagerFactory.createDisabled();
- }
-
- /**
- * Returns the font cache instance used by this font manager.
- * @return the font cache
- */
- public FontCache getFontCache() {
- return fontCacheManager.load();
- }
-
- /**
- * Saves the FontCache as necessary
- *
- * @throws FOPException fop exception
- */
- public void saveCache() throws FOPException {
- fontCacheManager.save();
- }
-
- /**
- * Deletes the current FontCache file
- * @throws FOPException if an error was thrown while deleting the cache
- */
- public void deleteCache() throws FOPException {
- fontCacheManager.delete();
- }
-
- /**
- * Sets up the fonts on a given FontInfo object. The fonts to setup are defined by an
- * array of {@link FontCollection} objects.
- * @param fontInfo the FontInfo object to set up
- * @param fontCollections the array of font collections/sources
- */
- public void setup(FontInfo fontInfo, FontCollection[] fontCollections) {
- int startNum = 1;
-
- for (int i = 0, c = fontCollections.length; i < c; i++) {
- startNum = fontCollections[i].setup(startNum, fontInfo);
- }
- // Make any defined substitutions in the font info
- getFontSubstitutions().adjustFontInfo(fontInfo);
- }
-
- /**
- * Sets the {@link FontTriplet.Matcher} that can be used to identify the fonts that shall
- * be referenced rather than embedded.
- * @param matcher the font triplet matcher
- */
- public void setReferencedFontsMatcher(FontTriplet.Matcher matcher) {
- this.referencedFontsMatcher = matcher;
- }
-
- /**
- * Gets the {@link FontTriplet.Matcher} that can be used to identify the fonts that shall
- * be referenced rather than embedded.
- * @return the font triplet matcher (or null if none is set)
- */
- public Matcher getReferencedFontsMatcher() {
- return this.referencedFontsMatcher;
- }
-
- /**
- * Updates the referenced font list using the FontManager's referenced fonts matcher
- * ({@link #getReferencedFontsMatcher()}).
- * @param fontInfoList a font info list
- */
- public void updateReferencedFonts(List<EmbedFontInfo> fontInfoList) {
- Matcher matcher = getReferencedFontsMatcher();
- updateReferencedFonts(fontInfoList, matcher);
- }
-
- /**
- * Updates the referenced font list.
- * @param fontInfoList a font info list
- * @param matcher the font triplet matcher to use
- */
- public void updateReferencedFonts(List<EmbedFontInfo> fontInfoList, Matcher matcher) {
- if (matcher == null) {
- return; //No referenced fonts
- }
- for (EmbedFontInfo fontInfo : fontInfoList) {
- for (FontTriplet triplet : fontInfo.getFontTriplets()) {
- if (matcher.matches(triplet)) {
- fontInfo.setEmbedded(false);
- break;
- }
- }
- }
- }
-
- /**
- * Detect fonts from the operating system via FOPs autodetect mechanism.
- *
- * @param autoDetectFonts if autodetect has been enabled
- * @param fontAdder the font adding mechanism
- * @param strict whether to enforce strict validation
- * @param listener the listener for font related events
- * @param fontInfoList a list of font info objects
- * @throws FOPException if an exception was thrown auto-detecting fonts
- */
- public void autoDetectFonts(boolean autoDetectFonts, FontAdder fontAdder, boolean strict,
- FontEventListener listener, List<EmbedFontInfo> fontInfoList) throws FOPException {
- if (autoDetectFonts) {
- fontDetector.detect(this, fontAdder, strict, listener, fontInfoList);
- }
- }
-}
diff --git a/src/java/org/apache/fop/fonts/FontManagerConfigurator.java b/src/java/org/apache/fop/fonts/FontManagerConfigurator.java
deleted file mode 100644
index 72c1684b6..000000000
--- a/src/java/org/apache/fop/fonts/FontManagerConfigurator.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * 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.net.URI;
-import java.net.URISyntaxException;
-import java.util.List;
-import java.util.regex.Pattern;
-
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.xmlgraphics.io.ResourceResolver;
-
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.apps.io.InternalResourceResolver;
-import org.apache.fop.apps.io.ResourceResolverFactory;
-import org.apache.fop.fonts.substitute.FontSubstitutions;
-import org.apache.fop.fonts.substitute.FontSubstitutionsConfigurator;
-import org.apache.fop.util.LogUtil;
-
-/**
- * Configurator of the FontManager
- */
-public class FontManagerConfigurator {
-
- /** logger instance */
- private static Log log = LogFactory.getLog(FontManagerConfigurator.class);
-
- private final Configuration cfg;
-
- private final URI baseURI;
-
- private final URI fallbackURI;
-
- private final ResourceResolver resourceResolver;
-
- /**
- * Main constructor
- * @param cfg the font manager configuration object
- * @param baseURI the URI against which to resolve relative URIs
- * @param fallbackURI the URI to use as a fallback if font-base is unspecified
- * @param resourceResolver the resource resolver
- */
- public FontManagerConfigurator(Configuration cfg, URI baseURI, URI fallbackURI,
- ResourceResolver resourceResolver) {
- this.cfg = cfg;
- this.baseURI = baseURI;
- this.fallbackURI = fallbackURI;
- this.resourceResolver = resourceResolver;
- }
-
- /**
- * Initializes font settings from the user configuration
- * @param fontManager a font manager
- * @param strict true if strict checking of the configuration is enabled
- * @throws FOPException if an exception occurs while processing the configuration
- */
- public void configure(FontManager fontManager, boolean strict) throws FOPException {
- if (cfg.getChild("font-base", false) != null) {
- try {
- URI fontBase = InternalResourceResolver.getBaseURI(cfg.getChild("font-base")
- .getValue(null));
- fontManager.setResourceResolver(ResourceResolverFactory.createInternalResourceResolver(
- baseURI.resolve(fontBase), resourceResolver));
- } catch (URISyntaxException use) {
- LogUtil.handleException(log, use, true);
- }
- } else {
- fontManager.setResourceResolver(ResourceResolverFactory.createInternalResourceResolver(
- fallbackURI, resourceResolver));
- }
- // caching (fonts)
- if (cfg.getChild("use-cache", false) != null) {
- try {
- if (!cfg.getChild("use-cache").getValueAsBoolean()) {
- fontManager.disableFontCache();
- } else {
- if (cfg.getChild("cache-file", false) != null) {
-
- fontManager.setCacheFile(URI.create(cfg.getChild("cache-file").getValue()));
- }
- }
- } catch (ConfigurationException mfue) {
- LogUtil.handleException(log, mfue, true);
- }
- }
- // [GA] permit configuration control over base14 kerning; without this,
- // there is no way for a user to enable base14 kerning other than by
- // programmatic API;
- if (cfg.getChild("base14-kerning", false) != null) {
- try {
- fontManager
- .setBase14KerningEnabled(cfg.getChild("base14-kerning").getValueAsBoolean());
- } catch (ConfigurationException e) {
- LogUtil.handleException(log, e, true);
- }
- }
-
- // global font configuration
- Configuration fontsCfg = cfg.getChild("fonts", false);
- if (fontsCfg != null) {
- // font substitution
- Configuration substitutionsCfg = fontsCfg.getChild("substitutions", false);
- if (substitutionsCfg != null) {
- FontSubstitutions substitutions = new FontSubstitutions();
- new FontSubstitutionsConfigurator(substitutionsCfg).configure(substitutions);
- fontManager.setFontSubstitutions(substitutions);
- }
- // referenced fonts (fonts which are not to be embedded)
- Configuration referencedFontsCfg = fontsCfg.getChild("referenced-fonts", false);
- if (referencedFontsCfg != null) {
- FontTriplet.Matcher matcher = createFontsMatcher(
- referencedFontsCfg, strict);
- fontManager.setReferencedFontsMatcher(matcher);
- }
- }
- }
-
- /**
- * Creates a font triplet matcher from a configuration object.
- * @param cfg the configuration object
- * @param strict true for strict configuraton error handling
- * @return the font matcher
- * @throws FOPException if an error occurs while building the matcher
- */
- public static FontTriplet.Matcher createFontsMatcher(
- Configuration cfg, boolean strict) throws FOPException {
- List<FontTriplet.Matcher> matcherList = new java.util.ArrayList<FontTriplet.Matcher>();
- Configuration[] matches = cfg.getChildren("match");
- for (int i = 0; i < matches.length; i++) {
- try {
- matcherList.add(new FontFamilyRegExFontTripletMatcher(
- matches[i].getAttribute("font-family")));
- } catch (ConfigurationException ce) {
- LogUtil.handleException(log, ce, strict);
- continue;
- }
- }
- FontTriplet.Matcher orMatcher = new OrFontTripletMatcher(
- matcherList.toArray(new FontTriplet.Matcher[matcherList.size()]));
- return orMatcher;
- }
-
- /**
- * Creates a font triplet matcher from a configuration object.
- * @param fontFamilies the list of font families
- * @param strict true for strict configuraton error handling
- * @return the font matcher
- * @throws FOPException if an error occurs while building the matcher
- */
- public static FontTriplet.Matcher createFontsMatcher(
- List<String> fontFamilies, boolean strict) throws FOPException {
- List<FontTriplet.Matcher> matcherList = new java.util.ArrayList<FontTriplet.Matcher>();
- for (String fontFamily : fontFamilies) {
- matcherList.add(new FontFamilyRegExFontTripletMatcher(fontFamily));
- }
- FontTriplet.Matcher orMatcher = new OrFontTripletMatcher(
- matcherList.toArray(new FontTriplet.Matcher[matcherList.size()]));
- return orMatcher;
- }
-
- private static class OrFontTripletMatcher implements FontTriplet.Matcher {
-
- private final FontTriplet.Matcher[] matchers;
-
- public OrFontTripletMatcher(FontTriplet.Matcher[] matchers) {
- this.matchers = matchers;
- }
-
- /** {@inheritDoc} */
- public boolean matches(FontTriplet triplet) {
- for (int i = 0, c = matchers.length; i < c; i++) {
- if (matchers[i].matches(triplet)) {
- return true;
- }
- }
- return false;
- }
-
- }
-
- private static class FontFamilyRegExFontTripletMatcher implements FontTriplet.Matcher {
-
- private final Pattern regex;
-
- public FontFamilyRegExFontTripletMatcher(String regex) {
- this.regex = Pattern.compile(regex);
- }
-
- /** {@inheritDoc} */
- public boolean matches(FontTriplet triplet) {
- return regex.matcher(triplet.getName()).matches();
- }
-
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/FontMetrics.java b/src/java/org/apache/fop/fonts/FontMetrics.java
deleted file mode 100644
index ce00e34b9..000000000
--- a/src/java/org/apache/fop/fonts/FontMetrics.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * 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.awt.Rectangle;
-import java.net.URI;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Main interface for access to font metrics.
- */
-public interface FontMetrics {
-
- /**
- * Returns the URI of the font file from which these metrics were loaded.
- * @return the font file's URI
- */
- URI getFontURI();
-
- /**
- * Returns the "PostScript" font name (Example: "Helvetica-BoldOblique").
- * @return the font name
- */
- String getFontName();
-
- /**
- * Returns the font's full name (Example: "Helvetica Bold Oblique").
- * @return the font's full name
- */
- String getFullName();
-
- /**
- * Returns the font's family names as a Set of Strings (Example: "Helvetica").
- * @return the font's family names (a Set of Strings)
- */
- Set<String> getFamilyNames();
-
- /**
- * Returns the font name for font embedding (may include a prefix, Example: "1E28bcArialMT").
- * @return the name for font embedding
- */
- String getEmbedFontName();
-
- /**
- * Returns the type of the font.
- * @return the font type
- */
- FontType getFontType();
-
-
- /**
- * Returns the maximum ascent of the font described by this
- * FontMetrics object. Note: This is not the same as getAscender().
- * @param size font size
- * @return ascent in milliponts
- */
- int getMaxAscent(int size);
-
- /**
- * Returns the ascent of the font described by this
- * FontMetrics object. It returns the nominal ascent within the em box.
- * @param size font size
- * @return ascent in milliponts
- */
- int getAscender(int size);
-
- /**
- * Returns the size of a capital letter measured from the font's baseline.
- * @param size font size
- * @return height of capital characters
- */
- int getCapHeight(int size);
-
-
- /**
- * Returns the descent of the font described by this
- * FontMetrics object.
- * @param size font size
- * @return descent in milliponts
- */
- int getDescender(int size);
-
-
- /**
- * Determines the typical font height of this
- * FontMetrics object
- * @param size font size
- * @return font height in millipoints
- */
- int getXHeight(int size);
-
- /**
- * Return the width (in 1/1000ths of point size) of the character at
- * code point i.
- * @param i code point index
- * @param size font size
- * @return the width of the character
- */
- int getWidth(int i, int size);
-
- /**
- * Return the array of widths.
- * <p>
- * This is used to get an array for inserting in an output format.
- * It should not be used for lookup.
- * @return an array of widths
- */
- int[] getWidths();
-
- /**
- * Returns the bounding box of the glyph at the given index, for the given font size.
- *
- * @param glyphIndex glyph index
- * @param size font size
- * @return the scaled bounding box scaled in 1/1000ths of the given size
- */
- Rectangle getBoundingBox(int glyphIndex, int size);
-
- /**
- * Indicates if the font has kerning information.
- * @return true if kerning is available.
- */
- boolean hasKerningInfo();
-
- /**
- * Returns the kerning map for the font.
- * @return the kerning map
- */
- Map<Integer, Map<Integer, Integer>> getKerningInfo();
-
- /**
- * Returns the distance from the baseline to the center of the underline (negative
- * value indicates below baseline).
- *
- * @param size font size
- * @return the position in 1/1000ths of the font size
- */
- int getUnderlinePosition(int size);
-
- /**
- * Returns the thickness of the underline.
- *
- * @param size font size
- * @return the thickness in 1/1000ths of the font size
- */
- int getUnderlineThickness(int size);
-
- /**
- * Returns the distance from the baseline to the center of the strikeout line
- * (negative value indicates below baseline).
- *
- * @param size font size
- * @return the position in 1/1000ths of the font size
- */
- int getStrikeoutPosition(int size);
-
- /**
- * Returns the thickness of the strikeout line.
- *
- * @param size font size
- * @return the thickness in 1/1000ths of the font size
- */
- int getStrikeoutThickness(int size);
-
- /**
- * Determine if metrics supports specific feature in specified font table.
- *
- * @param tableType type of table (GSUB, GPOS, ...), see GlyphTable.GLYPH_TABLE_TYPE_*
- * @param script to qualify feature lookup
- * @param language to qualify feature lookup
- * @param feature to test
- * @return true if feature supported (and has at least one lookup)
- */
- boolean hasFeature(int tableType, String script, String language, String feature);
-
- /**
- * Determines whether the font is a multibyte font.
- * @return True if it is multibyte
- */
- boolean isMultiByte();
-
-}
diff --git a/src/java/org/apache/fop/fonts/FontReader.java b/src/java/org/apache/fop/fonts/FontReader.java
deleted file mode 100644
index 9f5d54396..000000000
--- a/src/java/org/apache/fop/fonts/FontReader.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * 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;
-
-//Java
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.xml.parsers.SAXParserFactory;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.DefaultHandler;
-
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.apps.io.InternalResourceResolver;
-import org.apache.fop.fonts.apps.TTFReader;
-
-/**
- * Class for reading a metric.xml file and creating a font object.
- * Typical usage:
- * <pre>
- * FontReader reader = new FontReader(<path til metrics.xml>);
- * reader.setFontEmbedPath(<path to a .ttf or .pfb file or null to diable embedding>);
- * reader.useKerning(true);
- * Font f = reader.getFont();
- * </pre>
- */
-public class FontReader extends DefaultHandler {
-
- private boolean isCID;
- private CustomFont returnFont;
- private MultiByteFont multiFont;
- private SingleByteFont singleFont;
- private final InternalResourceResolver resourceResolver;
- private StringBuffer text = new StringBuffer();
-
- private List<Integer> cidWidths;
- //private int cidWidthIndex;
-
- private Map<Integer, Integer> currentKerning;
-
- private List<CMapSegment> bfranges;
-
- /**
- * Construct a FontReader object from a path to a metric.xml file
- * and read metric data
- * @param source Source of the font metric file
- * @throws FOPException if loading the font fails
- */
- public FontReader(InputSource source, InternalResourceResolver resourceResolver) throws FOPException {
- this.resourceResolver = resourceResolver;
- createFont(source);
- }
-
- private void createFont(InputSource source) throws FOPException {
- XMLReader parser = null;
-
- try {
- final SAXParserFactory factory = javax.xml.parsers.SAXParserFactory.newInstance();
- factory.setNamespaceAware(true);
- parser = factory.newSAXParser().getXMLReader();
- } catch (Exception e) {
- throw new FOPException(e);
- }
- if (parser == null) {
- throw new FOPException("Unable to create SAX parser");
- }
-
- try {
- parser.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
- } catch (SAXException e) {
- throw new FOPException("You need a SAX parser which supports SAX version 2", e);
- }
-
- parser.setContentHandler(this);
-
- try {
- parser.parse(source);
- } catch (SAXException e) {
- throw new FOPException(e);
- } catch (IOException e) {
- throw new FOPException(e);
- }
-
- }
-
- /**
- * Sets the path to embed a font. A null value disables font embedding.
- * @param path URI for the embeddable file
- */
- public void setFontEmbedURI(URI path) {
- returnFont.setEmbedURI(path);
- }
-
- /**
- * Enable/disable use of kerning for the font
- * @param enabled true to enable kerning, false to disable
- */
- public void setKerningEnabled(boolean enabled) {
- returnFont.setKerningEnabled(enabled);
- }
-
- /**
- * Enable/disable use of advanced typographic features for the font
- * @param enabled true to enable, false to disable
- */
- public void setAdvancedEnabled(boolean enabled) {
- returnFont.setAdvancedEnabled(enabled);
- }
-
- /**
- * Get the generated font object
- * @return the font
- */
- public Typeface getFont() {
- return returnFont;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void startDocument() {
- }
-
- /**
- * {@inheritDoc}
- */
- public void startElement(String uri, String localName, String qName, Attributes attributes)
- throws SAXException {
- if (localName.equals("font-metrics")) {
- if ("TYPE0".equals(attributes.getValue("type"))) {
- multiFont = new MultiByteFont(resourceResolver, EmbeddingMode.AUTO);
- returnFont = multiFont;
- isCID = true;
- TTFReader.checkMetricsVersion(attributes);
- } else if ("TRUETYPE".equals(attributes.getValue("type"))) {
- singleFont = new SingleByteFont(resourceResolver, EmbeddingMode.AUTO);
- singleFont.setFontType(FontType.TRUETYPE);
- returnFont = singleFont;
- isCID = false;
- TTFReader.checkMetricsVersion(attributes);
- } else {
- singleFont = new SingleByteFont(resourceResolver, EmbeddingMode.AUTO);
- singleFont.setFontType(FontType.TYPE1);
- returnFont = singleFont;
- isCID = false;
- }
- } else if ("embed".equals(localName)) {
- try {
- returnFont.setEmbedURI(InternalResourceResolver.cleanURI(attributes.getValue("file")));
- } catch (URISyntaxException e) {
- throw new SAXException("URI syntax error in metrics file: " + e.getMessage(), e);
- }
- returnFont.setEmbedResourceName(attributes.getValue("class"));
- } else if ("cid-widths".equals(localName)) {
- // This is unused
- // cidWidthIndex = getInt(attributes.getValue("start-index"));
- cidWidths = new ArrayList<Integer>();
- } else if ("kerning".equals(localName)) {
- currentKerning = new HashMap<Integer, Integer>();
- returnFont.putKerningEntry(getInt(attributes.getValue("kpx1")),
- currentKerning);
- } else if ("bfranges".equals(localName)) {
- bfranges = new ArrayList<CMapSegment>();
- } else if ("bf".equals(localName)) {
- CMapSegment entry = new CMapSegment(getInt(attributes.getValue("us")),
- getInt(attributes.getValue("ue")),
- getInt(attributes.getValue("gi")));
- bfranges.add(entry);
- } else if ("wx".equals(localName)) {
- cidWidths.add(getInt(attributes.getValue("w")));
- // } else if ("widths".equals(localName)) {
- // singleFont.width = new int[256];
- } else if ("char".equals(localName)) {
- try {
- singleFont.setWidth(getInt(attributes.getValue("idx")),
- getInt(attributes.getValue("wdt")));
- } catch (NumberFormatException ne) {
- throw new SAXException("Malformed width in metric file: " + ne.getMessage(), ne);
- }
- } else if ("pair".equals(localName)) {
- currentKerning.put(getInt(attributes.getValue("kpx2")),
- getInt(attributes.getValue("kern")));
- }
-
- }
-
- private int getInt(String str) throws SAXException {
- int ret = 0;
- try {
- ret = Integer.parseInt(str);
- } catch (Exception e) {
- throw new SAXException("Error while parsing integer value: " + str, e);
- }
- return ret;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void endElement(String uri, String localName, String qName) throws SAXException {
- String content = text.toString().trim();
- if ("font-name".equals(localName)) {
- returnFont.setFontName(content);
- } else if ("full-name".equals(localName)) {
- returnFont.setFullName(content);
- } else if ("family-name".equals(localName)) {
- Set<String> s = new HashSet<String>();
- s.add(content);
- returnFont.setFamilyNames(s);
- } else if ("ttc-name".equals(localName) && isCID) {
- multiFont.setTTCName(content);
- } else if ("encoding".equals(localName)) {
- if (singleFont != null && singleFont.getFontType() == FontType.TYPE1) {
- singleFont.setEncoding(content);
- }
- } else if ("cap-height".equals(localName)) {
- returnFont.setCapHeight(getInt(content));
- } else if ("x-height".equals(localName)) {
- returnFont.setXHeight(getInt(content));
- } else if ("ascender".equals(localName)) {
- returnFont.setAscender(getInt(content));
- } else if ("descender".equals(localName)) {
- returnFont.setDescender(getInt(content));
- } else if ("left".equals(localName)) {
- int[] bbox = returnFont.getFontBBox();
- bbox[0] = getInt(content);
- returnFont.setFontBBox(bbox);
- } else if ("bottom".equals(localName)) {
- int[] bbox = returnFont.getFontBBox();
- bbox[1] = getInt(content);
- returnFont.setFontBBox(bbox);
- } else if ("right".equals(localName)) {
- int[] bbox = returnFont.getFontBBox();
- bbox[2] = getInt(content);
- returnFont.setFontBBox(bbox);
- } else if ("top".equals(localName)) {
- int[] bbox = returnFont.getFontBBox();
- bbox[3] = getInt(content);
- returnFont.setFontBBox(bbox);
- } else if ("first-char".equals(localName)) {
- returnFont.setFirstChar(getInt(content));
- } else if ("last-char".equals(localName)) {
- returnFont.setLastChar(getInt(content));
- } else if ("flags".equals(localName)) {
- returnFont.setFlags(getInt(content));
- } else if ("stemv".equals(localName)) {
- returnFont.setStemV(getInt(content));
- } else if ("italic-angle".equals(localName)) {
- returnFont.setItalicAngle(getInt(content));
- } else if ("missing-width".equals(localName)) {
- returnFont.setMissingWidth(getInt(content));
- } else if ("cid-type".equals(localName)) {
- multiFont.setCIDType(CIDFontType.byName(content));
- } else if ("default-width".equals(localName)) {
- multiFont.setDefaultWidth(getInt(content));
- } else if ("cid-widths".equals(localName)) {
- int[] wds = new int[cidWidths.size()];
- int j = 0;
- for (int count = 0; count < cidWidths.size(); count++) {
- wds[j++] = cidWidths.get(count).intValue();
- }
-
- //multiFont.addCIDWidthEntry(cidWidthIndex, wds);
- multiFont.setWidthArray(wds);
-
- } else if ("bfranges".equals(localName)) {
- multiFont.setCMap(bfranges.toArray(new CMapSegment[bfranges.size()]));
- }
- text.setLength(0); //Reset text buffer (see characters())
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void characters(char[] ch, int start, int length) {
- text.append(ch, start, length);
- }
-}
diff --git a/src/java/org/apache/fop/fonts/FontSelector.java b/src/java/org/apache/fop/fonts/FontSelector.java
deleted file mode 100644
index a80a0e368..000000000
--- a/src/java/org/apache/fop/fonts/FontSelector.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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 org.apache.fop.datatypes.PercentBaseContext;
-import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.FOText;
-import org.apache.fop.fo.flow.Character;
-import org.apache.fop.fo.properties.CommonFont;
-
-/**
- * Helper class for automatic font selection.
- * <p>
- * TODO: Check if this could be merged with another font class, such as
- * {@link FontManager}.
- */
-public final class FontSelector {
- private FontSelector() {
- // Static since this is an utility class.
- }
-
- private static Font selectFontForCharacter(char c, FONode fonode,
- CommonFont commonFont, PercentBaseContext context) {
- FontInfo fi = fonode.getFOEventHandler().getFontInfo();
- FontTriplet[] fontkeys = commonFont.getFontState(fi);
- for (int i = 0; i < fontkeys.length; i++) {
- Font font = fi.getFontInstance(fontkeys[i], commonFont.fontSize
- .getValue(context));
- if (font.hasChar(c)) {
- return font;
- }
- }
- return fi.getFontInstance(fontkeys[0], commonFont.fontSize
- .getValue(context));
-
- }
-
- /**
- * Selects a font which is able to display the given character.
- *
- * @param fobj
- * a Character object containing the character and its
- * attributes.
- * @param context
- * the Percent-based context needed for creating the actual font.
- * @return a Font object.
- */
- public static Font selectFontForCharacter(Character fobj,
- PercentBaseContext context) {
- return FontSelector.selectFontForCharacter(fobj.getCharacter(), fobj,
- fobj.getCommonFont(), context);
- }
-
- /**
- * Selects a font which is able to display the given character.
- *
- * @param c
- * character to find.
- * @param text
- * the text object which contains the character
- * @param context
- * the Percent-based context needed for creating the actual font.
- * @return a Font object.
- */
- public static Font selectFontForCharacterInText(char c, FOText text,
- PercentBaseContext context) {
- return FontSelector.selectFontForCharacter(c, text, text
- .getCommonFont(), context);
- }
-
- /**
- * Selects a font which is able to display the most of the given characters.
- *
- * @param charSeq
- * Text to go through
- * @param firstIndex
- * first index within text.
- * @param breakIndex
- * last index +1 within text.
- * @param text
- * the text object which contains the character
- * @param context
- * the Percent-based context needed for creating the actual font.
- * @return a Font object.
- */
- public static Font selectFontForCharactersInText(CharSequence charSeq,
- int firstIndex, int breakIndex, FOText text,
- PercentBaseContext context) {
-
- final FontInfo fi = text.getFOEventHandler().getFontInfo();
- final CommonFont commonFont = text.getCommonFont();
- final FontTriplet[] fontkeys = commonFont.getFontState(fi);
- final int numFonts = fontkeys.length;
- final Font[] fonts = new Font[numFonts];
- final int[] fontCount = new int[numFonts];
-
- for (int fontnum = 0; fontnum < numFonts; fontnum++) {
- final Font font = fi.getFontInstance(fontkeys[fontnum],
- commonFont.fontSize.getValue(context));
- fonts[fontnum] = font;
- for (int pos = firstIndex; pos < breakIndex; pos++) {
- if (font.hasChar(charSeq.charAt(pos))) {
- fontCount[fontnum]++;
- }
- }
-
- // quick fall through if all characters can be displayed
- if (fontCount[fontnum] == (breakIndex - firstIndex)) {
- return font;
- }
- }
-
- Font font = fonts[0];
- int max = fontCount[0];
-
- for (int fontnum = 1; fontnum < numFonts; fontnum++) {
- final int curCount = fontCount[fontnum];
- if (curCount > max) {
- font = fonts[fontnum];
- max = curCount;
- }
- }
- return font;
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/FontSetup.java b/src/java/org/apache/fop/fonts/FontSetup.java
deleted file mode 100644
index f9bae3332..000000000
--- a/src/java/org/apache/fop/fonts/FontSetup.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * 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;
-
-// FOP (base 14 fonts)
-import java.util.List;
-
-import org.apache.fop.apps.io.InternalResourceResolver;
-import org.apache.fop.fonts.base14.Courier;
-import org.apache.fop.fonts.base14.CourierBold;
-import org.apache.fop.fonts.base14.CourierBoldOblique;
-import org.apache.fop.fonts.base14.CourierOblique;
-import org.apache.fop.fonts.base14.Helvetica;
-import org.apache.fop.fonts.base14.HelveticaBold;
-import org.apache.fop.fonts.base14.HelveticaBoldOblique;
-import org.apache.fop.fonts.base14.HelveticaOblique;
-import org.apache.fop.fonts.base14.Symbol;
-import org.apache.fop.fonts.base14.TimesBold;
-import org.apache.fop.fonts.base14.TimesBoldItalic;
-import org.apache.fop.fonts.base14.TimesItalic;
-import org.apache.fop.fonts.base14.TimesRoman;
-import org.apache.fop.fonts.base14.ZapfDingbats;
-
-//TODO remove small dependency on and refactor this
-
-/**
- * Default fonts for FOP application; currently this uses PDF's fonts
- * by default.
- *
- * Assigns the font (with metrics) to internal names like "F1" and
- * assigns family-style-weight triplets to the fonts
- */
-public final class FontSetup {
-
- private FontSetup() {
- }
-
- /**
- * Sets up a font info
- * @param fontInfo font info
- * @param base14Kerning true if base14 kerning applies
- */
- public static void setup(FontInfo fontInfo, boolean base14Kerning) {
- setup(fontInfo, null, null, base14Kerning);
- }
-
- /**
- * Sets up the font info object.
- *
- * Adds metrics for basic fonts and useful family-style-weight
- * triplets for lookup.
- *
- * @param fontInfo the font info object to set up
- * @param embedFontInfoList a list of EmbedFontInfo objects
- * @param resourceResolver the font resolver
- * @param base14Kerning true if base14 kerning applies
- */
- public static void setup(FontInfo fontInfo, List embedFontInfoList,
- InternalResourceResolver resourceResolver, boolean base14Kerning) {
- fontInfo.addMetrics("F1", new Helvetica(base14Kerning));
- fontInfo.addMetrics("F2", new HelveticaOblique(base14Kerning));
- fontInfo.addMetrics("F3", new HelveticaBold(base14Kerning));
- fontInfo.addMetrics("F4", new HelveticaBoldOblique(base14Kerning));
- fontInfo.addMetrics("F5", new TimesRoman(base14Kerning));
- fontInfo.addMetrics("F6", new TimesItalic(base14Kerning));
- fontInfo.addMetrics("F7", new TimesBold(base14Kerning));
- fontInfo.addMetrics("F8", new TimesBoldItalic(base14Kerning));
- fontInfo.addMetrics("F9", new Courier(base14Kerning));
- fontInfo.addMetrics("F10", new CourierOblique(base14Kerning));
- fontInfo.addMetrics("F11", new CourierBold(base14Kerning));
- fontInfo.addMetrics("F12", new CourierBoldOblique(base14Kerning));
- fontInfo.addMetrics("F13", new Symbol());
- fontInfo.addMetrics("F14", new ZapfDingbats());
-
- // Custom type 1 fonts step 1/2
- // fontInfo.addMetrics("F15", new OMEP());
- // fontInfo.addMetrics("F16", new GaramondLightCondensed());
- // fontInfo.addMetrics("F17", new BauerBodoniBoldItalic());
-
- /* any is treated as serif */
- fontInfo.addFontProperties("F5", "any", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "any", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "any", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F7", "any", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "any", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "any", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
-
- fontInfo.addFontProperties("F1", "sans-serif", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F2", "sans-serif", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F2", "sans-serif", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F3", "sans-serif", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F4", "sans-serif", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F4", "sans-serif", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F1", "SansSerif", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F2", "SansSerif", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F2", "SansSerif", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F3", "SansSerif", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F4", "SansSerif", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F4", "SansSerif", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F5", "serif", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "serif", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "serif", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F7", "serif", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "serif", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "serif", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F9", "monospace", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F10", "monospace", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F10", "monospace", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F11", "monospace", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F12", "monospace", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F12", "monospace", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F9", "Monospaced", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F10", "Monospaced", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F10", "Monospaced", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F11", "Monospaced", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F12", "Monospaced", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F12", "Monospaced", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
-
- fontInfo.addFontProperties("F1", "Helvetica", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F2", "Helvetica", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F2", "Helvetica", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F3", "Helvetica", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F4", "Helvetica", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F4", "Helvetica", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F5", "Times", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "Times", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "Times", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F7", "Times", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "Times", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "Times", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F9", "Courier", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F10", "Courier", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F10", "Courier", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F11", "Courier", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F12", "Courier", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F12", "Courier", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F13", "Symbol", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F14", "ZapfDingbats", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
-
- // Custom type 1 fonts step 2/2
- // fontInfo.addFontProperties("F15", "OMEP", "normal", FontInfo.NORMAL);
- // fontInfo.addFontProperties("F16", "Garamond-LightCondensed", "normal", FontInfo.NORMAL);
- // fontInfo.addFontProperties("F17", "BauerBodoni", "italic", FontInfo.BOLD);
-
- /* for compatibility with PassiveTex */
- fontInfo.addFontProperties("F5", "Times-Roman", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "Times-Roman", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "Times-Roman", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F7", "Times-Roman", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "Times-Roman", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "Times-Roman", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F5", "Times Roman", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "Times Roman", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "Times Roman", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F7", "Times Roman", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "Times Roman", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "Times Roman", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F9", "Computer-Modern-Typewriter",
- Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
-
- // All base 14 configured now, so any custom embedded fonts start from 15
- final int startNum = 15;
-
- /* Add configured fonts */
- addConfiguredFonts(fontInfo, embedFontInfoList, startNum, resourceResolver, base14Kerning);
- }
-
- /**
- * Add fonts from configuration file starting with internal name F<num>.
- * @param fontInfo the font info to set up
- * @param embedFontInfoList a list of EmbedFontInfo objects
- * @param num starting index for internal font numbering
- * @param resourceResolver the font resolver
- */
- private static void addConfiguredFonts(FontInfo fontInfo,
- List<EmbedFontInfo> embedFontInfoList, int num,
- InternalResourceResolver resourceResolver,
- boolean base14Kerning) {
- if (embedFontInfoList == null) {
- return; //No fonts to process
- }
- assert resourceResolver != null;
-
- String internalName = null;
-
- for (EmbedFontInfo embedFontInfo : embedFontInfoList) {
- internalName = "F" + num;
- num++;
-
- LazyFont font = new LazyFont(embedFontInfo, resourceResolver, false);
- fontInfo.addMetrics(internalName, font);
-
- List<FontTriplet> triplets = embedFontInfo.getFontTriplets();
- for (int tripletIndex = 0; tripletIndex < triplets.size(); tripletIndex++) {
- FontTriplet triplet = triplets.get(tripletIndex);
- fontInfo.addFontProperties(internalName, triplet);
- }
- }
- }
-}
diff --git a/src/java/org/apache/fop/fonts/FontTriplet.java b/src/java/org/apache/fop/fonts/FontTriplet.java
deleted file mode 100644
index a9728428a..000000000
--- a/src/java/org/apache/fop/fonts/FontTriplet.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * 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.ObjectInputStream;
-import java.io.Serializable;
-
-
-/**
- * FontTriplet contains information on name, style and weight of one font
- */
-public class FontTriplet implements Comparable<FontTriplet>, Serializable {
-
- public static final FontTriplet DEFAULT_FONT_TRIPLET
- = new FontTriplet("any", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
-
- /** serial version UID */
- private static final long serialVersionUID = 1168991106658033508L;
-
- private String name;
- private String style;
- private int weight;
- private int priority; // priority of this triplet/font mapping
-
- //This is only a cache
- private transient String key;
-
- public FontTriplet() {
- this(null, null, 0);
- }
-
- /**
- * Creates a new font triplet.
- * @param name font name
- * @param style font style (normal, italic etc.)
- * @param weight font weight (100, 200, 300...800, 900)
- */
- public FontTriplet(String name, String style, int weight) {
- this(name, style, weight, Font.PRIORITY_DEFAULT);
- }
-
- /**
- * Creates a new font triplet.
- * @param name font name
- * @param style font style (normal, italic etc.)
- * @param weight font weight (100, 200, 300...800, 900)
- * @param priority priority of this triplet/font mapping
- */
- public FontTriplet(String name, String style, int weight, int priority) {
- this.name = name;
- this.style = style;
- this.weight = weight;
- this.priority = priority;
- }
-
- private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
- ois.defaultReadObject();
- }
-
- /** @return the font name */
- public String getName() {
- return name;
- }
-
- /** @return the font style */
- public String getStyle() {
- return style;
- }
-
- /** @return the font weight */
- public int getWeight() {
- return weight;
- }
-
- /** @return the priority of this triplet/font mapping */
- public int getPriority() {
- return priority;
- }
-
- private String getKey() {
- if (this.key == null) {
- //This caches the combined key
- this.key = getName() + "," + getStyle() + "," + getWeight();
- }
- return this.key;
- }
-
- /** {@inheritDoc} */
- public int compareTo(FontTriplet o) {
- return getKey().compareTo(o.getKey());
- }
-
- /** {@inheritDoc} */
- public int hashCode() {
- return toString().hashCode();
- }
-
- /** {@inheritDoc} */
- public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- } else if (obj == this) {
- return true;
- } else {
- if (obj instanceof FontTriplet) {
- FontTriplet other = (FontTriplet)obj;
- return (getName().equals(other.getName())
- && getStyle().equals(other.getStyle())
- && (getWeight() == other.getWeight()));
- }
- }
- return false;
- }
-
- /** {@inheritDoc} */
- public String toString() {
- return getKey();
- }
-
-
- /**
- * Matcher interface for {@link FontTriplet}.
- */
- public interface Matcher {
-
- /**
- * Indicates whether the given {@link FontTriplet} matches a particular criterium.
- * @param triplet the font triplet
- * @return true if the font triplet is a match
- */
- boolean matches(FontTriplet triplet);
- }
-}
-
diff --git a/src/java/org/apache/fop/fonts/FontType.java b/src/java/org/apache/fop/fonts/FontType.java
deleted file mode 100644
index fc820c8b9..000000000
--- a/src/java/org/apache/fop/fonts/FontType.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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;
-
-/**
- * This class enumerates all supported font types.
- */
-public class FontType {
-
- /**
- * Collective identifier for "other" font types
- */
- public static final FontType OTHER = new FontType("Other", 0);
- /**
- * Adobe Type 0 fonts (composite font)
- */
- public static final FontType TYPE0 = new FontType("Type0", 1);
- /**
- * Adobe Type 1 fonts
- */
- public static final FontType TYPE1 = new FontType("Type1", 2);
- /**
- * Adobe Multiple Master Type 1 fonts
- */
- public static final FontType MMTYPE1 = new FontType("MMType1", 3);
- /**
- * Adobe Type 3 fonts ("user-defined" fonts)
- */
- public static final FontType TYPE3 = new FontType("Type3", 4);
- /**
- * TrueType fonts
- */
- public static final FontType TRUETYPE = new FontType("TrueType", 5);
-
- public static final FontType TYPE1C = new FontType("Type1C", 6);
-
- public static final FontType CIDTYPE0 = new FontType("CIDFontType0", 7);
-
- private final String name;
- private final int value;
-
-
- /**
- * Construct a font type.
- * @param name a font type name
- * @param value a font type value
- * @see org.apache.avalon.framework.Enum#Enum(String)
- */
- protected FontType(String name, int value) {
- this.name = name;
- this.value = value;
- }
-
-
- /**
- * Returns the FontType by name.
- * @param name Name of the font type to look up
- * @return the font type
- */
- public static FontType byName(String name) {
- if (name.equalsIgnoreCase(FontType.OTHER.getName())) {
- return FontType.OTHER;
- } else if (name.equalsIgnoreCase(FontType.TYPE0.getName())) {
- return FontType.TYPE0;
- } else if (name.equalsIgnoreCase(FontType.TYPE1.getName())) {
- return FontType.TYPE1;
- } else if (name.equalsIgnoreCase(FontType.MMTYPE1.getName())) {
- return FontType.MMTYPE1;
- } else if (name.equalsIgnoreCase(FontType.TYPE3.getName())) {
- return FontType.TYPE3;
- } else if (name.equalsIgnoreCase(FontType.TRUETYPE.getName())) {
- return FontType.TRUETYPE;
- } else {
- throw new IllegalArgumentException("Invalid font type: " + name);
- }
- }
-
-
- /**
- * Returns the FontType by value.
- * @param value Value of the font type to look up
- * @return the font type
- */
- public static FontType byValue(int value) {
- if (value == FontType.OTHER.getValue()) {
- return FontType.OTHER;
- } else if (value == FontType.TYPE0.getValue()) {
- return FontType.TYPE0;
- } else if (value == FontType.TYPE1.getValue()) {
- return FontType.TYPE1;
- } else if (value == FontType.MMTYPE1.getValue()) {
- return FontType.MMTYPE1;
- } else if (value == FontType.TYPE3.getValue()) {
- return FontType.TYPE3;
- } else if (value == FontType.TRUETYPE.getValue()) {
- return FontType.TRUETYPE;
- } else {
- throw new IllegalArgumentException("Invalid font type: " + value);
- }
- }
-
- /**
- * Returns the name
- *
- * @return the name
- */
- public String getName() {
- return name;
- }
-
- /**
- * Returns the value
- *
- * @return the value
- */
- public int getValue() {
- return value;
- }
-
- @Override
- public String toString() {
- return name;
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/FontUris.java b/src/java/org/apache/fop/fonts/FontUris.java
deleted file mode 100644
index fe0dfc21a..000000000
--- a/src/java/org/apache/fop/fonts/FontUris.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.Serializable;
-import java.net.URI;
-
-public class FontUris implements Serializable {
-
- private static final long serialVersionUID = 8571060588775532701L;
-
- private final URI embed;
- private final URI metrics;
- private final URI afm;
- private final URI pfm;
-
- public FontUris(URI embed, URI metrics, URI afm, URI pfm) {
- this.embed = embed;
- this.metrics = metrics;
- this.afm = afm;
- this.pfm = pfm;
- }
-
- public FontUris(URI embed, URI metrics) {
- this.embed = embed;
- this.metrics = metrics;
- this.afm = null;
- this.pfm = null;
- }
-
- public URI getEmbed() {
- return embed;
- }
-
- public URI getMetrics() {
- return metrics;
- }
-
- public URI getAfm() {
- return afm;
- }
-
- public URI getPfm() {
- return pfm;
- }
-
-}
-
diff --git a/src/java/org/apache/fop/fonts/FontUtil.java b/src/java/org/apache/fop/fonts/FontUtil.java
deleted file mode 100644
index 1966d9fca..000000000
--- a/src/java/org/apache/fop/fonts/FontUtil.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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;
-
-
-/**
- * Font utilities.
- */
-public final class FontUtil {
-
- private FontUtil() {
- }
-
- /**
- * Parses an CSS2 (SVG and XSL-FO) font weight (normal, bold, 100-900) to
- * an integer.
- * See http://www.w3.org/TR/REC-CSS2/fonts.html#propdef-font-weight
- * TODO: Implement "lighter" and "bolder".
- * @param text the font weight to parse
- * @return an integer between 100 and 900 (100, 200, 300...)
- */
- public static int parseCSS2FontWeight(String text) {
- int weight = 400;
- try {
- weight = Integer.parseInt(text);
- weight = (weight / 100) * 100;
- weight = Math.max(weight, 100);
- weight = Math.min(weight, 900);
- } catch (NumberFormatException nfe) {
- //weight is no number, so convert symbolic name to number
- if (text.equals("normal")) {
- weight = 400;
- } else if (text.equals("bold")) {
- weight = 700;
- } else {
- throw new IllegalArgumentException(
- "Illegal value for font weight: '"
- + text
- + "'. Use one of: 100, 200, 300, "
- + "400, 500, 600, 700, 800, 900, "
- + "normal (=400), bold (=700)");
- }
- }
- return weight;
- }
-
- /**
- * Removes all white space from a string (used primarily for font names)
- * @param str the string
- * @return the processed result
- */
- public static String stripWhiteSpace(String str) {
- if (str != null) {
- StringBuffer stringBuffer = new StringBuffer(str.length());
- for (int i = 0, strLen = str.length(); i < strLen; i++) {
- final char ch = str.charAt(i);
- if (ch != ' ' && ch != '\r' && ch != '\n' && ch != '\t') {
- stringBuffer.append(ch);
- }
- }
- return stringBuffer.toString();
- }
- return str;
- }
-
- /** font constituent names which identify a font as being of "italic" style */
- private static final String[] ITALIC_WORDS = {
- Font.STYLE_ITALIC, Font.STYLE_OBLIQUE, Font.STYLE_INCLINED
- };
-
- /** font constituent names which identify a font as being of "light" weight */
- private static final String[] LIGHT_WORDS = {"light"};
- /** font constituent names which identify a font as being of "medium" weight */
- private static final String[] MEDIUM_WORDS = {"medium"};
- /** font constituent names which identify a font as being of "demi/semi" weight */
- private static final String[] DEMI_WORDS = {"demi", "semi"};
- /** font constituent names which identify a font as being of "bold" weight */
- private static final String[] BOLD_WORDS = {"bold"};
- /** font constituent names which identify a font as being of "extra bold" weight */
- private static final String[] EXTRA_BOLD_WORDS = {"extrabold", "extra bold", "black",
- "heavy", "ultra", "super"};
-
- /**
- * Guesses the font style of a font using its name.
- * @param fontName the font name
- * @return "normal" or "italic"
- */
- public static String guessStyle(String fontName) {
- if (fontName != null) {
- for (int i = 0; i < ITALIC_WORDS.length; i++) {
- if (fontName.indexOf(ITALIC_WORDS[i]) != -1) {
- return Font.STYLE_ITALIC;
- }
- }
- }
- return Font.STYLE_NORMAL;
- }
-
- /**
- * Guesses the font weight of a font using its name.
- * @param fontName the font name
- * @return an integer between 100 and 900
- */
- public static int guessWeight(String fontName) {
- // weight
- int weight = Font.WEIGHT_NORMAL;
-
- for (int i = 0; i < BOLD_WORDS.length; i++) {
- if (fontName.indexOf(BOLD_WORDS[i]) != -1) {
- weight = Font.WEIGHT_BOLD;
- break;
- }
- }
- for (int i = 0; i < MEDIUM_WORDS.length; i++) {
- if (fontName.indexOf(MEDIUM_WORDS[i]) != -1) {
- weight = Font.WEIGHT_NORMAL + 100; //500
- break;
- }
- }
- //Search for "semi/demi" before "light", but after "bold"
- //(normally semi/demi-bold is meant, but it can also be semi/demi-light)
- for (int i = 0; i < DEMI_WORDS.length; i++) {
- if (fontName.indexOf(DEMI_WORDS[i]) != -1) {
- weight = Font.WEIGHT_BOLD - 100; //600
- break;
- }
- }
- for (int i = 0; i < EXTRA_BOLD_WORDS.length; i++) {
- if (fontName.indexOf(EXTRA_BOLD_WORDS[i]) != -1) {
- weight = Font.WEIGHT_EXTRA_BOLD;
- break;
- }
- }
- for (int i = 0; i < LIGHT_WORDS.length; i++) {
- if (fontName.indexOf(LIGHT_WORDS[i]) != -1) {
- weight = Font.WEIGHT_LIGHT;
- break;
- }
- }
- return weight;
- }
-}
diff --git a/src/java/org/apache/fop/fonts/GlyphMapping.java b/src/java/org/apache/fop/fonts/GlyphMapping.java
deleted file mode 100644
index 95db0ff48..000000000
--- a/src/java/org/apache/fop/fonts/GlyphMapping.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * 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.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.complexscripts.fonts.GlyphPositioningTable;
-import org.apache.fop.complexscripts.fonts.GlyphTable;
-import org.apache.fop.complexscripts.util.CharScript;
-import org.apache.fop.traits.MinOptMax;
-import org.apache.fop.util.CharUtilities;
-
-/**
- * Stores the mapping of a text fragment to glyphs, along with various information.
- */
-public class GlyphMapping {
-
- private static final Log LOG = LogFactory.getLog(GlyphMapping.class);
- /** Inclusive. */
- public final int startIndex;
- /** Exclusive. */
- public final int endIndex;
- private int wordCharLength;
- public final int wordSpaceCount;
- public int letterSpaceCount;
- public MinOptMax areaIPD;
- public final boolean isHyphenated;
- public final boolean isSpace;
- public boolean breakOppAfter;
- public final Font font;
- public final int level;
- public final int[][] gposAdjustments;
- public String mapping;
- public List associations;
-
- public GlyphMapping(int startIndex, int endIndex, int wordSpaceCount, int letterSpaceCount,
- MinOptMax areaIPD, boolean isHyphenated, boolean isSpace, boolean breakOppAfter,
- Font font, int level, int[][] gposAdjustments) {
- this(startIndex, endIndex, wordSpaceCount, letterSpaceCount, areaIPD, isHyphenated,
- isSpace, breakOppAfter, font, level, gposAdjustments, null, null);
- }
-
- public GlyphMapping(int startIndex, int endIndex, int wordSpaceCount, int letterSpaceCount,
- MinOptMax areaIPD, boolean isHyphenated, boolean isSpace, boolean breakOppAfter,
- Font font, int level, int[][] gposAdjustments, String mapping, List associations) {
- assert startIndex <= endIndex;
- this.startIndex = startIndex;
- this.endIndex = endIndex;
- this.wordCharLength = -1;
- this.wordSpaceCount = wordSpaceCount;
- this.letterSpaceCount = letterSpaceCount;
- this.areaIPD = areaIPD;
- this.isHyphenated = isHyphenated;
- this.isSpace = isSpace;
- this.breakOppAfter = breakOppAfter;
- this.font = font;
- this.level = level;
- this.gposAdjustments = gposAdjustments;
- this.mapping = mapping;
- this.associations = associations;
- }
-
- public static GlyphMapping doGlyphMapping(TextFragment text, int startIndex, int endIndex,
- Font font, MinOptMax letterSpaceIPD, MinOptMax[] letterSpaceAdjustArray,
- char precedingChar, char breakOpportunityChar, final boolean endsWithHyphen, int level,
- boolean dontOptimizeForIdentityMapping, boolean retainAssociations, boolean retainControls) {
- GlyphMapping mapping;
- if (font.performsSubstitution() || font.performsPositioning()) {
- mapping = processWordMapping(text, startIndex, endIndex, font,
- breakOpportunityChar, endsWithHyphen, level,
- dontOptimizeForIdentityMapping, retainAssociations, retainControls);
- } else {
- mapping = processWordNoMapping(text, startIndex, endIndex, font,
- letterSpaceIPD, letterSpaceAdjustArray, precedingChar, breakOpportunityChar, endsWithHyphen, level);
- }
- return mapping;
- }
-
- private static GlyphMapping processWordMapping(TextFragment text, int startIndex,
- int endIndex, final Font font, final char breakOpportunityChar,
- final boolean endsWithHyphen, int level,
- boolean dontOptimizeForIdentityMapping, boolean retainAssociations, boolean retainControls) {
- int e = endIndex; // end index of word in FOText character buffer
- int nLS = 0; // # of letter spaces
- String script = text.getScript();
- String language = text.getLanguage();
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("PW: [" + startIndex + "," + endIndex + "]: {"
- + " +M"
- + ", level = " + level
- + " }");
- }
-
- // 1. extract unmapped character sequence.
- CharSequence ics = text.subSequence(startIndex, e);
-
- // 2. if script is not specified (by FO property) or it is specified as 'auto',
- // then compute dominant script.
- if ((script == null) || "auto".equals(script)) {
- script = CharScript.scriptTagFromCode(CharScript.dominantScript(ics));
- }
- if ((language == null) || "none".equals(language)) {
- language = "dflt";
- }
-
- // 3. perform mapping of chars to glyphs ... to glyphs ... to chars, retaining
- // associations if requested.
- List associations = retainAssociations ? new java.util.ArrayList() : null;
- CharSequence mcs = font.performSubstitution(ics, script, language, associations, retainControls);
-
- // 4. compute glyph position adjustments on (substituted) characters.
- int[][] gpa = null;
- if (font.performsPositioning()) {
- // handle GPOS adjustments
- gpa = font.performPositioning(mcs, script, language);
- }
- if (useKerningAdjustments(font, script, language)) {
- // handle standard (non-GPOS) kerning adjustments
- gpa = getKerningAdjustments(mcs, font, gpa);
- }
-
- // 5. reorder combining marks so that they precede (within the mapped char sequence) the
- // base to which they are applied; N.B. position adjustments (gpa) are reordered in place.
- mcs = font.reorderCombiningMarks(mcs, gpa, script, language, associations);
-
- // 6. compute word ipd based on final position adjustments.
- MinOptMax ipd = MinOptMax.ZERO;
- for (int i = 0, n = mcs.length(); i < n; i++) {
- int c = mcs.charAt(i);
- // TODO !BMP
- int w = font.getCharWidth(c);
- if (w < 0) {
- w = 0;
- }
- if (gpa != null) {
- w += gpa[i][GlyphPositioningTable.Value.IDX_X_ADVANCE];
- }
- ipd = ipd.plus(w);
- }
-
- // [TBD] - handle letter spacing
-
- return new GlyphMapping(startIndex, e, 0, nLS, ipd, endsWithHyphen, false,
- breakOpportunityChar != 0, font, level, gpa,
- !dontOptimizeForIdentityMapping && CharUtilities.isSameSequence(mcs, ics) ? null : mcs.toString(),
- associations);
- }
-
- private static boolean useKerningAdjustments(final Font font, String script, String language) {
- return font.hasKerning() && !font.hasFeature(GlyphTable.GLYPH_TABLE_TYPE_POSITIONING, script, language, "kern");
- }
-
- /**
- * Given a mapped character sequence MCS, obtain glyph position adjustments from the
- * font's kerning data.
- *
- * @param mcs mapped character sequence
- * @param font applicable font
- * @return glyph position adjustments (or null if no kerning)
- */
- private static int[][] getKerningAdjustments(CharSequence mcs, final Font font, int[][] gpa) {
- int nc = mcs.length();
- // extract kerning array
- int[] ka = new int[nc]; // kerning array
- for (int i = 0, n = nc, cPrev = -1; i < n; i++) {
- int c = mcs.charAt(i);
- // TODO !BMP
- if (cPrev >= 0) {
- ka[i] = font.getKernValue(cPrev, c);
- }
- cPrev = c;
- }
- // was there a non-zero kerning?
- boolean hasKerning = false;
- for (int i = 0, n = nc; i < n; i++) {
- if (ka[i] != 0) {
- hasKerning = true;
- break;
- }
- }
- // if non-zero kerning, then create and return glyph position adjustment array
- if (hasKerning) {
- if (gpa == null) {
- gpa = new int[nc][4];
- }
- for (int i = 0, n = nc; i < n; i++) {
- if (i > 0) {
- gpa [i - 1][GlyphPositioningTable.Value.IDX_X_ADVANCE] += ka[i];
- }
- }
- return gpa;
- } else {
- return null;
- }
- }
-
- private static GlyphMapping processWordNoMapping(TextFragment text, int startIndex, int endIndex,
- final Font font, MinOptMax letterSpaceIPD, MinOptMax[] letterSpaceAdjustArray,
- char precedingChar, final char breakOpportunityChar, final boolean endsWithHyphen, int level) {
- boolean kerning = font.hasKerning();
- MinOptMax wordIPD = MinOptMax.ZERO;
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("PW: [" + startIndex + "," + endIndex + "]: {"
- + " -M"
- + ", level = " + level
- + " }");
- }
-
- for (int i = startIndex; i < endIndex; i++) {
- char currentChar = text.charAt(i);
-
- // character width
- int charWidth = font.getCharWidth(currentChar);
- wordIPD = wordIPD.plus(charWidth);
-
- // kerning
- if (kerning) {
- int kern = 0;
- if (i > startIndex) {
- char previousChar = text.charAt(i - 1);
- kern = font.getKernValue(previousChar, currentChar);
- } else if (precedingChar != 0) {
- kern = font.getKernValue(precedingChar, currentChar);
- }
- if (kern != 0) {
- addToLetterAdjust(letterSpaceAdjustArray, i, kern);
- wordIPD = wordIPD.plus(kern);
- }
- }
- }
- if (kerning
- && (breakOpportunityChar != 0)
- && !isSpace(breakOpportunityChar)
- && endIndex > 0
- && endsWithHyphen) {
- int kern = font.getKernValue(text.charAt(endIndex - 1), breakOpportunityChar);
- if (kern != 0) {
- addToLetterAdjust(letterSpaceAdjustArray, endIndex, kern);
- // TODO: add kern to wordIPD?
- }
- }
- // shy+chars at start of word: wordLength == 0 && breakOpportunity
- // shy only characters in word: wordLength == 0 && !breakOpportunity
- int wordLength = endIndex - startIndex;
- int letterSpaces = 0;
- if (wordLength != 0) {
- letterSpaces = wordLength - 1;
- // if there is a break opportunity and the next one (break character)
- // is not a space, it could be used as a line end;
- // add one more letter space, in case other text follows
- if ((breakOpportunityChar != 0) && !isSpace(breakOpportunityChar)) {
- letterSpaces++;
- }
- }
- assert letterSpaces >= 0;
- wordIPD = wordIPD.plus(letterSpaceIPD.mult(letterSpaces));
-
- // create and return the AreaInfo object
- return new GlyphMapping(startIndex, endIndex, 0, letterSpaces, wordIPD, endsWithHyphen, false,
- (breakOpportunityChar != 0) && !isSpace(breakOpportunityChar), font, level, null);
- }
-
- private static void addToLetterAdjust(MinOptMax[] letterSpaceAdjustArray, int index, int width) {
- if (letterSpaceAdjustArray[index] == null) {
- letterSpaceAdjustArray[index] = MinOptMax.getInstance(width);
- } else {
- letterSpaceAdjustArray[index] = letterSpaceAdjustArray[index].plus(width);
- }
- }
-
- /**
- * Indicates whether a character is a space in terms of this layout manager.
- *
- * @param ch the character
- * @return true if it's a space
- */
- public static boolean isSpace(final char ch) {
- return ch == CharUtilities.SPACE
- || CharUtilities.isNonBreakableSpace(ch)
- || CharUtilities.isFixedWidthSpace(ch);
- }
-
- /**
- * Obtain number of 'characters' contained in word. If word is mapped, then this
- * number may be less than or greater than the original length (breakIndex -
- * startIndex). We compute and memoize thius length upon first invocation of this
- * method.
- */
- public int getWordLength() {
- if (wordCharLength == -1) {
- if (mapping != null) {
- wordCharLength = mapping.length();
- } else {
- assert endIndex >= startIndex;
- wordCharLength = endIndex - startIndex;
- }
- }
- return wordCharLength;
- }
-
- public void addToAreaIPD(MinOptMax idp) {
- areaIPD = areaIPD.plus(idp);
- }
-
- public String toString() {
- return super.toString() + "{"
- + "interval = [" + startIndex + "," + endIndex + "]"
- + ", isSpace = " + isSpace
- + ", level = " + level
- + ", areaIPD = " + areaIPD
- + ", letterSpaceCount = " + letterSpaceCount
- + ", wordSpaceCount = " + wordSpaceCount
- + ", isHyphenated = " + isHyphenated
- + ", font = " + font
- + "}";
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/Glyphs.java b/src/java/org/apache/fop/fonts/Glyphs.java
deleted file mode 100644
index 04098f590..000000000
--- a/src/java/org/apache/fop/fonts/Glyphs.java
+++ /dev/null
@@ -1,1318 +0,0 @@
-/*
- * 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;
-
-/**
- * This class provides a number of constants for glyph management.
- * @deprecated Use the Glyphs class from XML Graphics Commons instead!
- */
-public final class Glyphs {
-
- private Glyphs() {
- }
-
- /**
- * Glyph name for the "notdef" glyph
- */
- public static final String NOTDEF = ".notdef";
-
- /**
- * Glyph names for Mac encoding
- */
- public static final String[] MAC_GLYPH_NAMES = {
- /* 0x00 */
- NOTDEF, ".null", "CR", "space", "exclam", "quotedbl", "numbersign",
- "dollar", "percent", "ampersand", "quotesingle", "parenleft",
- "parenright", "asterisk", "plus", "comma", /* 0x10 */
- "hyphen", "period", "slash", "zero", "one", "two", "three", "four",
- "five", "six", "seven", "eight", "nine", "colon",
- "semicolon", "less", /* 0x20 */
- "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F",
- "G", "H", "I", "J", "K", "L", /* 0x30 */
- "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
- "bracketleft", "backslash", /* 0x40 */
- "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c",
- "d", "e", "f", "g", "h", "i", "j", "k", "l",
- /* 0x50 */
- "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
- "braceleft", "bar", /* 0x60 */
- "braceright", "asciitilde", "Adieresis", "Aring", "Ccedilla",
- "Eacute", "Ntilde", "Odieresis", "Udieresis", "aacute",
- "agrave", "acircumflex", "adieresis", "atilde",
- "aring", "ccedilla", /* 0x70 */
- "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave",
- "icircumflex", "idieresis", "ntilde", "oacute", "ograve",
- "ocircumflex", "odieresis", "otilde", "uacute", "ugrave",
- /* 0x80 */
- "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling",
- "section", "bullet", "paragraph", "germandbls",
- "registered", "copyright", "trademark", "acute",
- "dieresis", "notequal", /* 0x90 */
- "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal",
- "yen", "mu", "partialdiff", "Sigma", "Pi", "pi", "integral",
- "ordfeminine", "ordmasculine", "Omega", /* 0xa0 */
- "ae", "oslash", "questiondown", "exclamdown", "logicalnot",
- "radical", "florin", "approxequal", "Delta", "guillemotleft",
- "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde",
- "Otilde", /* 0xb0 */
- "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright",
- "quoteleft", "quoteright", "divide", "lozenge", "ydieresis",
- "Ydieresis", "fraction", "currency", "guilsinglleft",
- "guilsinglright", /* 0xc0 */
- "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase",
- "quotedblbase", "perthousand", "Acircumflex", "Ecircumflex",
- "Aacute", "Edieresis", "Egrave", "Iacute", "Icircumflex",
- "Idieresis", "Igrave", /* 0xd0 */
- "Oacute", "Ocircumflex", "applelogo", "Ograve", "Uacute",
- "Ucircumflex", "Ugrave", "dotlessi", "circumflex", "tilde",
- "macron", "breve", "dotaccent", "ring", "cedilla",
- "hungarumlaut", /* 0xe0 */
- "ogonek", "caron", "Lslash", "lslash", "Scaron", "scaron", "Zcaron",
- "zcaron", "brokenbar", "Eth", "eth", "Yacute", "yacute",
- "Thorn", "thorn", "minus", /* 0xf0 */
- "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf",
- "onequarter", "threequarters", "franc", "Gbreve",
- "gbreve", "Idot", "Scedilla", "scedilla", "Cacute",
- "cacute", "Ccaron", /* 0x100 */
- "ccaron", "dmacron"
- };
-
- /**
- * Glyph names for tex8r encoding
- */
- public static final String[] TEX8R_GLYPH_NAMES = {
- // 0x00
- NOTDEF, "dotaccent", "fi", "fl", "fraction", "hungarumlaut",
- "Lslash", "lslash", "ogonek", "ring", ".notdef", "breve",
- "minus", ".notdef", "Zcaron", "zcaron", // 0x10
- "caron", "dotlessi", "dotlessj", "ff", "ffi", "ffl", ".notdef",
- ".notdef", ".notdef", ".notdef", ".notdef", ".notdef",
- ".notdef", ".notdef", "grave", "quotesingle", // 0x20
- "space", "exclam", "quotedbl", "numbersign", "dollar", "percent",
- "ampersand", "quoteright", "parenleft", "parenright",
- "asterisk", "plus", "comma", "hyphen", "period", "slash",
- // 0x30
- "zero", "one", "two", "three", "four", "five", "six", "seven",
- "eight", "nine", "colon", "semicolon", "less", "equal",
- "greater", "question", // 0x40
- "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",
- "M", "N", "O", // 0x50
- "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft",
- "backslash", "bracketright", "asciicircum", "underscore", // 0x60
- "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
- "l", "m", "n", "o", // 0x70
- "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft",
- "bar", "braceright", "asciitilde", ".notdef", // 0x80
- "Euro", ".notdef", "quotesinglbase", "florin", "quotedblbase",
- "ellipsis", "dagger", "daggerdbl", "circumflex",
- "perthousand", "Scaron", "guilsinglleft", "OE", ".notdef",
- ".notdef", ".notdef", // 0x90
- ".notdef", ".notdef", ".notdef", "quotedblleft", "quotedblright",
- "bullet", "endash", "emdash", "tilde", "trademark",
- "scaron", "guilsinglright", "oe", ".notdef", ".notdef",
- "Ydieresis", // 0xA0
- ".notdef", "exclamdown", "cent", "sterling", "currency", "yen",
- "brokenbar", "section", "dieresis", "copyright",
- "ordfeminine", "guillemotleft", "logicalnot", "hyphen",
- "registered", "macron", // 0xB0
- "degree", "plusminus", "twosuperior", "threesuperior", "acute", "mu",
- "paragraph", "periodcentered", "cedilla", "onesuperior",
- "ordmasculine", "guillemotright", "onequarter", "onehalf",
- "threequarters", "questiondown", // 0xC0
- "Agrave", "Aacute", "Acircumflex", "Atilde", "Adieresis", "Aring",
- "AE", "Ccedilla", "Egrave", "Eacute", "Ecircumflex",
- "Edieresis", "Igrave", "Iacute", "Icircumflex",
- "Idieresis", // 0xD0
- "Eth", "Ntilde", "Ograve", "Oacute", "Ocircumflex", "Otilde",
- "Odieresis", "multiply", "Oslash", "Ugrave", "Uacute",
- "Ucircumflex", "Udieresis", "Yacute", "Thorn", "germandbls",
- // 0xE0
- "agrave", "aacute", "acircumflex", "atilde", "adieresis", "aring",
- "ae", "ccedilla", "egrave", "eacute", "ecircumflex",
- "edieresis", "igrave", "iacute", "icircumflex",
- "idieresis", // 0xF0
- "eth", "ntilde", "ograve", "oacute", "ocircumflex", "otilde",
- "odieresis", "divide", "oslash", "ugrave", "uacute",
- "ucircumflex", "udieresis", "yacute", "thorn", "ydieresis"
- };
-
- /**
- * The characters in WinAnsiEncoding
- */
- public static final char[] WINANSI_ENCODING = {
- // not used until char 32
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20
- ' ', '\u0021', '\"', '\u0023', '$', '%', '&', '\'', '(', ')', '*', '+', ',',
- '\u002d', '\u002e', '/', // 0x30
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=',
- '>', '?', '@', // 0x40
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
- 'O', // 0x50
- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '\u005b', '\\',
- '\u005d', '^', '_', // 0x60
- '\u2018', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
- 'n', 'o', // 0x70
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '\u007b', '\u007c', '\u007d',
- '\u007e', '\u2022', // 0x80
- '\u20ac', '\u2022', '\u201a', '\u0192', '\u201e', '\u2026', '\u2020',
- '\u2021', '\u02c6', '\u2030', '\u0160', '\u2039', '\u0152', '\u2022',
- '\u017d', '\u2022', // 0x90
- '\u2022', '\u2018', // quoteleft
- '\u2019', // quoteright
- '\u201c', // quotedblleft
- '\u201d', // quotedblright
- '\u2022', // bullet
- '\u2013', // endash
- '\u2014', // emdash
- '~',
- '\u2122', // trademark
- '\u0161', '\u203a', '\u0153', '\u2022', '\u017e', '\u0178', // 0xA0
- ' ', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5',
- '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab',
- '\u00ac', '\u00ad', '\u00ae', '\u00af', // 0xb0
- '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4',
- '\u00b5', // This is hand-coded, the rest is assumption
- '\u00b6', // and *might* not be correct...
- '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd',
- '\u00be', '\u00bf', // 0xc0
- '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', // Aring
- '\u00c6', // AE
- '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc',
- '\u00cd', '\u00ce', '\u00cf', // 0xd0
- '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5',
- '\u00d6', '\u00d7', '\u00d8', // Oslash
- '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de',
- '\u00df', // 0xe0
- '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', // aring
- '\u00e6', // ae
- '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec',
- '\u00ed', '\u00ee', '\u00ef', // 0xf0
- '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5',
- '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb',
- '\u00fc', '\u00fd', '\u00fe', '\u00ff'
- };
-
- /**
- * List of unicode glyphs
- */
- public static final String[] UNICODE_GLYPHS = {
- "\u0041", "A",
- "\u00C6", "AE",
- "\u01FC", "AEacute",
- "\uF7E6", "AEsmall",
- "\u00C1", "Aacute",
- "\uF7E1", "Aacutesmall",
- "\u0102", "Abreve",
- "\u00C2", "Acircumflex",
- "\uF7E2", "Acircumflexsmall",
- "\uF6C9", "Acute",
- "\uF7B4", "Acutesmall",
- "\u00C4", "Adieresis",
- "\uF7E4", "Adieresissmall",
- "\u00C0", "Agrave",
- "\uF7E0", "Agravesmall",
- "\u0391", "Alpha",
- "\u0386", "Alphatonos",
- "\u0100", "Amacron",
- "\u0104", "Aogonek",
- "\u00C5", "Aring",
- "\u01FA", "Aringacute",
- "\uF7E5", "Aringsmall",
- "\uF761", "Asmall",
- "\u00C3", "Atilde",
- "\uF7E3", "Atildesmall",
- "\u0042", "B",
- "\u0392", "Beta",
- "\uF6F4", "Brevesmall",
- "\uF762", "Bsmall",
- "\u0043", "C",
- "\u0106", "Cacute",
- "\uF6CA", "Caron",
- "\uF6F5", "Caronsmall",
- "\u010C", "Ccaron",
- "\u00C7", "Ccedilla",
- "\uF7E7", "Ccedillasmall",
- "\u0108", "Ccircumflex",
- "\u010A", "Cdotaccent",
- "\uF7B8", "Cedillasmall",
- "\u03A7", "Chi",
- "\uF6F6", "Circumflexsmall",
- "\uF763", "Csmall",
- "\u0044", "D",
- "\u010E", "Dcaron",
- "\u0110", "Dcroat",
- "\u2206", "Delta",
- "\u0394", "Delta",
- "\uF6CB", "Dieresis",
- "\uF6CC", "DieresisAcute",
- "\uF6CD", "DieresisGrave",
- "\uF7A8", "Dieresissmall",
- "\uF6F7", "Dotaccentsmall",
- "\uF764", "Dsmall",
- "\u0045", "E",
- "\u00C9", "Eacute",
- "\uF7E9", "Eacutesmall",
- "\u0114", "Ebreve",
- "\u011A", "Ecaron",
- "\u00CA", "Ecircumflex",
- "\uF7EA", "Ecircumflexsmall",
- "\u00CB", "Edieresis",
- "\uF7EB", "Edieresissmall",
- "\u0116", "Edotaccent",
- "\u00C8", "Egrave",
- "\uF7E8", "Egravesmall",
- "\u0112", "Emacron",
- "\u014A", "Eng",
- "\u0118", "Eogonek",
- "\u0395", "Epsilon",
- "\u0388", "Epsilontonos",
- "\uF765", "Esmall",
- "\u0397", "Eta",
- "\u0389", "Etatonos",
- "\u00D0", "Eth",
- "\uF7F0", "Ethsmall",
- "\u20AC", "Euro",
- "\u0046", "F",
- "\uF766", "Fsmall",
- "\u0047", "G",
- "\u0393", "Gamma",
- "\u011E", "Gbreve",
- "\u01E6", "Gcaron",
- "\u011C", "Gcircumflex",
- "\u0122", "Gcommaaccent",
- "\u0120", "Gdotaccent",
- "\uF6CE", "Grave",
- "\uF760", "Gravesmall",
- "\uF767", "Gsmall",
- "\u0048", "H",
- "\u25CF", "H18533",
- "\u25AA", "H18543",
- "\u25AB", "H18551",
- "\u25A1", "H22073",
- "\u0126", "Hbar",
- "\u0124", "Hcircumflex",
- "\uF768", "Hsmall",
- "\uF6CF", "Hungarumlaut",
- "\uF6F8", "Hungarumlautsmall",
- "\u0049", "I",
- "\u0132", "IJ",
- "\u00CD", "Iacute",
- "\uF7ED", "Iacutesmall",
- "\u012C", "Ibreve",
- "\u00CE", "Icircumflex",
- "\uF7EE", "Icircumflexsmall",
- "\u00CF", "Idieresis",
- "\uF7EF", "Idieresissmall",
- "\u0130", "Idotaccent",
- "\u2111", "Ifraktur",
- "\u00CC", "Igrave",
- "\uF7EC", "Igravesmall",
- "\u012A", "Imacron",
- "\u012E", "Iogonek",
- "\u0399", "Iota",
- "\u03AA", "Iotadieresis",
- "\u038A", "Iotatonos",
- "\uF769", "Ismall",
- "\u0128", "Itilde",
- "\u004A", "J",
- "\u0134", "Jcircumflex",
- "\uF76A", "Jsmall",
- "\u004B", "K",
- "\u039A", "Kappa",
- "\u0136", "Kcommaaccent",
- "\uF76B", "Ksmall",
- "\u004C", "L",
- "\uF6BF", "LL",
- "\u0139", "Lacute",
- "\u039B", "Lambda",
- "\u013D", "Lcaron",
- "\u013B", "Lcommaaccent",
- "\u013F", "Ldot",
- "\u0141", "Lslash",
- "\uF6F9", "Lslashsmall",
- "\uF76C", "Lsmall",
- "\u004D", "M",
- "\uF6D0", "Macron",
- "\uF7AF", "Macronsmall",
- "\uF76D", "Msmall",
- "\u039C", "Mu",
- "\u004E", "N",
- "\u0143", "Nacute",
- "\u0147", "Ncaron",
- "\u0145", "Ncommaaccent",
- "\uF76E", "Nsmall",
- "\u00D1", "Ntilde",
- "\uF7F1", "Ntildesmall",
- "\u039D", "Nu",
- "\u004F", "O",
- "\u0152", "OE",
- "\uF6FA", "OEsmall",
- "\u00D3", "Oacute",
- "\uF7F3", "Oacutesmall",
- "\u014E", "Obreve",
- "\u00D4", "Ocircumflex",
- "\uF7F4", "Ocircumflexsmall",
- "\u00D6", "Odieresis",
- "\uF7F6", "Odieresissmall",
- "\uF6FB", "Ogoneksmall",
- "\u00D2", "Ograve",
- "\uF7F2", "Ogravesmall",
- "\u01A0", "Ohorn",
- "\u0150", "Ohungarumlaut",
- "\u014C", "Omacron",
- "\u2126", "Omega",
- "\u03A9", "Omega",
- "\u038F", "Omegatonos",
- "\u039F", "Omicron",
- "\u038C", "Omicrontonos",
- "\u00D8", "Oslash",
- "\u01FE", "Oslashacute",
- "\uF7F8", "Oslashsmall",
- "\uF76F", "Osmall",
- "\u00D5", "Otilde",
- "\uF7F5", "Otildesmall",
- "\u0050", "P",
- "\u03A6", "Phi",
- "\u03A0", "Pi",
- "\u03A8", "Psi",
- "\uF770", "Psmall",
- "\u0051", "Q",
- "\uF771", "Qsmall",
- "\u0052", "R",
- "\u0154", "Racute",
- "\u0158", "Rcaron",
- "\u0156", "Rcommaaccent",
- "\u211C", "Rfraktur",
- "\u03A1", "Rho",
- "\uF6FC", "Ringsmall",
- "\uF772", "Rsmall",
- "\u0053", "S",
- "\u250C", "SF010000",
- "\u2514", "SF020000",
- "\u2510", "SF030000",
- "\u2518", "SF040000",
- "\u253C", "SF050000",
- "\u252C", "SF060000",
- "\u2534", "SF070000",
- "\u251C", "SF080000",
- "\u2524", "SF090000",
- "\u2500", "SF100000",
- "\u2502", "SF110000",
- "\u2561", "SF190000",
- "\u2562", "SF200000",
- "\u2556", "SF210000",
- "\u2555", "SF220000",
- "\u2563", "SF230000",
- "\u2551", "SF240000",
- "\u2557", "SF250000",
- "\u255D", "SF260000",
- "\u255C", "SF270000",
- "\u255B", "SF280000",
- "\u255E", "SF360000",
- "\u255F", "SF370000",
- "\u255A", "SF380000",
- "\u2554", "SF390000",
- "\u2569", "SF400000",
- "\u2566", "SF410000",
- "\u2560", "SF420000",
- "\u2550", "SF430000",
- "\u256C", "SF440000",
- "\u2567", "SF450000",
- "\u2568", "SF460000",
- "\u2564", "SF470000",
- "\u2565", "SF480000",
- "\u2559", "SF490000",
- "\u2558", "SF500000",
- "\u2552", "SF510000",
- "\u2553", "SF520000",
- "\u256B", "SF530000",
- "\u256A", "SF540000",
- "\u015A", "Sacute",
- "\u0160", "Scaron",
- "\uF6FD", "Scaronsmall",
- "\u015E", "Scedilla",
- "\uF6C1", "Scedilla",
- "\u015C", "Scircumflex",
- "\u0218", "Scommaaccent",
- "\u03A3", "Sigma",
- "\uF773", "Ssmall",
- "\u0054", "T",
- "\u03A4", "Tau",
- "\u0166", "Tbar",
- "\u0164", "Tcaron",
- "\u0162", "Tcommaaccent",
- "\u021A", "Tcommaaccent",
- "\u0398", "Theta",
- "\u00DE", "Thorn",
- "\uF7FE", "Thornsmall",
- "\uF6FE", "Tildesmall",
- "\uF774", "Tsmall",
- "\u0055", "U",
- "\u00DA", "Uacute",
- "\uF7FA", "Uacutesmall",
- "\u016C", "Ubreve",
- "\u00DB", "Ucircumflex",
- "\uF7FB", "Ucircumflexsmall",
- "\u00DC", "Udieresis",
- "\uF7FC", "Udieresissmall",
- "\u00D9", "Ugrave",
- "\uF7F9", "Ugravesmall",
- "\u01AF", "Uhorn",
- "\u0170", "Uhungarumlaut",
- "\u016A", "Umacron",
- "\u0172", "Uogonek",
- "\u03A5", "Upsilon",
- "\u03D2", "Upsilon1",
- "\u03AB", "Upsilondieresis",
- "\u038E", "Upsilontonos",
- "\u016E", "Uring",
- "\uF775", "Usmall",
- "\u0168", "Utilde",
- "\u0056", "V",
- "\uF776", "Vsmall",
- "\u0057", "W",
- "\u1E82", "Wacute",
- "\u0174", "Wcircumflex",
- "\u1E84", "Wdieresis",
- "\u1E80", "Wgrave",
- "\uF777", "Wsmall",
- "\u0058", "X",
- "\u039E", "Xi",
- "\uF778", "Xsmall",
- "\u0059", "Y",
- "\u00DD", "Yacute",
- "\uF7FD", "Yacutesmall",
- "\u0176", "Ycircumflex",
- "\u0178", "Ydieresis",
- "\uF7FF", "Ydieresissmall",
- "\u1EF2", "Ygrave",
- "\uF779", "Ysmall",
- "\u005A", "Z",
- "\u0179", "Zacute",
- "\u017D", "Zcaron",
- "\uF6FF", "Zcaronsmall",
- "\u017B", "Zdotaccent",
- "\u0396", "Zeta",
- "\uF77A", "Zsmall",
- "\u0061", "a",
- "\u00E1", "aacute",
- "\u0103", "abreve",
- "\u00E2", "acircumflex",
- "\u00B4", "acute",
- "\u0301", "acutecomb",
- "\u00E4", "adieresis",
- "\u00E6", "ae",
- "\u01FD", "aeacute",
- "\u2015", "afii00208",
- "\u0410", "afii10017",
- "\u0411", "afii10018",
- "\u0412", "afii10019",
- "\u0413", "afii10020",
- "\u0414", "afii10021",
- "\u0415", "afii10022",
- "\u0401", "afii10023",
- "\u0416", "afii10024",
- "\u0417", "afii10025",
- "\u0418", "afii10026",
- "\u0419", "afii10027",
- "\u041A", "afii10028",
- "\u041B", "afii10029",
- "\u041C", "afii10030",
- "\u041D", "afii10031",
- "\u041E", "afii10032",
- "\u041F", "afii10033",
- "\u0420", "afii10034",
- "\u0421", "afii10035",
- "\u0422", "afii10036",
- "\u0423", "afii10037",
- "\u0424", "afii10038",
- "\u0425", "afii10039",
- "\u0426", "afii10040",
- "\u0427", "afii10041",
- "\u0428", "afii10042",
- "\u0429", "afii10043",
- "\u042A", "afii10044",
- "\u042B", "afii10045",
- "\u042C", "afii10046",
- "\u042D", "afii10047",
- "\u042E", "afii10048",
- "\u042F", "afii10049",
- "\u0490", "afii10050",
- "\u0402", "afii10051",
- "\u0403", "afii10052",
- "\u0404", "afii10053",
- "\u0405", "afii10054",
- "\u0406", "afii10055",
- "\u0407", "afii10056",
- "\u0408", "afii10057",
- "\u0409", "afii10058",
- "\u040A", "afii10059",
- "\u040B", "afii10060",
- "\u040C", "afii10061",
- "\u040E", "afii10062",
- "\uF6C4", "afii10063",
- "\uF6C5", "afii10064",
- "\u0430", "afii10065",
- "\u0431", "afii10066",
- "\u0432", "afii10067",
- "\u0433", "afii10068",
- "\u0434", "afii10069",
- "\u0435", "afii10070",
- "\u0451", "afii10071",
- "\u0436", "afii10072",
- "\u0437", "afii10073",
- "\u0438", "afii10074",
- "\u0439", "afii10075",
- "\u043A", "afii10076",
- "\u043B", "afii10077",
- "\u043C", "afii10078",
- "\u043D", "afii10079",
- "\u043E", "afii10080",
- "\u043F", "afii10081",
- "\u0440", "afii10082",
- "\u0441", "afii10083",
- "\u0442", "afii10084",
- "\u0443", "afii10085",
- "\u0444", "afii10086",
- "\u0445", "afii10087",
- "\u0446", "afii10088",
- "\u0447", "afii10089",
- "\u0448", "afii10090",
- "\u0449", "afii10091",
- "\u044A", "afii10092",
- "\u044B", "afii10093",
- "\u044C", "afii10094",
- "\u044D", "afii10095",
- "\u044E", "afii10096",
- "\u044F", "afii10097",
- "\u0491", "afii10098",
- "\u0452", "afii10099",
- "\u0453", "afii10100",
- "\u0454", "afii10101",
- "\u0455", "afii10102",
- "\u0456", "afii10103",
- "\u0457", "afii10104",
- "\u0458", "afii10105",
- "\u0459", "afii10106",
- "\u045A", "afii10107",
- "\u045B", "afii10108",
- "\u045C", "afii10109",
- "\u045E", "afii10110",
- "\u040F", "afii10145",
- "\u0462", "afii10146",
- "\u0472", "afii10147",
- "\u0474", "afii10148",
- "\uF6C6", "afii10192",
- "\u045F", "afii10193",
- "\u0463", "afii10194",
- "\u0473", "afii10195",
- "\u0475", "afii10196",
- "\uF6C7", "afii10831",
- "\uF6C8", "afii10832",
- "\u04D9", "afii10846",
- "\u200E", "afii299",
- "\u200F", "afii300",
- "\u200D", "afii301",
- "\u066A", "afii57381",
- "\u060C", "afii57388",
- "\u0660", "afii57392",
- "\u0661", "afii57393",
- "\u0662", "afii57394",
- "\u0663", "afii57395",
- "\u0664", "afii57396",
- "\u0665", "afii57397",
- "\u0666", "afii57398",
- "\u0667", "afii57399",
- "\u0668", "afii57400",
- "\u0669", "afii57401",
- "\u061B", "afii57403",
- "\u061F", "afii57407",
- "\u0621", "afii57409",
- "\u0622", "afii57410",
- "\u0623", "afii57411",
- "\u0624", "afii57412",
- "\u0625", "afii57413",
- "\u0626", "afii57414",
- "\u0627", "afii57415",
- "\u0628", "afii57416",
- "\u0629", "afii57417",
- "\u062A", "afii57418",
- "\u062B", "afii57419",
- "\u062C", "afii57420",
- "\u062D", "afii57421",
- "\u062E", "afii57422",
- "\u062F", "afii57423",
- "\u0630", "afii57424",
- "\u0631", "afii57425",
- "\u0632", "afii57426",
- "\u0633", "afii57427",
- "\u0634", "afii57428",
- "\u0635", "afii57429",
- "\u0636", "afii57430",
- "\u0637", "afii57431",
- "\u0638", "afii57432",
- "\u0639", "afii57433",
- "\u063A", "afii57434",
- "\u0640", "afii57440",
- "\u0641", "afii57441",
- "\u0642", "afii57442",
- "\u0643", "afii57443",
- "\u0644", "afii57444",
- "\u0645", "afii57445",
- "\u0646", "afii57446",
- "\u0648", "afii57448",
- "\u0649", "afii57449",
- "\u064A", "afii57450",
- "\u064B", "afii57451",
- "\u064C", "afii57452",
- "\u064D", "afii57453",
- "\u064E", "afii57454",
- "\u064F", "afii57455",
- "\u0650", "afii57456",
- "\u0651", "afii57457",
- "\u0652", "afii57458",
- "\u0647", "afii57470",
- "\u06A4", "afii57505",
- "\u067E", "afii57506",
- "\u0686", "afii57507",
- "\u0698", "afii57508",
- "\u06AF", "afii57509",
- "\u0679", "afii57511",
- "\u0688", "afii57512",
- "\u0691", "afii57513",
- "\u06BA", "afii57514",
- "\u06D2", "afii57519",
- "\u06D5", "afii57534",
- "\u20AA", "afii57636",
- "\u05BE", "afii57645",
- "\u05C3", "afii57658",
- "\u05D0", "afii57664",
- "\u05D1", "afii57665",
- "\u05D2", "afii57666",
- "\u05D3", "afii57667",
- "\u05D4", "afii57668",
- "\u05D5", "afii57669",
- "\u05D6", "afii57670",
- "\u05D7", "afii57671",
- "\u05D8", "afii57672",
- "\u05D9", "afii57673",
- "\u05DA", "afii57674",
- "\u05DB", "afii57675",
- "\u05DC", "afii57676",
- "\u05DD", "afii57677",
- "\u05DE", "afii57678",
- "\u05DF", "afii57679",
- "\u05E0", "afii57680",
- "\u05E1", "afii57681",
- "\u05E2", "afii57682",
- "\u05E3", "afii57683",
- "\u05E4", "afii57684",
- "\u05E5", "afii57685",
- "\u05E6", "afii57686",
- "\u05E7", "afii57687",
- "\u05E8", "afii57688",
- "\u05E9", "afii57689",
- "\u05EA", "afii57690",
- "\uFB2A", "afii57694",
- "\uFB2B", "afii57695",
- "\uFB4B", "afii57700",
- "\uFB1F", "afii57705",
- "\u05F0", "afii57716",
- "\u05F1", "afii57717",
- "\u05F2", "afii57718",
- "\uFB35", "afii57723",
- "\u05B4", "afii57793",
- "\u05B5", "afii57794",
- "\u05B6", "afii57795",
- "\u05BB", "afii57796",
- "\u05B8", "afii57797",
- "\u05B7", "afii57798",
- "\u05B0", "afii57799",
- "\u05B2", "afii57800",
- "\u05B1", "afii57801",
- "\u05B3", "afii57802",
- "\u05C2", "afii57803",
- "\u05C1", "afii57804",
- "\u05B9", "afii57806",
- "\u05BC", "afii57807",
- "\u05BD", "afii57839",
- "\u05BF", "afii57841",
- "\u05C0", "afii57842",
- "\u02BC", "afii57929",
- "\u2105", "afii61248",
- "\u2113", "afii61289",
- "\u2116", "afii61352",
- "\u202C", "afii61573",
- "\u202D", "afii61574",
- "\u202E", "afii61575",
- "\u200C", "afii61664",
- "\u066D", "afii63167",
- "\u02BD", "afii64937",
- "\u00E0", "agrave",
- "\u2135", "aleph",
- "\u03B1", "alpha",
- "\u03AC", "alphatonos",
- "\u0101", "amacron",
- "\u0026", "ampersand",
- "\uF726", "ampersandsmall",
- "\u2220", "angle",
- "\u2329", "angleleft",
- "\u232A", "angleright",
- "\u0387", "anoteleia",
- "\u0105", "aogonek",
- "\u2248", "approxequal",
- "\u00E5", "aring",
- "\u01FB", "aringacute",
- "\u2194", "arrowboth",
- "\u21D4", "arrowdblboth",
- "\u21D3", "arrowdbldown",
- "\u21D0", "arrowdblleft",
- "\u21D2", "arrowdblright",
- "\u21D1", "arrowdblup",
- "\u2193", "arrowdown",
- "\uF8E7", "arrowhorizex",
- "\u2190", "arrowleft",
- "\u2192", "arrowright",
- "\u2191", "arrowup",
- "\u2195", "arrowupdn",
- "\u21A8", "arrowupdnbse",
- "\uF8E6", "arrowvertex",
- "\u005E", "asciicircum",
- "\u007E", "asciitilde",
- "\u002A", "asterisk",
- "\u2217", "asteriskmath",
- "\uF6E9", "asuperior",
- "\u0040", "at",
- "\u00E3", "atilde",
- "\u0062", "b",
- //"\u005C", "backslash",
- "\\", "backslash",
- "\u007C", "bar",
- "\u03B2", "beta",
- "\u2588", "block",
- "\uF8F4", "braceex",
- "\u007B", "braceleft",
- "\uF8F3", "braceleftbt",
- "\uF8F2", "braceleftmid",
- "\uF8F1", "bracelefttp",
- "\u007D", "braceright",
- "\uF8FE", "bracerightbt",
- "\uF8FD", "bracerightmid",
- "\uF8FC", "bracerighttp",
- "\u005B", "bracketleft",
- "\uF8F0", "bracketleftbt",
- "\uF8EF", "bracketleftex",
- "\uF8EE", "bracketlefttp",
- "\u005D", "bracketright",
- "\uF8FB", "bracketrightbt",
- "\uF8FA", "bracketrightex",
- "\uF8F9", "bracketrighttp",
- "\u02D8", "breve",
- "\u00A6", "brokenbar",
- "\uF6EA", "bsuperior",
- "\u2022", "bullet",
- "\u0063", "c",
- "\u0107", "cacute",
- "\u02C7", "caron",
- "\u21B5", "carriagereturn",
- "\u010D", "ccaron",
- "\u00E7", "ccedilla",
- "\u0109", "ccircumflex",
- "\u010B", "cdotaccent",
- "\u00B8", "cedilla",
- "\u00A2", "cent",
- "\uF6DF", "centinferior",
- "\uF7A2", "centoldstyle",
- "\uF6E0", "centsuperior",
- "\u03C7", "chi",
- "\u25CB", "circle",
- "\u2297", "circlemultiply",
- "\u2295", "circleplus",
- "\u02C6", "circumflex",
- "\u2663", "club",
- "\u003A", "colon",
- "\u20A1", "colonmonetary",
- "\u002C", "comma",
- "\uF6C3", "commaaccent",
- "\uF6E1", "commainferior",
- "\uF6E2", "commasuperior",
- "\u2245", "congruent",
- "\u00A9", "copyright",
- "\uF8E9", "copyrightsans",
- "\uF6D9", "copyrightserif",
- "\u00A4", "currency",
- "\uF6D1", "cyrBreve",
- "\uF6D2", "cyrFlex",
- "\uF6D4", "cyrbreve",
- "\uF6D5", "cyrflex",
- "\u0064", "d",
- "\u2020", "dagger",
- "\u2021", "daggerdbl",
- "\uF6D3", "dblGrave",
- "\uF6D6", "dblgrave",
- "\u010F", "dcaron",
- "\u0111", "dcroat",
- "\u00B0", "degree",
- "\u03B4", "delta",
- "\u2666", "diamond",
- "\u00A8", "dieresis",
- "\uF6D7", "dieresisacute",
- "\uF6D8", "dieresisgrave",
- "\u0385", "dieresistonos",
- "\u00F7", "divide",
- "\u2593", "dkshade",
- "\u2584", "dnblock",
- "\u0024", "dollar",
- "\uF6E3", "dollarinferior",
- "\uF724", "dollaroldstyle",
- "\uF6E4", "dollarsuperior",
- "\u20AB", "dong",
- "\u02D9", "dotaccent",
- "\u0323", "dotbelowcomb",
- "\u0131", "dotlessi",
- "\uF6BE", "dotlessj",
- "\u22C5", "dotmath",
- "\uF6EB", "dsuperior",
- "\u0065", "e",
- "\u00E9", "eacute",
- "\u0115", "ebreve",
- "\u011B", "ecaron",
- "\u00EA", "ecircumflex",
- "\u00EB", "edieresis",
- "\u0117", "edotaccent",
- "\u00E8", "egrave",
- "\u0038", "eight",
- "\u2088", "eightinferior",
- "\uF738", "eightoldstyle",
- "\u2078", "eightsuperior",
- "\u2208", "element",
- "\u2026", "ellipsis",
- "\u0113", "emacron",
- "\u2014", "emdash",
- "\u2205", "emptyset",
- "\u2013", "endash",
- "\u014B", "eng",
- "\u0119", "eogonek",
- "\u03B5", "epsilon",
- "\u03AD", "epsilontonos",
- "\u003D", "equal",
- "\u2261", "equivalence",
- "\u212E", "estimated",
- "\uF6EC", "esuperior",
- "\u03B7", "eta",
- "\u03AE", "etatonos",
- "\u00F0", "eth",
- "\u0021", "exclam",
- "\u203C", "exclamdbl",
- "\u00A1", "exclamdown",
- "\uF7A1", "exclamdownsmall",
- "\uF721", "exclamsmall",
- "\u2203", "existential",
- "\u0066", "f",
- "\u2640", "female",
- "\uFB00", "ff",
- "\uFB03", "ffi",
- "\uFB04", "ffl",
- "\uFB01", "fi",
- "\u2012", "figuredash",
- "\u25A0", "filledbox",
- "\u25AC", "filledrect",
- "\u0035", "five",
- "\u215D", "fiveeighths",
- "\u2085", "fiveinferior",
- "\uF735", "fiveoldstyle",
- "\u2075", "fivesuperior",
- "\uFB02", "fl",
- "\u0192", "florin",
- "\u0034", "four",
- "\u2084", "fourinferior",
- "\uF734", "fouroldstyle",
- "\u2074", "foursuperior",
- "\u2044", "fraction",
- "\u2215", "fraction",
- "\u20A3", "franc",
- "\u0067", "g",
- "\u03B3", "gamma",
- "\u011F", "gbreve",
- "\u01E7", "gcaron",
- "\u011D", "gcircumflex",
- "\u0123", "gcommaaccent",
- "\u0121", "gdotaccent",
- "\u00DF", "germandbls",
- "\u2207", "gradient",
- "\u0060", "grave",
- "\u0300", "gravecomb",
- "\u003E", "greater",
- "\u2265", "greaterequal",
- "\u00AB", "guillemotleft",
- "\u00BB", "guillemotright",
- "\u2039", "guilsinglleft",
- "\u203A", "guilsinglright",
- "\u0068", "h",
- "\u0127", "hbar",
- "\u0125", "hcircumflex",
- "\u2665", "heart",
- "\u0309", "hookabovecomb",
- "\u2302", "house",
- "\u02DD", "hungarumlaut",
- "\u002D", "hyphen",
- "\u00AD", "hyphen",
- "\uF6E5", "hypheninferior",
- "\uF6E6", "hyphensuperior",
- "\u0069", "i",
- "\u00ED", "iacute",
- "\u012D", "ibreve",
- "\u00EE", "icircumflex",
- "\u00EF", "idieresis",
- "\u00EC", "igrave",
- "\u0133", "ij",
- "\u012B", "imacron",
- "\u221E", "infinity",
- "\u222B", "integral",
- "\u2321", "integralbt",
- "\uF8F5", "integralex",
- "\u2320", "integraltp",
- "\u2229", "intersection",
- "\u25D8", "invbullet",
- "\u25D9", "invcircle",
- "\u263B", "invsmileface",
- "\u012F", "iogonek",
- "\u03B9", "iota",
- "\u03CA", "iotadieresis",
- "\u0390", "iotadieresistonos",
- "\u03AF", "iotatonos",
- "\uF6ED", "isuperior",
- "\u0129", "itilde",
- "\u006A", "j",
- "\u0135", "jcircumflex",
- "\u006B", "k",
- "\u03BA", "kappa",
- "\u0137", "kcommaaccent",
- "\u0138", "kgreenlandic",
- "\u006C", "l",
- "\u013A", "lacute",
- "\u03BB", "lambda",
- "\u013E", "lcaron",
- "\u013C", "lcommaaccent",
- "\u0140", "ldot",
- "\u003C", "less",
- "\u2264", "lessequal",
- "\u258C", "lfblock",
- "\u20A4", "lira",
- "\uF6C0", "ll",
- "\u2227", "logicaland",
- "\u00AC", "logicalnot",
- "\u2228", "logicalor",
- "\u017F", "longs",
- "\u25CA", "lozenge",
- "\u0142", "lslash",
- "\uF6EE", "lsuperior",
- "\u2591", "ltshade",
- "\u006D", "m",
- "\u00AF", "macron",
- "\u02C9", "macron",
- "\u2642", "male",
- "\u2212", "minus",
- "\u2032", "minute",
- "\uF6EF", "msuperior",
- "\u00B5", "mu",
- "\u03BC", "mu",
- "\u00D7", "multiply",
- "\u266A", "musicalnote",
- "\u266B", "musicalnotedbl",
- "\u006E", "n",
- "\u0144", "nacute",
- "\u0149", "napostrophe",
- "\u0148", "ncaron",
- "\u0146", "ncommaaccent",
- "\u0039", "nine",
- "\u2089", "nineinferior",
- "\uF739", "nineoldstyle",
- "\u2079", "ninesuperior",
- "\u2209", "notelement",
- "\u2260", "notequal",
- "\u2284", "notsubset",
- "\u207F", "nsuperior",
- "\u00F1", "ntilde",
- "\u03BD", "nu",
- "\u0023", "numbersign",
- "\u006F", "o",
- "\u00F3", "oacute",
- "\u014F", "obreve",
- "\u00F4", "ocircumflex",
- "\u00F6", "odieresis",
- "\u0153", "oe",
- "\u02DB", "ogonek",
- "\u00F2", "ograve",
- "\u01A1", "ohorn",
- "\u0151", "ohungarumlaut",
- "\u014D", "omacron",
- "\u03C9", "omega",
- "\u03D6", "omega1",
- "\u03CE", "omegatonos",
- "\u03BF", "omicron",
- "\u03CC", "omicrontonos",
- "\u0031", "one",
- "\u2024", "onedotenleader",
- "\u215B", "oneeighth",
- "\uF6DC", "onefitted",
- "\u00BD", "onehalf",
- "\u2081", "oneinferior",
- "\uF731", "oneoldstyle",
- "\u00BC", "onequarter",
- "\u00B9", "onesuperior",
- "\u2153", "onethird",
- "\u25E6", "openbullet",
- "\u00AA", "ordfeminine",
- "\u00BA", "ordmasculine",
- "\u221F", "orthogonal",
- "\u00F8", "oslash",
- "\u01FF", "oslashacute",
- "\uF6F0", "osuperior",
- "\u00F5", "otilde",
- "\u0070", "p",
- "\u00B6", "paragraph",
- "\u0028", "parenleft",
- "\uF8ED", "parenleftbt",
- "\uF8EC", "parenleftex",
- "\u208D", "parenleftinferior",
- "\u207D", "parenleftsuperior",
- "\uF8EB", "parenlefttp",
- "\u0029", "parenright",
- "\uF8F8", "parenrightbt",
- "\uF8F7", "parenrightex",
- "\u208E", "parenrightinferior",
- "\u207E", "parenrightsuperior",
- "\uF8F6", "parenrighttp",
- "\u2202", "partialdiff",
- "\u0025", "percent",
- "\u002E", "period",
- "\u00B7", "periodcentered",
- "\u2219", "periodcentered",
- "\uF6E7", "periodinferior",
- "\uF6E8", "periodsuperior",
- "\u22A5", "perpendicular",
- "\u2030", "perthousand",
- "\u20A7", "peseta",
- "\u03C6", "phi",
- "\u03D5", "phi1",
- "\u03C0", "pi",
- "\u002B", "plus",
- "\u00B1", "plusminus",
- "\u211E", "prescription",
- "\u220F", "product",
- "\u2282", "propersubset",
- "\u2283", "propersuperset",
- "\u221D", "proportional",
- "\u03C8", "psi",
- "\u0071", "q",
- "\u003F", "question",
- "\u00BF", "questiondown",
- "\uF7BF", "questiondownsmall",
- "\uF73F", "questionsmall",
- "\"", "quotedbl",
-// "\u0022", "quotedbl",
- "\u201E", "quotedblbase",
- "\u201C", "quotedblleft",
- "\u201D", "quotedblright",
- "\u2018", "quoteleft",
- "\u201B", "quotereversed",
- "\u2019", "quoteright",
- "\u201A", "quotesinglbase",
- "\u0027", "quotesingle",
- "\u0072", "r",
- "\u0155", "racute",
- "\u221A", "radical",
- "\uF8E5", "radicalex",
- "\u0159", "rcaron",
- "\u0157", "rcommaaccent",
- "\u2286", "reflexsubset",
- "\u2287", "reflexsuperset",
- "\u00AE", "registered",
- "\uF8E8", "registersans",
- "\uF6DA", "registerserif",
- "\u2310", "revlogicalnot",
- "\u03C1", "rho",
- "\u02DA", "ring",
- "\uF6F1", "rsuperior",
- "\u2590", "rtblock",
- "\uF6DD", "rupiah",
- "\u0073", "s",
- "\u015B", "sacute",
- "\u0161", "scaron",
- "\u015F", "scedilla",
- "\uF6C2", "scedilla",
- "\u015D", "scircumflex",
- "\u0219", "scommaaccent",
- "\u2033", "second",
- "\u00A7", "section",
- "\u003B", "semicolon",
- "\u0037", "seven",
- "\u215E", "seveneighths",
- "\u2087", "seveninferior",
- "\uF737", "sevenoldstyle",
- "\u2077", "sevensuperior",
- "\u2592", "shade",
- "\u03C3", "sigma",
- "\u03C2", "sigma1",
- "\u223C", "similar",
- "\u0036", "six",
- "\u2086", "sixinferior",
- "\uF736", "sixoldstyle",
- "\u2076", "sixsuperior",
- "\u002F", "slash",
- "\u263A", "smileface",
- "\u0020", "space",
- "\u00A0", "space",
- "\u2660", "spade",
- "\uF6F2", "ssuperior",
- "\u00A3", "sterling",
- "\u220B", "suchthat",
- "\u2211", "summation",
- "\u263C", "sun",
- "\u0074", "t",
- "\u03C4", "tau",
- "\u0167", "tbar",
- "\u0165", "tcaron",
- "\u0163", "tcommaaccent",
- "\u021B", "tcommaaccent",
- "\u2234", "therefore",
- "\u03B8", "theta",
- "\u03D1", "theta1",
- "\u00FE", "thorn",
- "\u0033", "three",
- "\u215C", "threeeighths",
- "\u2083", "threeinferior",
- "\uF733", "threeoldstyle",
- "\u00BE", "threequarters",
- "\uF6DE", "threequartersemdash",
- "\u00B3", "threesuperior",
- "\u02DC", "tilde",
- "\u0303", "tildecomb",
- "\u0384", "tonos",
- "\u2122", "trademark",
- "\uF8EA", "trademarksans",
- "\uF6DB", "trademarkserif",
- "\u25BC", "triagdn",
- "\u25C4", "triaglf",
- "\u25BA", "triagrt",
- "\u25B2", "triagup",
- "\uF6F3", "tsuperior",
- "\u0032", "two",
- "\u2025", "twodotenleader",
- "\u2082", "twoinferior",
- "\uF732", "twooldstyle",
- "\u00B2", "twosuperior",
- "\u2154", "twothirds",
- "\u0075", "u",
- "\u00FA", "uacute",
- "\u016D", "ubreve",
- "\u00FB", "ucircumflex",
- "\u00FC", "udieresis",
- "\u00F9", "ugrave",
- "\u01B0", "uhorn",
- "\u0171", "uhungarumlaut",
- "\u016B", "umacron",
- "\u005F", "underscore",
- "\u2017", "underscoredbl",
- "\u222A", "union",
- "\u2200", "universal",
- "\u0173", "uogonek",
- "\u2580", "upblock",
- "\u03C5", "upsilon",
- "\u03CB", "upsilondieresis",
- "\u03B0", "upsilondieresistonos",
- "\u03CD", "upsilontonos",
- "\u016F", "uring",
- "\u0169", "utilde",
- "\u0076", "v",
- "\u0077", "w",
- "\u1E83", "wacute",
- "\u0175", "wcircumflex",
- "\u1E85", "wdieresis",
- "\u2118", "weierstrass",
- "\u1E81", "wgrave",
- "\u0078", "x",
- "\u03BE", "xi",
- "\u0079", "y",
- "\u00FD", "yacute",
- "\u0177", "ycircumflex",
- "\u00FF", "ydieresis",
- "\u00A5", "yen",
- "\u1EF3", "ygrave",
- "\u007A", "z",
- "\u017A", "zacute",
- "\u017E", "zcaron",
- "\u017C", "zdotaccent",
- "\u0030", "zero",
- "\u2080", "zeroinferior",
- "\uF730", "zerooldstyle",
- "\u2070", "zerosuperior",
- "\u03B6", "zeta"
- };
-
- /**
- * Return the glyphname from a character,
- * eg, charToGlyphName('\\') returns "backslash"
- *
- * @param ch glyph to evaluate
- * @return the name of the glyph
- */
- public static String charToGlyphName(char ch) {
- return stringToGlyph(Character.toString(ch));
- }
-
- /**
- * Return the glyphname from a string,
- * eg, glyphToString("\\") returns "backslash"
- *
- * @param name glyph to evaluate
- * @return the name of the glyph
- * TODO: javadocs for glyphToString and stringToGlyph are confused
- * TODO: Improve method names
- */
- public static String glyphToString(String name) {
- for (int i = 0; i < UNICODE_GLYPHS.length; i += 2) {
- if (UNICODE_GLYPHS[i + 1].equals(name)) {
- return UNICODE_GLYPHS[i];
- }
- }
- return "";
- }
-
- /**
- * Return the string representation of a glyphname,
- * eg stringToGlyph("backslash") returns "\\"
- *
- * @param name name of the glyph
- * @return the string representation
- */
- public static String stringToGlyph(String name) {
- for (int i = 0; i < UNICODE_GLYPHS.length; i += 2) {
- if (UNICODE_GLYPHS[i].equals(name)) {
- return UNICODE_GLYPHS[i + 1];
- }
- }
- return "";
- }
-
-}
-
diff --git a/src/java/org/apache/fop/fonts/LazyFont.java b/src/java/org/apache/fop/fonts/LazyFont.java
deleted file mode 100644
index 06b106534..000000000
--- a/src/java/org/apache/fop/fonts/LazyFont.java
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- * 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.awt.Rectangle;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.xml.sax.InputSource;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.apps.io.InternalResourceResolver;
-import org.apache.fop.complexscripts.fonts.Positionable;
-import org.apache.fop.complexscripts.fonts.Substitutable;
-
-/**
- * This class is used to defer the loading of a font until it is really used.
- */
-public class LazyFont extends Typeface implements FontDescriptor, Substitutable, Positionable {
-
- private static Log log = LogFactory.getLog(LazyFont.class);
-
- private final FontUris fontUris;
-
- private final boolean useKerning;
- private final boolean useAdvanced;
- private final EncodingMode encodingMode;
- private final EmbeddingMode embeddingMode;
- private final String subFontName;
- private final boolean embedded;
- private final InternalResourceResolver resourceResolver;
-
- private boolean isMetricsLoaded;
- private Typeface realFont;
- private FontDescriptor realFontDescriptor;
-
- /**
- * Main constructor
- * @param fontInfo the font info to embed
- * @param resourceResolver the font resolver to handle font URIs
- */
- public LazyFont(EmbedFontInfo fontInfo, InternalResourceResolver resourceResolver,
- boolean useComplexScripts) {
-
- this.fontUris = fontInfo.getFontUris();
- this.useKerning = fontInfo.getKerning();
- if (resourceResolver != null) {
- this.useAdvanced = useComplexScripts;
- } else {
- this.useAdvanced = fontInfo.getAdvanced();
- }
- this.encodingMode = fontInfo.getEncodingMode() != null ? fontInfo.getEncodingMode()
- : EncodingMode.AUTO;
- this.embeddingMode = fontInfo.getEmbeddingMode() != null ? fontInfo.getEmbeddingMode()
- : EmbeddingMode.AUTO;
- this.subFontName = fontInfo.getSubFontName();
- this.embedded = fontInfo.isEmbedded();
- this.resourceResolver = resourceResolver;
- }
-
- /** {@inheritDoc} */
- public String toString() {
- StringBuffer sbuf = new StringBuffer(super.toString());
- sbuf.append('{');
- sbuf.append("metrics-url=" + fontUris.getMetrics());
- sbuf.append(",embed-url=" + fontUris.getEmbed());
- sbuf.append(",kerning=" + useKerning);
- sbuf.append(",advanced=" + useAdvanced);
- sbuf.append('}');
- return sbuf.toString();
- }
-
- private void load(boolean fail) {
- if (!isMetricsLoaded) {
- try {
- if (fontUris.getMetrics() != null) {
- /**@todo Possible thread problem here */
- FontReader reader = null;
- InputStream in = resourceResolver.getResource(fontUris.getMetrics());
- InputSource src = new InputSource(in);
- src.setSystemId(fontUris.getMetrics().toASCIIString());
- reader = new FontReader(src, resourceResolver);
- reader.setKerningEnabled(useKerning);
- reader.setAdvancedEnabled(useAdvanced);
- if (this.embedded) {
- reader.setFontEmbedURI(fontUris.getEmbed());
- }
- realFont = reader.getFont();
- } else {
- if (fontUris.getEmbed() == null) {
- throw new RuntimeException("Cannot load font. No font URIs available.");
- }
- realFont = FontLoader.loadFont(fontUris, subFontName, embedded,
- embeddingMode, encodingMode, useKerning, useAdvanced, resourceResolver);
- }
- if (realFont instanceof FontDescriptor) {
- realFontDescriptor = (FontDescriptor) realFont;
- }
- } catch (FOPException fopex) {
- log.error("Failed to read font metrics file " + fontUris.getMetrics(), fopex);
- if (fail) {
- throw new RuntimeException(fopex);
- }
- } catch (IOException ioex) {
- log.error("Failed to read font metrics file " + fontUris.getMetrics(), ioex);
- if (fail) {
- throw new RuntimeException(ioex);
- }
- }
- realFont.setEventListener(this.eventListener);
- isMetricsLoaded = true;
- }
- }
-
- /**
- * Gets the real font.
- * @return the real font
- */
- public Typeface getRealFont() {
- load(false);
- return realFont;
- }
-
- // ---- Font ----
- /** {@inheritDoc} */
- public String getEncodingName() {
- load(true);
- return realFont.getEncodingName();
- }
-
- /**
- * {@inheritDoc}
- */
- public char mapChar(char c) {
- if (!isMetricsLoaded) {
- load(true);
- }
- return realFont.mapChar(c);
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean hadMappingOperations() {
- load(true);
- return realFont.hadMappingOperations();
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean hasChar(char c) {
- if (!isMetricsLoaded) {
- load(true);
- }
- return realFont.hasChar(c);
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isMultiByte() {
- load(true);
- return realFont.isMultiByte();
- }
-
- // ---- FontMetrics interface ----
- /** {@inheritDoc} */
- public URI getFontURI() {
- load(true);
- return realFont.getFontURI();
- }
-
- /** {@inheritDoc} */
- public String getFontName() {
- load(true);
- return realFont.getFontName();
- }
-
- /** {@inheritDoc} */
- public String getEmbedFontName() {
- load(true);
- return realFont.getEmbedFontName();
- }
-
- /** {@inheritDoc} */
- public String getFullName() {
- load(true);
- return realFont.getFullName();
- }
-
- /** {@inheritDoc} */
- public Set<String> getFamilyNames() {
- load(true);
- return realFont.getFamilyNames();
- }
-
- /**
- * {@inheritDoc}
- */
- public int getMaxAscent(int size) {
- load(true);
- return realFont.getMaxAscent(size);
- }
-
- /**
- * {@inheritDoc}
- */
- public int getAscender(int size) {
- load(true);
- return realFont.getAscender(size);
- }
-
- /**
- * {@inheritDoc}
- */
- public int getCapHeight(int size) {
- load(true);
- return realFont.getCapHeight(size);
- }
-
- /**
- * {@inheritDoc}
- */
- public int getDescender(int size) {
- load(true);
- return realFont.getDescender(size);
- }
-
- /**
- * {@inheritDoc}
- */
- public int getXHeight(int size) {
- load(true);
- return realFont.getXHeight(size);
- }
-
- public int getUnderlinePosition(int size) {
- load(true);
- return realFont.getUnderlinePosition(size);
- }
-
- public int getUnderlineThickness(int size) {
- load(true);
- return realFont.getUnderlineThickness(size);
- }
-
- public int getStrikeoutPosition(int size) {
- load(true);
- return realFont.getStrikeoutPosition(size);
- }
-
- public int getStrikeoutThickness(int size) {
- load(true);
- return realFont.getStrikeoutThickness(size);
- }
-
- /**
- * {@inheritDoc}
- */
- public int getWidth(int i, int size) {
- if (!isMetricsLoaded) {
- load(true);
- }
- return realFont.getWidth(i, size);
- }
-
- /**
- * {@inheritDoc}
- */
- public int[] getWidths() {
- load(true);
- return realFont.getWidths();
- }
-
- public Rectangle getBoundingBox(int glyphIndex, int size) {
- load(true);
- return realFont.getBoundingBox(glyphIndex, size);
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean hasKerningInfo() {
- load(true);
- return realFont.hasKerningInfo();
- }
-
- /**
- * {@inheritDoc}
- */
- public Map<Integer, Map<Integer, Integer>> getKerningInfo() {
- load(true);
- return realFont.getKerningInfo();
- }
-
- /** {@inheritDoc} */
- public boolean hasFeature(int tableType, String script, String language, String feature) {
- load(true);
- return realFont.hasFeature(tableType, script, language, feature);
- }
-
- // ---- FontDescriptor interface ----
- /**
- * {@inheritDoc}
- */
- public int getCapHeight() {
- load(true);
- return realFontDescriptor.getCapHeight();
- }
-
- /**
- * {@inheritDoc}
- */
- public int getDescender() {
- load(true);
- return realFontDescriptor.getDescender();
- }
-
- /**
- * {@inheritDoc}
- */
- public int getAscender() {
- load(true);
- return realFontDescriptor.getAscender();
- }
-
- /** {@inheritDoc} */
- public int getFlags() {
- load(true);
- return realFontDescriptor.getFlags();
- }
-
- /** {@inheritDoc} */
- public boolean isSymbolicFont() {
- load(true);
- return realFontDescriptor.isSymbolicFont();
- }
-
- /**
- * {@inheritDoc}
- */
- public int[] getFontBBox() {
- load(true);
- return realFontDescriptor.getFontBBox();
- }
-
- /**
- * {@inheritDoc}
- */
- public int getItalicAngle() {
- load(true);
- return realFontDescriptor.getItalicAngle();
- }
-
- /**
- * {@inheritDoc}
- */
- public int getStemV() {
- load(true);
- return realFontDescriptor.getStemV();
- }
-
- /**
- * {@inheritDoc}
- */
- public FontType getFontType() {
- load(true);
- return realFontDescriptor.getFontType();
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isEmbeddable() {
- load(true);
- return realFontDescriptor.isEmbeddable();
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean performsSubstitution() {
- load(true);
- if (realFontDescriptor instanceof Substitutable) {
- return ((Substitutable)realFontDescriptor).performsSubstitution();
- } else {
- return false;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public CharSequence performSubstitution(CharSequence cs, String script, String language, List associations,
- boolean retainControls) {
- load(true);
- if (realFontDescriptor instanceof Substitutable) {
- return ((Substitutable)realFontDescriptor).performSubstitution(cs,
- script, language, associations, retainControls);
- } else {
- return cs;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public CharSequence reorderCombiningMarks(
- CharSequence cs, int[][] gpa, String script, String language, List associations) {
- if (!isMetricsLoaded) {
- load(true);
- }
- if (realFontDescriptor instanceof Substitutable) {
- return ((Substitutable)realFontDescriptor)
- .reorderCombiningMarks(cs, gpa, script, language, associations);
- } else {
- return cs;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean performsPositioning() {
- if (!isMetricsLoaded) {
- load(true);
- }
- if (realFontDescriptor instanceof Positionable) {
- return ((Positionable)realFontDescriptor).performsPositioning();
- } else {
- return false;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public int[][]
- performPositioning(CharSequence cs, String script, String language, int fontSize) {
- if (!isMetricsLoaded) {
- load(true);
- }
- if (realFontDescriptor instanceof Positionable) {
- return ((Positionable)realFontDescriptor)
- .performPositioning(cs, script, language, fontSize);
- } else {
- return null;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public int[][]
- performPositioning(CharSequence cs, String script, String language) {
- if (!isMetricsLoaded) {
- load(true);
- }
- if (realFontDescriptor instanceof Positionable) {
- return ((Positionable)realFontDescriptor)
- .performPositioning(cs, script, language);
- } else {
- return null;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isSubsetEmbedded() {
- load(true);
- if (realFont.isMultiByte() && this.embeddingMode == EmbeddingMode.FULL) {
- return false;
- }
- return realFont.isMultiByte();
- }
-}
-
diff --git a/src/java/org/apache/fop/fonts/MultiByteFont.java b/src/java/org/apache/fop/fonts/MultiByteFont.java
deleted file mode 100644
index db72bee0c..000000000
--- a/src/java/org/apache/fop/fonts/MultiByteFont.java
+++ /dev/null
@@ -1,807 +0,0 @@
-/*
- * 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.awt.Rectangle;
-import java.io.InputStream;
-import java.nio.CharBuffer;
-import java.nio.IntBuffer;
-import java.util.BitSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.apps.io.InternalResourceResolver;
-import org.apache.fop.complexscripts.fonts.GlyphDefinitionTable;
-import org.apache.fop.complexscripts.fonts.GlyphPositioningTable;
-import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable;
-import org.apache.fop.complexscripts.fonts.GlyphTable;
-import org.apache.fop.complexscripts.fonts.Positionable;
-import org.apache.fop.complexscripts.fonts.Substitutable;
-import org.apache.fop.complexscripts.util.CharAssociation;
-import org.apache.fop.complexscripts.util.CharNormalize;
-import org.apache.fop.complexscripts.util.GlyphSequence;
-import org.apache.fop.util.CharUtilities;
-
-/**
- * Generic MultiByte (CID) font
- */
-public class MultiByteFont extends CIDFont implements Substitutable, Positionable {
-
- /** logging instance */
- private static final Log log
- = LogFactory.getLog(MultiByteFont.class);
-
- private String ttcName;
- private String encoding = "Identity-H";
-
- private int defaultWidth;
- private CIDFontType cidType = CIDFontType.CIDTYPE2;
-
- protected final CIDSet cidSet;
-
- /* advanced typographic support */
- private GlyphDefinitionTable gdef;
- private GlyphSubstitutionTable gsub;
- private GlyphPositioningTable gpos;
-
- /* dynamic private use (character) mappings */
- private int numMapped;
- private int numUnmapped;
- private int nextPrivateUse = 0xE000;
- private int firstPrivate;
- private int lastPrivate;
- private int firstUnmapped;
- private int lastUnmapped;
-
- /** Contains the character bounding boxes for all characters in the font */
- protected Rectangle[] boundingBoxes;
-
- private boolean isOTFFile;
-
- // since for most users the most likely glyphs are in the first cmap segments we store their mapping.
- private static final int NUM_MOST_LIKELY_GLYPHS = 256;
- private int[] mostLikelyGlyphs = new int[NUM_MOST_LIKELY_GLYPHS];
-
- //A map to store each used glyph from the CID set against the glyph name.
- private LinkedHashMap<Integer, String> usedGlyphNames = new LinkedHashMap<Integer, String>();
-
- /**
- * Default constructor
- */
- public MultiByteFont(InternalResourceResolver resourceResolver, EmbeddingMode embeddingMode) {
- super(resourceResolver);
- setFontType(FontType.TYPE0);
- setEmbeddingMode(embeddingMode);
- if (embeddingMode != EmbeddingMode.FULL) {
- cidSet = new CIDSubset(this);
- } else {
- cidSet = new CIDFull(this);
- }
- }
-
- /** {@inheritDoc} */
- @Override
- public int getDefaultWidth() {
- return defaultWidth;
- }
-
- /** {@inheritDoc} */
- @Override
- public String getRegistry() {
- return "Adobe";
- }
-
- /** {@inheritDoc} */
- @Override
- public String getOrdering() {
- return "UCS";
- }
-
- /** {@inheritDoc} */
- @Override
- public int getSupplement() {
- return 0;
- }
-
- /** {@inheritDoc} */
- @Override
- public CIDFontType getCIDType() {
- return cidType;
- }
-
- public void setIsOTFFile(boolean isOTFFile) {
- this.isOTFFile = isOTFFile;
- }
-
- public boolean isOTFFile() {
- return this.isOTFFile;
- }
-
- /**
- * Sets the CIDType.
- * @param cidType The cidType to set
- */
- public void setCIDType(CIDFontType cidType) {
- this.cidType = cidType;
- }
-
- /** {@inheritDoc} */
- @Override
- public String getEmbedFontName() {
- if (isEmbeddable()) {
- return FontUtil.stripWhiteSpace(super.getFontName());
- } else {
- return super.getFontName();
- }
- }
-
- /** {@inheritDoc} */
- public boolean isEmbeddable() {
- return !(getEmbedFileURI() == null && getEmbedResourceName() == null);
- }
-
- public boolean isSubsetEmbedded() {
- if (getEmbeddingMode() == EmbeddingMode.FULL) {
- return false;
- }
- return true;
- }
-
- /** {@inheritDoc} */
- @Override
- public CIDSet getCIDSet() {
- return this.cidSet;
- }
-
- public void mapUsedGlyphName(int gid, String value) {
- usedGlyphNames.put(gid, value);
- }
-
- public LinkedHashMap<Integer, String> getUsedGlyphNames() {
- return usedGlyphNames;
- }
-
- /** {@inheritDoc} */
- @Override
- public String getEncodingName() {
- return encoding;
- }
-
- /** {@inheritDoc} */
- public int getWidth(int i, int size) {
- if (isEmbeddable()) {
- int glyphIndex = cidSet.getOriginalGlyphIndex(i);
- return size * width[glyphIndex];
- } else {
- return size * width[i];
- }
- }
-
- /** {@inheritDoc} */
- public int[] getWidths() {
- int[] arr = new int[width.length];
- System.arraycopy(width, 0, arr, 0, width.length);
- return arr;
- }
-
- public Rectangle getBoundingBox(int glyphIndex, int size) {
- int index = isEmbeddable() ? cidSet.getOriginalGlyphIndex(glyphIndex) : glyphIndex;
- Rectangle bbox = boundingBoxes[index];
- return new Rectangle(bbox.x * size, bbox.y * size, bbox.width * size, bbox.height * size);
- }
-
- /**
- * Returns the glyph index for a Unicode character. The method returns 0 if there's no
- * such glyph in the character map.
- * @param c the Unicode character index
- * @return the glyph index (or 0 if the glyph is not available)
- */
- // [TBD] - needs optimization, i.e., change from linear search to binary search
- public int findGlyphIndex(int c) {
- int idx = c;
- int retIdx = SingleByteEncoding.NOT_FOUND_CODE_POINT;
-
- // for most users the most likely glyphs are in the first cmap segments (meaning the one with
- // the lowest unicode start values)
- if (idx < NUM_MOST_LIKELY_GLYPHS && mostLikelyGlyphs[idx] != 0) {
- return mostLikelyGlyphs[idx];
- }
- for (CMapSegment i : cmap) {
- if (retIdx == 0
- && i.getUnicodeStart() <= idx
- && i.getUnicodeEnd() >= idx) {
- retIdx = i.getGlyphStartIndex()
- + idx
- - i.getUnicodeStart();
- if (idx < NUM_MOST_LIKELY_GLYPHS) {
- mostLikelyGlyphs[idx] = retIdx;
- }
- if (retIdx != 0) {
- break;
- }
- }
- }
- return retIdx;
- }
-
- /**
- * Add a private use mapping {PU,GI} to the existing character map.
- * N.B. Does not insert in order, merely appends to end of existing map.
- */
- protected synchronized void addPrivateUseMapping(int pu, int gi) {
- assert findGlyphIndex(pu) == SingleByteEncoding.NOT_FOUND_CODE_POINT;
- cmap.add(new CMapSegment(pu, pu, gi));
- }
-
- /**
- * Given a glyph index, create a new private use mapping, augmenting the bfentries
- * table. This is needed to accommodate the presence of an (output) glyph index in a
- * complex script glyph substitution that does not correspond to a character in the
- * font's CMAP. The creation of such private use mappings is deferred until an
- * attempt is actually made to perform the reverse lookup from the glyph index. This
- * is necessary in order to avoid exhausting the private use space on fonts containing
- * many such non-mapped glyph indices, if these mappings had been created statically
- * at font load time.
- * @param gi glyph index
- * @returns unicode scalar value
- */
- private int createPrivateUseMapping(int gi) {
- while ((nextPrivateUse < 0xF900)
- && (findGlyphIndex(nextPrivateUse) != SingleByteEncoding.NOT_FOUND_CODE_POINT)) {
- nextPrivateUse++;
- }
- if (nextPrivateUse < 0xF900) {
- int pu = nextPrivateUse;
- addPrivateUseMapping(pu, gi);
- if (firstPrivate == 0) {
- firstPrivate = pu;
- }
- lastPrivate = pu;
- numMapped++;
- if (log.isDebugEnabled()) {
- log.debug("Create private use mapping from "
- + CharUtilities.format(pu)
- + " to glyph index " + gi
- + " in font '" + getFullName() + "'");
- }
- return pu;
- } else {
- if (firstUnmapped == 0) {
- firstUnmapped = gi;
- }
- lastUnmapped = gi;
- numUnmapped++;
- log.warn("Exhausted private use area: unable to map "
- + numUnmapped + " glyphs in glyph index range ["
- + firstUnmapped + "," + lastUnmapped
- + "] (inclusive) of font '" + getFullName() + "'");
- return 0;
- }
- }
-
- /**
- * Returns the Unicode scalar value that corresponds to the glyph index. If more than
- * one correspondence exists, then the first one is returned (ordered by bfentries[]).
- * @param gi glyph index
- * @returns unicode scalar value
- */
- // [TBD] - needs optimization, i.e., change from linear search to binary search
- private int findCharacterFromGlyphIndex(int gi, boolean augment) {
- int cc = 0;
- for (CMapSegment segment : cmap) {
- int s = segment.getGlyphStartIndex();
- int e = s + (segment.getUnicodeEnd() - segment.getUnicodeStart());
- if ((gi >= s) && (gi <= e)) {
- cc = segment.getUnicodeStart() + (gi - s);
- break;
- }
- }
- if ((cc == 0) && augment) {
- cc = createPrivateUseMapping(gi);
- }
- return cc;
- }
-
- private int findCharacterFromGlyphIndex(int gi) {
- return findCharacterFromGlyphIndex(gi, true);
- }
-
- protected BitSet getGlyphIndices() {
- BitSet bitset = new BitSet();
- bitset.set(0);
- bitset.set(1);
- bitset.set(2);
- for (CMapSegment i : cmap) {
- int start = i.getUnicodeStart();
- int end = i.getUnicodeEnd();
- int glyphIndex = i.getGlyphStartIndex();
- while (start++ < end + 1) {
- bitset.set(glyphIndex++);
- }
- }
- return bitset;
- }
-
- protected char[] getChars() {
- // the width array is set when the font is built
- char[] chars = new char[width.length];
- for (CMapSegment i : cmap) {
- int start = i.getUnicodeStart();
- int end = i.getUnicodeEnd();
- int glyphIndex = i.getGlyphStartIndex();
- while (start < end + 1) {
- chars[glyphIndex++] = (char) start++;
- }
- }
- return chars;
- }
-
- /** {@inheritDoc} */
- @Override
- public char mapChar(char c) {
- notifyMapOperation();
- int glyphIndex = findGlyphIndex(c);
- if (glyphIndex == SingleByteEncoding.NOT_FOUND_CODE_POINT) {
- warnMissingGlyph(c);
- if (!isOTFFile) {
- glyphIndex = findGlyphIndex(Typeface.NOT_FOUND);
- }
- }
- if (isEmbeddable()) {
- glyphIndex = cidSet.mapChar(glyphIndex, c);
- }
- return (char) glyphIndex;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean hasChar(char c) {
- return (findGlyphIndex(c) != SingleByteEncoding.NOT_FOUND_CODE_POINT);
- }
-
- /**
- * Sets the defaultWidth.
- * @param defaultWidth The defaultWidth to set
- */
- public void setDefaultWidth(int defaultWidth) {
- this.defaultWidth = defaultWidth;
- }
-
- /**
- * Returns the TrueType Collection Name.
- * @return the TrueType Collection Name
- */
- public String getTTCName() {
- return ttcName;
- }
-
- /**
- * Sets the the TrueType Collection Name.
- * @param ttcName the TrueType Collection Name
- */
- public void setTTCName(String ttcName) {
- this.ttcName = ttcName;
- }
-
- /**
- * Sets the width array.
- * @param wds array of widths.
- */
- public void setWidthArray(int[] wds) {
- this.width = wds;
- }
-
- /**
- * Sets the bounding boxes array.
- * @param boundingBoxes array of bounding boxes.
- */
- public void setBBoxArray(Rectangle[] boundingBoxes) {
- this.boundingBoxes = boundingBoxes;
- }
-
- /**
- * Returns a Map of used Glyphs.
- * @return Map Map of used Glyphs
- */
- public Map<Integer, Integer> getUsedGlyphs() {
- return cidSet.getGlyphs();
- }
-
- /**
- * Returns the character from it's original glyph index in the font
- * @param glyphIndex The original index of the character
- * @return The character
- */
- public char getUnicodeFromGID(int glyphIndex) {
- return cidSet.getUnicodeFromGID(glyphIndex);
- }
-
- /**
- * Gets the original glyph index in the font from a character.
- * @param ch The character
- * @return The glyph index in the font
- */
- public int getGIDFromChar(char ch) {
- return cidSet.getGIDFromChar(ch);
- }
-
- /**
- * Establishes the glyph definition table.
- * @param gdef the glyph definition table to be used by this font
- */
- public void setGDEF(GlyphDefinitionTable gdef) {
- if ((this.gdef == null) || (gdef == null)) {
- this.gdef = gdef;
- } else {
- throw new IllegalStateException("font already associated with GDEF table");
- }
- }
-
- /**
- * Obtain glyph definition table.
- * @return glyph definition table or null if none is associated with font
- */
- public GlyphDefinitionTable getGDEF() {
- return gdef;
- }
-
- /**
- * Establishes the glyph substitution table.
- * @param gsub the glyph substitution table to be used by this font
- */
- public void setGSUB(GlyphSubstitutionTable gsub) {
- if ((this.gsub == null) || (gsub == null)) {
- this.gsub = gsub;
- } else {
- throw new IllegalStateException("font already associated with GSUB table");
- }
- }
-
- /**
- * Obtain glyph substitution table.
- * @return glyph substitution table or null if none is associated with font
- */
- public GlyphSubstitutionTable getGSUB() {
- return gsub;
- }
-
- /**
- * Establishes the glyph positioning table.
- * @param gpos the glyph positioning table to be used by this font
- */
- public void setGPOS(GlyphPositioningTable gpos) {
- if ((this.gpos == null) || (gpos == null)) {
- this.gpos = gpos;
- } else {
- throw new IllegalStateException("font already associated with GPOS table");
- }
- }
-
- /**
- * Obtain glyph positioning table.
- * @return glyph positioning table or null if none is associated with font
- */
- public GlyphPositioningTable getGPOS() {
- return gpos;
- }
-
- /** {@inheritDoc} */
- public boolean performsSubstitution() {
- return gsub != null;
- }
-
- /** {@inheritDoc} */
- public CharSequence performSubstitution(CharSequence cs, String script, String language, List associations,
- boolean retainControls) {
- if (gsub != null) {
- CharSequence ncs = normalize(cs, associations);
- GlyphSequence igs = mapCharsToGlyphs(ncs, associations);
- GlyphSequence ogs = gsub.substitute(igs, script, language);
- if (associations != null) {
- associations.clear();
- associations.addAll(ogs.getAssociations());
- }
- if (!retainControls) {
- ogs = elideControls(ogs);
- }
- CharSequence ocs = mapGlyphsToChars(ogs);
- return ocs;
- } else {
- return cs;
- }
- }
-
- /** {@inheritDoc} */
- public CharSequence reorderCombiningMarks(
- CharSequence cs, int[][] gpa, String script, String language, List associations) {
- if (gdef != null) {
- GlyphSequence igs = mapCharsToGlyphs(cs, associations);
- GlyphSequence ogs = gdef.reorderCombiningMarks(igs, getUnscaledWidths(igs), gpa, script, language);
- if (associations != null) {
- associations.clear();
- associations.addAll(ogs.getAssociations());
- }
- CharSequence ocs = mapGlyphsToChars(ogs);
- return ocs;
- } else {
- return cs;
- }
- }
-
- protected int[] getUnscaledWidths(GlyphSequence gs) {
- int[] widths = new int[gs.getGlyphCount()];
- for (int i = 0, n = widths.length; i < n; ++i) {
- if (i < width.length) {
- widths[i] = width[i];
- }
- }
- return widths;
- }
-
- /** {@inheritDoc} */
- public boolean performsPositioning() {
- return gpos != null;
- }
-
- /** {@inheritDoc} */
- public int[][]
- performPositioning(CharSequence cs, String script, String language, int fontSize) {
- if (gpos != null) {
- GlyphSequence gs = mapCharsToGlyphs(cs, null);
- int[][] adjustments = new int [ gs.getGlyphCount() ] [ 4 ];
- if (gpos.position(gs, script, language, fontSize, this.width, adjustments)) {
- return scaleAdjustments(adjustments, fontSize);
- } else {
- return null;
- }
- } else {
- return null;
- }
- }
-
- /** {@inheritDoc} */
- public int[][] performPositioning(CharSequence cs, String script, String language) {
- throw new UnsupportedOperationException();
- }
-
-
- private int[][] scaleAdjustments(int[][] adjustments, int fontSize) {
- if (adjustments != null) {
- for (int i = 0, n = adjustments.length; i < n; i++) {
- int[] gpa = adjustments [ i ];
- for (int k = 0; k < 4; k++) {
- gpa [ k ] = (gpa [ k ] * fontSize) / 1000;
- }
- }
- return adjustments;
- } else {
- return null;
- }
- }
-
- /**
- * Map sequence CS, comprising a sequence of UTF-16 encoded Unicode Code Points, to
- * an output character sequence GS, comprising a sequence of Glyph Indices. N.B. Unlike
- * mapChar(), this method does not make use of embedded subset encodings.
- * @param cs a CharSequence containing UTF-16 encoded Unicode characters
- * @returns a CharSequence containing glyph indices
- */
- private GlyphSequence mapCharsToGlyphs(CharSequence cs, List associations) {
- IntBuffer cb = IntBuffer.allocate(cs.length());
- IntBuffer gb = IntBuffer.allocate(cs.length());
- int gi;
- int giMissing = findGlyphIndex(Typeface.NOT_FOUND);
- for (int i = 0, n = cs.length(); i < n; i++) {
- int cc = cs.charAt(i);
- if ((cc >= 0xD800) && (cc < 0xDC00)) {
- if ((i + 1) < n) {
- int sh = cc;
- int sl = cs.charAt(++i);
- if ((sl >= 0xDC00) && (sl < 0xE000)) {
- cc = 0x10000 + ((sh - 0xD800) << 10) + ((sl - 0xDC00) << 0);
- } else {
- throw new IllegalArgumentException(
- "ill-formed UTF-16 sequence, "
- + "contains isolated high surrogate at index " + i);
- }
- } else {
- throw new IllegalArgumentException(
- "ill-formed UTF-16 sequence, "
- + "contains isolated high surrogate at end of sequence");
- }
- } else if ((cc >= 0xDC00) && (cc < 0xE000)) {
- throw new IllegalArgumentException(
- "ill-formed UTF-16 sequence, "
- + "contains isolated low surrogate at index " + i);
- }
- notifyMapOperation();
- gi = findGlyphIndex(cc);
- if (gi == SingleByteEncoding.NOT_FOUND_CODE_POINT) {
- warnMissingGlyph((char) cc);
- gi = giMissing;
- }
- cb.put(cc);
- gb.put(gi);
- }
- cb.flip();
- gb.flip();
- if ((associations != null) && (associations.size() == cs.length())) {
- associations = new java.util.ArrayList(associations);
- } else {
- associations = null;
- }
- return new GlyphSequence(cb, gb, associations);
- }
-
- /**
- * Map sequence GS, comprising a sequence of Glyph Indices, to output sequence CS,
- * comprising a sequence of UTF-16 encoded Unicode Code Points.
- * @param gs a GlyphSequence containing glyph indices
- * @returns a CharSequence containing UTF-16 encoded Unicode characters
- */
- private CharSequence mapGlyphsToChars(GlyphSequence gs) {
- int ng = gs.getGlyphCount();
- CharBuffer cb = CharBuffer.allocate(ng);
- int ccMissing = Typeface.NOT_FOUND;
- for (int i = 0, n = ng; i < n; i++) {
- int gi = gs.getGlyph(i);
- int cc = findCharacterFromGlyphIndex(gi);
- if ((cc == 0) || (cc > 0x10FFFF)) {
- cc = ccMissing;
- log.warn("Unable to map glyph index " + gi
- + " to Unicode scalar in font '"
- + getFullName() + "', substituting missing character '"
- + (char) cc + "'");
- }
- if (cc > 0x00FFFF) {
- int sh;
- int sl;
- cc -= 0x10000;
- sh = ((cc >> 10) & 0x3FF) + 0xD800;
- sl = ((cc >> 0) & 0x3FF) + 0xDC00;
- cb.put((char) sh);
- cb.put((char) sl);
- } else {
- cb.put((char) cc);
- }
- }
- cb.flip();
- return cb;
- }
-
- private CharSequence normalize(CharSequence cs, List associations) {
- return hasDecomposable(cs) ? decompose(cs, associations) : cs;
- }
-
- private boolean hasDecomposable(CharSequence cs) {
- for (int i = 0, n = cs.length(); i < n; i++) {
- int cc = cs.charAt(i);
- if (CharNormalize.isDecomposable(cc)) {
- return true;
- }
- }
- return false;
- }
-
- private CharSequence decompose(CharSequence cs, List associations) {
- StringBuffer sb = new StringBuffer(cs.length());
- int[] daBuffer = new int[CharNormalize.maximumDecompositionLength()];
- for (int i = 0, n = cs.length(); i < n; i++) {
- int cc = cs.charAt(i);
- int[] da = CharNormalize.decompose(cc, daBuffer);
- for (int j = 0; j < da.length; j++) {
- if (da[j] > 0) {
- sb.append((char) da[j]);
- } else {
- break;
- }
- }
- }
- return sb;
- }
-
- private static GlyphSequence elideControls(GlyphSequence gs) {
- if (hasElidableControl(gs)) {
- int[] ca = gs.getCharacterArray(false);
- IntBuffer ngb = IntBuffer.allocate(gs.getGlyphCount());
- List nal = new java.util.ArrayList(gs.getGlyphCount());
- for (int i = 0, n = gs.getGlyphCount(); i < n; ++i) {
- CharAssociation a = gs.getAssociation(i);
- int s = a.getStart();
- int e = a.getEnd();
- while (s < e) {
- int ch = ca [ s ];
- if (isElidableControl(ch)) {
- break;
- } else {
- ++s;
- }
- }
- if (s == e) {
- ngb.put(gs.getGlyph(i));
- nal.add(a);
- }
- }
- ngb.flip();
- return new GlyphSequence(gs.getCharacters(), ngb, nal, gs.getPredications());
- } else {
- return gs;
- }
- }
-
- private static boolean hasElidableControl(GlyphSequence gs) {
- int[] ca = gs.getCharacterArray(false);
- for (int i = 0, n = ca.length; i < n; ++i) {
- int ch = ca [ i ];
- if (isElidableControl(ch)) {
- return true;
- }
- }
- return false;
- }
-
- private static boolean isElidableControl(int ch) {
- if (ch < 0x0020) {
- return true;
- } else if ((ch >= 0x80) && (ch < 0x00A0)) {
- return true;
- } else if ((ch >= 0x2000) && (ch <= 0x206F)) {
- if ((ch >= 0x200B) && (ch <= 0x200F)) {
- return true;
- } else if ((ch >= 0x2028) && (ch <= 0x202E)) {
- return true;
- } else if ((ch >= 0x2066) && (ch <= 0x206F)) {
- return true;
- } else {
- return ch == 0x2060;
- }
- } else {
- return false;
- }
- }
-
- @Override
- public boolean hasFeature(int tableType, String script, String language, String feature) {
- GlyphTable table;
- if (tableType == GlyphTable.GLYPH_TABLE_TYPE_SUBSTITUTION) {
- table = getGSUB();
- } else if (tableType == GlyphTable.GLYPH_TABLE_TYPE_POSITIONING) {
- table = getGPOS();
- } else if (tableType == GlyphTable.GLYPH_TABLE_TYPE_DEFINITION) {
- table = getGDEF();
- } else {
- table = null;
- }
- return (table != null) && table.hasFeature(script, language, feature);
- }
-
- public Map<Integer, Integer> getWidthsMap() {
- return null;
- }
-
- public InputStream getCmapStream() {
- return null;
- }
-}
-
diff --git a/src/java/org/apache/fop/fonts/MutableFont.java b/src/java/org/apache/fop/fonts/MutableFont.java
deleted file mode 100644
index f02eb2b49..000000000
--- a/src/java/org/apache/fop/fonts/MutableFont.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * 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.net.URI;
-import java.util.Map;
-import java.util.Set;
-
-
-
-/**
- * This interface is used to set the values of a font during configuration time.
- */
-public interface MutableFont {
-
- /**
- * Sets the URI from which this font is or will be loaded.
- * @param uri URI from which font is or will be loaded
- */
- void setFontURI(URI uri);
-
- /**
- * Sets the "PostScript" font name (Example: "Helvetica-BoldOblique").
- * @param name font name
- */
- void setFontName(String name);
-
- /**
- * Sets the font's full name (usually the one that the operating system displays). Example:
- * "Helvetica Bold Oblique".
- * @param name font' full name
- */
- void setFullName(String name);
-
- /**
- * Sets the font's family names (Example: "Helvetica").
- * @param names the font's family names (a Set of Strings)
- */
- void setFamilyNames(Set<String> names);
-
- /**
- * Sets the URI to the embeddable font.
- * @param path URI to the font
- */
- void setEmbedURI(URI path);
-
- /**
- * Sets the resource name of the embeddable font file.
- * @param name resource name
- */
- void setEmbedResourceName(String name);
-
- /**
- * Sets the embedding mode.
- * @param embeddingMode the embedding mode
- */
- void setEmbeddingMode(EmbeddingMode embeddingMode);
-
- /**
- * Sets the capital height value.
- * @param capHeight capital height
- */
- void setCapHeight(int capHeight);
-
- /**
- * Sets the ascent value.
- * @param ascender ascent height
- */
- void setAscender(int ascender);
-
- /**
- * Sets the descent value.
- * @param descender descent value
- */
- void setDescender(int descender);
-
- /**
- * Sets the font's bounding box
- * @param bbox bounding box
- */
- void setFontBBox(int[] bbox);
-
- /**
- * Sets the font's flags
- * @param flags flags
- */
- void setFlags(int flags);
-
- /**
- * Sets the font's StemV value.
- * @param stemV StemV
- */
- void setStemV(int stemV);
-
- /**
- * Sets the font's italic angle.
- * @param italicAngle italic angle
- */
- void setItalicAngle(int italicAngle);
-
- /**
- * Sets the font's default width
- * @param width default width
- */
- void setMissingWidth(int width);
-
- /**
- * Sets the font type.
- * @param fontType font type
- */
- void setFontType(FontType fontType);
-
- /**
- * Sets the index of the first character in the character table.
- * @param index index of first character
- */
- void setFirstChar(int index);
-
- /**
- * Sets the index of the last character in the character table.
- * @param index index of the last character
- */
- void setLastChar(int index);
-
- /**
- * Enables/disabled kerning.
- * @param enabled True if kerning should be enabled if available
- */
- void setKerningEnabled(boolean enabled);
-
- /**
- * Enables/disabled advanced typographic features.
- * @param enabled true if advanced typographic features should be enabled if available
- */
- void setAdvancedEnabled(boolean enabled);
-
- /**
- * Adds an entry to the kerning table.
- * @param key Kerning key
- * @param value Kerning value
- */
- void putKerningEntry(Integer key, Map<Integer, Integer> value);
-
-}
diff --git a/src/java/org/apache/fop/fonts/NamedCharacter.java b/src/java/org/apache/fop/fonts/NamedCharacter.java
deleted file mode 100644
index 9877ec6ec..000000000
--- a/src/java/org/apache/fop/fonts/NamedCharacter.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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 org.apache.xmlgraphics.fonts.Glyphs;
-
-import org.apache.fop.util.CharUtilities;
-
-/**
- * Represents an named character with character name (from the Adobe glyph list) and a Unicode
- * sequence that this character represents.
- */
-public class NamedCharacter {
-
- private String charName;
- private String unicodeSequence;
-
- /**
- * Main constructor.
- * @param charName the character name
- * @param unicodeSequence the Unicode sequence associated with this character
- */
- public NamedCharacter(String charName, String unicodeSequence) {
- if (charName == null) {
- throw new NullPointerException("charName must not be null");
- }
- this.charName = charName;
- if (unicodeSequence != null) {
- this.unicodeSequence = unicodeSequence;
- } else {
- this.unicodeSequence = Glyphs.getUnicodeSequenceForGlyphName(charName);
- }
- }
-
- /**
- * Simple constructor.
- * @param charName the character name
- */
- public NamedCharacter(String charName) {
- this(charName, null);
- }
-
- /** {@inheritDoc} */
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((charName == null) ? 0 : charName.hashCode());
- return result;
- }
-
- /** {@inheritDoc} */
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final NamedCharacter other = (NamedCharacter)obj;
- return charName.equals(other.charName);
- }
-
- /**
- * Returns the character name (as defined by the Adobe glyph list).
- * @return the character name
- */
- public String getName() {
- return this.charName;
- }
-
- /**
- * Returns the Unicode sequence associated with this character.
- * @return the Unicode sequence (or null if no Unicode sequence is associated)
- */
- public String getUnicodeSequence() {
- return this.unicodeSequence;
- }
-
- /**
- * Indicates whether a single Unicode value is associated with this character.
- * @return true if exactly one Unicode value is associated with this character, false otherwise
- */
- public boolean hasSingleUnicodeValue() {
- return (this.unicodeSequence != null && this.unicodeSequence.length() == 1);
- }
-
- /**
- * Returns the single Unicode value associated with this named character. Check
- * {@link #hasSingleUnicodeValue()} before you call this method because an
- * IllegalStateException is thrown is a Unicode sequence with more than one character is
- * associated with this character.
- * @return the single Unicode value (or FFFF ("NOT A CHARACTER") if no Unicode value is
- * available)
- * @throws IllegalStateException if a Unicode sequence with more than one value is associated
- * with the named character
- */
- public char getSingleUnicodeValue() throws IllegalStateException {
- if (this.unicodeSequence == null) {
- return CharUtilities.NOT_A_CHARACTER;
- }
- if (this.unicodeSequence.length() > 1) {
- throw new IllegalStateException("getSingleUnicodeValue() may not be called for a"
- + " named character that has more than one Unicode value (a sequence)"
- + " associated with the named character!");
- }
- return this.unicodeSequence.charAt(0);
- }
-
- /** {@inheritDoc} */
- public String toString() {
- StringBuffer sb = new StringBuffer(this.unicodeSequence);
- sb.append(" (");
- if (this.unicodeSequence != null) {
- for (int i = 0, c = this.unicodeSequence.length(); i < c; i++) {
- sb.append("0x").append(Integer.toHexString(this.unicodeSequence.charAt(0)));
- }
- sb.append(", ");
- }
- sb.append(getName()).append(')');
- return sb.toString();
- }
-}
diff --git a/src/java/org/apache/fop/fonts/SimpleSingleByteEncoding.java b/src/java/org/apache/fop/fonts/SimpleSingleByteEncoding.java
deleted file mode 100644
index 0180d4540..000000000
--- a/src/java/org/apache/fop/fonts/SimpleSingleByteEncoding.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * 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.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.xmlgraphics.fonts.Glyphs;
-
-import org.apache.fop.util.CharUtilities;
-
-/**
- * A simple implementation of the OneByteEncoding mostly used for encodings that are constructed
- * on-the-fly.
- */
-public class SimpleSingleByteEncoding implements SingleByteEncoding {
-
- private final String name;
- private final List<NamedCharacter> mapping = new ArrayList<NamedCharacter>();
- private final Map<Character, Character> charMap = new HashMap<Character, Character>();
-
- /**
- * Main constructor.
- * @param name the encoding's name
- */
- public SimpleSingleByteEncoding(String name) {
- this.name = name;
- }
-
- /** {@inheritDoc} */
- public String getName() {
- return this.name;
- }
-
- /** {@inheritDoc} */
- public char mapChar(char c) {
- Character nc = charMap.get(Character.valueOf(c));
- if (nc != null) {
- return nc.charValue();
- }
- return NOT_FOUND_CODE_POINT;
- }
-
- /** {@inheritDoc} */
- public String[] getCharNameMap() {
- String[] map = new String[getSize()];
- Arrays.fill(map, Glyphs.NOTDEF);
- for (int i = getFirstChar(); i <= getLastChar(); i++) {
- NamedCharacter ch = this.mapping.get(i - 1);
- map[i] = ch.getName();
- }
- return map;
- }
-
- /**
- * Returns the index of the first defined character.
- * @return the index of the first defined character (always 1 for this class)
- */
- public int getFirstChar() {
- return 1;
- }
-
- /**
- * Returns the index of the last defined character.
- * @return the index of the last defined character
- */
- public int getLastChar() {
- return this.mapping.size();
- }
-
- /**
- * Returns the number of characters defined by this encoding.
- * @return the number of characters
- */
- public int getSize() {
- return this.mapping.size() + 1;
- }
-
- /**
- * Indicates whether the encoding is full (with 256 code points).
- * @return true if the encoding is full
- */
- public boolean isFull() {
- return (getSize() == 256);
- }
-
- /**
- * Adds a new character to the encoding.
- * @param ch the named character
- * @return the code point assigned to the character
- */
- public char addCharacter(NamedCharacter ch) {
- if (!ch.hasSingleUnicodeValue()) {
- throw new IllegalArgumentException("Only NamedCharacters with a single Unicode value"
- + " are currently supported!");
- }
- if (isFull()) {
- throw new IllegalStateException("Encoding is full!");
- }
- char newSlot = (char)(getLastChar() + 1);
- this.mapping.add(ch);
- this.charMap.put(Character.valueOf(ch.getSingleUnicodeValue()), Character.valueOf(newSlot));
- return newSlot;
- }
-
- /**
- * Returns the named character at a given code point in the encoding.
- * @param codePoint the code point of the character
- * @return the NamedCharacter (or null if no character is at this position)
- */
- public NamedCharacter getCharacterForIndex(int codePoint) {
- if (codePoint < 0 || codePoint > 255) {
- throw new IllegalArgumentException("codePoint must be between 0 and 255");
- }
- if (codePoint <= getLastChar()) {
- return this.mapping.get(codePoint - 1);
- } else {
- return null;
- }
- }
-
- /** {@inheritDoc} */
- public char[] getUnicodeCharMap() {
- char[] map = new char[getLastChar() + 1];
- for (int i = 0; i < getFirstChar(); i++) {
- map[i] = CharUtilities.NOT_A_CHARACTER;
- }
- for (int i = getFirstChar(); i <= getLastChar(); i++) {
- map[i] = getCharacterForIndex(i).getSingleUnicodeValue();
- }
- return map;
- }
-
- /** {@inheritDoc} */
- @Override
- public String toString() {
- return getName() + " (" + getSize() + " chars)";
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/SingleByteEncoding.java b/src/java/org/apache/fop/fonts/SingleByteEncoding.java
deleted file mode 100644
index ad9d691f6..000000000
--- a/src/java/org/apache/fop/fonts/SingleByteEncoding.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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;
-
-/**
- * The interface defines a 1-byte character encoding (with 256 characters).
- */
-public interface SingleByteEncoding {
-
- /** Code point that is used if no code point for a specific character has been found. */
- char NOT_FOUND_CODE_POINT = '\0';
-
- /**
- * Returns the encoding's name.
- * @return the name of the encoding
- */
- String getName();
-
- /**
- * Maps a Unicode character to a code point in the encoding.
- * @param c the Unicode character to map
- * @return the code point in the encoding or 0 (=.notdef) if not found
- */
- char mapChar(char c);
-
- /**
- * Returns the array of character names for this encoding.
- * @return the array of character names
- * (unmapped code points are represented by a ".notdef" value)
- */
- String[] getCharNameMap();
-
- /**
- * Returns a character array with Unicode scalar values which can be used to map encoding
- * code points to Unicode values. Note that this does not return all possible Unicode values
- * that the encoding maps.
- * @return a character array with Unicode scalar values
- */
- char[] getUnicodeCharMap();
-
-}
diff --git a/src/java/org/apache/fop/fonts/SingleByteFont.java b/src/java/org/apache/fop/fonts/SingleByteFont.java
deleted file mode 100644
index e3037a524..000000000
--- a/src/java/org/apache/fop/fonts/SingleByteFont.java
+++ /dev/null
@@ -1,552 +0,0 @@
-/*
- * 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.awt.Rectangle;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.xmlgraphics.fonts.Glyphs;
-
-import org.apache.fop.apps.io.InternalResourceResolver;
-import org.apache.fop.fonts.truetype.OpenFont.PostScriptVersion;
-import org.apache.fop.util.CharUtilities;
-
-/**
- * Generic SingleByte font
- */
-public class SingleByteFont extends CustomFont {
-
- /** logger */
- private static Log log = LogFactory.getLog(SingleByteFont.class);
-
- protected SingleByteEncoding mapping;
- private boolean useNativeEncoding;
-
- protected int[] width;
-
- private Rectangle[] boundingBoxes;
-
- private Map<Character, UnencodedCharacter> unencodedCharacters;
- private List<SimpleSingleByteEncoding> additionalEncodings;
- private Map<Character, Character> alternativeCodes;
-
- private PostScriptVersion ttPostScriptVersion;
-
- private int usedGlyphsCount;
- private LinkedHashMap<Integer, String> usedGlyphNames;
- private Map<Integer, Integer> usedGlyphs;
- private Map<Integer, Character> usedCharsIndex;
- private Map<Character, Integer> charGIDMappings;
-
- public SingleByteFont(InternalResourceResolver resourceResolver) {
- super(resourceResolver);
- setEncoding(CodePointMapping.WIN_ANSI_ENCODING);
- }
-
- public SingleByteFont(InternalResourceResolver resourceResolver, EmbeddingMode embeddingMode) {
- this(resourceResolver);
- setEmbeddingMode(embeddingMode);
- if (embeddingMode != EmbeddingMode.FULL) {
- usedGlyphNames = new LinkedHashMap<Integer, String>();
- usedGlyphs = new HashMap<Integer, Integer>();
- usedCharsIndex = new HashMap<Integer, Character>();
- charGIDMappings = new HashMap<Character, Integer>();
-
- // The zeroth value is reserved for .notdef
- usedGlyphs.put(0, 0);
- usedGlyphsCount++;
- }
- }
-
- /** {@inheritDoc} */
- public boolean isEmbeddable() {
- return (!(getEmbedFileURI() == null
- && getEmbedResourceName() == null));
- }
-
- /** {@inheritDoc} */
- public boolean isSubsetEmbedded() {
- return getEmbeddingMode() != EmbeddingMode.FULL;
- }
-
- /** {@inheritDoc} */
- public String getEncodingName() {
- return this.mapping.getName();
- }
-
- /**
- * Returns the code point mapping (encoding) of this font.
- * @return the code point mapping
- */
- public SingleByteEncoding getEncoding() {
- return this.mapping;
- }
-
- /** {@inheritDoc} */
- public int getWidth(int i, int size) {
- if (i < 256) {
- int idx = i - getFirstChar();
- if (idx >= 0 && idx < width.length) {
- return size * width[idx];
- }
- } else if (this.additionalEncodings != null) {
- int encodingIndex = (i / 256) - 1;
- SimpleSingleByteEncoding encoding = getAdditionalEncoding(encodingIndex);
- int codePoint = i % 256;
- NamedCharacter nc = encoding.getCharacterForIndex(codePoint);
- UnencodedCharacter uc
- = this.unencodedCharacters.get(Character.valueOf(nc.getSingleUnicodeValue()));
- return size * uc.getWidth();
- }
- return 0;
- }
-
- /** {@inheritDoc} */
- public int[] getWidths() {
- int[] arr = new int[width.length];
- System.arraycopy(width, 0, arr, 0, width.length);
- return arr;
- }
-
- public Rectangle getBoundingBox(int glyphIndex, int size) {
- Rectangle bbox = null;
- if (glyphIndex < 256) {
- int idx = glyphIndex - getFirstChar();
- if (idx >= 0 && idx < boundingBoxes.length) {
- bbox = boundingBoxes[idx];
- }
- } else if (this.additionalEncodings != null) {
- int encodingIndex = (glyphIndex / 256) - 1;
- SimpleSingleByteEncoding encoding = getAdditionalEncoding(encodingIndex);
- int codePoint = glyphIndex % 256;
- NamedCharacter nc = encoding.getCharacterForIndex(codePoint);
- UnencodedCharacter uc = this.unencodedCharacters.get(Character.valueOf(nc.getSingleUnicodeValue()));
- bbox = uc.getBBox();
- }
- return bbox == null ? null : new Rectangle(bbox.x * size, bbox.y * size, bbox.width * size, bbox.height * size);
- }
-
- /**
- * Lookup a character using its alternative names. If found, cache it so we
- * can speed up lookups.
- * @param c the character
- * @return the suggested alternative character present in the font
- */
- private char findAlternative(char c) {
- char d;
- if (alternativeCodes == null) {
- alternativeCodes = new java.util.HashMap<Character, Character>();
- } else {
- Character alternative = alternativeCodes.get(c);
- if (alternative != null) {
- return alternative;
- }
- }
- String charName = Glyphs.charToGlyphName(c);
- String[] charNameAlternatives = Glyphs.getCharNameAlternativesFor(charName);
- if (charNameAlternatives != null && charNameAlternatives.length > 0) {
- for (int i = 0; i < charNameAlternatives.length; i++) {
- if (log.isDebugEnabled()) {
- log.debug("Checking alternative for char " + c + " (charname="
- + charName + "): " + charNameAlternatives[i]);
- }
- String s = Glyphs.getUnicodeSequenceForGlyphName(charNameAlternatives[i]);
- if (s != null) {
- d = lookupChar(s.charAt(0));
- if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) {
- alternativeCodes.put(c, d);
- return d;
- }
- }
- }
- }
-
- return SingleByteEncoding.NOT_FOUND_CODE_POINT;
- }
-
- private char lookupChar(char c) {
- char d = mapping.mapChar(c);
- if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) {
- return d;
- }
-
- // Check unencoded characters which are available in the font by
- // character name
- d = mapUnencodedChar(c);
- return d;
- }
-
- private boolean isSubset() {
- return getEmbeddingMode() == EmbeddingMode.SUBSET;
- }
-
- /** {@inheritDoc} */
- @Override
- public char mapChar(char c) {
- notifyMapOperation();
- char d = lookupChar(c);
- if (d == SingleByteEncoding.NOT_FOUND_CODE_POINT) {
- // Check for alternative
- d = findAlternative(c);
- if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) {
- return d;
- } else {
- this.warnMissingGlyph(c);
- return Typeface.NOT_FOUND;
- }
- }
- if (isEmbeddable() && isSubset()) {
- mapChar(d, c);
- }
- return d;
- }
-
- private int mapChar(int glyphIndex, char unicode) {
- // Reencode to a new subset font or get the reencoded value
- // IOW, accumulate the accessed characters and build a character map for them
- Integer subsetCharSelector = usedGlyphs.get(glyphIndex);
- if (subsetCharSelector == null) {
- int selector = usedGlyphsCount;
- usedGlyphs.put(glyphIndex, selector);
- usedCharsIndex.put(selector, unicode);
- charGIDMappings.put(unicode, glyphIndex);
- usedGlyphsCount++;
- return selector;
- } else {
- return subsetCharSelector;
- }
- }
-
- private char getUnicode(int index) {
- Character mapValue = usedCharsIndex.get(index);
- if (mapValue != null) {
- return mapValue.charValue();
- } else {
- return CharUtilities.NOT_A_CHARACTER;
- }
- }
-
- private char mapUnencodedChar(char ch) {
- if (this.unencodedCharacters != null) {
- UnencodedCharacter unencoded = this.unencodedCharacters.get(Character.valueOf(ch));
- if (unencoded != null) {
- if (this.additionalEncodings == null) {
- this.additionalEncodings = new ArrayList<SimpleSingleByteEncoding>();
- }
- SimpleSingleByteEncoding encoding = null;
- char mappedStart = 0;
- int additionalsCount = this.additionalEncodings.size();
- for (int i = 0; i < additionalsCount; i++) {
- mappedStart += 256;
- encoding = getAdditionalEncoding(i);
- char alt = encoding.mapChar(ch);
- if (alt != 0) {
- return (char)(mappedStart + alt);
- }
- }
- if (encoding != null && encoding.isFull()) {
- encoding = null;
- }
- if (encoding == null) {
- encoding = new SimpleSingleByteEncoding(
- getFontName() + "EncodingSupp" + (additionalsCount + 1));
- this.additionalEncodings.add(encoding);
- mappedStart += 256;
- }
- return (char)(mappedStart + encoding.addCharacter(unencoded.getCharacter()));
- }
- }
- return 0;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean hasChar(char c) {
- char d = mapping.mapChar(c);
- if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) {
- return true;
- }
- //Check unencoded characters which are available in the font by character name
- d = mapUnencodedChar(c);
- if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) {
- return true;
- }
- // Check if an alternative exists
- d = findAlternative(c);
- if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) {
- return true;
- }
- return false;
- }
-
- /* ---- single byte font specific setters --- */
-
- /**
- * Updates the mapping variable based on the encoding.
- * @param encoding the name of the encoding
- */
- protected void updateMapping(String encoding) {
- try {
- this.mapping = CodePointMapping.getMapping(encoding);
- } catch (UnsupportedOperationException e) {
- log.error("Font '" + super.getFontName() + "': " + e.getMessage());
- }
- }
-
- /**
- * Sets the encoding of the font.
- * @param encoding the encoding (ex. "WinAnsiEncoding" or "SymbolEncoding")
- */
- public void setEncoding(String encoding) {
- updateMapping(encoding);
- }
-
- /**
- * Sets the encoding of the font.
- * @param encoding the encoding information
- */
- public void setEncoding(CodePointMapping encoding) {
- this.mapping = encoding;
- }
-
- /**
- * Controls whether the font is configured to use its native encoding or if it
- * may need to be re-encoded for the target format.
- * @param value true indicates that the configured encoding is the font's native encoding
- */
- public void setUseNativeEncoding(boolean value) {
- this.useNativeEncoding = value;
- }
-
- /**
- * Indicates whether this font is configured to use its native encoding. This
- * method is used to determine whether the font needs to be re-encoded.
- * @return true if the font uses its native encoding.
- */
- public boolean isUsingNativeEncoding() {
- return this.useNativeEncoding;
- }
-
- /**
- * Sets a width for a character.
- * @param index index of the character
- * @param w the width of the character
- */
- public void setWidth(int index, int w) {
- if (this.width == null) {
- this.width = new int[getLastChar() - getFirstChar() + 1];
- }
- this.width[index - getFirstChar()] = w;
- }
-
- public void setBoundingBox(int index, Rectangle bbox) {
- if (this.boundingBoxes == null) {
- this.boundingBoxes = new Rectangle[getLastChar() - getFirstChar() + 1];
- }
- this.boundingBoxes[index - getFirstChar()] = bbox;
- }
-
- /**
- * Adds an unencoded character (one that is not supported by the primary encoding).
- * @param ch the named character
- * @param width the width of the character
- */
- public void addUnencodedCharacter(NamedCharacter ch, int width, Rectangle bbox) {
- if (this.unencodedCharacters == null) {
- this.unencodedCharacters = new HashMap<Character, UnencodedCharacter>();
- }
- if (ch.hasSingleUnicodeValue()) {
- UnencodedCharacter uc = new UnencodedCharacter(ch, width, bbox);
- this.unencodedCharacters.put(Character.valueOf(ch.getSingleUnicodeValue()), uc);
- } else {
- //Cannot deal with unicode sequences, so ignore this character
- }
- }
-
- /**
- * Makes all unencoded characters available through additional encodings. This method
- * is used in cases where the fonts need to be encoded in the target format before
- * all text of the document is processed (for example in PostScript when resource optimization
- * is disabled).
- */
- public void encodeAllUnencodedCharacters() {
- if (this.unencodedCharacters != null) {
- Set<Character> sortedKeys = new TreeSet<Character>(this.unencodedCharacters.keySet());
- for (Character ch : sortedKeys) {
- char mapped = mapChar(ch.charValue());
- assert mapped != Typeface.NOT_FOUND;
- }
- }
- }
-
- /**
- * Indicates whether the encoding has additional encodings besides the primary encoding.
- * @return true if there are additional encodings.
- */
- public boolean hasAdditionalEncodings() {
- return (this.additionalEncodings != null) && (this.additionalEncodings.size() > 0);
- }
-
- /**
- * Returns the number of additional encodings this single-byte font maintains.
- * @return the number of additional encodings
- */
- public int getAdditionalEncodingCount() {
- if (hasAdditionalEncodings()) {
- return this.additionalEncodings.size();
- } else {
- return 0;
- }
- }
-
- /**
- * Returns an additional encoding.
- * @param index the index of the additional encoding
- * @return the additional encoding
- * @throws IndexOutOfBoundsException if the index is out of bounds
- */
- public SimpleSingleByteEncoding getAdditionalEncoding(int index)
- throws IndexOutOfBoundsException {
- if (hasAdditionalEncodings()) {
- return this.additionalEncodings.get(index);
- } else {
- throw new IndexOutOfBoundsException("No additional encodings available");
- }
- }
-
- /**
- * Returns an array with the widths for an additional encoding.
- * @param index the index of the additional encoding
- * @return the width array
- */
- public int[] getAdditionalWidths(int index) {
- SimpleSingleByteEncoding enc = getAdditionalEncoding(index);
- int[] arr = new int[enc.getLastChar() - enc.getFirstChar() + 1];
- for (int i = 0, c = arr.length; i < c; i++) {
- NamedCharacter nc = enc.getCharacterForIndex(enc.getFirstChar() + i);
- UnencodedCharacter uc = this.unencodedCharacters.get(
- Character.valueOf(nc.getSingleUnicodeValue()));
- arr[i] = uc.getWidth();
- }
- return arr;
- }
-
- private static final class UnencodedCharacter {
-
- private final NamedCharacter character;
- private final int width;
- private final Rectangle bbox;
-
- public UnencodedCharacter(NamedCharacter character, int width, Rectangle bbox) {
- this.character = character;
- this.width = width;
- this.bbox = bbox;
- }
-
- public NamedCharacter getCharacter() {
- return this.character;
- }
-
- public int getWidth() {
- return this.width;
- }
-
- public Rectangle getBBox() {
- return bbox;
- }
-
- /** {@inheritDoc} */
- @Override
- public String toString() {
- return getCharacter().toString();
- }
- }
-
- /**
- * Sets the version of the PostScript table stored in the TrueType font represented by
- * this instance.
- *
- * @param version version of the <q>post</q> table
- */
- public void setTrueTypePostScriptVersion(PostScriptVersion version) {
- ttPostScriptVersion = version;
- }
-
- /**
- * Returns the version of the PostScript table stored in the TrueType font represented by
- * this instance.
- *
- * @return the version of the <q>post</q> table
- */
- public PostScriptVersion getTrueTypePostScriptVersion() {
- assert getFontType() == FontType.TRUETYPE;
- return ttPostScriptVersion;
- }
-
- /**
- * Returns a Map of used Glyphs.
- * @return Map Map of used Glyphs
- */
- public Map<Integer, Integer> getUsedGlyphs() {
- return Collections.unmodifiableMap(usedGlyphs);
- }
-
- public char getUnicodeFromSelector(int selector) {
- return getUnicode(selector);
- }
-
- public int getGIDFromChar(char ch) {
- return charGIDMappings.get(ch);
- }
-
- public char getUnicodeFromGID(int glyphIndex) {
- int selector = usedGlyphs.get(glyphIndex);
- return usedCharsIndex.get(selector);
- }
-
- public void mapUsedGlyphName(int gid, String value) {
- usedGlyphNames.put(gid, value);
- }
-
- public Map<Integer, String> getUsedGlyphNames() {
- return usedGlyphNames;
- }
-
- public String getGlyphName(int idx) {
- if (idx < mapping.getCharNameMap().length) {
- return mapping.getCharNameMap()[idx];
- } else {
- int selector = usedGlyphs.get(idx);
- char theChar = usedCharsIndex.get(selector);
- return unencodedCharacters.get(theChar).getCharacter().getName();
- }
- }
-}
-
diff --git a/src/java/org/apache/fop/fonts/TextFragment.java b/src/java/org/apache/fop/fonts/TextFragment.java
deleted file mode 100644
index 8722ecf2e..000000000
--- a/src/java/org/apache/fop/fonts/TextFragment.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.text.CharacterIterator;
-
-/**
- * Encapsulates a sub-sequence (fragement) of a text iterator (or other text source),
- * where begin index and end index are indices into larger text iterator that denote
- * [begin,end) of sub-sequence range. Additionally associated with a designated script
- * (or "auto"), a designated language (or "none"), and a (single) bidi level (or -1
- * if not known).
- */
-public interface TextFragment {
-
- /**
- * Obtain reference to underlying iterator.
- */
- CharacterIterator getIterator();
-
- /**
- * Obtain beginning index (inclusive) of sub-sequence of fragment in overall text source.
- */
- int getBeginIndex();
-
- /**
- * Obtain ending index (exclusive) of sub-sequence of fragment in overall text source.
- */
- int getEndIndex();
-
- /**
- * Obtain associated script (if designated) or "auto" if not.
- */
- String getScript();
-
- /**
- * Obtain associated language (if designated) or "none" if not.
- */
- String getLanguage();
-
- /**
- * Obtain associated bidi level (if known) or -1 if not.
- */
- int getBidiLevel();
-
- /**
- * Obtain character at specified index within this fragment's sub-sequence,
- * where index 0 corresponds to beginning index in overal text source, and
- * subSequenceIndex must be less than ending index - beginning index.
- */
- char charAt(int subSequenceIndex);
-
- CharSequence subSequence(int startIndex, int endIndex);
-}
diff --git a/src/java/org/apache/fop/fonts/Typeface.java b/src/java/org/apache/fop/fonts/Typeface.java
deleted file mode 100644
index 3232d7605..000000000
--- a/src/java/org/apache/fop/fonts/Typeface.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * 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.util.HashSet;
-import java.util.Set;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.xmlgraphics.fonts.Glyphs;
-
-/**
- * Base class for font classes
- */
-public abstract class Typeface implements FontMetrics {
-
- /**
- * Code point that is used if no code point for a specific character has
- * been found.
- */
- public static final char NOT_FOUND = '#';
-
- /** logger */
- private static Log log = LogFactory.getLog(Typeface.class);
-
- /**
- * Used to identify whether a font has been used (a character map operation
- * is used as the trigger). This could just as well be a boolean but is a
- * long out of statistical interest.
- */
- private long charMapOps;
-
- /** An optional event listener that receives events such as missing glyphs etc. */
- protected FontEventListener eventListener;
-
- private Set<Character> warnedChars;
-
- /**
- * Get the encoding of the font.
- * @return the encoding
- */
- public abstract String getEncodingName();
-
- /**
- * Map a Unicode character to a code point in the font.
- * @param c character to map
- * @return the mapped character
- */
- public abstract char mapChar(char c);
-
- /**
- * Used for keeping track of character mapping operations in order to determine if a font
- * was used at all or not.
- */
- protected void notifyMapOperation() {
- this.charMapOps++;
- }
-
- /**
- * Indicates whether this font had to do any character mapping operations. If that was
- * not the case, it's an indication that the font has never actually been used.
- * @return true if the font had to do any character mapping operations
- */
- public boolean hadMappingOperations() {
- return (this.charMapOps > 0);
- }
-
- /**
- * Determines whether this font contains a particular character/glyph.
- * @param c character to check
- * @return True if the character is supported, Falso otherwise
- */
- public abstract boolean hasChar(char c);
-
- /**
- * Determines whether the font is a multibyte font.
- * @return True if it is multibyte
- */
- public boolean isMultiByte() {
- return false;
- }
-
- /** {@inheritDoc} */
- public int getMaxAscent(int size) {
- return getAscender(size);
- }
-
- /** {@inheritDoc} */
- public boolean hasFeature(int tableType, String script, String language, String feature) {
- return false;
- }
-
- /**
- * Sets the font event listener that can be used to receive events about particular events
- * in this class.
- * @param listener the font event listener
- */
- public void setEventListener(FontEventListener listener) {
- this.eventListener = listener;
- }
-
- /**
- * Provide proper warning if a glyph is not available.
- *
- * @param c
- * the character which is missing.
- */
- protected void warnMissingGlyph(char c) {
- // Give up, character is not available
- Character ch = new Character(c);
- if (warnedChars == null) {
- warnedChars = new HashSet<Character>();
- }
- if (warnedChars.size() < 8 && !warnedChars.contains(ch)) {
- warnedChars.add(ch);
- if (this.eventListener != null) {
- this.eventListener.glyphNotAvailable(this, c, getFontName());
- } else {
- if (warnedChars.size() == 8) {
- log.warn("Many requested glyphs are not available in font "
- + getFontName());
- } else {
- log.warn("Glyph " + (int) c + " (0x"
- + Integer.toHexString(c) + ", "
- + Glyphs.charToGlyphName(c)
- + ") not available in font " + getFontName());
- }
- }
- }
- }
-
- /** {@inheritDoc} */
- public String toString() {
- StringBuffer sbuf = new StringBuffer(super.toString());
- sbuf.append('{');
- sbuf.append(getFullName());
- sbuf.append('}');
- return sbuf.toString();
- }
-}
diff --git a/src/java/org/apache/fop/fonts/apps/AbstractFontReader.java b/src/java/org/apache/fop/fonts/apps/AbstractFontReader.java
deleted file mode 100644
index 4aa9b77a2..000000000
--- a/src/java/org/apache/fop/fonts/apps/AbstractFontReader.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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.apps;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.List;
-import java.util.Map;
-
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Abstract base class for the PFM and TTF Reader command-line applications.
- */
-public abstract class AbstractFontReader {
-
- /** Logger instance */
- protected static final Log log = LogFactory.getLog(AbstractFontReader.class);
-
- /**
- * Main constructor.
- */
- protected AbstractFontReader() {
- }
-
- /**
- * Parse commandline arguments. put options in the HashMap and return
- * arguments in the String array
- * the arguments: -fn Perpetua,Bold -cn PerpetuaBold per.ttf Perpetua.xml
- * returns a String[] with the per.ttf and Perpetua.xml. The hash
- * will have the (key, value) pairs: (-fn, Perpetua) and (-cn, PerpetuaBold)
- * @param options Map that will receive options
- * @param args the command-line arguments
- * @return the arguments
- */
- protected static String[] parseArguments(Map options, String[] args) {
- List arguments = new java.util.ArrayList();
- for (int i = 0; i < args.length; i++) {
- if (args[i].startsWith("-")) {
- if ("-t".equals(args[i]) || "-d".equals(args[i]) || "-q".equals(args[i])) {
- options.put(args[i], "");
- } else if ((i + 1) < args.length && !args[i + 1].startsWith("-")) {
- options.put(args[i], args[i + 1]);
- i++;
- } else {
- options.put(args[i], "");
- }
- } else {
- arguments.add(args[i]);
- }
- }
- return (String[])arguments.toArray(new String[arguments.size()]);
- }
-
- /**
- * Sets the logging level.
- * @param level the logging level ("debug", "info", "error" etc., see Jakarta Commons Logging)
- */
- protected static void setLogLevel(String level) {
- // Set the evel for future loggers.
- LogFactory.getFactory().setAttribute("level", level);
- }
-
- /**
- * Determines the log level based of the options from the command-line.
- * @param options the command-line options
- */
- protected static void determineLogLevel(Map options) {
- //Determine log level
- if (options.get("-t") != null) {
- setLogLevel("trace");
- } else if (options.get("-d") != null) {
- setLogLevel("debug");
- } else if (options.get("-q") != null) {
- setLogLevel("error");
- } else {
- setLogLevel("info");
- }
- }
-
- /**
- * Writes the generated DOM Document to a file.
- *
- * @param doc The DOM Document to save.
- * @param target The target filename for the XML file.
- * @throws TransformerException if an error occurs during serialization
- */
- public void writeFontXML(org.w3c.dom.Document doc, String target) throws TransformerException {
- writeFontXML(doc, new File(target));
- }
-
- /**
- * Writes the generated DOM Document to a file.
- *
- * @param doc The DOM Document to save.
- * @param target The target file for the XML file.
- * @throws TransformerException if an error occurs during serialization
- */
- public void writeFontXML(org.w3c.dom.Document doc, File target) throws TransformerException {
- log.info("Writing xml font file " + target + "...");
-
- try {
- OutputStream out = new java.io.FileOutputStream(target);
- out = new java.io.BufferedOutputStream(out);
- try {
- TransformerFactory factory = TransformerFactory.newInstance();
- Transformer transformer = factory.newTransformer();
- transformer.transform(
- new javax.xml.transform.dom.DOMSource(doc),
- new javax.xml.transform.stream.StreamResult(out));
- } finally {
- out.close();
- }
- } catch (IOException ioe) {
- throw new TransformerException("Error writing the output file", ioe);
- }
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/apps/PFMReader.java b/src/java/org/apache/fop/fonts/apps/PFMReader.java
deleted file mode 100644
index dd7f7343c..000000000
--- a/src/java/org/apache/fop/fonts/apps/PFMReader.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * 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.apps;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Iterator;
-import java.util.Map;
-
-import javax.xml.parsers.DocumentBuilderFactory;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import org.apache.fop.Version;
-import org.apache.fop.fonts.type1.PFMFile;
-
-/**
- * A tool which reads PFM files from Adobe Type 1 fonts and creates
- * XML font metrics file for use in FOP.
- */
-public class PFMReader extends AbstractFontReader {
-
- /**
- * Main constructor.
- */
- public PFMReader() {
- super();
- }
-
- private static void displayUsage() {
- System.out.println(
- "java " + PFMReader.class.getName() + " [options] metricfile.pfm xmlfile.xml");
- System.out.println();
- System.out.println("where options can be:");
- System.out.println("-d Debug mode");
- System.out.println("-q Quiet mode");
- System.out.println("-fn <fontname>");
- System.out.println(" default is to use the fontname in the .pfm file, but");
- System.out.println(" you can override that name to make sure that the");
- System.out.println(" embedded font is used (if you're embedding fonts)");
- System.out.println(" instead of installed fonts when viewing documents ");
- System.out.println(" with Acrobat Reader.");
- }
-
-
- /**
- * The main method for the PFM reader tool.
- *
- * @param args Command-line arguments: [options] metricfile.pfm xmlfile.xml
- * where options can be:
- * -fn <fontname>
- * default is to use the fontname in the .pfm file, but you can override
- * that name to make sure that the embedded font is used instead of installed
- * fonts when viewing documents with Acrobat Reader.
- * -cn <classname>
- * default is to use the fontname
- * -ef <path to the Type1 .pfb fontfile>
- * will add the possibility to embed the font. When running fop, fop will look
- * for this file to embed it
- * -er <path to Type1 fontfile relative to org/apache/fop/render/pdf/fonts>
- * you can also include the fontfile in the fop.jar file when building fop.
- * You can use both -ef and -er. The file specified in -ef will be searched first,
- * then the -er file.
- */
- public static void main(String[] args) {
- String embFile = null;
- String embResource = null;
- String className = null;
- String fontName = null;
-
- Map options = new java.util.HashMap();
- String[] arguments = parseArguments(options, args);
-
- determineLogLevel(options);
-
- PFMReader app = new PFMReader();
-
- log.info("PFM Reader for Apache FOP " + Version.getVersion() + "\n");
-
- if (options.get("-ef") != null) {
- embFile = (String)options.get("-ef");
- }
-
- if (options.get("-er") != null) {
- embResource = (String)options.get("-er");
- }
-
- if (options.get("-fn") != null) {
- fontName = (String)options.get("-fn");
- }
-
- if (options.get("-cn") != null) {
- className = (String)options.get("-cn");
- }
-
- if (arguments.length != 2 || options.get("-h") != null
- || options.get("-help") != null || options.get("--help") != null) {
- displayUsage();
- } else {
- try {
- log.info("Parsing font...");
- PFMFile pfm = app.loadPFM(arguments[0]);
- if (pfm != null) {
- app.preview(pfm);
-
- Document doc = app.constructFontXML(pfm,
- fontName, className, embResource, embFile);
-
- app.writeFontXML(doc, arguments[1]);
- }
- log.info("XML font metrics file successfullly created.");
- } catch (Exception e) {
- log.error("Error while building XML font metrics file", e);
- System.exit(-1);
- }
- }
- }
-
- /**
- * Read a PFM file and returns it as an object.
- *
- * @param filename The filename of the PFM file.
- * @return The PFM as an object.
- * @throws IOException In case of an I/O problem
- */
- public PFMFile loadPFM(String filename) throws IOException {
- log.info("Reading " + filename + "...");
- log.info("");
- InputStream in = new java.io.FileInputStream(filename);
- try {
- PFMFile pfm = new PFMFile();
- pfm.load(in);
- return pfm;
- } finally {
- in.close();
- }
- }
-
- /**
- * Displays a preview of the PFM file on the console.
- *
- * @param pfm The PFM file to preview.
- */
- public void preview(PFMFile pfm) {
- if (log != null && log.isInfoEnabled()) {
- log.info("Font: " + pfm.getWindowsName());
- log.info("Name: " + pfm.getPostscriptName());
- log.info("CharSet: " + pfm.getCharSetName());
- log.info("CapHeight: " + pfm.getCapHeight());
- log.info("XHeight: " + pfm.getXHeight());
- log.info("LowerCaseAscent: " + pfm.getLowerCaseAscent());
- log.info("LowerCaseDescent: " + pfm.getLowerCaseDescent());
- log.info("Having widths for " + (pfm.getLastChar() - pfm.getFirstChar())
- + " characters (" + pfm.getFirstChar()
- + "-" + pfm.getLastChar() + ").");
- log.info("for example: Char " + pfm.getFirstChar()
- + " has a width of " + pfm.getCharWidth(pfm.getFirstChar()));
- log.info("");
- }
- }
-
- /**
- * Generates the font metrics file from the PFM file.
- *
- * @param pfm The PFM file to generate the font metrics from.
- * @param fontName name of the font
- * @param className class name for the font
- * @param resource path to the font as embedded resource
- * @param file path to the font as file
- * @return The DOM document representing the font metrics file.
- */
- public org.w3c.dom.Document constructFontXML(PFMFile pfm,
- String fontName, String className, String resource, String file) {
- log.info("Creating xml font file...");
- log.info("");
-
- Document doc;
- try {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- doc = factory.newDocumentBuilder().newDocument();
- } catch (javax.xml.parsers.ParserConfigurationException e) {
- log.error("Can't create DOM implementation", e);
- return null;
- }
- Element root = doc.createElement("font-metrics");
- doc.appendChild(root);
- root.setAttribute("type", "TYPE1");
-
- Element el = doc.createElement("font-name");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(pfm.getPostscriptName()));
-
- // Currently unused.
- // String s = pfm.getPostscriptName();
- // int pos = s.indexOf("-");
- // if (pos >= 0) {
- // char[] sb = new char[s.length() - 1];
- // s.getChars(0, pos, sb, 0);
- // s.getChars(pos + 1, s.length(), sb, pos);
- // s = new String(sb);
- // }
-
- el = doc.createElement("embed");
- root.appendChild(el);
- if (file != null) {
- el.setAttribute("file", file);
- }
- if (resource != null) {
- el.setAttribute("class", resource);
- }
-
- el = doc.createElement("encoding");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(pfm.getCharSetName() + "Encoding"));
-
- el = doc.createElement("cap-height");
- root.appendChild(el);
- Integer value = new Integer(pfm.getCapHeight());
- el.appendChild(doc.createTextNode(value.toString()));
-
- el = doc.createElement("x-height");
- root.appendChild(el);
- value = new Integer(pfm.getXHeight());
- el.appendChild(doc.createTextNode(value.toString()));
-
- el = doc.createElement("ascender");
- root.appendChild(el);
- value = new Integer(pfm.getLowerCaseAscent());
- el.appendChild(doc.createTextNode(value.toString()));
-
- el = doc.createElement("descender");
- root.appendChild(el);
- value = new Integer(pfm.getLowerCaseDescent());
- el.appendChild(doc.createTextNode(value.toString()));
-
- Element bbox = doc.createElement("bbox");
- root.appendChild(bbox);
- int[] bb = pfm.getFontBBox();
- final String[] names = {"left", "bottom", "right", "top"};
- for (int i = 0; i < names.length; i++) {
- el = doc.createElement(names[i]);
- bbox.appendChild(el);
- value = new Integer(bb[i]);
- el.appendChild(doc.createTextNode(value.toString()));
- }
-
- el = doc.createElement("flags");
- root.appendChild(el);
- value = new Integer(pfm.getFlags());
- el.appendChild(doc.createTextNode(value.toString()));
-
- el = doc.createElement("stemv");
- root.appendChild(el);
- value = new Integer(pfm.getStemV());
- el.appendChild(doc.createTextNode(value.toString()));
-
- el = doc.createElement("italicangle");
- root.appendChild(el);
- value = new Integer(pfm.getItalicAngle());
- el.appendChild(doc.createTextNode(value.toString()));
-
- el = doc.createElement("first-char");
- root.appendChild(el);
- value = new Integer(pfm.getFirstChar());
- el.appendChild(doc.createTextNode(value.toString()));
-
- el = doc.createElement("last-char");
- root.appendChild(el);
- value = new Integer(pfm.getLastChar());
- el.appendChild(doc.createTextNode(value.toString()));
-
- Element widths = doc.createElement("widths");
- root.appendChild(widths);
-
- for (short i = pfm.getFirstChar(); i <= pfm.getLastChar(); i++) {
- el = doc.createElement("char");
- widths.appendChild(el);
- el.setAttribute("idx", Integer.toString(i));
- el.setAttribute("wdt", Integer.toString(pfm.getCharWidth(i)));
- }
-
-
- // Get kerning
- Iterator iter = pfm.getKerning().keySet().iterator();
- while (iter.hasNext()) {
- Integer kpx1 = (Integer)iter.next();
- el = doc.createElement("kerning");
- el.setAttribute("kpx1", kpx1.toString());
- root.appendChild(el);
- Element el2 = null;
-
- Map h2 = (Map) pfm.getKerning().get(kpx1);
- Iterator enum2 = h2.entrySet().iterator();
- while (enum2.hasNext()) {
- Map.Entry entry = (Map.Entry) enum2.next();
- Integer kpx2 = (Integer) entry.getKey();
- el2 = doc.createElement("pair");
- el2.setAttribute("kpx2", kpx2.toString());
- Integer val = (Integer) entry.getValue();
- el2.setAttribute("kern", val.toString());
- el.appendChild(el2);
- }
- }
- return doc;
- }
-}
-
-
-
-
diff --git a/src/java/org/apache/fop/fonts/apps/TTFReader.java b/src/java/org/apache/fop/fonts/apps/TTFReader.java
deleted file mode 100644
index 6f80fd098..000000000
--- a/src/java/org/apache/fop/fonts/apps/TTFReader.java
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * 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.apps;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Map;
-import java.util.Set;
-
-import javax.xml.parsers.DocumentBuilderFactory;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-
-import org.apache.fop.Version;
-import org.apache.fop.fonts.CMapSegment;
-import org.apache.fop.fonts.FontUtil;
-import org.apache.fop.fonts.truetype.FontFileReader;
-import org.apache.fop.fonts.truetype.OFFontLoader;
-import org.apache.fop.fonts.truetype.TTFFile;
-
-/**
- * A tool which reads TTF files and generates
- * XML font metrics file for use in FOP.
- */
-public class TTFReader extends AbstractFontReader {
-
- /** Used to detect incompatible versions of the generated XML files */
- public static final String METRICS_VERSION_ATTR = "metrics-version";
- /** Current version number for the metrics file */
- public static final int METRICS_VERSION = 2;
-
- /**
- * Main constructor.
- */
- public TTFReader() {
- super();
- }
-
- private static void displayUsage() {
- System.out.println(
- "java " + TTFReader.class.getName() + " [options] fontfile.ttf xmlfile.xml");
- System.out.println();
- System.out.println("where options can be:");
- System.out.println("-t Trace mode");
- System.out.println("-d Debug mode");
- System.out.println("-q Quiet mode");
- System.out.println("-enc ansi");
- System.out.println(" With this option you create a WinAnsi encoded font.");
- System.out.println(" The default is to create a CID keyed font.");
- System.out.println(" If you're not going to use characters outside the");
- System.out.println(" pdfencoding range (almost the same as iso-8889-1)");
- System.out.println(" you can add this option.");
- System.out.println("-ttcname <fontname>");
- System.out.println(" If you're reading data from a TrueType Collection");
- System.out.println(" (.ttc file) you must specify which font from the");
- System.out.println(" collection you will read metrics from. If you read");
- System.out.println(" from a .ttc file without this option, the fontnames");
- System.out.println(" will be listed for you.");
- System.out.println(" -fn <fontname>");
- System.out.println(" default is to use the fontname in the .ttf file, but");
- System.out.println(" you can override that name to make sure that the");
- System.out.println(" embedded font is used (if you're embedding fonts)");
- System.out.println(" instead of installed fonts when viewing documents ");
- System.out.println(" with Acrobat Reader.");
- }
-
-
- /**
- * The main method for the TTFReader tool.
- *
- * @param args Command-line arguments: [options] fontfile.ttf xmlfile.xml
- * where options can be:
- * -fn <fontname>
- * default is to use the fontname in the .ttf file, but you can override
- * that name to make sure that the embedded font is used instead of installed
- * fonts when viewing documents with Acrobat Reader.
- * -cn <classname>
- * default is to use the fontname
- * -ef <path to the truetype fontfile>
- * will add the possibility to embed the font. When running fop, fop will look
- * for this file to embed it
- * -er <path to truetype fontfile relative to org/apache/fop/render/pdf/fonts>
- * you can also include the fontfile in the fop.jar file when building fop.
- * You can use both -ef and -er. The file specified in -ef will be searched first,
- * then the -er file.
- * -nocs
- * if complex script features are disabled
- */
- public static void main(String[] args) {
- String embFile = null;
- String embResource = null;
- String className = null;
- String fontName = null;
- String ttcName = null;
- boolean isCid = true;
-
- Map options = new java.util.HashMap();
- String[] arguments = parseArguments(options, args);
-
- determineLogLevel(options);
-
- TTFReader app = new TTFReader();
-
- log.info("TTF Reader for Apache FOP " + Version.getVersion() + "\n");
-
- if (options.get("-enc") != null) {
- String enc = (String)options.get("-enc");
- if ("ansi".equals(enc)) {
- isCid = false;
- }
- }
-
- if (options.get("-ttcname") != null) {
- ttcName = (String)options.get("-ttcname");
- }
-
- if (options.get("-ef") != null) {
- embFile = (String)options.get("-ef");
- }
-
- if (options.get("-er") != null) {
- embResource = (String)options.get("-er");
- }
-
- if (options.get("-fn") != null) {
- fontName = (String)options.get("-fn");
- }
-
- if (options.get("-cn") != null) {
- className = (String)options.get("-cn");
- }
-
- boolean useKerning = true;
- boolean useAdvanced = true;
- if (options.get("-nocs") != null) {
- useAdvanced = false;
- }
-
- if (arguments.length != 2 || options.get("-h") != null
- || options.get("-help") != null || options.get("--help") != null) {
- displayUsage();
- } else {
- try {
- log.info("Parsing font...");
- TTFFile ttf = app.loadTTF(arguments[0], ttcName, useKerning, useAdvanced);
- if (ttf != null) {
- org.w3c.dom.Document doc = app.constructFontXML(ttf,
- fontName, className, embResource, embFile, isCid,
- ttcName);
-
- if (isCid) {
- log.info("Creating CID encoded metrics...");
- } else {
- log.info("Creating WinAnsi encoded metrics...");
- }
-
- if (doc != null) {
- app.writeFontXML(doc, arguments[1]);
- }
-
- if (ttf.isEmbeddable()) {
- log.info("This font contains no embedding license restrictions.");
- } else {
- log.info("** Note: This font contains license retrictions for\n"
- + " embedding. This font shouldn't be embedded.");
- }
- }
- log.info("");
- log.info("XML font metrics file successfully created.");
- } catch (Exception e) {
- log.error("Error while building XML font metrics file.", e);
- System.exit(-1);
- }
- }
- }
-
- /**
- * Read a TTF file and returns it as an object.
- *
- * @param fileName The filename of the TTF file.
- * @param fontName The name of the font
- * @param useKerning true if should load kerning data
- * @param useAdvanced true if should load advanced typographic table data
- * @return The TTF as an object, null if the font is incompatible.
- * @throws IOException In case of an I/O problem
- */
- public TTFFile loadTTF(String fileName, String fontName, boolean useKerning, boolean useAdvanced)
- throws IOException {
- TTFFile ttfFile = new TTFFile(useKerning, useAdvanced);
- log.info("Reading " + fileName + "...");
- InputStream stream = new FileInputStream(fileName);
- try {
- FontFileReader reader = new FontFileReader(stream);
- String header = OFFontLoader.readHeader(reader);
- boolean supported = ttfFile.readFont(reader, header, fontName);
- if (!supported) {
- return null;
- }
- } finally {
- stream.close();
- }
-
- log.info("Font Family: " + ttfFile.getFamilyNames());
- if (ttfFile.isCFF()) {
- throw new UnsupportedOperationException(
- "OpenType fonts with CFF data are not supported, yet");
- }
- return ttfFile;
- }
-
-
- /**
- * Generates the font metrics file from the TTF/TTC file.
- *
- * @param ttf The PFM file to generate the font metrics from.
- * @param fontName Name of the font
- * @param className Class name for the font
- * @param resource path to the font as embedded resource
- * @param file path to the font as file
- * @param isCid True if the font is CID encoded
- * @param ttcName Name of the TrueType Collection
- * @return The DOM document representing the font metrics file.
- */
- public org.w3c.dom.Document constructFontXML(TTFFile ttf,
- String fontName, String className, String resource, String file,
- boolean isCid, String ttcName) {
- log.info("Creating xml font file...");
-
- Document doc;
- try {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- doc = factory.newDocumentBuilder().newDocument();
- } catch (javax.xml.parsers.ParserConfigurationException e) {
- log.error("Can't create DOM implementation", e);
- return null;
- }
- Element root = doc.createElement("font-metrics");
- doc.appendChild(root);
- root.setAttribute(METRICS_VERSION_ATTR, String.valueOf(METRICS_VERSION));
- if (isCid) {
- root.setAttribute("type", "TYPE0");
- } else {
- root.setAttribute("type", "TRUETYPE");
- }
-
- Element el = doc.createElement("font-name");
- root.appendChild(el);
-
- // Note that the PostScript name usually is something like
- // "Perpetua-Bold", but the TrueType spec says that in the ttf file
- // it should be "Perpetua,Bold".
-
- String s = FontUtil.stripWhiteSpace(ttf.getPostScriptName());
-
- if (fontName != null) {
- el.appendChild(doc.createTextNode(FontUtil.stripWhiteSpace(fontName)));
- } else {
- el.appendChild(doc.createTextNode(s));
- }
- if (ttf.getFullName() != null) {
- el = doc.createElement("full-name");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(ttf.getFullName()));
- }
- Set<String> familyNames = ttf.getFamilyNames();
- if (familyNames.size() > 0) {
- String familyName = familyNames.iterator().next();
- el = doc.createElement("family-name");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(familyName));
- }
-
- el = doc.createElement("embed");
- root.appendChild(el);
- if (file != null && ttf.isEmbeddable()) {
- el.setAttribute("file", file);
- }
- if (resource != null && ttf.isEmbeddable()) {
- el.setAttribute("class", resource);
- }
-
- el = doc.createElement("cap-height");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(String.valueOf(ttf.getCapHeight())));
-
- el = doc.createElement("x-height");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(String.valueOf(ttf.getXHeight())));
-
- el = doc.createElement("ascender");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(String.valueOf(ttf.getLowerCaseAscent())));
-
- el = doc.createElement("descender");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(String.valueOf(ttf.getLowerCaseDescent())));
-
- Element bbox = doc.createElement("bbox");
- root.appendChild(bbox);
- int[] bb = ttf.getFontBBox();
- final String[] names = {"left", "bottom", "right", "top"};
- for (int i = 0; i < names.length; i++) {
- el = doc.createElement(names[i]);
- bbox.appendChild(el);
- el.appendChild(doc.createTextNode(String.valueOf(bb[i])));
- }
-
- el = doc.createElement("flags");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(String.valueOf(ttf.getFlags())));
-
- el = doc.createElement("stemv");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(ttf.getStemV()));
-
- el = doc.createElement("italicangle");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(ttf.getItalicAngle()));
-
- if (ttcName != null) {
- el = doc.createElement("ttc-name");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(ttcName));
- }
-
- el = doc.createElement("subtype");
- root.appendChild(el);
-
- // Fill in extras for CID keyed fonts
- if (isCid) {
- el.appendChild(doc.createTextNode("TYPE0"));
-
- generateDOM4MultiByteExtras(root, ttf, isCid);
- } else {
- // Fill in extras for singlebyte fonts
- el.appendChild(doc.createTextNode("TRUETYPE"));
-
- generateDOM4SingleByteExtras(root, ttf, isCid);
- }
-
- generateDOM4Kerning(root, ttf, isCid);
-
- return doc;
- }
-
- private void generateDOM4MultiByteExtras(Element parent, TTFFile ttf, boolean isCid) {
- Element el;
- Document doc = parent.getOwnerDocument();
-
- Element mel = doc.createElement("multibyte-extras");
- parent.appendChild(mel);
-
- el = doc.createElement("cid-type");
- mel.appendChild(el);
- el.appendChild(doc.createTextNode("CIDFontType2"));
-
- el = doc.createElement("default-width");
- mel.appendChild(el);
- el.appendChild(doc.createTextNode("0"));
-
- el = doc.createElement("bfranges");
- mel.appendChild(el);
- for (CMapSegment ce : ttf.getCMaps()) {
- Element el2 = doc.createElement("bf");
- el.appendChild(el2);
- el2.setAttribute("us", String.valueOf(ce.getUnicodeStart()));
- el2.setAttribute("ue", String.valueOf(ce.getUnicodeEnd()));
- el2.setAttribute("gi", String.valueOf(ce.getGlyphStartIndex()));
- }
-
- el = doc.createElement("cid-widths");
- el.setAttribute("start-index", "0");
- mel.appendChild(el);
-
- int[] wx = ttf.getWidths();
- for (int i = 0; i < wx.length; i++) {
- Element wxel = doc.createElement("wx");
- wxel.setAttribute("w", String.valueOf(wx[i]));
- int[] bbox = ttf.getBBox(i);
- wxel.setAttribute("xMin", String.valueOf(bbox[0]));
- wxel.setAttribute("yMin", String.valueOf(bbox[1]));
- wxel.setAttribute("xMax", String.valueOf(bbox[2]));
- wxel.setAttribute("yMax", String.valueOf(bbox[3]));
- el.appendChild(wxel);
- }
- }
-
- private void generateDOM4SingleByteExtras(Element parent, TTFFile ttf, boolean isCid) {
- Element el;
- Document doc = parent.getOwnerDocument();
-
- Element sel = doc.createElement("singlebyte-extras");
- parent.appendChild(sel);
-
- el = doc.createElement("encoding");
- sel.appendChild(el);
- el.appendChild(doc.createTextNode(ttf.getCharSetName()));
-
- el = doc.createElement("first-char");
- sel.appendChild(el);
- el.appendChild(doc.createTextNode(String.valueOf(ttf.getFirstChar())));
-
- el = doc.createElement("last-char");
- sel.appendChild(el);
- el.appendChild(doc.createTextNode(String.valueOf(ttf.getLastChar())));
-
- Element widths = doc.createElement("widths");
- sel.appendChild(widths);
-
- for (short i = ttf.getFirstChar(); i <= ttf.getLastChar(); i++) {
- el = doc.createElement("char");
- widths.appendChild(el);
- el.setAttribute("idx", String.valueOf(i));
- el.setAttribute("wdt", String.valueOf(ttf.getCharWidth(i)));
- }
- }
-
- private void generateDOM4Kerning(Element parent, TTFFile ttf, boolean isCid) {
- Element el;
- Document doc = parent.getOwnerDocument();
-
- // Get kerning
- Set<Integer> kerningKeys;
- if (isCid) {
- kerningKeys = ttf.getKerning().keySet();
- } else {
- kerningKeys = ttf.getAnsiKerning().keySet();
- }
-
- for (Integer kpx1 : kerningKeys) {
-
- el = doc.createElement("kerning");
- el.setAttribute("kpx1", kpx1.toString());
- parent.appendChild(el);
- Element el2 = null;
-
- Map<Integer, Integer> h2;
- if (isCid) {
- h2 = ttf.getKerning().get(kpx1);
- } else {
- h2 = ttf.getAnsiKerning().get(kpx1);
- }
-
- for (Map.Entry<Integer, Integer> e : h2.entrySet()) {
- Integer kpx2 = e.getKey();
- if (isCid || kpx2.intValue() < 256) {
- el2 = doc.createElement("pair");
- el2.setAttribute("kpx2", kpx2.toString());
- Integer val = e.getValue();
- el2.setAttribute("kern", val.toString());
- el.appendChild(el2);
- }
- }
- }
- }
-
- /**
- * Bugzilla 40739, check that attr has a metrics-version attribute
- * compatible with ours.
- * @param attr attributes read from the root element of a metrics XML file
- * @throws SAXException if incompatible
- */
- public static void checkMetricsVersion(Attributes attr) throws SAXException {
- String err = null;
- final String str = attr.getValue(METRICS_VERSION_ATTR);
- if (str == null) {
- err = "Missing " + METRICS_VERSION_ATTR + " attribute";
- } else {
- int version = 0;
- try {
- version = Integer.parseInt(str);
- if (version < METRICS_VERSION) {
- err = "Incompatible " + METRICS_VERSION_ATTR
- + " value (" + version + ", should be " + METRICS_VERSION
- + ")";
- }
- } catch (NumberFormatException e) {
- err = "Invalid " + METRICS_VERSION_ATTR
- + " attribute value (" + str + ")";
- }
- }
-
- if (err != null) {
- throw new SAXException(
- err
- + " - please regenerate the font metrics file with "
- + "a more recent version of FOP."
- );
- }
- }
-
-}
-
diff --git a/src/java/org/apache/fop/fonts/apps/package.html b/src/java/org/apache/fop/fonts/apps/package.html
deleted file mode 100644
index 5e0551c23..000000000
--- a/src/java/org/apache/fop/fonts/apps/package.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!--
- 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$ -->
-<HTML>
-<TITLE>org.apache.fop.fonts.apps Package</TITLE>
-<BODY>
-<P>Command-line tools for generating XML font metric files from Type 1 and TrueType fonts.</P>
-</BODY>
-</HTML> \ No newline at end of file
diff --git a/src/java/org/apache/fop/fonts/autodetect/FontDirFinder.java b/src/java/org/apache/fop/fonts/autodetect/FontDirFinder.java
deleted file mode 100644
index 383c5283d..000000000
--- a/src/java/org/apache/fop/fonts/autodetect/FontDirFinder.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.autodetect;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-/**
- * Implementers provide find method for searching native operating system
- * for available fonts.
- */
-public interface FontDirFinder {
-
- /**
- * Finds a list of font files.
- *
- * @return list of font files.
- * @throws IOException
- * In case of an I/O problem
- */
- List<File> find() throws IOException;
-
-}
diff --git a/src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java b/src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java
deleted file mode 100644
index 8100c4b9b..000000000
--- a/src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * 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.autodetect;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.commons.io.DirectoryWalker;
-import org.apache.commons.io.IOCase;
-import org.apache.commons.io.filefilter.FileFilterUtils;
-import org.apache.commons.io.filefilter.IOFileFilter;
-import org.apache.commons.io.filefilter.WildcardFileFilter;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.fonts.FontEventListener;
-
-/**
- * Helps to autodetect/locate available operating system fonts.
- */
-public class FontFileFinder extends DirectoryWalker implements FontFinder {
-
- /** logging instance */
- private final Log log = LogFactory.getLog(FontFileFinder.class);
-
- /** default depth limit of recursion when searching for font files **/
- public static final int DEFAULT_DEPTH_LIMIT = -1;
- private final FontEventListener eventListener;
-
- /**
- * Default constructor
- * @param listener for throwing font related events
- */
- public FontFileFinder(FontEventListener listener) {
- this(DEFAULT_DEPTH_LIMIT, listener);
- }
-
- /**
- * Constructor
- * @param depthLimit recursion depth limit
- * @param listener for throwing font related events
- */
- public FontFileFinder(int depthLimit, FontEventListener listener) {
- super(getDirectoryFilter(), getFileFilter(), depthLimit);
- eventListener = listener;
- }
-
- /**
- * Font directory filter. Currently ignores hidden directories.
- * @return IOFileFilter font directory filter
- */
- protected static IOFileFilter getDirectoryFilter() {
- return FileFilterUtils.andFileFilter(
- FileFilterUtils.directoryFileFilter(),
- FileFilterUtils.notFileFilter(FileFilterUtils.prefixFileFilter("."))
- );
- }
-
- /**
- * Font file filter. Currently searches for files with .ttf, .ttc, .otf, and .pfb extensions.
- * @return IOFileFilter font file filter
- */
- protected static IOFileFilter getFileFilter() {
- return FileFilterUtils.andFileFilter(
- FileFilterUtils.fileFileFilter(),
- new WildcardFileFilter(
- new String[] {"*.ttf", "*.otf", "*.pfb", "*.ttc"},
- IOCase.INSENSITIVE)
- );
- }
-
- /**
- * @param directory directory to handle
- * @param depth recursion depth
- * @param results collection
- * @return whether directory should be handled
- * {@inheritDoc}
- */
- @Override
- protected boolean handleDirectory(File directory, int depth, Collection results) {
- return true;
- }
-
- /**
- * @param file file to handle
- * @param depth recursion depth
- * @param results collection
- * {@inheritDoc}
- */
- @Override
- protected void handleFile(File file, int depth, Collection results) {
- try {
- // Looks Strange, but is actually recommended over just .URL()
- results.add(file.toURI().toURL());
- } catch (MalformedURLException e) {
- log.debug("MalformedURLException" + e.getMessage());
- }
- }
-
- /**
- * @param directory the directory being processed
- * @param depth the current directory level
- * @param results the collection of results objects
- * {@inheritDoc}
- */
- @Override
- protected void handleDirectoryEnd(File directory, int depth, Collection results) {
- if (log.isDebugEnabled()) {
- log.debug(directory + ": found " + results.size() + " font"
- + ((results.size() == 1) ? "" : "s"));
- }
- }
-
- /**
- * Automagically finds a list of font files on local system
- *
- * @return List&lt;URL&gt; of font files
- * @throws IOException io exception
- * {@inheritDoc}
- */
- public List<URL> find() throws IOException {
- final FontDirFinder fontDirFinder;
- final String osName = System.getProperty("os.name");
- if (osName.startsWith("Windows")) {
- fontDirFinder = new WindowsFontDirFinder();
- } else {
- if (osName.startsWith("Mac")) {
- fontDirFinder = new MacFontDirFinder();
- } else {
- fontDirFinder = new UnixFontDirFinder();
- }
- }
- List<File> fontDirs = fontDirFinder.find();
- List<URL> results = new java.util.ArrayList<URL>();
- for (File dir : fontDirs) {
- super.walk(dir, results);
- }
- return results;
- }
-
- /**
- * Searches a given directory for font files
- *
- * @param dir directory to search
- * @return list of font files
- * @throws IOException thrown if an I/O exception of some sort has occurred
- */
- public List<URL> find(String dir) throws IOException {
- List<URL> results = new java.util.ArrayList<URL>();
- File directory = new File(dir);
- if (!directory.isDirectory()) {
- eventListener.fontDirectoryNotFound(this, dir);
- } else {
- super.walk(directory, results);
- }
- return results;
- }
-}
diff --git a/src/java/org/apache/fop/fonts/autodetect/FontFinder.java b/src/java/org/apache/fop/fonts/autodetect/FontFinder.java
deleted file mode 100644
index 51e79443a..000000000
--- a/src/java/org/apache/fop/fonts/autodetect/FontFinder.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.autodetect;
-
-import java.io.IOException;
-import java.net.URL;
-import java.util.List;
-
-/**
- * Implementers provide find method for searching native operating system
- * for available fonts.
- */
-public interface FontFinder {
-
- /**
- * Finds a list of font files.
- *
- * @return list of font files.
- * @throws IOException
- * In case of an I/O problem
- */
- List<URL> find() throws IOException;
-
-}
diff --git a/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java b/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java
deleted file mode 100644
index a1d65459a..000000000
--- a/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * 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.autodetect;
-
-import java.io.InputStream;
-import java.net.URI;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-import java.util.regex.Pattern;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.apps.io.InternalResourceResolver;
-import org.apache.fop.fonts.CustomFont;
-import org.apache.fop.fonts.EmbedFontInfo;
-import org.apache.fop.fonts.EmbeddingMode;
-import org.apache.fop.fonts.EncodingMode;
-import org.apache.fop.fonts.Font;
-import org.apache.fop.fonts.FontCache;
-import org.apache.fop.fonts.FontEventListener;
-import org.apache.fop.fonts.FontLoader;
-import org.apache.fop.fonts.FontTriplet;
-import org.apache.fop.fonts.FontUris;
-import org.apache.fop.fonts.FontUtil;
-import org.apache.fop.fonts.MultiByteFont;
-import org.apache.fop.fonts.truetype.FontFileReader;
-import org.apache.fop.fonts.truetype.OFFontLoader;
-import org.apache.fop.fonts.truetype.TTFFile;
-
-/**
- * Attempts to determine correct FontInfo
- */
-public class FontInfoFinder {
-
- /** logging instance */
- private final Log log = LogFactory.getLog(FontInfoFinder.class);
-
- private FontEventListener eventListener;
-
- /**
- * Sets the font event listener that can be used to receive events about particular events
- * in this class.
- * @param listener the font event listener
- */
- public void setEventListener(FontEventListener listener) {
- this.eventListener = listener;
- }
-
- /**
- * Attempts to determine FontTriplets from a given CustomFont.
- * It seems to be fairly accurate but will probably require some tweaking over time
- *
- * @param customFont CustomFont
- * @param triplets Collection that will take the generated triplets
- */
- private void generateTripletsFromFont(CustomFont customFont, Collection<FontTriplet> triplets) {
- if (log.isTraceEnabled()) {
- log.trace("Font: " + customFont.getFullName()
- + ", family: " + customFont.getFamilyNames()
- + ", PS: " + customFont.getFontName()
- + ", EmbedName: " + customFont.getEmbedFontName());
- }
-
- // default style and weight triplet vales (fallback)
- String strippedName = stripQuotes(customFont.getStrippedFontName());
- //String subName = customFont.getFontSubName();
- String fullName = stripQuotes(customFont.getFullName());
- String searchName = fullName.toLowerCase();
-
- String style = guessStyle(customFont, searchName);
- int weight; //= customFont.getWeight();
- int guessedWeight = FontUtil.guessWeight(searchName);
- //We always take the guessed weight for now since it yield much better results.
- //OpenType's OS/2 usWeightClass value proves to be unreliable.
- weight = guessedWeight;
-
- //Full Name usually includes style/weight info so don't use these traits
- //If we still want to use these traits, we have to make FontInfo.fontLookup() smarter
- triplets.add(new FontTriplet(fullName, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL));
- if (!fullName.equals(strippedName)) {
- triplets.add(new FontTriplet(strippedName, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL));
- }
- Set<String> familyNames = customFont.getFamilyNames();
- for (String familyName : familyNames) {
- familyName = stripQuotes(familyName);
- if (!fullName.equals(familyName)) {
- /* Heuristic:
- * The more similar the family name to the full font name,
- * the higher the priority of its triplet.
- * (Lower values indicate higher priorities.) */
- int priority = fullName.startsWith(familyName)
- ? fullName.length() - familyName.length()
- : fullName.length();
- triplets.add(new FontTriplet(familyName, style, weight, priority));
- }
- }
- }
-
- private final Pattern quotePattern = Pattern.compile("'");
-
- private String stripQuotes(String name) {
- return quotePattern.matcher(name).replaceAll("");
- }
-
- private String guessStyle(CustomFont customFont, String fontName) {
- // style
- String style = Font.STYLE_NORMAL;
- if (customFont.getItalicAngle() > 0) {
- style = Font.STYLE_ITALIC;
- } else {
- style = FontUtil.guessStyle(fontName);
- }
- return style;
- }
-
- /**
- * Attempts to determine FontInfo from a given custom font
- * @param fontUri the font URI
- * @param customFont the custom font
- * @param fontCache font cache (may be null)
- * @return FontInfo from the given custom font
- */
- private EmbedFontInfo getFontInfoFromCustomFont(URI fontUri, CustomFont customFont,
- FontCache fontCache, InternalResourceResolver resourceResolver) {
- FontUris fontUris = new FontUris(fontUri, null);
- List<FontTriplet> fontTripletList = new java.util.ArrayList<FontTriplet>();
- generateTripletsFromFont(customFont, fontTripletList);
- String subFontName = null;
- if (customFont instanceof MultiByteFont) {
- subFontName = ((MultiByteFont) customFont).getTTCName();
- }
- EmbedFontInfo fontInfo = new EmbedFontInfo(fontUris, customFont.isKerningEnabled(),
- customFont.isAdvancedEnabled(), fontTripletList, subFontName,
- EncodingMode.AUTO, EmbeddingMode.AUTO);
- fontInfo.setPostScriptName(customFont.getFontName());
- if (fontCache != null) {
- fontCache.addFont(fontInfo, resourceResolver);
- }
- return fontInfo;
- }
-
- /**
- * Attempts to determine EmbedFontInfo from a given font file.
- *
- * @param fontURI the URI of the font resource
- * @param resourceResolver font resolver used to resolve font
- * @param fontCache font cache (may be null)
- * @return an array of newly created embed font info. Generally, this array
- * will have only one entry, unless the fontUrl is a TrueType Collection
- */
- public EmbedFontInfo[] find(URI fontURI, InternalResourceResolver resourceResolver, FontCache fontCache) {
- URI embedUri = resourceResolver.resolveFromBase(fontURI);
- String embedStr = embedUri.toASCIIString();
- boolean useKerning = true;
- boolean useAdvanced = true;
-
- long fileLastModified = -1;
- if (fontCache != null) {
- fileLastModified = FontCache.getLastModified(fontURI);
- // firstly try and fetch it from cache before loading/parsing the font file
- if (fontCache.containsFont(embedStr)) {
- EmbedFontInfo[] fontInfos = fontCache.getFontInfos(embedStr, fileLastModified);
- if (fontInfos != null) {
- return fontInfos;
- }
- // is this a previously failed parsed font?
- } else if (fontCache.isFailedFont(embedStr, fileLastModified)) {
- if (log.isDebugEnabled()) {
- log.debug("Skipping font file that failed to load previously: " + embedUri);
- }
- return null;
- }
- }
-
-
- // try to determine triplet information from font file
- CustomFont customFont = null;
- if (fontURI.toASCIIString().toLowerCase().endsWith(".ttc")) {
- // Get a list of the TTC Font names
- List<String> ttcNames = null;
- InputStream in = null;
- try {
- in = resourceResolver.getResource(fontURI);
- TTFFile ttf = new TTFFile(false, false);
- FontFileReader reader = new FontFileReader(in);
- ttcNames = ttf.getTTCnames(reader);
- } catch (Exception e) {
- if (this.eventListener != null) {
- this.eventListener.fontLoadingErrorAtAutoDetection(this,
- fontURI.toASCIIString(), e);
- }
- return null;
- } finally {
- IOUtils.closeQuietly(in);
- }
-
- List<EmbedFontInfo> embedFontInfoList = new java.util.ArrayList<EmbedFontInfo>();
-
- // For each font name ...
- for (String fontName : ttcNames) {
- if (log.isDebugEnabled()) {
- log.debug("Loading " + fontName);
- }
- try {
- OFFontLoader ttfLoader = new OFFontLoader(fontURI, fontName, true,
- EmbeddingMode.AUTO, EncodingMode.AUTO, useKerning, useAdvanced,
- resourceResolver);
- customFont = ttfLoader.getFont();
- if (this.eventListener != null) {
- customFont.setEventListener(this.eventListener);
- }
- } catch (Exception e) {
- if (fontCache != null) {
- fontCache.registerFailedFont(embedUri.toASCIIString(), fileLastModified);
- }
- if (this.eventListener != null) {
- this.eventListener.fontLoadingErrorAtAutoDetection(this,
- embedUri.toASCIIString(), e);
- }
- continue;
- }
- EmbedFontInfo fi = getFontInfoFromCustomFont(fontURI, customFont, fontCache,
- resourceResolver);
- if (fi != null) {
- embedFontInfoList.add(fi);
- }
- }
- return embedFontInfoList.toArray(
- new EmbedFontInfo[embedFontInfoList.size()]);
- } else {
- // The normal case
- try {
- FontUris fontUris = new FontUris(fontURI, null);
- customFont = FontLoader.loadFont(fontUris, null, true, EmbeddingMode.AUTO, EncodingMode.AUTO,
- useKerning, useAdvanced, resourceResolver);
- if (this.eventListener != null) {
- customFont.setEventListener(this.eventListener);
- }
- } catch (Exception e) {
- if (fontCache != null) {
- fontCache.registerFailedFont(embedUri.toASCIIString(), fileLastModified);
- }
- if (this.eventListener != null) {
- this.eventListener.fontLoadingErrorAtAutoDetection(this,
- embedUri.toASCIIString(), e);
- }
- return null;
- }
- EmbedFontInfo fi = getFontInfoFromCustomFont(fontURI, customFont, fontCache, resourceResolver);
- if (fi != null) {
- return new EmbedFontInfo[] {fi};
- } else {
- return null;
- }
- }
-
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/autodetect/MacFontDirFinder.java b/src/java/org/apache/fop/fonts/autodetect/MacFontDirFinder.java
deleted file mode 100644
index 1231badf2..000000000
--- a/src/java/org/apache/fop/fonts/autodetect/MacFontDirFinder.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.autodetect;
-
-/**
- * Mac font directory finder
- */
-public class MacFontDirFinder extends NativeFontDirFinder {
-
- /**
- * Some guesses at possible unix font directory locations
- * @return a array of possible font directory locations
- */
- protected String[] getSearchableDirectories() {
- return new String[] {
- System.getProperty("user.home") + "/Library/Fonts/", // user
- "/Library/Fonts/", // local
- "/System/Library/Fonts/", // system
- "/Network/Library/Fonts/" // network
- };
- }
-}
diff --git a/src/java/org/apache/fop/fonts/autodetect/NativeFontDirFinder.java b/src/java/org/apache/fop/fonts/autodetect/NativeFontDirFinder.java
deleted file mode 100644
index 9f723a308..000000000
--- a/src/java/org/apache/fop/fonts/autodetect/NativeFontDirFinder.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.autodetect;
-
-import java.io.File;
-import java.util.List;
-
-/**
- * Native font finder base class
- */
-public abstract class NativeFontDirFinder implements FontDirFinder {
-
- /**
- * Generic method used by Mac and Unix font finders.
- * @return list of natively existing font directories
- * {@inheritDoc}
- */
- public List<File> find() {
- List<File> fontDirList = new java.util.ArrayList<File>();
- String[] searchableDirectories = getSearchableDirectories();
- if (searchableDirectories != null) {
- for (int i = 0; i < searchableDirectories.length; i++) {
- File fontDir = new File(searchableDirectories[i]);
- if (fontDir.exists() && fontDir.canRead()) {
- fontDirList.add(fontDir);
- }
- }
- }
- return fontDirList;
- }
-
- /**
- * Returns an array of directories to search for fonts in.
- * @return an array of directories
- */
- protected abstract String[] getSearchableDirectories();
-
-}
diff --git a/src/java/org/apache/fop/fonts/autodetect/UnixFontDirFinder.java b/src/java/org/apache/fop/fonts/autodetect/UnixFontDirFinder.java
deleted file mode 100644
index b6d596f03..000000000
--- a/src/java/org/apache/fop/fonts/autodetect/UnixFontDirFinder.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.autodetect;
-
-/**
- * Unix font directory finder
- */
-public class UnixFontDirFinder extends NativeFontDirFinder {
-
- /**
- * Some guesses at possible unix font directory locations
- * @return a list of possible font locations
- */
- protected String[] getSearchableDirectories() {
- return new String[] {
- System.getProperty("user.home") + "/.fonts", // user
- "/usr/local/fonts", // local
- "/usr/local/share/fonts", // local shared
- "/usr/share/fonts", // system
- "/usr/X11R6/lib/X11/fonts" // X
- };
- }
-}
diff --git a/src/java/org/apache/fop/fonts/autodetect/WindowsFontDirFinder.java b/src/java/org/apache/fop/fonts/autodetect/WindowsFontDirFinder.java
deleted file mode 100644
index bd506d9ed..000000000
--- a/src/java/org/apache/fop/fonts/autodetect/WindowsFontDirFinder.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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.autodetect;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.List;
-
-import org.apache.commons.io.IOUtils;
-
-/**
- * FontFinder for native Windows platforms
- */
-public class WindowsFontDirFinder implements FontDirFinder {
-
- /**
- * Attempts to read windir environment variable on windows
- * (disclaimer: This is a bit dirty but seems to work nicely)
- */
- private String getWinDir(String osName) throws IOException {
- Process process = null;
- Runtime runtime = Runtime.getRuntime();
- if (osName.startsWith("Windows 9")) {
- process = runtime.exec("command.com /c echo %windir%");
- } else {
- process = runtime.exec("cmd.exe /c echo %windir%");
- }
- InputStreamReader isr = null;
- BufferedReader bufferedReader = null;
- String dir = "";
- try {
- isr = new InputStreamReader(process.getInputStream());
- bufferedReader = new BufferedReader(isr);
- dir = bufferedReader.readLine();
- } finally {
- IOUtils.closeQuietly(bufferedReader);
- IOUtils.closeQuietly(isr);
- }
- return dir;
- }
-
- /**
- * {@inheritDoc}
- * @return a list of detected font files
- */
- public List<File> find() {
- List<File> fontDirList = new java.util.ArrayList<File>();
- String windir = null;
- try {
- windir = System.getProperty("env.windir");
- } catch (SecurityException e) {
- // should continue if this fails
- }
- String osName = System.getProperty("os.name");
- if (windir == null) {
- try {
- windir = getWinDir(osName);
- } catch (IOException e) {
- // should continue if this fails
- }
- }
- File osFontsDir = null;
- File psFontsDir = null;
- if (windir != null) {
- // remove any trailing '/'
- if (windir.endsWith("/")) {
- windir = windir.substring(0, windir.length() - 1);
- }
- osFontsDir = new File(windir + File.separator + "FONTS");
- if (osFontsDir.exists() && osFontsDir.canRead()) {
- fontDirList.add(osFontsDir);
- }
- psFontsDir = new File(windir.substring(0, 2) + File.separator + "PSFONTS");
- if (psFontsDir.exists() && psFontsDir.canRead()) {
- fontDirList.add(psFontsDir);
- }
- } else {
- String windowsDirName = osName.endsWith("NT") ? "WINNT" : "WINDOWS";
- // look for true type font folder
- for (char driveLetter = 'C'; driveLetter <= 'E'; driveLetter++) {
- osFontsDir = new File(
- driveLetter + ":"
- + File.separator + windowsDirName
- + File.separator + "FONTS");
- if (osFontsDir.exists() && osFontsDir.canRead()) {
- fontDirList.add(osFontsDir);
- break;
- }
- }
- // look for type 1 font folder
- for (char driveLetter = 'C'; driveLetter <= 'E'; driveLetter++) {
- psFontsDir = new File(driveLetter + ":" + File.separator + "PSFONTS");
- if (psFontsDir.exists() && psFontsDir.canRead()) {
- fontDirList.add(psFontsDir);
- break;
- }
- }
- }
- return fontDirList;
- }
-}
diff --git a/src/java/org/apache/fop/fonts/autodetect/package.html b/src/java/org/apache/fop/fonts/autodetect/package.html
deleted file mode 100644
index 0a29acbb1..000000000
--- a/src/java/org/apache/fop/fonts/autodetect/package.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!--
- 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: $ -->
-<HTML>
-<TITLE>org.apache.fop.fonts.autodetect Package</TITLE>
-<BODY>
-<P>A collection of classes that aid in the autodetection of installed system fonts.</P>
-</BODY>
-</HTML>
diff --git a/src/java/org/apache/fop/fonts/base14/Base14FontCollection.java b/src/java/org/apache/fop/fonts/base14/Base14FontCollection.java
deleted file mode 100644
index ac01c9850..000000000
--- a/src/java/org/apache/fop/fonts/base14/Base14FontCollection.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * 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.base14;
-
-import org.apache.fop.fonts.Font;
-import org.apache.fop.fonts.FontCollection;
-import org.apache.fop.fonts.FontInfo;
-
-/**
- * Sets up Base 14 fonts
- */
-public class Base14FontCollection implements FontCollection {
-
- private boolean kerning;
-
- /**
- * Main constructor
- *
- * @param kerning set to true when font kerning is enabled
- */
- public Base14FontCollection(boolean kerning) {
- this.kerning = kerning;
- }
-
- /**
- * {@inheritDoc}
- */
- public int setup(int start, FontInfo fontInfo) {
- fontInfo.addMetrics("F1", new Helvetica(kerning));
- fontInfo.addMetrics("F2", new HelveticaOblique(kerning));
- fontInfo.addMetrics("F3", new HelveticaBold(kerning));
- fontInfo.addMetrics("F4", new HelveticaBoldOblique(kerning));
- fontInfo.addMetrics("F5", new TimesRoman(kerning));
- fontInfo.addMetrics("F6", new TimesItalic(kerning));
- fontInfo.addMetrics("F7", new TimesBold(kerning));
- fontInfo.addMetrics("F8", new TimesBoldItalic(kerning));
- fontInfo.addMetrics("F9", new Courier(kerning));
- fontInfo.addMetrics("F10", new CourierOblique(kerning));
- fontInfo.addMetrics("F11", new CourierBold(kerning));
- fontInfo.addMetrics("F12", new CourierBoldOblique(kerning));
- fontInfo.addMetrics("F13", new Symbol());
- fontInfo.addMetrics("F14", new ZapfDingbats());
-
- // Custom type 1 fonts step 1/2
- // fontInfo.addMetrics("F15", new OMEP());
- // fontInfo.addMetrics("F16", new GaramondLightCondensed());
- // fontInfo.addMetrics("F17", new BauerBodoniBoldItalic());
-
- /* any is treated as serif */
- fontInfo.addFontProperties("F5", "any", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "any", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "any", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F7", "any", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "any", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "any", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
-
- fontInfo.addFontProperties("F1", "sans-serif", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F2", "sans-serif", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F2", "sans-serif", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F3", "sans-serif", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F4", "sans-serif", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F4", "sans-serif", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F1", "SansSerif", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F2", "SansSerif", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F2", "SansSerif", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F3", "SansSerif", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F4", "SansSerif", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F4", "SansSerif", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F5", "serif", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "serif", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "serif", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F7", "serif", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "serif", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "serif", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F9", "monospace", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F10", "monospace", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F10", "monospace", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F11", "monospace", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F12", "monospace", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F12", "monospace", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F9", "Monospaced", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F10", "Monospaced", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F10", "Monospaced", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F11", "Monospaced", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F12", "Monospaced", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F12", "Monospaced", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
-
- fontInfo.addFontProperties("F1", "Helvetica", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F2", "Helvetica", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F2", "Helvetica", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F3", "Helvetica", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F4", "Helvetica", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F4", "Helvetica", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F5", "Times", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "Times", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "Times", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F7", "Times", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "Times", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "Times", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F9", "Courier", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F10", "Courier", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F10", "Courier", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F11", "Courier", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F12", "Courier", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F12", "Courier", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F13", "Symbol", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F14", "ZapfDingbats", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
-
- // Custom type 1 fonts step 2/2
- // fontInfo.addFontProperties("F15", "OMEP", "normal", FontInfo.NORMAL);
- // fontInfo.addFontProperties("F16", "Garamond-LightCondensed", "normal", FontInfo.NORMAL);
- // fontInfo.addFontProperties("F17", "BauerBodoni", "italic", FontInfo.BOLD);
-
- /* for compatibility with PassiveTex */
- fontInfo.addFontProperties("F5", "Times-Roman", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "Times-Roman", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "Times-Roman", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F7", "Times-Roman", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "Times-Roman", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "Times-Roman", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F5", "Times Roman", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "Times Roman", Font.STYLE_OBLIQUE, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F6", "Times Roman", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
- fontInfo.addFontProperties("F7", "Times Roman", Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "Times Roman", Font.STYLE_OBLIQUE, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F8", "Times Roman", Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
- fontInfo.addFontProperties("F9", "Computer-Modern-Typewriter",
- Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
-
- return 15;
- }
-}
diff --git a/src/java/org/apache/fop/fonts/base14/package.html b/src/java/org/apache/fop/fonts/base14/package.html
deleted file mode 100644
index 90c58d555..000000000
--- a/src/java/org/apache/fop/fonts/base14/package.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<HTML>
-<TITLE>org.apache.fop.fonts.base14 Package</TITLE>
-<BODY>
-<P>Base 14 fonts used for PDF and PostScript. Generated entirely from XML files.</P>
-</BODY>
-</HTML> \ No newline at end of file
diff --git a/src/java/org/apache/fop/fonts/cff/CFFDataReader.java b/src/java/org/apache/fop/fonts/cff/CFFDataReader.java
deleted file mode 100644
index 3ce63a2a4..000000000
--- a/src/java/org/apache/fop/fonts/cff/CFFDataReader.java
+++ /dev/null
@@ -1,929 +0,0 @@
-/*
- * 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.cff;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.fontbox.cff.CFFDataInput;
-import org.apache.fontbox.cff.CFFOperator;
-
-import org.apache.fop.fonts.truetype.FontFileReader;
-import org.apache.fop.fonts.truetype.OTFFile;
-
-/**
- * A class to read the CFF data from an OTF CFF font file.
- */
-public class CFFDataReader {
- private CFFDataInput cffData;
-
- private byte[] header;
- private CFFIndexData nameIndex;
- private CFFIndexData topDICTIndex;
- private CFFIndexData stringIndex;
- private CFFIndexData charStringIndex;
- private CFFIndexData globalIndexSubr;
- private CFFIndexData localIndexSubr;
- private CustomEncoding encoding;
- private FDSelect fdSelect;
- private List<FontDict> fdFonts;
-
- private static final int DOUBLE_BYTE_OPERATOR = 12;
- private static final int NUM_STANDARD_STRINGS = 391;
-
- /** Commonly used parsed dictionaries */
- private LinkedHashMap<String, DICTEntry> topDict;
-
- public CFFDataReader() {
-
- }
-
- /**
- * Constructor for the CFF data reader which accepts the CFF byte data
- * as an argument.
- * @param cffDataArray A byte array which holds the CFF data
- */
- public CFFDataReader(byte[] cffDataArray) throws IOException {
- cffData = new CFFDataInput(cffDataArray);
- readCFFData();
- }
-
- /**
- * Constructor for the CFF data reader which accepts a FontFileReader object
- * which points to the original font file as an argument.
- * @param fontFile The font file as represented by a FontFileReader object
- */
- public CFFDataReader(FontFileReader fontFile) throws IOException {
- cffData = new CFFDataInput(OTFFile.getCFFData(fontFile));
- readCFFData();
- }
-
- private void readCFFData() throws IOException {
- header = readHeader();
- nameIndex = readIndex();
- topDICTIndex = readIndex();
- topDict = parseDictData(topDICTIndex.getData());
- stringIndex = readIndex();
- globalIndexSubr = readIndex();
- charStringIndex = readCharStringIndex();
- encoding = readEncoding();
- fdSelect = readFDSelect();
- localIndexSubr = readLocalIndexSubrs();
- fdFonts = parseCIDData();
- }
-
- public Map<String, DICTEntry> getPrivateDict(DICTEntry privateEntry) throws IOException {
- return parseDictData(getPrivateDictBytes(privateEntry));
- }
-
- public byte[] getPrivateDictBytes(DICTEntry privateEntry) throws IOException {
- int privateLength = privateEntry.getOperands().get(0).intValue();
- int privateOffset = privateEntry.getOperands().get(1).intValue();
- return getCFFOffsetBytes(privateOffset, privateLength);
- }
-
- /**
- * Retrieves a number of bytes from the CFF data stream
- * @param offset The offset of the bytes to retrieve
- * @param length The number of bytes to retrieve
- * @return Returns a byte array of requested bytes
- * @throws IOException Throws an IO Exception if an error occurs
- */
- private byte[] getCFFOffsetBytes(int offset, int length) throws IOException {
- cffData.setPosition(offset);
- return cffData.readBytes(length);
- }
-
- /**
- * Parses the dictionary data and returns a map of objects for each entry
- * @param dictData The data for the dictionary data
- * @return Returns a map of type DICTEntry identified by the operand name
- * @throws IOException Throws an IO Exception if an error occurs
- */
- public LinkedHashMap<String, DICTEntry> parseDictData(byte[] dictData) throws IOException {
- LinkedHashMap<String, DICTEntry> dictEntries = new LinkedHashMap<String, DICTEntry>();
- List<Number> operands = new ArrayList<Number>();
- List<Integer> operandLengths = new ArrayList<Integer>();
- int lastOperandLength = 0;
- for (int i = 0; i < dictData.length; i++) {
- int readByte = dictData[i] & 0xFF;
- if (readByte < 28) {
- int[] operator = new int[(readByte == DOUBLE_BYTE_OPERATOR) ? 2 : 1];
- if (readByte == DOUBLE_BYTE_OPERATOR) {
- operator[0] = dictData[i];
- operator[1] = dictData[i + 1];
- i++;
- } else {
- operator[0] = dictData[i];
- }
- String operatorName = "";
- CFFOperator tempOp = null;
- if (operator.length > 1) {
- tempOp = CFFOperator.getOperator(new CFFOperator.Key(operator[0], operator[1]));
- } else {
- tempOp = CFFOperator.getOperator(new CFFOperator.Key(operator[0]));
- }
- if (tempOp != null) {
- operatorName = tempOp.getName();
- }
- DICTEntry newEntry = new DICTEntry();
- newEntry.setOperator(operator);
- newEntry.setOperands(new ArrayList<Number>(operands));
- newEntry.setOperatorName(operatorName);
- newEntry.setOffset(i - lastOperandLength);
- newEntry.setOperandLength(lastOperandLength);
- newEntry.setOperandLengths(new ArrayList<Integer>(operandLengths));
- byte[] byteData = new byte[lastOperandLength + operator.length];
- System.arraycopy(dictData, i - operator.length - (lastOperandLength - 1),
- byteData, 0, operator.length + lastOperandLength);
- newEntry.setByteData(byteData);
- dictEntries.put(operatorName, newEntry);
- operands.clear();
- operandLengths.clear();
- lastOperandLength = 0;
- } else {
- if (readByte >= 32 && readByte <= 246) {
- operands.add(readByte - 139);
- lastOperandLength += 1;
- operandLengths.add(1);
- } else if (readByte >= 247 && readByte <= 250) {
- operands.add((readByte - 247) * 256 + (dictData[i + 1] & 0xFF) + 108);
- lastOperandLength += 2;
- operandLengths.add(2);
- i++;
- } else if (readByte >= 251 && readByte <= 254) {
- operands.add(-(readByte - 251) * 256 - (dictData[i + 1] & 0xFF) - 108);
- lastOperandLength += 2;
- operandLengths.add(2);
- i++;
- } else if (readByte == 28) {
- operands.add((dictData[i + 1] & 0xFF) << 8 | (dictData[i + 2] & 0xFF));
- lastOperandLength += 3;
- operandLengths.add(3);
- i += 2;
- } else if (readByte == 29) {
- operands.add((dictData[i + 1] & 0xFF) << 24 | (dictData[i + 2] & 0xFF) << 16
- | (dictData[i + 3] & 0xFF) << 8 | (dictData[i + 4] & 0xFF));
- lastOperandLength += 5;
- operandLengths.add(5);
- i += 4;
- } else if (readByte == 30) {
- boolean terminatorFound = false;
- StringBuilder realNumber = new StringBuilder();
- int byteCount = 1;
- do {
- byte nibblesByte = dictData[++i];
- byteCount++;
- terminatorFound = readNibble(realNumber, (nibblesByte >> 4) & 0x0F);
- if (!terminatorFound) {
- terminatorFound = readNibble(realNumber, nibblesByte & 0x0F);
- }
- } while (!terminatorFound);
- operands.add(Double.valueOf(realNumber.toString()));
- lastOperandLength += byteCount;
- operandLengths.add(byteCount);
- }
- }
- }
- return dictEntries;
- }
-
- private boolean readNibble(StringBuilder realNumber, int nibble) {
- if (nibble <= 0x9) {
- realNumber.append(nibble);
- } else {
- switch (nibble) {
- case 0xa: realNumber.append("."); break;
- case 0xb: realNumber.append("E"); break;
- case 0xc: realNumber.append("E-"); break;
- case 0xd: break;
- case 0xe: realNumber.append("-"); break;
- case 0xf: return true;
- default: throw new AssertionError("Unexpected nibble value");
- }
- }
- return false;
- }
-
- /**
- * A class containing data for a dictionary entry
- */
- public static class DICTEntry {
- private int[] operator;
- private List<Number> operands;
- private List<Integer> operandLengths;
- private String operatorName;
- private int offset;
- private int operandLength;
- private byte[] data = new byte[0];
-
- public void setOperator(int[] operator) {
- this.operator = operator;
- }
-
- public int[] getOperator() {
- return this.operator;
- }
-
- public void setOperands(List<Number> operands) {
- this.operands = operands;
- }
-
- public List<Number> getOperands() {
- return this.operands;
- }
-
- public void setOperatorName(String operatorName) {
- this.operatorName = operatorName;
- }
-
- public String getOperatorName() {
- return this.operatorName;
- }
-
- public void setOffset(int offset) {
- this.offset = offset;
- }
-
- public int getOffset() {
- return this.offset;
- }
-
- public void setOperandLength(int operandLength) {
- this.operandLength = operandLength;
- }
-
- public int getOperandLength() {
- return this.operandLength;
- }
-
- public void setByteData(byte[] data) {
- this.data = data.clone();
- }
-
- public byte[] getByteData() {
- return data.clone();
- }
-
- public void setOperandLengths(List<Integer> operandLengths) {
- this.operandLengths = operandLengths;
- }
-
- public List<Integer> getOperandLengths() {
- return operandLengths;
- }
- }
-
- private byte[] readHeader() throws IOException {
- //Read known header
- byte[] fixedHeader = cffData.readBytes(4);
- int hdrSize = (fixedHeader[2] & 0xFF);
- byte[] extra = cffData.readBytes(hdrSize - 4);
- byte[] header = new byte[hdrSize];
- for (int i = 0; i < fixedHeader.length; i++) {
- header[i] = fixedHeader[i];
- }
- for (int i = 4; i < extra.length; i++) {
- header[i] = extra[i - 4];
- }
- return header;
- }
-
- /**
- * Reads a CFF index object are the specified offset position
- * @param offset The position of the index object to read
- * @return Returns an object representing the index
- * @throws IOException Throws an IO Exception if an error occurs
- */
- public CFFIndexData readIndex(int offset) throws IOException {
- cffData.setPosition(offset);
- return readIndex();
- }
-
- private CFFIndexData readIndex() throws IOException {
- return readIndex(cffData);
- }
-
- /**
- * Reads an index from the current position of the CFFDataInput object
- * @param input The object holding the CFF byte data
- * @return Returns an object representing the index
- * @throws IOException Throws an IO Exception if an error occurs
- */
- public CFFIndexData readIndex(CFFDataInput input) throws IOException {
- CFFIndexData nameIndex = new CFFIndexData();
- if (input != null) {
- int origPos = input.getPosition();
- nameIndex.parseIndexHeader(input);
- int tableSize = input.getPosition() - origPos;
- nameIndex.setByteData(input.getPosition() - tableSize, tableSize);
- }
- return nameIndex;
- }
-
- /**
- * Retrieves the SID for the given GID object
- * @param charsetOffset The offset of the charset data
- * @param GID The GID for which to retrieve the SID
- * @return Returns the SID as an integer
- */
- public int getSIDFromGID(int charsetOffset, int gid) throws IOException {
- if (gid == 0) {
- return 0;
- }
- cffData.setPosition(charsetOffset);
- int charsetFormat = cffData.readCard8();
- switch (charsetFormat) {
- case 0: //Adjust for .notdef character
- cffData.setPosition(cffData.getPosition() + (--gid * 2));
- return cffData.readSID();
- case 1: return getSIDFromGIDFormat(gid, 1);
- case 2: return getSIDFromGIDFormat(gid, 2);
- default: return 0;
- }
- }
-
- private int getSIDFromGIDFormat(int gid, int format) throws IOException {
- int glyphCount = 0;
- while (true) {
- int oldGlyphCount = glyphCount;
- int start = cffData.readSID();
- glyphCount += ((format == 1) ? cffData.readCard8() : cffData.readCard16()) + 1;
- if (gid <= glyphCount) {
- return start + (gid - oldGlyphCount) - 1;
- }
- }
- }
-
- public byte[] getHeader() {
- return header.clone();
- }
-
- public CFFIndexData getNameIndex() {
- return nameIndex;
- }
-
- public CFFIndexData getTopDictIndex() {
- return topDICTIndex;
- }
-
- public LinkedHashMap<String, DICTEntry> getTopDictEntries() {
- return topDict;
- }
-
- public CFFIndexData getStringIndex() {
- return stringIndex;
- }
-
- public CFFIndexData getGlobalIndexSubr() {
- return globalIndexSubr;
- }
-
- public CFFIndexData getLocalIndexSubr() {
- return localIndexSubr;
- }
-
- public CFFIndexData getCharStringIndex() {
- return charStringIndex;
- }
-
- public CFFDataInput getCFFData() {
- return cffData;
- }
-
- public CustomEncoding getEncoding() {
- return encoding;
- }
-
- public FDSelect getFDSelect() {
- return fdSelect;
- }
-
- public List<FontDict> getFDFonts() {
- return fdFonts;
- }
-
- public CFFDataInput getLocalSubrsForGlyph(int glyph) throws IOException {
- //Subsets are currently written using a Format0 FDSelect
- FDSelect fontDictionary = getFDSelect();
- if (fontDictionary instanceof Format0FDSelect) {
- Format0FDSelect fdSelect = (Format0FDSelect)fontDictionary;
- int found = fdSelect.getFDIndexes()[glyph];
- FontDict font = getFDFonts().get(found);
- byte[] localSubrData = font.getLocalSubrData().getByteData();
- if (localSubrData != null) {
- return new CFFDataInput(localSubrData);
- } else {
- return null;
- }
- } else if (fontDictionary instanceof Format3FDSelect) {
- Format3FDSelect fdSelect = (Format3FDSelect)fontDictionary;
- int index = 0;
- for (int first : fdSelect.getRanges().keySet()) {
- if (first > glyph) {
- break;
- }
- index++;
- }
- FontDict font = getFDFonts().get(index);
- byte[] localSubrsData = font.getLocalSubrData().getByteData();
- if (localSubrsData != null) {
- return new CFFDataInput(localSubrsData);
- } else {
- return null;
- }
- }
- return null;
- }
-
- /**
- * Parses the char string index from the CFF byte data
- * @param offset The offset to the char string index
- * @return Returns the char string index object
- * @throws IOException Throws an IO Exception if an error occurs
- */
- public CFFIndexData readCharStringIndex() throws IOException {
- int offset = topDict.get("CharStrings").getOperands().get(0).intValue();
- cffData.setPosition(offset);
- return readIndex();
- }
-
- private CustomEncoding readEncoding() throws IOException {
- CustomEncoding foundEncoding = null;
- if (topDict.get("Encoding") != null) {
- int offset = topDict.get("Encoding").getOperands().get(0).intValue();
- if (offset != 0 && offset != 1) {
- //No need to set the offset as we are reading the data sequentially.
- int format = cffData.readCard8();
- int numEntries = cffData.readCard8();
- switch (format) {
- case 0:
- foundEncoding = readFormat0Encoding(format, numEntries);
- break;
- case 1:
- foundEncoding = readFormat1Encoding(format, numEntries);
- break;
- default: break;
- }
- }
- }
- return foundEncoding;
- }
-
- private Format0Encoding readFormat0Encoding(int format, int numEntries)
- throws IOException {
- Format0Encoding newEncoding = new Format0Encoding();
- newEncoding.setFormat(format);
- newEncoding.setNumEntries(numEntries);
- int[] codes = new int[numEntries];
- for (int i = 0; i < numEntries; i++) {
- codes[i] = cffData.readCard8();
- }
- newEncoding.setCodes(codes);
- return newEncoding;
- }
-
- private Format1Encoding readFormat1Encoding(int format, int numEntries)
- throws IOException {
- Format1Encoding newEncoding = new Format1Encoding();
- newEncoding.setFormat(format);
- newEncoding.setNumEntries(numEntries);
- LinkedHashMap<Integer, Integer> ranges = new LinkedHashMap<Integer, Integer>();
- for (int i = 0; i < numEntries; i++) {
- int first = cffData.readCard8();
- int left = cffData.readCard8();
- ranges.put(first, left);
- }
- newEncoding.setRanges(ranges);
- return newEncoding;
- }
-
- private FDSelect readFDSelect() throws IOException {
- FDSelect fdSelect = null;
- DICTEntry fdSelectEntry = topDict.get("FDSelect");
- if (fdSelectEntry != null) {
- int fdOffset = fdSelectEntry.getOperands().get(0).intValue();
- cffData.setPosition(fdOffset);
- int format = cffData.readCard8();
- switch (format) {
- case 0:
- fdSelect = readFormat0FDSelect();
- break;
- case 3:
- fdSelect = readFormat3FDSelect();
- break;
- default:
- }
- }
- return fdSelect;
- }
-
- private Format0FDSelect readFormat0FDSelect() throws IOException {
- Format0FDSelect newFDs = new Format0FDSelect();
- newFDs.setFormat(0);
- int glyphCount = charStringIndex.getNumObjects();
- int[] fds = new int[glyphCount];
- for (int i = 0; i < glyphCount; i++) {
- fds[i] = cffData.readCard8();
- }
- newFDs.setFDIndexes(fds);
- return newFDs;
- }
-
- private Format3FDSelect readFormat3FDSelect() throws IOException {
- Format3FDSelect newFDs = new Format3FDSelect();
- newFDs.setFormat(3);
- int rangeCount = cffData.readCard16();
- newFDs.setRangeCount(rangeCount);
- LinkedHashMap<Integer, Integer> ranges = new LinkedHashMap<Integer, Integer>();
- for (int i = 0; i < rangeCount; i++) {
- int first = cffData.readCard16();
- int fd = cffData.readCard8();
- ranges.put(first, fd);
- }
- newFDs.setRanges(ranges);
- newFDs.setSentinelGID(cffData.readCard16());
- return newFDs;
- }
-
- private List<FontDict> parseCIDData() throws IOException {
- ArrayList<FontDict> fdFonts = new ArrayList<FontDict>();
- if (topDict.get("ROS") != null) {
- DICTEntry fdArray = topDict.get("FDArray");
- if (fdArray != null) {
- int fdIndex = fdArray.getOperands().get(0).intValue();
- CFFIndexData fontDicts = readIndex(fdIndex);
- for (int i = 0; i < fontDicts.getNumObjects(); i++) {
- FontDict newFontDict = new FontDict();
-
- byte[] fdData = fontDicts.getValue(i);
- LinkedHashMap<String, DICTEntry> fdEntries = parseDictData(fdData);
- newFontDict.setByteData(fontDicts.getValuePosition(i), fontDicts.getValueLength(i));
- DICTEntry fontFDEntry = fdEntries.get("FontName");
- if (fontFDEntry != null) {
- newFontDict.setFontName(getString(fontFDEntry.getOperands().get(0).intValue()));
- }
- DICTEntry privateFDEntry = fdEntries.get("Private");
- if (privateFDEntry != null) {
- newFontDict = setFDData(privateFDEntry, newFontDict);
- }
-
- fdFonts.add(newFontDict);
- }
- }
- }
- return fdFonts;
- }
-
- private FontDict setFDData(DICTEntry privateFDEntry, FontDict newFontDict) throws IOException {
- int privateFDLength = privateFDEntry.getOperands().get(0).intValue();
- int privateFDOffset = privateFDEntry.getOperands().get(1).intValue();
- cffData.setPosition(privateFDOffset);
- byte[] privateDict = cffData.readBytes(privateFDLength);
- newFontDict.setPrivateDictData(privateFDOffset, privateFDLength);
- LinkedHashMap<String, DICTEntry> privateEntries = parseDictData(privateDict);
- DICTEntry subroutines = privateEntries.get("Subrs");
- if (subroutines != null) {
- CFFIndexData localSubrs = readIndex(privateFDOffset
- + subroutines.getOperands().get(0).intValue());
- newFontDict.setLocalSubrData(localSubrs);
- } else {
- newFontDict.setLocalSubrData(new CFFIndexData());
- }
- return newFontDict;
- }
-
- private String getString(int sid) throws IOException {
- return new String(stringIndex.getValue(sid - NUM_STANDARD_STRINGS));
- }
-
- private CFFIndexData readLocalIndexSubrs() throws IOException {
- CFFIndexData localSubrs = null;
- DICTEntry privateEntry = topDict.get("Private");
- if (privateEntry != null) {
- int length = privateEntry.getOperands().get(0).intValue();
- int offset = privateEntry.getOperands().get(1).intValue();
- cffData.setPosition(offset);
- byte[] privateData = cffData.readBytes(length);
- LinkedHashMap<String, DICTEntry> privateDict = parseDictData(privateData);
- DICTEntry localSubrsEntry = privateDict.get("Subrs");
- if (localSubrsEntry != null) {
- int localOffset = offset + localSubrsEntry.getOperands().get(0).intValue();
- cffData.setPosition(localOffset);
- localSubrs = readIndex();
- }
- }
- return localSubrs;
- }
-
- /**
- * Parent class which provides the ability to retrieve byte data from
- * a sub-table.
- */
- public class CFFSubTable {
- private DataLocation dataLocation = new DataLocation();
-
- public void setByteData(int position, int length) {
- dataLocation = new DataLocation(position, length);
- }
-
- public byte[] getByteData() throws IOException {
- int oldPos = cffData.getPosition();
- try {
- cffData.setPosition(dataLocation.getDataPosition());
- return cffData.readBytes(dataLocation.getDataLength());
- } finally {
- cffData.setPosition(oldPos);
- }
- }
- }
-
- /**
- * An object used to hold index data from the CFF data
- */
- public class CFFIndexData extends CFFSubTable {
- private int numObjects;
- private int offSize;
- private int[] offsets = new int[0];
- private DataLocation dataLocation = new DataLocation();
-
- public void setNumObjects(int numObjects) {
- this.numObjects = numObjects;
- }
-
- public int getNumObjects() {
- return this.numObjects;
- }
-
- public void setOffSize(int offSize) {
- this.offSize = offSize;
- }
-
- public int getOffSize() {
- return this.offSize;
- }
-
- public void setOffsets(int[] offsets) {
- this.offsets = offsets.clone();
- }
-
- public int[] getOffsets() {
- return offsets.clone();
- }
-
- public void setData(int position, int length) {
- dataLocation = new DataLocation(position, length);
- }
-
- public byte[] getData() throws IOException {
- int origPos = cffData.getPosition();
- try {
- cffData.setPosition(dataLocation.getDataPosition());
- return cffData.readBytes(dataLocation.getDataLength());
- } finally {
- cffData.setPosition(origPos);
- }
- }
-
- /**
- * Parses index data from an index object found within the CFF byte data
- * @param cffData A byte array containing the CFF data
- * @throws IOException Throws an IO Exception if an error occurs
- */
- public void parseIndexHeader(CFFDataInput cffData) throws IOException {
- setNumObjects(cffData.readCard16());
- setOffSize(cffData.readOffSize());
- int[] offsets = new int[getNumObjects() + 1];
- byte[] bytes;
- //Fills the offsets array
- for (int i = 0; i <= getNumObjects(); i++) {
- switch (getOffSize()) {
- case 1:
- offsets[i] = cffData.readCard8();
- break;
- case 2:
- offsets[i] = cffData.readCard16();
- break;
- case 3:
- bytes = cffData.readBytes(3);
- offsets[i] = ((bytes[0] & 0xFF) << 16) + ((bytes[1] & 0xFF) << 8) + (bytes[2] & 0xFF);
- break;
- case 4:
- bytes = cffData.readBytes(4);
- offsets[i] = ((bytes[0] & 0xFF) << 24) + ((bytes[1] & 0xFF) << 16)
- + ((bytes[2] & 0xFF) << 8) + (bytes[3] & 0xFF);
- break;
- default: continue;
- }
- }
- setOffsets(offsets);
- int position = cffData.getPosition();
- int dataSize = offsets[offsets.length - 1] - offsets[0];
-
- cffData.setPosition(cffData.getPosition() + dataSize);
- setData(position, dataSize);
- }
-
- /**
- * Retrieves data from the index data
- * @param index The index position of the data to retrieve
- * @return Returns the byte data for the given index
- * @throws IOException Throws an IO Exception if an error occurs
- */
- public byte[] getValue(int index) throws IOException {
- int oldPos = cffData.getPosition();
- try {
- cffData.setPosition(dataLocation.getDataPosition() + (offsets[index] - 1));
- return cffData.readBytes(offsets[index + 1] - offsets[index]);
- } finally {
- cffData.setPosition(oldPos);
- }
- }
-
- public int getValuePosition(int index) {
- return dataLocation.getDataPosition() + (offsets[index] - 1);
- }
-
- public int getValueLength(int index) {
- return offsets[index + 1] - offsets[index];
- }
- }
-
- public abstract class CustomEncoding {
- private int format;
- private int numEntries;
-
- public void setFormat(int format) {
- this.format = format;
- }
-
- public int getFormat() {
- return format;
- }
-
- public void setNumEntries(int numEntries) {
- this.numEntries = numEntries;
- }
-
- public int getNumEntries() {
- return numEntries;
- }
- }
-
- public class Format0Encoding extends CustomEncoding {
- private int[] codes = new int[0];
-
- public void setCodes(int[] codes) {
- this.codes = codes.clone();
- }
-
- public int[] getCodes() {
- return codes.clone();
- }
- }
-
- public class Format1Encoding extends CustomEncoding {
- private LinkedHashMap<Integer, Integer> ranges;
-
- public void setRanges(LinkedHashMap<Integer, Integer> ranges) {
- this.ranges = ranges;
- }
-
- public LinkedHashMap<Integer, Integer> getRanges() {
- return ranges;
- }
- }
-
- public class FDSelect {
- private int format;
-
- public void setFormat(int format) {
- this.format = format;
- }
-
- public int getFormat() {
- return format;
- }
- }
-
- public class Format0FDSelect extends FDSelect {
- private int[] fds = new int[0];
-
- public void setFDIndexes(int[] fds) {
- this.fds = fds.clone();
- }
-
- public int[] getFDIndexes() {
- return fds.clone();
- }
- }
-
- public class Format3FDSelect extends FDSelect {
- private int rangeCount;
- private LinkedHashMap<Integer, Integer> ranges;
- private int sentinelGID;
-
- public void setRangeCount(int rangeCount) {
- this.rangeCount = rangeCount;
- }
-
- public int getRangeCount() {
- return rangeCount;
- }
-
- public void setRanges(LinkedHashMap<Integer, Integer> ranges) {
- this.ranges = ranges;
- }
-
- public LinkedHashMap<Integer, Integer> getRanges() {
- return ranges;
- }
-
- public void setSentinelGID(int sentinelGID) {
- this.sentinelGID = sentinelGID;
- }
-
- public int getSentinelGID() {
- return sentinelGID;
- }
- }
-
- public class FontDict extends CFFSubTable {
- private String fontName;
- private DataLocation dataLocation = new DataLocation();
- private CFFIndexData localSubrData;
-
- public void setFontName(String groupName) {
- this.fontName = groupName;
- }
-
- public String getFontName() {
- return fontName;
- }
-
- public void setPrivateDictData(int position, int length) {
- dataLocation = new DataLocation(position, length);
- }
-
- public byte[] getPrivateDictData() throws IOException {
- int origPos = cffData.getPosition();
- try {
- cffData.setPosition(dataLocation.getDataPosition());
- return cffData.readBytes(dataLocation.getDataLength());
- } finally {
- cffData.setPosition(origPos);
- }
- }
-
- public void setLocalSubrData(CFFIndexData localSubrData) {
- this.localSubrData = localSubrData;
- }
-
- public CFFIndexData getLocalSubrData() {
- return localSubrData;
- }
- }
-
- private static class DataLocation {
- private int dataPosition;
- private int dataLength;
-
- public DataLocation() {
- dataPosition = 0;
- dataLength = 0;
- }
-
- public DataLocation(int position, int length) {
- this.dataPosition = position;
- this.dataLength = length;
- }
-
- public int getDataPosition() {
- return dataPosition;
- }
-
- public int getDataLength() {
- return dataLength;
- }
- }
-}
diff --git a/src/java/org/apache/fop/fonts/package.html b/src/java/org/apache/fop/fonts/package.html
deleted file mode 100644
index fee0bf827..000000000
--- a/src/java/org/apache/fop/fonts/package.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!--
- 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.html 643433 2008-04-01 15:08:24Z acumiskey $ -->
-<HTML>
-<TITLE>org.apache.fop.fonts Package</TITLE>
-<BODY>
-<P>Classes for font handling. Subpackages contain command line applications for font metrics generation, font parsing classes etc.</P>
-</BODY>
-</HTML> \ No newline at end of file
diff --git a/src/java/org/apache/fop/fonts/substitute/AttributeValue.java b/src/java/org/apache/fop/fonts/substitute/AttributeValue.java
deleted file mode 100644
index bfe888d3c..000000000
--- a/src/java/org/apache/fop/fonts/substitute/AttributeValue.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.substitute;
-
-import java.util.StringTokenizer;
-
-/**
- * Encapsulates a font attribute value
- */
-public class AttributeValue extends java.util.ArrayList {
-
- private static final long serialVersionUID = 748610847500940557L;
-
- /**
- * Returns an <code>AttributeValue</code> object holding the
- * value of the specified <code>String</code>.
- *
- * @param valuesString the value to be parsed
- * @return an <code>AttributeValue</code> object holding the value
- * represented by the string argument.
- */
- public static AttributeValue valueOf(String valuesString) {
- AttributeValue attribute = new AttributeValue();
- StringTokenizer stringTokenizer = new StringTokenizer(valuesString, ",");
- if (stringTokenizer.countTokens() > 1) {
- while (stringTokenizer.hasMoreTokens()) {
- String token = stringTokenizer.nextToken().trim();
- AttributeValue tokenAttribute = AttributeValue.valueOf(token);
- attribute.addAll(tokenAttribute);
- }
- } else {
- String token = stringTokenizer.nextToken().trim();
- Object value = null;
- try {
- value = Integer.valueOf(token);
- } catch (NumberFormatException ex) {
- value = FontWeightRange.valueOf(token);
- if (value == null) {
- value = token;
- }
- }
- if (value != null) {
- attribute.add(value);
- }
- }
- return attribute;
- }
-}
diff --git a/src/java/org/apache/fop/fonts/substitute/FontQualifier.java b/src/java/org/apache/fop/fonts/substitute/FontQualifier.java
deleted file mode 100644
index 8e9213e9d..000000000
--- a/src/java/org/apache/fop/fonts/substitute/FontQualifier.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * 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.substitute;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.fonts.Font;
-import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.fonts.FontTriplet;
-import org.apache.fop.fonts.FontUtil;
-
-/**
- * Encapsulates a font substitution qualifier
- */
-public class FontQualifier {
-
- /** logger instance */
- private static Log log = LogFactory.getLog(FontQualifier.class);
-
- /** font family attribute value */
- private AttributeValue fontFamilyAttributeValue;
-
- /** font style attribute value */
- private AttributeValue fontStyleAttributeValue;
-
- /** font weight attribute value */
- private AttributeValue fontWeightAttributeValue;
-
- /**
- * Default constructor
- */
- public FontQualifier() {
- }
-
- /**
- * Sets the font family
- * @param fontFamily the font family
- */
- public void setFontFamily(String fontFamily) {
- AttributeValue fontFamilyAttribute = AttributeValue.valueOf(fontFamily);
- if (fontFamilyAttribute == null) {
- log.error("Invalid font-family value '" + fontFamily + "'");
- return;
- }
- this.fontFamilyAttributeValue = fontFamilyAttribute;
- }
-
- /**
- * Sets the font style
- * @param fontStyle the font style
- */
- public void setFontStyle(String fontStyle) {
- AttributeValue fontStyleAttribute = AttributeValue.valueOf(fontStyle);
- if (fontStyleAttribute != null) {
- this.fontStyleAttributeValue = fontStyleAttribute;
- }
- }
-
- /**
- * Sets the font weight
- * @param fontWeight the font weight
- */
- public void setFontWeight(String fontWeight) {
- AttributeValue fontWeightAttribute = AttributeValue.valueOf(fontWeight);
- if (fontWeightAttribute != null) {
- for (Iterator it = fontWeightAttribute.iterator(); it.hasNext();) {
- Object weightObj = it.next();
- if (weightObj instanceof String) {
- String weightString = ((String)weightObj).trim();
- try {
- FontUtil.parseCSS2FontWeight(weightString);
- } catch (IllegalArgumentException ex) {
- log.error("Invalid font-weight value '" + weightString + "'");
- return;
- }
- }
- }
- this.fontWeightAttributeValue = fontWeightAttribute;
- }
- }
-
- /**
- * @return the font family attribute
- */
- public AttributeValue getFontFamily() {
- return this.fontFamilyAttributeValue;
- }
-
- /**
- * @return the font style attribute
- */
- public AttributeValue getFontStyle() {
- if (fontStyleAttributeValue == null) {
- return AttributeValue.valueOf(Font.STYLE_NORMAL);
- }
- return this.fontStyleAttributeValue;
- }
-
- /**
- * @return the font weight attribute
- */
- public AttributeValue getFontWeight() {
- if (fontWeightAttributeValue == null) {
- return AttributeValue.valueOf(Integer.toString(Font.WEIGHT_NORMAL));
- }
- return this.fontWeightAttributeValue;
- }
-
- /**
- * @return true if this rule has a font weight
- */
- public boolean hasFontWeight() {
- return this.fontWeightAttributeValue != null;
- }
-
- /**
- * @return true if this rule has a font style
- */
- public boolean hasFontStyle() {
- return this.fontStyleAttributeValue != null;
- }
-
- /**
- * Returns a list of matching font triplet found in a given font info
- *
- * @param fontInfo the font info
- * @return a list of matching font triplets
- */
- protected List/*<FontTriplet>*/ match(FontInfo fontInfo) {
- AttributeValue fontFamilyValue = getFontFamily();
- AttributeValue weightValue = getFontWeight();
- AttributeValue styleValue = getFontStyle();
-
- List/*<FontTriplet>*/ matchingTriplets = new java.util.ArrayList/*<FontTriplet>*/();
-
- // try to find matching destination font triplet
- for (Iterator attrIt = fontFamilyValue.iterator(); attrIt.hasNext();) {
- String fontFamilyString = (String)attrIt.next();
- Map/*<FontTriplet>*/ triplets = (Map/*<FontTriplet>*/)fontInfo.getFontTriplets();
- if (triplets != null) {
- Set/*<FontTriplet>*/ tripletSet = triplets.keySet();
- for (Iterator/*<FontTriplet>*/ tripletIt = tripletSet.iterator();
- tripletIt.hasNext();) {
- FontTriplet triplet = (FontTriplet)tripletIt.next();
- String fontName = triplet.getName();
-
- // matched font family name
- if (fontFamilyString.toLowerCase().equals(fontName.toLowerCase())) {
-
- // try and match font weight
- boolean weightMatched = false;
- int fontWeight = triplet.getWeight();
- for (Iterator weightIt = weightValue.iterator(); weightIt.hasNext();) {
- Object weightObj = weightIt.next();
- if (weightObj instanceof FontWeightRange) {
- FontWeightRange intRange = (FontWeightRange)weightObj;
- if (intRange.isWithinRange(fontWeight)) {
- weightMatched = true;
- }
- } else if (weightObj instanceof String) {
- String fontWeightString = (String)weightObj;
- int fontWeightValue = FontUtil.parseCSS2FontWeight(
- fontWeightString);
- if (fontWeightValue == fontWeight) {
- weightMatched = true;
- }
- } else if (weightObj instanceof Integer) {
- Integer fontWeightInteger = (Integer)weightObj;
- int fontWeightValue = fontWeightInteger.intValue();
- if (fontWeightValue == fontWeight) {
- weightMatched = true;
- }
- }
- }
-
- // try and match font style
- boolean styleMatched = false;
- String fontStyleString = triplet.getStyle();
- for (Iterator styleIt = styleValue.iterator(); styleIt.hasNext();) {
- String style = (String)styleIt.next();
- if (fontStyleString.equals(style)) {
- styleMatched = true;
- }
- }
-
- if (weightMatched && styleMatched) {
- matchingTriplets.add(triplet);
- }
- }
- }
- }
- }
- return matchingTriplets;
- }
-
- /**
- * Returns the highest priority matching font triplet found in a given font info
- * @param fontInfo the font info
- * @return the highest priority matching font triplet
- */
- protected FontTriplet bestMatch(FontInfo fontInfo) {
- List/*<FontTriplet>*/ matchingTriplets = match(fontInfo);
- FontTriplet bestTriplet = null;
- if (matchingTriplets.size() == 1) {
- bestTriplet = (FontTriplet)matchingTriplets.get(0);
- } else {
- for (Iterator iterator = matchingTriplets.iterator(); iterator.hasNext();) {
- FontTriplet triplet = (FontTriplet)iterator.next();
- if (bestTriplet == null) {
- bestTriplet = triplet;
- } else {
- int priority = triplet.getPriority();
- if (priority < bestTriplet.getPriority()) {
- bestTriplet = triplet;
- }
- }
- }
- }
- return bestTriplet;
- }
-
- /**
- * @return a list of font triplets matching this qualifier
- */
- public List/*<FontTriplet>*/ getTriplets() {
- List/*<FontTriplet>*/ triplets = new java.util.ArrayList/*<FontTriplet>*/();
-
- AttributeValue fontFamilyValue = getFontFamily();
- for (Iterator fontFamilyIt = fontFamilyValue.iterator(); fontFamilyIt.hasNext();) {
- String name = (String)fontFamilyIt.next();
-
- AttributeValue styleValue = getFontStyle();
- for (Iterator styleIt = styleValue.iterator(); styleIt.hasNext();) {
- String style = (String)styleIt.next();
-
- AttributeValue weightValue = getFontWeight();
- for (Iterator weightIt = weightValue.iterator(); weightIt.hasNext();) {
- Object weightObj = weightIt.next();
-
- if (weightObj instanceof FontWeightRange) {
- FontWeightRange fontWeightRange = (FontWeightRange)weightObj;
- int[] weightRange = fontWeightRange.toArray();
- for (int i = 0; i < weightRange.length; i++) {
- triplets.add(new FontTriplet(name, style, weightRange[i]));
- }
- } else if (weightObj instanceof String) {
- String weightString = (String)weightObj;
- int weight = FontUtil.parseCSS2FontWeight(weightString);
- triplets.add(new FontTriplet(name, style, weight));
- } else if (weightObj instanceof Integer) {
- Integer weightInteger = (Integer)weightObj;
- int weight = weightInteger.intValue();
- triplets.add(new FontTriplet(name, style, weight));
- }
- }
- }
- }
- return triplets;
- }
-
- /**
- * {@inheritDoc}
- */
- public String toString() {
- String str = "";
- if (fontFamilyAttributeValue != null) {
- str += "font-family=" + fontFamilyAttributeValue;
- }
- if (fontStyleAttributeValue != null) {
- if (str.length() > 0) {
- str += ", ";
- }
- str += "font-style=" + fontStyleAttributeValue;
- }
- if (fontWeightAttributeValue != null) {
- if (str.length() > 0) {
- str += ", ";
- }
- str += "font-weight=" + fontWeightAttributeValue;
- }
- return str;
- }
-}
diff --git a/src/java/org/apache/fop/fonts/substitute/FontSubstitution.java b/src/java/org/apache/fop/fonts/substitute/FontSubstitution.java
deleted file mode 100644
index 7725fc147..000000000
--- a/src/java/org/apache/fop/fonts/substitute/FontSubstitution.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.substitute;
-
-/**
- * Encapsulates a pair of substitution qualifiers
- */
-public class FontSubstitution {
-
- private FontQualifier fromQualifier;
- private FontQualifier toQualifier;
-
- /**
- * Main constructor
- *
- * @param fromQualifier the substitution from qualifier
- * @param toQualifier the substitution to qualifier
- */
- public FontSubstitution(FontQualifier fromQualifier, FontQualifier toQualifier) {
- this.fromQualifier = fromQualifier;
- this.toQualifier = toQualifier;
- }
-
- /**
- * @return the substitution from qualifier
- */
- public FontQualifier getFromQualifier() {
- return fromQualifier;
- }
-
- /**
- * @return the substitution to qualifier
- */
- public FontQualifier getToQualifier() {
- return toQualifier;
- }
-
- /**
- * {@inheritDoc}
- */
- public String toString() {
- return "from=" + fromQualifier + ", to=" + toQualifier;
- }
-}
diff --git a/src/java/org/apache/fop/fonts/substitute/FontSubstitutions.java b/src/java/org/apache/fop/fonts/substitute/FontSubstitutions.java
deleted file mode 100644
index e96459577..000000000
--- a/src/java/org/apache/fop/fonts/substitute/FontSubstitutions.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.substitute;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.fonts.FontTriplet;
-
-/**
- * Font substitutions
- */
-public class FontSubstitutions extends java.util.ArrayList/*<Substitutions>*/ {
-
- private static final long serialVersionUID = -9173104935431899722L;
-
- /** logging instance */
- protected static final Log log = LogFactory.getLog(FontSubstitutions.class);
-
- /**
- * Adjusts a given fontInfo using this font substitution catalog
- * @param fontInfo font info
- */
- public void adjustFontInfo(FontInfo fontInfo) {
- for (Iterator/*<FontSubstitution>*/ subsIt = super.iterator(); subsIt.hasNext();) {
- FontSubstitution substitution = (FontSubstitution)subsIt.next();
-
- // find the best matching font triplet
- FontQualifier toQualifier = substitution.getToQualifier();
- FontTriplet fontTriplet = toQualifier.bestMatch(fontInfo);
- if (fontTriplet == null) {
- log.error("Unable to match font substitution for destination qualifier "
- + toQualifier);
- continue;
- }
- String internalFontKey = fontInfo.getInternalFontKey(fontTriplet);
-
- FontQualifier fromQualifier = substitution.getFromQualifier();
- List/*<FontTriplet>*/ tripletList = fromQualifier.getTriplets();
- for (Iterator tripletit = tripletList.iterator(); tripletit.hasNext();) {
- FontTriplet triplet = (FontTriplet) tripletit.next();
- fontInfo.addFontProperties(internalFontKey, triplet);
- }
- }
- }
-}
diff --git a/src/java/org/apache/fop/fonts/substitute/FontSubstitutionsConfigurator.java b/src/java/org/apache/fop/fonts/substitute/FontSubstitutionsConfigurator.java
deleted file mode 100644
index fb60473fc..000000000
--- a/src/java/org/apache/fop/fonts/substitute/FontSubstitutionsConfigurator.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.substitute;
-
-import org.apache.avalon.framework.configuration.Configuration;
-
-import org.apache.fop.apps.FOPException;
-
-/**
- * Configures a font substitution catalog
- */
-public class FontSubstitutionsConfigurator {
-
- private Configuration cfg;
-
- /**
- * Main constructor
- *
- * @param cfg a configuration
- */
- public FontSubstitutionsConfigurator(Configuration cfg) {
- this.cfg = cfg;
- }
-
- private static FontQualifier getQualfierFromConfiguration(Configuration cfg)
- throws FOPException {
- String fontFamily = cfg.getAttribute("font-family", null);
- if (fontFamily == null) {
- throw new FOPException("substitution qualifier must have a font-family");
- }
- FontQualifier qualifier = new FontQualifier();
- qualifier.setFontFamily(fontFamily);
- String fontWeight = cfg.getAttribute("font-weight", null);
- if (fontWeight != null) {
- qualifier.setFontWeight(fontWeight);
- }
- String fontStyle = cfg.getAttribute("font-style", null);
- if (fontStyle != null) {
- qualifier.setFontStyle(fontStyle);
- }
- return qualifier;
- }
-
- /**
- * Configures a font substitution catalog
- *
- * @param substitutions font substitutions
- * @throws FOPException if something's wrong with the config data
- */
- public void configure(FontSubstitutions substitutions) throws FOPException {
- Configuration[] substitutionCfgs = cfg.getChildren("substitution");
- for (int i = 0; i < substitutionCfgs.length; i++) {
- Configuration fromCfg = substitutionCfgs[i].getChild("from", false);
- if (fromCfg == null) {
- throw new FOPException("'substitution' element without child 'from' element");
- }
- Configuration toCfg = substitutionCfgs[i].getChild("to", false);
- if (fromCfg == null) {
- throw new FOPException("'substitution' element without child 'to' element");
- }
- FontQualifier fromQualifier = getQualfierFromConfiguration(fromCfg);
- FontQualifier toQualifier = getQualfierFromConfiguration(toCfg);
- FontSubstitution substitution = new FontSubstitution(fromQualifier, toQualifier);
- substitutions.add(substitution);
- }
- }
-}
diff --git a/src/java/org/apache/fop/fonts/substitute/FontWeightRange.java b/src/java/org/apache/fop/fonts/substitute/FontWeightRange.java
deleted file mode 100644
index 34e04eb67..000000000
--- a/src/java/org/apache/fop/fonts/substitute/FontWeightRange.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.substitute;
-
-import java.util.StringTokenizer;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Encapsulates a range of font weight values
- */
-public class FontWeightRange {
-
- /** logging instance */
- protected static final Log log = LogFactory.getLog("org.apache.fop.render.fonts");
-
- /**
- * Returns an <code>FontWeightRange</code> object holding the
- * range values of the specified <code>String</code>.
- *
- * @param weightRangeString the value range string
- * @return an <code>FontWeightRange</code> object holding the value ranges
- */
- public static FontWeightRange valueOf(String weightRangeString) {
- StringTokenizer rangeToken = new StringTokenizer(weightRangeString, "..");
- FontWeightRange weightRange = null;
- if (rangeToken.countTokens() == 2) {
- String weightString = rangeToken.nextToken().trim();
- try {
- int start = Integer.parseInt(weightString);
- if (start % 100 != 0) {
- log.error("font-weight start range is not a multiple of 100");
- }
- int end = Integer.parseInt(rangeToken.nextToken());
- if (end % 100 != 0) {
- log.error("font-weight end range is not a multiple of 100");
- }
- if (start <= end) {
- weightRange = new FontWeightRange(start, end);
- } else {
- log.error("font-weight start range is greater than end range");
- }
- } catch (NumberFormatException e) {
- log.error("invalid font-weight value " + weightString);
- }
- }
- return weightRange;
- }
-
- /** the start range */
- private int start;
-
- /** the end range */
- private int end;
-
- /**
- * Main constructor
- * @param start the start value range
- * @param end the end value range
- */
- public FontWeightRange(int start, int end) {
- this.start = start;
- this.end = end;
- }
-
- /**
- * Returns true if the given integer value is within this integer range
- * @param value the integer value
- * @return true if the given integer value is within this integer range
- */
- public boolean isWithinRange(int value) {
- return (value >= start && value <= end);
- }
-
- /**
- * {@inheritDoc}
- */
- public String toString() {
- return start + ".." + end;
- }
-
- /**
- * @return an integer array containing the weight ranges
- */
- public int[] toArray() {
- int cnt = 0;
- for (int i = start; i <= end; i += 100) {
- cnt++;
- }
- int[] range = new int[cnt];
- for (int i = 0; i < cnt; i++) {
- range[i] = start + (i * 100);
- }
- return range;
- }
-}
diff --git a/src/java/org/apache/fop/fonts/substitute/package.html b/src/java/org/apache/fop/fonts/substitute/package.html
deleted file mode 100644
index c144ca1f8..000000000
--- a/src/java/org/apache/fop/fonts/substitute/package.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!--
- 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$ -->
-<HTML>
-<TITLE>org.apache.fop.fonts.substitute Package</TITLE>
-<BODY>
-<P>Font substitution facilities.</P>
-</BODY>
-</HTML> \ No newline at end of file
diff --git a/src/java/org/apache/fop/fonts/truetype/FontFileReader.java b/src/java/org/apache/fop/fonts/truetype/FontFileReader.java
deleted file mode 100644
index 790e885bc..000000000
--- a/src/java/org/apache/fop/fonts/truetype/FontFileReader.java
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * 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.truetype;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.commons.io.IOUtils;
-
-/**
- * Reads a TrueType font file into a byte array and
- * provides file like functions for array access.
- */
-public class FontFileReader {
-
- private final int fsize; // file size
- private int current; // current position in file
- private final byte[] file;
-
- /**
- * Constructor
- *
- * @param in InputStream to read from
- * @throws IOException In case of an I/O problem
- */
- public FontFileReader(InputStream in) throws IOException {
- this.file = IOUtils.toByteArray(in);
- this.fsize = this.file.length;
- this.current = 0;
- }
-
-
- /**
- * Set current file position to offset
- *
- * @param offset The new offset to set
- * @throws IOException In case of an I/O problem
- */
- public void seekSet(long offset) throws IOException {
- if (offset > fsize || offset < 0) {
- throw new java.io.EOFException("Reached EOF, file size=" + fsize
- + " offset=" + offset);
- }
- current = (int)offset;
- }
-
- /**
- * Skip a given number of bytes.
- *
- * @param add The number of bytes to advance
- * @throws IOException In case of an I/O problem
- */
- public void skip(long add) throws IOException {
- seekSet(current + add);
- }
-
- /**
- * Returns current file position.
- *
- * @return int The current position.
- */
- public int getCurrentPos() {
- return current;
- }
-
- /**
- * Returns the size of the file.
- *
- * @return int The filesize
- */
- public int getFileSize() {
- return fsize;
- }
-
- /**
- * Read 1 byte.
- *
- * @return One byte
- * @throws IOException If EOF is reached
- */
- private byte read() throws IOException {
- if (current >= fsize) {
- throw new java.io.EOFException("Reached EOF, file size=" + fsize);
- }
-
- final byte ret = file[current++];
- return ret;
- }
-
- /**
- * Read 1 signed byte.
- *
- * @return One byte
- * @throws IOException If EOF is reached
- */
- public final byte readTTFByte() throws IOException {
- return read();
- }
-
- /**
- * Read 1 unsigned byte.
- *
- * @return One unsigned byte
- * @throws IOException If EOF is reached
- */
- public final int readTTFUByte() throws IOException {
- final byte buf = read();
-
- if (buf < 0) {
- return (256 + buf);
- } else {
- return buf;
- }
- }
-
- /**
- * Read 2 bytes signed.
- *
- * @return One signed short
- * @throws IOException If EOF is reached
- */
- public final short readTTFShort() throws IOException {
- final int ret = (readTTFUByte() << 8) + readTTFUByte();
- final short sret = (short)ret;
- return sret;
- }
-
- /**
- * Read 2 bytes unsigned.
- *
- * @return One unsigned short
- * @throws IOException If EOF is reached
- */
- public final int readTTFUShort() throws IOException {
- final int ret = (readTTFUByte() << 8) + readTTFUByte();
- return ret;
- }
-
- /**
- * Write a USHort at a given position.
- *
- * @param pos The absolute position to write to
- * @param val The value to write
- * @throws IOException If EOF is reached
- */
- public final void writeTTFUShort(long pos, int val) throws IOException {
- if ((pos + 2) > fsize) {
- throw new java.io.EOFException("Reached EOF");
- }
- final byte b1 = (byte)((val >> 8) & 0xff);
- final byte b2 = (byte)(val & 0xff);
- final int fileIndex = (int) pos;
- file[fileIndex] = b1;
- file[fileIndex + 1] = b2;
- }
-
- /**
- * Read 2 bytes signed at position pos without changing current position.
- *
- * @param pos The absolute position to read from
- * @return One signed short
- * @throws IOException If EOF is reached
- */
- public final short readTTFShort(long pos) throws IOException {
- final long cp = getCurrentPos();
- seekSet(pos);
- final short ret = readTTFShort();
- seekSet(cp);
- return ret;
- }
-
- /**
- * Read 2 bytes unsigned at position pos without changing current position.
- *
- * @param pos The absolute position to read from
- * @return One unsigned short
- * @throws IOException If EOF is reached
- */
- public final int readTTFUShort(long pos) throws IOException {
- long cp = getCurrentPos();
- seekSet(pos);
- int ret = readTTFUShort();
- seekSet(cp);
- return ret;
- }
-
- /**
- * Read 4 bytes.
- *
- * @return One signed integer
- * @throws IOException If EOF is reached
- */
- public final int readTTFLong() throws IOException {
- long ret = readTTFUByte(); // << 8;
- ret = (ret << 8) + readTTFUByte();
- ret = (ret << 8) + readTTFUByte();
- ret = (ret << 8) + readTTFUByte();
-
- return (int)ret;
- }
-
- /**
- * Read 4 bytes.
- *
- * @return One unsigned integer
- * @throws IOException If EOF is reached
- */
- public final long readTTFULong() throws IOException {
- long ret = readTTFUByte();
- ret = (ret << 8) + readTTFUByte();
- ret = (ret << 8) + readTTFUByte();
- ret = (ret << 8) + readTTFUByte();
-
- return ret;
- }
-
- /**
- * Read a NUL terminated ISO-8859-1 string.
- *
- * @return A String
- * @throws IOException If EOF is reached
- */
- public final String readTTFString() throws IOException {
- int i = current;
- while (file[i++] != 0) {
- if (i >= fsize) {
- throw new java.io.EOFException("Reached EOF, file size="
- + fsize);
- }
- }
-
- byte[] tmp = new byte[i - current - 1];
- System.arraycopy(file, current, tmp, 0, i - current - 1);
- return new String(tmp, "ISO-8859-1");
- }
-
-
- /**
- * Read an ISO-8859-1 string of len bytes.
- *
- * @param len The length of the string to read
- * @return A String
- * @throws IOException If EOF is reached
- */
- public final String readTTFString(int len) throws IOException {
- if ((len + current) > fsize) {
- throw new java.io.EOFException("Reached EOF, file size=" + fsize);
- }
-
- byte[] tmp = new byte[len];
- System.arraycopy(file, current, tmp, 0, len);
- current += len;
- final String encoding;
- if ((tmp.length > 0) && (tmp[0] == 0)) {
- encoding = "UTF-16BE";
- } else {
- encoding = "ISO-8859-1";
- }
- return new String(tmp, encoding);
- }
-
- /**
- * Read an ISO-8859-1 string of len bytes.
- *
- * @param len The length of the string to read
- * @param encodingID the string encoding id (presently ignored; always uses UTF-16BE)
- * @return A String
- * @throws IOException If EOF is reached
- */
- public final String readTTFString(int len, int encodingID) throws IOException {
- if ((len + current) > fsize) {
- throw new java.io.EOFException("Reached EOF, file size=" + fsize);
- }
-
- byte[] tmp = new byte[len];
- System.arraycopy(file, current, tmp, 0, len);
- current += len;
- final String encoding;
- encoding = "UTF-16BE"; //Use this for all known encoding IDs for now
- return new String(tmp, encoding);
- }
-
- /**
- * Return a copy of the internal array
- *
- * @param offset The absolute offset to start reading from
- * @param length The number of bytes to read
- * @return An array of bytes
- * @throws IOException if out of bounds
- */
- public byte[] getBytes(int offset,
- int length) throws IOException {
- if ((offset + length) > fsize) {
- throw new java.io.IOException("Reached EOF");
- }
-
- byte[] ret = new byte[length];
- System.arraycopy(file, offset, ret, 0, length);
- return ret;
- }
- /**
- * Returns the full byte array representation of the file.
- * @return byte array.
- */
- public byte[] getAllBytes() {
- return file;
- }
-}
diff --git a/src/java/org/apache/fop/fonts/truetype/GlyfTable.java b/src/java/org/apache/fop/fonts/truetype/GlyfTable.java
deleted file mode 100644
index 6ad479a0e..000000000
--- a/src/java/org/apache/fop/fonts/truetype/GlyfTable.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * 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.truetype;
-
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-
-/**
- * This "glyf" table in a TrueType font file contains information that describes the glyphs. This
- * class is responsible for creating a subset of the "glyf" table given a set of glyph indices.
- */
-public class GlyfTable {
-
- private final OFMtxEntry[] mtxTab;
-
- private final long tableOffset;
-
- private final Set<Long> remappedComposites;
-
- protected final Map<Integer, Integer> subset;
-
- private final FontFileReader in;
-
- /** All the composite glyphs that appear in the subset. */
- private Set<Integer> compositeGlyphs = new TreeSet<Integer>();
-
- /** All the glyphs that are composed, but do not appear in the subset. */
- protected Set<Integer> composedGlyphs = new TreeSet<Integer>();
-
- public GlyfTable(FontFileReader in, OFMtxEntry[] metrics, OFDirTabEntry dirTableEntry,
- Map<Integer, Integer> glyphs) throws IOException {
- mtxTab = metrics;
- tableOffset = dirTableEntry.getOffset();
- remappedComposites = new HashSet<Long>();
- this.subset = glyphs;
- this.in = in;
- }
-
- private static enum GlyfFlags {
-
- ARG_1_AND_2_ARE_WORDS(4, 2),
- ARGS_ARE_XY_VALUES,
- ROUND_XY_TO_GRID,
- WE_HAVE_A_SCALE(2),
- RESERVED,
- MORE_COMPONENTS,
- WE_HAVE_AN_X_AND_Y_SCALE(4),
- WE_HAVE_A_TWO_BY_TWO(8),
- WE_HAVE_INSTRUCTIONS,
- USE_MY_METRICS,
- OVERLAP_COMPOUND,
- SCALED_COMPONENT_OFFSET,
- UNSCALED_COMPONENT_OFFSET;
-
- private final int bitMask;
- private final int argsCountIfSet;
- private final int argsCountIfNotSet;
-
- private GlyfFlags(int argsCountIfSet, int argsCountIfNotSet) {
- this.bitMask = 1 << this.ordinal();
- this.argsCountIfSet = argsCountIfSet;
- this.argsCountIfNotSet = argsCountIfNotSet;
- }
-
- private GlyfFlags(int argsCountIfSet) {
- this(argsCountIfSet, 0);
- }
-
- private GlyfFlags() {
- this(0, 0);
- }
-
- /**
- * Calculates, from the given flags, the offset to the next glyph index.
- *
- * @param flags the glyph data flags
- * @return offset to the next glyph if any, or 0
- */
- static int getOffsetToNextComposedGlyf(int flags) {
- int offset = 0;
- for (GlyfFlags flag : GlyfFlags.values()) {
- offset += (flags & flag.bitMask) > 0 ? flag.argsCountIfSet : flag.argsCountIfNotSet;
- }
- return offset;
- }
-
- /**
- * Checks the given flags to see if there is another composed glyph.
- *
- * @param flags the glyph data flags
- * @return true if there is another composed glyph, otherwise false.
- */
- static boolean hasMoreComposites(int flags) {
- return (flags & MORE_COMPONENTS.bitMask) > 0;
- }
- }
-
- /**
- * Populates the map of subset glyphs with all the glyphs that compose the glyphs in the subset.
- * This also re-maps the indices of composed glyphs to their new index in the subset font.
- *
- * @throws IOException an I/O error
- */
- protected void populateGlyphsWithComposites() throws IOException {
- for (int indexInOriginal : subset.keySet()) {
- scanGlyphsRecursively(indexInOriginal);
- }
-
- addAllComposedGlyphsToSubset();
-
- for (int compositeGlyph : compositeGlyphs) {
- long offset = tableOffset + mtxTab[compositeGlyph].getOffset() + 10;
- if (!remappedComposites.contains(offset)) {
- remapComposite(offset);
- }
- }
- }
-
- /**
- * Scans each glyph for any composed glyphs. This populates <code>compositeGlyphs</code> with
- * all the composite glyphs being used in the subset. This also populates <code>newGlyphs</code>
- * with any new glyphs that are composed and do not appear in the subset of glyphs.
- *
- * For example the double quote mark (") is often composed of two apostrophes ('), if an
- * apostrophe doesn't appear in the glyphs in the subset, it will be included and will be added
- * to newGlyphs.
- *
- * @param indexInOriginal the index of the glyph to test from the original font
- * @throws IOException an I/O error
- */
- private void scanGlyphsRecursively(int indexInOriginal) throws IOException {
- if (!subset.containsKey(indexInOriginal)) {
- composedGlyphs.add(indexInOriginal);
- }
-
- if (isComposite(indexInOriginal)) {
- compositeGlyphs.add(indexInOriginal);
- Set<Integer> composedGlyphs = retrieveComposedGlyphs(indexInOriginal);
- for (Integer composedGlyph : composedGlyphs) {
- scanGlyphsRecursively(composedGlyph);
- }
- }
- }
-
- /**
- * Adds to the subset, all the glyphs that are composed by a glyph, but do not appear themselves
- * in the subset.
- */
- protected void addAllComposedGlyphsToSubset() {
- int newIndex = subset.size();
- for (int composedGlyph : composedGlyphs) {
- subset.put(composedGlyph, newIndex++);
- }
- }
-
- /**
- * Re-maps the index of composed glyphs in the original font to the index of the same glyph in
- * the subset font.
- *
- * @param glyphOffset the offset of the composite glyph
- * @throws IOException an I/O error
- */
- private void remapComposite(long glyphOffset) throws IOException {
- long currentGlyphOffset = glyphOffset;
-
- remappedComposites.add(currentGlyphOffset);
-
- int flags = 0;
- do {
- flags = in.readTTFUShort(currentGlyphOffset);
- int glyphIndex = in.readTTFUShort(currentGlyphOffset + 2);
- Integer indexInSubset = subset.get(glyphIndex);
- assert indexInSubset != null;
- /*
- * TODO: this should not be done here!! We're writing to the stream we're reading from,
- * this is asking for trouble! What should happen is when the glyph data is copied from
- * subset, the remapping should be done there. So the original stream is left untouched.
- */
- in.writeTTFUShort(currentGlyphOffset + 2, indexInSubset);
-
- currentGlyphOffset += 4 + GlyfFlags.getOffsetToNextComposedGlyf(flags);
- } while (GlyfFlags.hasMoreComposites(flags));
- }
-
- public boolean isComposite(int indexInOriginal) throws IOException {
- int numberOfContours = in.readTTFShort(tableOffset + mtxTab[indexInOriginal].getOffset());
- return numberOfContours < 0;
- }
-
- /**
- * Reads a composite glyph at a given index and retrieves all the glyph indices of contingent
- * composed glyphs.
- *
- * @param indexInOriginal the glyph index of the composite glyph
- * @return the set of glyph indices this glyph composes
- * @throws IOException an I/O error
- */
- public Set<Integer> retrieveComposedGlyphs(int indexInOriginal)
- throws IOException {
- Set<Integer> composedGlyphs = new HashSet<Integer>();
- long offset = tableOffset + mtxTab[indexInOriginal].getOffset() + 10;
- int flags = 0;
- do {
- flags = in.readTTFUShort(offset);
- composedGlyphs.add(in.readTTFUShort(offset + 2));
- offset += 4 + GlyfFlags.getOffsetToNextComposedGlyf(flags);
- } while (GlyfFlags.hasMoreComposites(flags));
-
- return composedGlyphs;
- }
-}
diff --git a/src/java/org/apache/fop/fonts/truetype/OFDirTabEntry.java b/src/java/org/apache/fop/fonts/truetype/OFDirTabEntry.java
deleted file mode 100644
index 34e7fba14..000000000
--- a/src/java/org/apache/fop/fonts/truetype/OFDirTabEntry.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.truetype;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-
-
-/**
- * This class represents an entry to a TrueType font's Dir Tab.
- */
-public class OFDirTabEntry {
-
- private byte[] tag = new byte[4];
- private long checksum;
- private long offset;
- private long length;
-
- public OFDirTabEntry() {
- }
-
- public OFDirTabEntry(long offset, long length) {
- this.offset = offset;
- this.length = length;
- }
-
- /**
- * Read Dir Tab.
- * @param in font file reader
- * @return tag name
- * @throws IOException upon I/O exception
- */
- public String read(FontFileReader in) throws IOException {
- tag[0] = in.readTTFByte();
- tag[1] = in.readTTFByte();
- tag[2] = in.readTTFByte();
- tag[3] = in.readTTFByte();
-
- checksum = in.readTTFLong();
- offset = in.readTTFULong();
- length = in.readTTFULong();
-
- return getTagString();
- }
-
-
- @Override
- public String toString() {
- return "Read dir tab [" + Arrays.toString(tag) + "]"
- + " offset: " + offset
- + " length: " + length
- + " name: " + getTagString();
- }
-
- /**
- * Returns the checksum.
- * @return int
- */
- public long getChecksum() {
- return checksum;
- }
-
- /**
- * Returns the length.
- * @return long
- */
- public long getLength() {
- return length;
- }
-
- /**
- * Returns the offset.
- * @return long
- */
- public long getOffset() {
- return offset;
- }
-
- /**
- * Returns the tag bytes.
- * @return byte[]
- */
- public byte[] getTag() {
- return tag;
- }
-
- /**
- * Returns the tag bytes.
- * @return byte[]
- */
- public String getTagString() {
- try {
- return new String(tag, "ISO-8859-1");
- } catch (UnsupportedEncodingException e) {
- return this.toString(); // Should never happen.
- }
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/truetype/OFFontLoader.java b/src/java/org/apache/fop/fonts/truetype/OFFontLoader.java
deleted file mode 100644
index 7c8774933..000000000
--- a/src/java/org/apache/fop/fonts/truetype/OFFontLoader.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * 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.truetype;
-
-import java.awt.Rectangle;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.commons.io.IOUtils;
-
-import org.apache.fop.apps.io.InternalResourceResolver;
-import org.apache.fop.fonts.CIDFontType;
-import org.apache.fop.fonts.CMapSegment;
-import org.apache.fop.fonts.EmbeddingMode;
-import org.apache.fop.fonts.EncodingMode;
-import org.apache.fop.fonts.FontLoader;
-import org.apache.fop.fonts.FontType;
-import org.apache.fop.fonts.MultiByteFont;
-import org.apache.fop.fonts.NamedCharacter;
-import org.apache.fop.fonts.SingleByteFont;
-import org.apache.fop.fonts.truetype.OpenFont.PostScriptVersion;
-import org.apache.fop.util.HexEncoder;
-
-/**
- * Loads a TrueType font into memory directly from the original font file.
- */
-public class OFFontLoader extends FontLoader {
-
- private MultiByteFont multiFont;
- private SingleByteFont singleFont;
- private final String subFontName;
- private EncodingMode encodingMode;
- private EmbeddingMode embeddingMode;
-
- /**
- * Default constructor
- * @param fontFileURI the URI representing the font file
- * @param resourceResolver the resource resolver for font URI resolution
- */
- public OFFontLoader(URI fontFileURI, InternalResourceResolver resourceResolver) {
- this(fontFileURI, null, true, EmbeddingMode.AUTO, EncodingMode.AUTO, true, true, resourceResolver);
- }
-
- /**
- * Additional constructor for TrueType Collections.
- * @param fontFileURI the URI representing the font file
- * @param subFontName the sub-fontname of a font in a TrueType Collection (or null for normal
- * TrueType fonts)
- * @param embedded indicates whether the font is embedded or referenced
- * @param embeddingMode the embedding mode of the font
- * @param encodingMode the requested encoding mode
- * @param useKerning true to enable loading kerning info if available, false to disable
- * @param useAdvanced true to enable loading advanced info if available, false to disable
- * @param resolver the FontResolver for font URI resolution
- */
- public OFFontLoader(URI fontFileURI, String subFontName, boolean embedded,
- EmbeddingMode embeddingMode, EncodingMode encodingMode, boolean useKerning,
- boolean useAdvanced, InternalResourceResolver resolver) {
- super(fontFileURI, embedded, useKerning, useAdvanced, resolver);
- this.subFontName = subFontName;
- this.encodingMode = encodingMode;
- this.embeddingMode = embeddingMode;
- if (this.encodingMode == EncodingMode.AUTO) {
- this.encodingMode = EncodingMode.CID; //Default to CID mode for TrueType
- }
- if (this.embeddingMode == EmbeddingMode.AUTO) {
- this.embeddingMode = EmbeddingMode.SUBSET;
- }
- }
-
- /** {@inheritDoc} */
- protected void read() throws IOException {
- read(this.subFontName);
- }
-
- /**
- * Reads a TrueType font.
- * @param ttcFontName the TrueType sub-font name of TrueType Collection (may be null for
- * normal TrueType fonts)
- * @throws IOException if an I/O error occurs
- */
- private void read(String ttcFontName) throws IOException {
- InputStream in = resourceResolver.getResource(this.fontFileURI);
- try {
- FontFileReader reader = new FontFileReader(in);
- String header = readHeader(reader);
- boolean isCFF = header.equals("OTTO");
- OpenFont otf = (isCFF) ? new OTFFile() : new TTFFile(useKerning, useAdvanced);
- boolean supported = otf.readFont(reader, header, ttcFontName);
- if (!supported) {
- throw new IOException("The font does not have a Unicode cmap table: " + fontFileURI);
- }
- buildFont(otf, ttcFontName);
- loaded = true;
- } finally {
- IOUtils.closeQuietly(in);
- }
- }
-
- public static String readHeader(FontFileReader fontFile) throws IOException {
- if (fontFile != null) {
- fontFile.seekSet(0);
- return fontFile.readTTFString(4); // TTF_FIXED_SIZE (4 bytes)
- }
- return null;
- }
-
- private void buildFont(OpenFont otf, String ttcFontName) {
- boolean isCid = this.embedded;
- if (this.encodingMode == EncodingMode.SINGLE_BYTE) {
- isCid = false;
- }
-
- if (isCid) {
- multiFont = new MultiByteFont(resourceResolver, embeddingMode);
- multiFont.setIsOTFFile(otf instanceof OTFFile);
- returnFont = multiFont;
- multiFont.setTTCName(ttcFontName);
- } else {
- singleFont = new SingleByteFont(resourceResolver, embeddingMode);
- returnFont = singleFont;
- }
-
- returnFont.setFontURI(fontFileURI);
- returnFont.setFontName(otf.getPostScriptName());
- returnFont.setFullName(otf.getFullName());
- returnFont.setFamilyNames(otf.getFamilyNames());
- returnFont.setFontSubFamilyName(otf.getSubFamilyName());
- returnFont.setCapHeight(otf.getCapHeight());
- returnFont.setXHeight(otf.getXHeight());
- returnFont.setAscender(otf.getLowerCaseAscent());
- returnFont.setDescender(otf.getLowerCaseDescent());
- returnFont.setFontBBox(otf.getFontBBox());
- returnFont.setUnderlinePosition(otf.getUnderlinePosition() - otf.getUnderlineThickness() / 2);
- returnFont.setUnderlineThickness(otf.getUnderlineThickness());
- returnFont.setStrikeoutPosition(otf.getStrikeoutPosition() - otf.getStrikeoutThickness() / 2);
- returnFont.setStrikeoutThickness(otf.getStrikeoutThickness());
- returnFont.setFlags(otf.getFlags());
- returnFont.setStemV(Integer.parseInt(otf.getStemV())); //not used for TTF
- returnFont.setItalicAngle(Integer.parseInt(otf.getItalicAngle()));
- returnFont.setMissingWidth(0);
- returnFont.setWeight(otf.getWeightClass());
- returnFont.setEmbeddingMode(this.embeddingMode);
- if (isCid) {
- if (otf instanceof OTFFile) {
- multiFont.setCIDType(CIDFontType.CIDTYPE0);
- } else {
- multiFont.setCIDType(CIDFontType.CIDTYPE2);
- }
- multiFont.setWidthArray(otf.getWidths());
- multiFont.setBBoxArray(otf.getBoundingBoxes());
- } else {
- singleFont.setFontType(FontType.TRUETYPE);
- singleFont.setEncoding(otf.getCharSetName());
- returnFont.setFirstChar(otf.getFirstChar());
- returnFont.setLastChar(otf.getLastChar());
- singleFont.setTrueTypePostScriptVersion(otf.getPostScriptVersion());
- copyGlyphMetricsSingleByte(otf);
- }
- returnFont.setCMap(getCMap(otf));
-
- if (otf.getKerning() != null && useKerning) {
- copyKerning(otf, isCid);
- }
- if (useAdvanced) {
- copyAdvanced(otf);
- }
- if (this.embedded) {
- if (otf.isEmbeddable()) {
- returnFont.setEmbedURI(this.fontFileURI);
- } else {
- String msg = "The font " + this.fontFileURI + " is not embeddable due to a"
- + " licensing restriction.";
- throw new RuntimeException(msg);
- }
- }
- }
-
- private CMapSegment[] getCMap(OpenFont otf) {
- CMapSegment[] array = new CMapSegment[otf.getCMaps().size()];
- return otf.getCMaps().toArray(array);
- }
-
- private void copyGlyphMetricsSingleByte(OpenFont otf) {
- int[] wx = otf.getWidths();
- Rectangle[] bboxes = otf.getBoundingBoxes();
- for (int i = singleFont.getFirstChar(); i <= singleFont.getLastChar(); i++) {
- singleFont.setWidth(i, otf.getCharWidth(i));
- int[] bbox = otf.getBBox(i);
- singleFont.setBoundingBox(i,
- new Rectangle(bbox[0], bbox[1], bbox[2] - bbox[0], bbox[3] - bbox[1]));
- }
-
- for (CMapSegment segment : otf.getCMaps()) {
- if (segment.getUnicodeStart() < 0xFFFE) {
- for (char u = (char)segment.getUnicodeStart(); u <= segment.getUnicodeEnd(); u++) {
- int codePoint = singleFont.getEncoding().mapChar(u);
- if (codePoint <= 0) {
- int glyphIndex = segment.getGlyphStartIndex() + u - segment.getUnicodeStart();
- String glyphName = otf.getGlyphName(glyphIndex);
- if (glyphName.length() == 0 && otf.getPostScriptVersion() != PostScriptVersion.V2) {
- glyphName = "u" + HexEncoder.encode(u);
- }
- if (glyphName.length() > 0) {
- String unicode = Character.toString(u);
- NamedCharacter nc = new NamedCharacter(glyphName, unicode);
- singleFont.addUnencodedCharacter(nc, wx[glyphIndex], bboxes[glyphIndex]);
- }
- }
- }
- }
- }
- }
-
- /**
- * Copy kerning information.
- */
- private void copyKerning(OpenFont otf, boolean isCid) {
-
- // Get kerning
- Set<Integer> kerningSet;
- if (isCid) {
- kerningSet = otf.getKerning().keySet();
- } else {
- kerningSet = otf.getAnsiKerning().keySet();
- }
-
- for (Integer kpx1 : kerningSet) {
- Map<Integer, Integer> h2;
- if (isCid) {
- h2 = otf.getKerning().get(kpx1);
- } else {
- h2 = otf.getAnsiKerning().get(kpx1);
- }
- returnFont.putKerningEntry(kpx1, h2);
- }
- }
-
- /**
- * Copy advanced typographic information.
- */
- private void copyAdvanced(OpenFont otf) {
- if (returnFont instanceof MultiByteFont) {
- MultiByteFont mbf = (MultiByteFont) returnFont;
- mbf.setGDEF(otf.getGDEF());
- mbf.setGSUB(otf.getGSUB());
- mbf.setGPOS(otf.getGPOS());
- }
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/truetype/OFMtxEntry.java b/src/java/org/apache/fop/fonts/truetype/OFMtxEntry.java
deleted file mode 100644
index b52f03849..000000000
--- a/src/java/org/apache/fop/fonts/truetype/OFMtxEntry.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * 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.truetype;
-
-import java.util.List;
-
-/**
- * This class represents a TrueType Mtx Entry.
- */
-public class OFMtxEntry {
-
- private int wx;
- private int lsb;
- private String name = "";
- private int index;
- private List unicodeIndex = new java.util.ArrayList();
- private int[] boundingBox = new int[4];
- private long offset;
- private byte found;
-
- /**
- * Returns a String representation of this object.
- *
- * @param t TTFFile to use for unit conversion
- * @return String String representation
- */
- public String toString(TTFFile t) {
- return "Glyph " + name + " index: " + getIndexAsString() + " bbox ["
- + t.convertTTFUnit2PDFUnit(boundingBox[0]) + " "
- + t.convertTTFUnit2PDFUnit(boundingBox[1]) + " "
- + t.convertTTFUnit2PDFUnit(boundingBox[2]) + " "
- + t.convertTTFUnit2PDFUnit(boundingBox[3]) + "] wx: "
- + t.convertTTFUnit2PDFUnit(wx);
- }
-
- /**
- * Returns the boundingBox.
- * @return int[]
- */
- public int[] getBoundingBox() {
- return boundingBox;
- }
-
- /**
- * Sets the boundingBox.
- * @param boundingBox The boundingBox to set
- */
- public void setBoundingBox(int[] boundingBox) {
- this.boundingBox = boundingBox;
- }
-
- /**
- * Returns the found.
- * @return byte
- */
- public byte getFound() {
- return found;
- }
-
- /**
- * Returns the index.
- * @return int
- */
- public int getIndex() {
- return index;
- }
-
- /**
- * Determines whether this index represents a reserved character.
- * @return True if it is reserved
- */
- public boolean isIndexReserved() {
- return (getIndex() >= 32768) && (getIndex() <= 65535);
- }
-
- /**
- * Returns a String representation of the index taking into account if
- * the index is in the reserved range.
- * @return index as String
- */
- public String getIndexAsString() {
- if (isIndexReserved()) {
- return Integer.toString(getIndex()) + " (reserved)";
- } else {
- return Integer.toString(getIndex());
- }
- }
-
- /**
- * Returns the lsb.
- * @return int
- */
- public int getLsb() {
- return lsb;
- }
-
- /**
- * Returns the name.
- * @return String
- */
- public String getName() {
- return name;
- }
-
- /**
- * Returns the offset.
- * @return long
- */
- public long getOffset() {
- return offset;
- }
-
- /**
- * Returns the unicodeIndex.
- * @return List
- */
- public List getUnicodeIndex() {
- return unicodeIndex;
- }
-
- /**
- * Returns the wx.
- * @return int
- */
- public int getWx() {
- return wx;
- }
-
- /**
- * Sets the found.
- * @param found The found to set
- */
- public void setFound(byte found) {
- this.found = found;
- }
-
- /**
- * Sets the index.
- * @param index The index to set
- */
- public void setIndex(int index) {
- this.index = index;
- }
-
- /**
- * Sets the lsb.
- * @param lsb The lsb to set
- */
- public void setLsb(int lsb) {
- this.lsb = lsb;
- }
-
- /**
- * Sets the name.
- * @param name The name to set
- */
- public void setName(String name) {
- this.name = name;
- }
-
- /**
- * Sets the offset.
- * @param offset The offset to set
- */
- public void setOffset(long offset) {
- this.offset = offset;
- }
-
- /**
- * Sets the wx.
- * @param wx The wx to set
- */
- public void setWx(int wx) {
- this.wx = wx;
- }
-
-
-}
diff --git a/src/java/org/apache/fop/fonts/truetype/OFTableName.java b/src/java/org/apache/fop/fonts/truetype/OFTableName.java
deleted file mode 100644
index f6264129a..000000000
--- a/src/java/org/apache/fop/fonts/truetype/OFTableName.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * 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.truetype;
-
-
-/**
- * Represents table names as found in a TrueType font's Table Directory.
- * TrueType fonts may have custom tables so we cannot use an enum.
- */
-public final class OFTableName {
-
- /** The first table in a TrueType font file containing metadata about other tables. */
- public static final OFTableName TABLE_DIRECTORY = new OFTableName("tableDirectory");
-
- /** Baseline data */
- public static final OFTableName BASE = new OFTableName("BASE");
-
- /** CFF data/ */
- public static final OFTableName CFF = new OFTableName("CFF ");
-
- /** Embedded bitmap data. */
- public static final OFTableName EBDT = new OFTableName("EBDT");
-
- /** Embedded bitmap location data. */
- public static final OFTableName EBLC = new OFTableName("EBLC");
-
- /** Embedded bitmap scaling data. */
- public static final OFTableName EBSC = new OFTableName("EBSC");
-
- /** A FontForge specific table. */
- public static final OFTableName FFTM = new OFTableName("FFTM");
-
- /** Divides glyphs into various classes that make using the GPOS/GSUB tables easier. */
- public static final OFTableName GDEF = new OFTableName("GDEF");
-
- /** Provides kerning information, mark-to-base, etc. for opentype fonts. */
- public static final OFTableName GPOS = new OFTableName("GPOS");
-
- /** Provides ligature information, swash, etc. for opentype fonts. */
- public static final OFTableName GSUB = new OFTableName("GSUB");
-
- /** Linear threshold table. */
- public static final OFTableName LTSH = new OFTableName("LTSH");
-
- /** OS/2 and Windows specific metrics. */
- public static final OFTableName OS2 = new OFTableName("OS/2");
-
- /** PCL 5 data. */
- public static final OFTableName PCLT = new OFTableName("PCLT");
-
- /** Vertical Device Metrics table. */
- public static final OFTableName VDMX = new OFTableName("VDMX");
-
- /** Character to glyph mapping. */
- public static final OFTableName CMAP = new OFTableName("cmap");
-
- /** Control Value Table. */
- public static final OFTableName CVT = new OFTableName("cvt ");
-
- /** Font program. */
- public static final OFTableName FPGM = new OFTableName("fpgm");
-
- /** Grid-fitting and scan conversion procedure (grayscale). */
- public static final OFTableName GASP = new OFTableName("gasp");
-
- /** Glyph data. */
- public static final OFTableName GLYF = new OFTableName("glyf");
-
- /** Horizontal device metrics. */
- public static final OFTableName HDMX = new OFTableName("hdmx");
-
- /** Font header. */
- public static final OFTableName HEAD = new OFTableName("head");
-
- /** Horizontal header. */
- public static final OFTableName HHEA = new OFTableName("hhea");
-
- /** Horizontal metrics. */
- public static final OFTableName HMTX = new OFTableName("hmtx");
-
- /** Kerning. */
- public static final OFTableName KERN = new OFTableName("kern");
-
- /** Index to location. */
- public static final OFTableName LOCA = new OFTableName("loca");
-
- /** Maximum profile. */
- public static final OFTableName MAXP = new OFTableName("maxp");
-
- /** Naming table. */
- public static final OFTableName NAME = new OFTableName("name");
-
- /** PostScript information. */
- public static final OFTableName POST = new OFTableName("post");
-
- /** CVT Program. */
- public static final OFTableName PREP = new OFTableName("prep");
-
- /** Vertical Metrics header. */
- public static final OFTableName VHEA = new OFTableName("vhea");
-
- /** Vertical Metrics. */
- public static final OFTableName VMTX = new OFTableName("vmtx");
-
- private final String name;
-
- private OFTableName(String name) {
- this.name = name;
- }
-
- /**
- * Returns the name of the table as it should be in the Directory Table.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Returns an instance of this class corresponding to the given string representation.
- * @param tableName table name as in the Table Directory
- * @return TTFTableName
- */
- public static OFTableName getValue(String tableName) {
- if (tableName != null) {
- return new OFTableName(tableName);
- }
- throw new IllegalArgumentException("A TrueType font table name must not be null");
- }
-
- @Override
- public int hashCode() {
- return name.hashCode();
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
- if (!(o instanceof OFTableName)) {
- return false;
- }
- OFTableName to = (OFTableName) o;
- return this.name.equals(to.getName());
- }
-
- @Override
- public String toString() {
- return name;
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/truetype/OTFFile.java b/src/java/org/apache/fop/fonts/truetype/OTFFile.java
deleted file mode 100644
index 1ac7a565e..000000000
--- a/src/java/org/apache/fop/fonts/truetype/OTFFile.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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.truetype;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.fontbox.cff.CFFDataInput;
-import org.apache.fontbox.cff.CFFFont;
-import org.apache.fontbox.cff.CFFParser;
-import org.apache.fontbox.cff.charset.CFFCharset;
-
-public class OTFFile extends OpenFont {
-
- protected CFFFont fileFont;
-
- public OTFFile() throws IOException {
- checkForFontbox();
- }
-
- private void checkForFontbox() throws IOException {
- try {
- Class.forName("org.apache.fontbox.cff.CFFFont");
- } catch (ClassNotFoundException ex) {
- throw new IOException("The Fontbox jar was not found in the classpath. This is "
- + "required for OTF CFF ssupport.");
- }
- }
-
- @Override
- protected void updateBBoxAndOffset() throws IOException {
- List<Mapping> gidMappings = getGIDMappings(fileFont);
- Map<Integer, String> sidNames = constructNameMap(gidMappings);
- UnicodeMapping[] mappings = unicodeMappings.toArray(new UnicodeMapping[unicodeMappings.size()]);
- for (int i = 0; i < mappings.length; i++) {
- int glyphIdx = mappings[i].getGlyphIndex();
- Mapping m = gidMappings.get(glyphIdx);
- String name = sidNames.get(m.getSID());
- mtxTab[glyphIdx].setName(name);
- }
- }
-
- private List<Mapping> getGIDMappings(CFFFont font) {
- List<Mapping> gidMappings = new ArrayList<Mapping>();
- Mapping notdef = new Mapping();
- gidMappings.add(notdef);
- for (CFFCharset.Entry entry : font.getCharset().getEntries()) {
- String name = entry.getName();
- byte[] bytes = font.getCharStringsDict().get(name);
- if (bytes == null) {
- continue;
- }
- Mapping mapping = new Mapping();
- mapping.setSID(entry.getSID());
- mapping.setName(name);
- mapping.setBytes(bytes);
- gidMappings.add(mapping);
- }
- return gidMappings;
- }
-
- private Map<Integer, String> constructNameMap(Collection<Mapping> mappings) {
- Map<Integer, String> sidNames = new HashMap<Integer, String>();
- Iterator<Mapping> it = mappings.iterator();
- while (it.hasNext()) {
- Mapping mapping = it.next();
- sidNames.put(mapping.getSID(), mapping.getName());
- }
- return sidNames;
- }
-
- private static class Mapping {
- private int sid;
- private String name;
- private byte[] bytes;
-
- public void setSID(int sid) {
- this.sid = sid;
- }
-
- public int getSID() {
- return sid;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- public void setBytes(byte[] bytes) {
- this.bytes = bytes;
- }
-
- public byte[] getBytes() {
- return bytes;
- }
- }
-
-
- @Override
- protected void initializeFont(FontFileReader in) throws IOException {
- fontFile = in;
- fontFile.seekSet(0);
- CFFParser parser = new CFFParser();
- fileFont = parser.parse(in.getAllBytes()).get(0);
- }
-
- protected void readName() throws IOException {
- Object familyName = fileFont.getProperty("FamilyName");
- if (familyName != null && !familyName.equals("")) {
- familyNames.add(familyName.toString());
- fullName = familyName.toString();
- } else {
- fullName = fileFont.getName();
- familyNames.add(fullName);
- }
- }
-
- /**
- * Reads the CFFData from a given font file
- * @param fontFile The font file being read
- * @return The byte data found in the CFF table
- */
- public static byte[] getCFFData(FontFileReader fontFile) throws IOException {
- byte[] cff = fontFile.getAllBytes();
- CFFDataInput input = new CFFDataInput(fontFile.getAllBytes());
- input.readBytes(4); //OTTO
- short numTables = input.readShort();
- input.readShort(); //searchRange
- input.readShort(); //entrySelector
- input.readShort(); //rangeShift
-
- for (int q = 0; q < numTables; q++) {
- String tagName = new String(input.readBytes(4));
- readLong(input); //Checksum
- long offset = readLong(input);
- long length = readLong(input);
- if (tagName.equals("CFF ")) {
- cff = new byte[(int)length];
- System.arraycopy(fontFile.getAllBytes(), (int)offset, cff, 0, cff.length);
- break;
- }
- }
- return cff;
- }
-
- private static long readLong(CFFDataInput input) throws IOException {
- return (input.readCard16() << 16) | input.readCard16();
- }
-}
diff --git a/src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java b/src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java
deleted file mode 100644
index 2c083add2..000000000
--- a/src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java
+++ /dev/null
@@ -1,1129 +0,0 @@
-/*
- * 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.truetype;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.apache.fontbox.cff.CFFStandardString;
-import org.apache.fontbox.cff.encoding.CFFEncoding;
-
-import org.apache.fop.fonts.MultiByteFont;
-import org.apache.fop.fonts.cff.CFFDataReader;
-import org.apache.fop.fonts.cff.CFFDataReader.CFFIndexData;
-import org.apache.fop.fonts.cff.CFFDataReader.DICTEntry;
-import org.apache.fop.fonts.cff.CFFDataReader.FDSelect;
-import org.apache.fop.fonts.cff.CFFDataReader.FontDict;
-import org.apache.fop.fonts.cff.CFFDataReader.Format0FDSelect;
-import org.apache.fop.fonts.cff.CFFDataReader.Format3FDSelect;
-
-/**
- * Reads an OpenType CFF file and generates a subset
- * The OpenType specification can be found at the Microsoft
- * Typography site: http://www.microsoft.com/typography/otspec/
- */
-public class OTFSubSetFile extends OTFFile {
-
- protected byte[] output;
- protected int currentPos;
- private int realSize;
-
- /** A map containing each glyph to be included in the subset
- * with their existing and new GID's **/
- protected LinkedHashMap<Integer, Integer> subsetGlyphs = new LinkedHashMap<Integer, Integer>();
-
- /** A map of the new GID to SID used to construct the charset table **/
- protected LinkedHashMap<Integer, Integer> gidToSID;
-
- protected CFFIndexData localIndexSubr;
- protected CFFIndexData globalIndexSubr;
-
- /** List of subroutines to write to the local / global indexes in the subset font **/
- protected List<byte[]> subsetLocalIndexSubr;
- protected List<byte[]> subsetGlobalIndexSubr;
-
- /** For fonts which have an FDSelect or ROS flag in Top Dict, this is used to store the
- * local subroutine indexes for each group as opposed to the above subsetLocalIndexSubr */
- private ArrayList<List<byte[]>> fdSubrs;
-
- /** The subset FD Select table used to store the mappings between glyphs and their
- * associated FDFont object which point to a private dict and local subroutines. */
- private LinkedHashMap<Integer, FDIndexReference> subsetFDSelect;
-
- /** A list of unique subroutines from the global / local subroutine indexes */
- protected List<Integer> localUniques;
- protected List<Integer> globalUniques;
-
- /** A store of the number of subroutines each global / local subroutine will store **/
- protected int subsetLocalSubrCount;
- protected int subsetGlobalSubrCount;
-
- /** A list of char string data for each glyph to be stored in the subset font **/
- protected List<byte[]> subsetCharStringsIndex;
-
- /** The embedded name to change in the name table **/
- protected String embeddedName;
-
- /** An array used to hold the string index data for the subset font **/
- protected List<byte[]> stringIndexData = new ArrayList<byte[]>();
-
- /** The CFF reader object used to read data and offsets from the original font file */
- protected CFFDataReader cffReader;
-
- /** The class used to represent this font **/
- private MultiByteFont mbFont;
-
- /** The number of standard strings in CFF **/
- public static final int NUM_STANDARD_STRINGS = 391;
- /** The operator used to identify a local subroutine reference */
- private static final int LOCAL_SUBROUTINE = 10;
- /** The operator used to identify a global subroutine reference */
- private static final int GLOBAL_SUBROUTINE = 29;
-
- public OTFSubSetFile() throws IOException {
- super();
- }
-
- public void readFont(FontFileReader in, String embeddedName, String header,
- MultiByteFont mbFont) throws IOException {
- this.mbFont = mbFont;
- readFont(in, embeddedName, header, mbFont.getUsedGlyphs());
- }
-
- /**
- * Reads and creates a subset of the font.
- *
- * @param in FontFileReader to read from
- * @param name Name to be checked for in the font file
- * @param header The header of the font file
- * @param glyphs Map of glyphs (glyphs has old index as (Integer) key and
- * new index as (Integer) value)
- * @throws IOException in case of an I/O problem
- */
- void readFont(FontFileReader in, String embeddedName, String header,
- Map<Integer, Integer> usedGlyphs) throws IOException {
- fontFile = in;
-
- currentPos = 0;
- realSize = 0;
-
- this.embeddedName = embeddedName;
-
- //Sort by the new GID and store in a LinkedHashMap
- subsetGlyphs = sortByValue(usedGlyphs);
-
- output = new byte[in.getFileSize()];
-
- initializeFont(in);
-
- cffReader = new CFFDataReader(fontFile);
-
- //Create the CIDFontType0C data
- createCFF();
- }
-
- private LinkedHashMap<Integer, Integer> sortByValue(Map<Integer, Integer> map) {
- List<Entry<Integer, Integer>> list = new ArrayList<Entry<Integer, Integer>>(map.entrySet());
- Collections.sort(list, new Comparator<Entry<Integer, Integer>>() {
- public int compare(Entry<Integer, Integer> o1, Entry<Integer, Integer> o2) {
- return ((Comparable<Integer>) o1.getValue()).compareTo(o2.getValue());
- }
- });
-
- LinkedHashMap<Integer, Integer> result = new LinkedHashMap<Integer, Integer>();
- for (Entry<Integer, Integer> entry : list) {
- result.put(entry.getKey(), entry.getValue());
- }
- return result;
- }
-
- protected void createCFF() throws IOException {
- //Header
- writeBytes(cffReader.getHeader());
-
- //Name Index
- writeIndex(Arrays.asList(embeddedName.getBytes()));
-
- //Keep offset of the topDICT so it can be updated once all data has been written
- int topDictOffset = currentPos;
- //Top DICT Index and Data
- byte[] topDictIndex = cffReader.getTopDictIndex().getByteData();
- int offSize = topDictIndex[2];
- writeBytes(topDictIndex, 0, 3 + (offSize * 2));
- int topDictDataOffset = currentPos;
- writeTopDICT();
-
- //Create the char string index data and related local / global subroutines
- if (cffReader.getFDSelect() == null) {
- createCharStringData();
- } else {
- createCharStringDataCID();
- }
-
- //If it is a CID-Keyed font, store each FD font and add each SID
- List<Integer> fontNameSIDs = null;
- List<Integer> subsetFDFonts = null;
- if (cffReader.getFDSelect() != null) {
- subsetFDFonts = getUsedFDFonts();
- fontNameSIDs = storeFDStrings(subsetFDFonts);
- }
-
- //String index
- writeStringIndex();
-
- //Global subroutine index
- writeIndex(subsetGlobalIndexSubr);
-
- //Encoding
- int encodingOffset = currentPos;
- writeEncoding(fileFont.getEncoding());
-
- //Charset table
- int charsetOffset = currentPos;
- writeCharsetTable(cffReader.getFDSelect() != null);
-
- //FDSelect table
- int fdSelectOffset = currentPos;
- if (cffReader.getFDSelect() != null) {
- writeFDSelect();
- }
-
- //Char Strings Index
- int charStringOffset = currentPos;
- writeIndex(subsetCharStringsIndex);
-
- if (cffReader.getFDSelect() == null) {
- //Keep offset to modify later with the local subroutine index offset
- int privateDictOffset = currentPos;
- writePrivateDict();
-
- //Local subroutine index
- int localIndexOffset = currentPos;
- writeIndex(subsetLocalIndexSubr);
-
- //Update the offsets
- updateOffsets(topDictOffset, charsetOffset, charStringOffset, privateDictOffset,
- localIndexOffset, encodingOffset);
- } else {
- List<Integer> privateDictOffsets = writeCIDDictsAndSubrs(subsetFDFonts);
- int fdArrayOffset = writeFDArray(subsetFDFonts, privateDictOffsets, fontNameSIDs);
-
- updateCIDOffsets(topDictDataOffset, fdArrayOffset, fdSelectOffset, charsetOffset,
- charStringOffset, encodingOffset);
- }
- }
-
- protected List<Integer> storeFDStrings(List<Integer> uniqueNewRefs) throws IOException {
- ArrayList<Integer> fontNameSIDs = new ArrayList<Integer>();
- List<FontDict> fdFonts = cffReader.getFDFonts();
- for (int i = 0; i < uniqueNewRefs.size(); i++) {
- FontDict fdFont = fdFonts.get(uniqueNewRefs.get(i));
- byte[] fdFontByteData = fdFont.getByteData();
- Map<String, DICTEntry> fdFontDict = cffReader.parseDictData(fdFontByteData);
- fontNameSIDs.add(stringIndexData.size() + NUM_STANDARD_STRINGS);
- stringIndexData.add(cffReader.getStringIndex().getValue(fdFontDict.get("FontName")
- .getOperands().get(0).intValue() - NUM_STANDARD_STRINGS));
- }
- return fontNameSIDs;
- }
-
- protected void writeBytes(byte[] out) {
- for (int i = 0; i < out.length; i++) {
- writeByte(out[i]);
- }
- }
-
- protected void writeBytes(byte[] out, int offset, int length) {
- for (int i = offset; i < offset + length; i++) {
- output[currentPos++] = out[i];
- realSize++;
- }
- }
-
- private void writeEncoding(CFFEncoding encoding) throws IOException {
- LinkedHashMap<String, DICTEntry> topDICT = cffReader.getTopDictEntries();
- DICTEntry encodingEntry = topDICT.get("Encoding");
- if (encodingEntry != null && encodingEntry.getOperands().get(0).intValue() != 0
- && encodingEntry.getOperands().get(0).intValue() != 1) {
- writeByte(0);
- writeByte(gidToSID.size());
- for (int gid : gidToSID.keySet()) {
- int code = encoding.getCode(gidToSID.get(gid));
- writeByte(code);
- }
- }
- }
-
- protected void writeTopDICT() throws IOException {
- LinkedHashMap<String, DICTEntry> topDICT = cffReader.getTopDictEntries();
- List<String> topDictStringEntries = Arrays.asList("version", "Notice", "Copyright",
- "FullName", "FamilyName", "Weight", "PostScript");
- for (Map.Entry<String, DICTEntry> dictEntry : topDICT.entrySet()) {
- String dictKey = dictEntry.getKey();
- DICTEntry entry = dictEntry.getValue();
- //If the value is an SID, update the reference but keep the size the same
- if (dictKey.equals("ROS")) {
- writeROSEntry(entry);
- } else if (dictKey.equals("CIDCount")) {
- writeCIDCount(entry);
- } else if (topDictStringEntries.contains(dictKey)) {
- writeTopDictStringEntry(entry);
- } else {
- writeBytes(entry.getByteData());
- }
- }
- }
-
- private void writeROSEntry(DICTEntry dictEntry) throws IOException {
- int sidA = dictEntry.getOperands().get(0).intValue();
- if (sidA > 390) {
- stringIndexData.add(cffReader.getStringIndex().getValue(sidA - NUM_STANDARD_STRINGS));
- }
- int sidAStringIndex = stringIndexData.size() + 390;
- int sidB = dictEntry.getOperands().get(1).intValue();
- if (sidB > 390) {
- stringIndexData.add("Identity".getBytes());
- }
- int sidBStringIndex = stringIndexData.size() + 390;
- byte[] cidEntryByteData = dictEntry.getByteData();
- cidEntryByteData = updateOffset(cidEntryByteData, 0, dictEntry.getOperandLengths().get(0),
- sidAStringIndex);
- cidEntryByteData = updateOffset(cidEntryByteData, dictEntry.getOperandLengths().get(0),
- dictEntry.getOperandLengths().get(1), sidBStringIndex);
- cidEntryByteData = updateOffset(cidEntryByteData, dictEntry.getOperandLengths().get(0)
- + dictEntry.getOperandLengths().get(1), dictEntry.getOperandLengths().get(2), 139);
- writeBytes(cidEntryByteData);
- }
-
- protected void writeCIDCount(DICTEntry dictEntry) throws IOException {
- byte[] cidCountByteData = dictEntry.getByteData();
- cidCountByteData = updateOffset(cidCountByteData, 0, dictEntry.getOperandLengths().get(0),
- subsetGlyphs.size());
- writeBytes(cidCountByteData);
- }
-
- private void writeTopDictStringEntry(DICTEntry dictEntry) throws IOException {
- int sid = dictEntry.getOperands().get(0).intValue();
- if (sid > 391) {
- stringIndexData.add(cffReader.getStringIndex().getValue(sid - 391));
- }
-
- byte[] newDictEntry = createNewRef(stringIndexData.size() + 390, dictEntry.getOperator(),
- dictEntry.getOperandLength());
- writeBytes(newDictEntry);
- }
-
- private void writeStringIndex() throws IOException {
- Map<String, DICTEntry> topDICT = cffReader.getTopDictEntries();
- int charsetOffset = topDICT.get("charset").getOperands().get(0).intValue();
-
- gidToSID = new LinkedHashMap<Integer, Integer>();
-
- for (int gid : subsetGlyphs.keySet()) {
- int sid = cffReader.getSIDFromGID(charsetOffset, gid);
- //Check whether the SID falls into the standard string set
- if (sid < NUM_STANDARD_STRINGS) {
- gidToSID.put(subsetGlyphs.get(gid), sid);
- if (mbFont != null) {
- mbFont.mapUsedGlyphName(subsetGlyphs.get(gid),
- CFFStandardString.getName(sid));
- }
- } else {
- int index = sid - NUM_STANDARD_STRINGS;
- if (index <= cffReader.getStringIndex().getNumObjects()) {
- if (mbFont != null) {
- mbFont.mapUsedGlyphName(subsetGlyphs.get(gid),
- new String(cffReader.getStringIndex().getValue(index)));
- }
- gidToSID.put(subsetGlyphs.get(gid), stringIndexData.size() + 391);
- stringIndexData.add(cffReader.getStringIndex().getValue(index));
- } else {
- if (mbFont != null) {
- mbFont.mapUsedGlyphName(subsetGlyphs.get(gid), ".notdef");
- }
- gidToSID.put(subsetGlyphs.get(gid), index);
- }
- }
- }
- //Write the String Index
- writeIndex(stringIndexData);
- }
-
- protected void createCharStringDataCID() throws IOException {
- CFFIndexData charStringsIndex = cffReader.getCharStringIndex();
-
- FDSelect fontDictionary = cffReader.getFDSelect();
- if (fontDictionary instanceof Format0FDSelect) {
- throw new UnsupportedOperationException("OTF CFF CID Format0 currently not implemented");
- } else if (fontDictionary instanceof Format3FDSelect) {
- Format3FDSelect fdSelect = (Format3FDSelect)fontDictionary;
- Map<Integer, Integer> subsetGroups = new HashMap<Integer, Integer>();
-
- List<Integer> uniqueGroups = new ArrayList<Integer>();
- for (int gid : subsetGlyphs.keySet()) {
- Set<Integer> rangeKeys = fdSelect.getRanges().keySet();
- Integer[] ranges = rangeKeys.toArray(new Integer[rangeKeys.size()]);
- for (int i = 0; i < ranges.length; i++) {
- int nextRange = -1;
- if (i < ranges.length - 1) {
- nextRange = ranges[i + 1];
- } else {
- nextRange = fdSelect.getSentinelGID();
- }
- if (gid >= ranges[i] && gid < nextRange) {
- subsetGroups.put(gid, fdSelect.getRanges().get(ranges[i]));
- if (!uniqueGroups.contains(fdSelect.getRanges().get(ranges[i]))) {
- uniqueGroups.add(fdSelect.getRanges().get(ranges[i]));
- }
- }
- }
- }
-
- //Prepare resources
- globalIndexSubr = cffReader.getGlobalIndexSubr();
-
- //Create the new char string index
- subsetCharStringsIndex = new ArrayList<byte[]>();
-
- globalUniques = new ArrayList<Integer>();
-
- subsetFDSelect = new LinkedHashMap<Integer, FDIndexReference>();
-
- List<List<Integer>> foundLocalUniques = new ArrayList<List<Integer>>();
- for (int i = 0; i < uniqueGroups.size(); i++) {
- foundLocalUniques.add(new ArrayList<Integer>());
- }
- for (int gid : subsetGlyphs.keySet()) {
- int group = subsetGroups.get(gid);
- localIndexSubr = cffReader.getFDFonts().get(group).getLocalSubrData();
- localUniques = foundLocalUniques.get(uniqueGroups.indexOf(subsetGroups.get(gid)));
-
- FDIndexReference newFDReference = new FDIndexReference(
- uniqueGroups.indexOf(subsetGroups.get(gid)), subsetGroups.get(gid));
- subsetFDSelect.put(subsetGlyphs.get(gid), newFDReference);
- byte[] data = charStringsIndex.getValue(gid);
- preScanForSubsetIndexSize(data);
- }
-
- //Create the two lists which are to store the local and global subroutines
- subsetGlobalIndexSubr = new ArrayList<byte[]>();
-
- fdSubrs = new ArrayList<List<byte[]>>();
- subsetGlobalSubrCount = globalUniques.size();
- globalUniques.clear();
- localUniques = null;
-
- for (int l = 0; l < foundLocalUniques.size(); l++) {
- fdSubrs.add(new ArrayList<byte[]>());
- }
- List<List<Integer>> foundLocalUniquesB = new ArrayList<List<Integer>>();
- for (int k = 0; k < uniqueGroups.size(); k++) {
- foundLocalUniquesB.add(new ArrayList<Integer>());
- }
- for (Integer gid : subsetGlyphs.keySet()) {
- int group = subsetGroups.get(gid);
- localIndexSubr = cffReader.getFDFonts().get(group).getLocalSubrData();
- localUniques = foundLocalUniquesB.get(subsetFDSelect.get(subsetGlyphs.get(gid)).getNewFDIndex());
- byte[] data = charStringsIndex.getValue(gid);
- subsetLocalIndexSubr = fdSubrs.get(subsetFDSelect.get(subsetGlyphs.get(gid)).getNewFDIndex());
- subsetLocalSubrCount = foundLocalUniques.get(subsetFDSelect.get(subsetGlyphs.get(gid))
- .getNewFDIndex()).size();
- data = readCharStringData(data, subsetLocalSubrCount);
- subsetCharStringsIndex.add(data);
- }
- }
- }
-
- protected void writeFDSelect() {
- writeByte(0); //Format
- for (Integer gid : subsetFDSelect.keySet()) {
- writeByte(subsetFDSelect.get(gid).getNewFDIndex());
- }
- }
-
- protected List<Integer> getUsedFDFonts() {
- List<Integer> uniqueNewRefs = new ArrayList<Integer>();
- for (int gid : subsetFDSelect.keySet()) {
- int fdIndex = subsetFDSelect.get(gid).getOldFDIndex();
- if (!uniqueNewRefs.contains(fdIndex)) {
- uniqueNewRefs.add(fdIndex);
- }
- }
- return uniqueNewRefs;
- }
-
- protected List<Integer> writeCIDDictsAndSubrs(List<Integer> uniqueNewRefs)
- throws IOException {
- List<Integer> privateDictOffsets = new ArrayList<Integer>();
- List<FontDict> fdFonts = cffReader.getFDFonts();
- for (int i = 0; i < uniqueNewRefs.size(); i++) {
- FontDict curFDFont = fdFonts.get(uniqueNewRefs.get(i));
- HashMap<String, DICTEntry> fdPrivateDict = cffReader.parseDictData(
- curFDFont.getPrivateDictData());
- int privateDictOffset = currentPos;
- privateDictOffsets.add(privateDictOffset);
- byte[] fdPrivateDictByteData = curFDFont.getPrivateDictData();
- if (fdPrivateDict.get("Subrs") != null) {
- int encodingValue = 0;
- if (fdPrivateDict.get("Subrs").getOperandLength() == 1) {
- encodingValue = 139;
- }
- fdPrivateDictByteData = updateOffset(fdPrivateDictByteData, fdPrivateDict.get("Subrs").getOffset(),
- fdPrivateDict.get("Subrs").getOperandLength(),
- fdPrivateDictByteData.length + encodingValue);
- }
- writeBytes(fdPrivateDictByteData);
- writeIndex(fdSubrs.get(i));
- }
- return privateDictOffsets;
- }
-
- protected int writeFDArray(List<Integer> uniqueNewRefs, List<Integer> privateDictOffsets,
- List<Integer> fontNameSIDs)
- throws IOException {
- int offset = currentPos;
- List<FontDict> fdFonts = cffReader.getFDFonts();
-
- writeCard16(uniqueNewRefs.size());
- writeByte(1); //Offset size
- writeByte(1); //First offset
-
- int count = 1;
- for (int i = 0; i < uniqueNewRefs.size(); i++) {
- FontDict fdFont = fdFonts.get(uniqueNewRefs.get(i));
- count += fdFont.getByteData().length;
- writeByte(count);
- }
-
- for (int i = 0; i < uniqueNewRefs.size(); i++) {
- FontDict fdFont = fdFonts.get(uniqueNewRefs.get(i));
- byte[] fdFontByteData = fdFont.getByteData();
- Map<String, DICTEntry> fdFontDict = cffReader.parseDictData(fdFontByteData);
- //Update the SID to the FontName
- fdFontByteData = updateOffset(fdFontByteData, fdFontDict.get("FontName").getOffset() - 1,
- fdFontDict.get("FontName").getOperandLengths().get(0),
- fontNameSIDs.get(i));
- //Update the Private dict reference
- fdFontByteData = updateOffset(fdFontByteData, fdFontDict.get("Private").getOffset()
- + fdFontDict.get("Private").getOperandLengths().get(0),
- fdFontDict.get("Private").getOperandLengths().get(1),
- privateDictOffsets.get(i));
- writeBytes(fdFontByteData);
- }
- return offset;
- }
-
- private class FDIndexReference {
- private int newFDIndex;
- private int oldFDIndex;
-
- public FDIndexReference(int newFDIndex, int oldFDIndex) {
- this.newFDIndex = newFDIndex;
- this.oldFDIndex = oldFDIndex;
- }
-
- public int getNewFDIndex() {
- return newFDIndex;
- }
-
- public int getOldFDIndex() {
- return oldFDIndex;
- }
- }
-
- private void createCharStringData() throws IOException {
- Map<String, DICTEntry> topDICT = cffReader.getTopDictEntries();
-
- CFFIndexData charStringsIndex = cffReader.getCharStringIndex();
-
- DICTEntry privateEntry = topDICT.get("Private");
- if (privateEntry != null) {
- int privateOffset = privateEntry.getOperands().get(1).intValue();
- Map<String, DICTEntry> privateDICT = cffReader.getPrivateDict(privateEntry);
-
- if (privateDICT.get("Subrs") != null) {
- int localSubrOffset = privateOffset + privateDICT.get("Subrs").getOperands().get(0).intValue();
- localIndexSubr = cffReader.readIndex(localSubrOffset);
- } else {
- localIndexSubr = cffReader.readIndex(null);
- }
- }
-
- globalIndexSubr = cffReader.getGlobalIndexSubr();
-
- //Create the two lists which are to store the local and global subroutines
- subsetLocalIndexSubr = new ArrayList<byte[]>();
- subsetGlobalIndexSubr = new ArrayList<byte[]>();
-
- //Create the new char string index
- subsetCharStringsIndex = new ArrayList<byte[]>();
-
- localUniques = new ArrayList<Integer>();
- globalUniques = new ArrayList<Integer>();
-
- for (int gid : subsetGlyphs.keySet()) {
- byte[] data = charStringsIndex.getValue(gid);
- preScanForSubsetIndexSize(data);
- }
-
- //Store the size of each subset index and clear the unique arrays
- subsetLocalSubrCount = localUniques.size();
- subsetGlobalSubrCount = globalUniques.size();
- localUniques.clear();
- globalUniques.clear();
-
- for (int gid : subsetGlyphs.keySet()) {
- byte[] data = charStringsIndex.getValue(gid);
- //Retrieve modified char string data and fill local / global subroutine arrays
- data = readCharStringData(data, subsetLocalSubrCount);
- subsetCharStringsIndex.add(data);
- }
- }
-
- private void preScanForSubsetIndexSize(byte[] data) throws IOException {
- boolean hasLocalSubroutines = localIndexSubr != null && localIndexSubr.getNumObjects() > 0;
- boolean hasGlobalSubroutines = globalIndexSubr != null && globalIndexSubr.getNumObjects() > 0;
- BytesNumber operand = new BytesNumber(-1, -1);
- for (int dataPos = 0; dataPos < data.length; dataPos++) {
- int b0 = data[dataPos] & 0xff;
- if (b0 == LOCAL_SUBROUTINE && hasLocalSubroutines) {
- int subrNumber = getSubrNumber(localIndexSubr.getNumObjects(), operand.getNumber());
-
- if (!localUniques.contains(subrNumber) && subrNumber < localIndexSubr.getNumObjects()) {
- localUniques.add(subrNumber);
- byte[] subr = localIndexSubr.getValue(subrNumber);
- preScanForSubsetIndexSize(subr);
- }
- operand.clearNumber();
- } else if (b0 == GLOBAL_SUBROUTINE && hasGlobalSubroutines) {
- int subrNumber = getSubrNumber(globalIndexSubr.getNumObjects(), operand.getNumber());
-
- if (!globalUniques.contains(subrNumber) && subrNumber < globalIndexSubr.getNumObjects()) {
- globalUniques.add(subrNumber);
- byte[] subr = globalIndexSubr.getValue(subrNumber);
- preScanForSubsetIndexSize(subr);
- }
- operand.clearNumber();
- } else if ((b0 >= 0 && b0 <= 27) || (b0 >= 29 && b0 <= 31)) {
- operand.clearNumber();
- if (b0 == 19 || b0 == 20) {
- dataPos += 1;
- }
- } else if (b0 == 28 || (b0 >= 32 && b0 <= 255)) {
- operand = readNumber(b0, data, dataPos);
- dataPos += operand.getNumBytes() - 1;
- }
- }
- }
-
- private int getSubrNumber(int numSubroutines, int operand) {
- int bias = getBias(numSubroutines);
- return bias + operand;
- }
-
- private byte[] readCharStringData(byte[] data, int subsetLocalSubrCount) throws IOException {
- boolean hasLocalSubroutines = localIndexSubr != null && localIndexSubr.getNumObjects() > 0;
- boolean hasGlobalSubroutines = globalIndexSubr != null && globalIndexSubr.getNumObjects() > 0;
- BytesNumber operand = new BytesNumber(-1, -1);
- for (int dataPos = 0; dataPos < data.length; dataPos++) {
- int b0 = data[dataPos] & 0xff;
- if (b0 == 10 && hasLocalSubroutines) {
- int subrNumber = getSubrNumber(localIndexSubr.getNumObjects(), operand.getNumber());
-
- int newRef = getNewRefForReference(subrNumber, localUniques, localIndexSubr, subsetLocalIndexSubr,
- subsetLocalSubrCount);
-
- if (newRef != -1) {
- byte[] newData = constructNewRefData(dataPos, data, operand, subsetLocalSubrCount,
- newRef, new int[] {10});
- dataPos -= data.length - newData.length;
- data = newData;
- }
-
- operand.clearNumber();
- } else if (b0 == 29 && hasGlobalSubroutines) {
- int subrNumber = getSubrNumber(globalIndexSubr.getNumObjects(), operand.getNumber());
-
- int newRef = getNewRefForReference(subrNumber, globalUniques, globalIndexSubr, subsetGlobalIndexSubr,
- subsetGlobalSubrCount);
-
- if (newRef != -1) {
- byte[] newData = constructNewRefData(dataPos, data, operand, subsetGlobalSubrCount,
- newRef, new int[] {29});
- dataPos -= (data.length - newData.length);
- data = newData;
- }
-
- operand.clearNumber();
- } else if ((b0 >= 0 && b0 <= 27) || (b0 >= 29 && b0 <= 31)) {
- operand.clearNumber();
- if (b0 == 19) {
- dataPos += 1;
- }
- } else if (b0 == 28 || (b0 >= 32 && b0 <= 255)) {
- operand = readNumber(b0, data, dataPos);
- dataPos += operand.getNumBytes() - 1;
- }
- }
-
- //Return the data with the modified references to our arrays
- return data;
- }
-
- private int getNewRefForReference(int subrNumber, List<Integer> uniquesArray,
- CFFIndexData indexSubr, List<byte[]> subsetIndexSubr, int subrCount) throws IOException {
- int newRef = -1;
- if (!uniquesArray.contains(subrNumber)) {
- if (subrNumber < indexSubr.getNumObjects()) {
- byte[] subr = indexSubr.getValue(subrNumber);
- subr = readCharStringData(subr, subrCount);
- if (!uniquesArray.contains(subrNumber)) {
- uniquesArray.add(subrNumber);
- subsetIndexSubr.add(subr);
- newRef = subsetIndexSubr.size() - 1;
- } else {
- newRef = uniquesArray.indexOf(subrNumber);
- }
- }
- } else {
- newRef = uniquesArray.indexOf(subrNumber);
- }
- return newRef;
- }
-
- private int getBias(int subrCount) {
- if (subrCount < 1240) {
- return 107;
- } else if (subrCount < 33900) {
- return 1131;
- } else {
- return 32768;
- }
- }
-
- private byte[] constructNewRefData(int curDataPos, byte[] currentData, BytesNumber operand,
- int fullSubsetIndexSize, int curSubsetIndexSize, int[] operatorCode) {
- //Create the new array with the modified reference
- byte[] newData;
- int startRef = curDataPos - operand.getNumBytes();
- int length = operand.getNumBytes() + 1;
- byte[] preBytes = new byte[startRef];
- System.arraycopy(currentData, 0, preBytes, 0, startRef);
- int newBias = getBias(fullSubsetIndexSize);
- int newRef = curSubsetIndexSize - newBias;
- byte[] newRefBytes = createNewRef(newRef, operatorCode, -1);
- newData = concatArray(preBytes, newRefBytes);
- byte[] postBytes = new byte[currentData.length - (startRef + length)];
- System.arraycopy(currentData, startRef + length, postBytes, 0,
- currentData.length - (startRef + length));
- return concatArray(newData, postBytes);
- }
-
- public static byte[] createNewRef(int newRef, int[] operatorCode, int forceLength) {
- byte[] newRefBytes;
- int sizeOfOperator = operatorCode.length;
- if ((forceLength == -1 && newRef <= 107) || forceLength == 1) {
- newRefBytes = new byte[1 + sizeOfOperator];
- //The index values are 0 indexed
- newRefBytes[0] = (byte)(newRef + 139);
- for (int i = 0; i < operatorCode.length; i++) {
- newRefBytes[1 + i] = (byte)operatorCode[i];
- }
- } else if ((forceLength == -1 && newRef <= 1131) || forceLength == 2) {
- newRefBytes = new byte[2 + sizeOfOperator];
- if (newRef <= 363) {
- newRefBytes[0] = (byte)247;
- } else if (newRef <= 619) {
- newRefBytes[0] = (byte)248;
- } else if (newRef <= 875) {
- newRefBytes[0] = (byte)249;
- } else {
- newRefBytes[0] = (byte)250;
- }
- newRefBytes[1] = (byte)(newRef - 108);
- for (int i = 0; i < operatorCode.length; i++) {
- newRefBytes[2 + i] = (byte)operatorCode[i];
- }
- } else if ((forceLength == -1 && newRef <= 32767) || forceLength == 3) {
- newRefBytes = new byte[3 + sizeOfOperator];
- newRefBytes[0] = 28;
- newRefBytes[1] = (byte)(newRef >> 8);
- newRefBytes[2] = (byte)newRef;
- for (int i = 0; i < operatorCode.length; i++) {
- newRefBytes[3 + i] = (byte)operatorCode[i];
- }
- } else {
- newRefBytes = new byte[5 + sizeOfOperator];
- newRefBytes[0] = 29;
- newRefBytes[1] = (byte)(newRef >> 24);
- newRefBytes[2] = (byte)(newRef >> 16);
- newRefBytes[3] = (byte)(newRef >> 8);
- newRefBytes[4] = (byte)newRef;
- for (int i = 0; i < operatorCode.length; i++) {
- newRefBytes[5 + i] = (byte)operatorCode[i];
- }
- }
- return newRefBytes;
- }
-
- public static byte[] concatArray(byte[] a, byte[] b) {
- int aLen = a.length;
- int bLen = b.length;
- byte[] c = new byte[aLen + bLen];
- System.arraycopy(a, 0, c, 0, aLen);
- System.arraycopy(b, 0, c, aLen, bLen);
- return c;
- }
-
- protected int writeIndex(List<byte[]> dataArray) {
- int hdrTotal = 3;
- //2 byte number of items
- this.writeCard16(dataArray.size());
- //Offset Size: 1 byte = 256, 2 bytes = 65536 etc.
- int totLength = 0;
- for (int i = 0; i < dataArray.size(); i++) {
- totLength += dataArray.get(i).length;
- }
- int offSize = 1;
- if (totLength <= (1 << 8)) {
- offSize = 1;
- } else if (totLength <= (1 << 16)) {
- offSize = 2;
- } else if (totLength <= (1 << 24)) {
- offSize = 3;
- } else {
- offSize = 4;
- }
- this.writeByte(offSize);
- //Count the first offset 1
- hdrTotal += offSize;
- int total = 0;
- for (int i = 0; i < dataArray.size(); i++) {
- hdrTotal += offSize;
- int length = dataArray.get(i).length;
- switch (offSize) {
- case 1:
- if (i == 0) {
- writeByte(1);
- }
- total += length;
- writeByte(total + 1);
- break;
- case 2:
- if (i == 0) {
- writeCard16(1);
- }
- total += length;
- writeCard16(total + 1);
- break;
- case 3:
- if (i == 0) {
- writeThreeByteNumber(1);
- }
- total += length;
- writeThreeByteNumber(total + 1);
- break;
- case 4:
- if (i == 0) {
- writeULong(1);
- }
- total += length;
- writeULong(total + 1);
- break;
- default:
- throw new AssertionError("Offset Size was not an expected value.");
- }
- }
- for (int i = 0; i < dataArray.size(); i++) {
- writeBytes(dataArray.get(i));
- }
- return hdrTotal + total;
- }
-
- private BytesNumber readNumber(int b0, byte[] input, int curPos) throws IOException {
- if (b0 == 28) {
- int b1 = input[curPos + 1] & 0xff;
- int b2 = input[curPos + 2] & 0xff;
- return new BytesNumber(Integer.valueOf((short) (b1 << 8 | b2)), 3);
- } else if (b0 >= 32 && b0 <= 246) {
- return new BytesNumber(Integer.valueOf(b0 - 139), 1);
- } else if (b0 >= 247 && b0 <= 250) {
- int b1 = input[curPos + 1] & 0xff;
- return new BytesNumber(Integer.valueOf((b0 - 247) * 256 + b1 + 108), 2);
- } else if (b0 >= 251 && b0 <= 254) {
- int b1 = input[curPos + 1] & 0xff;
- return new BytesNumber(Integer.valueOf(-(b0 - 251) * 256 - b1 - 108), 2);
- } else if (b0 == 255) {
- int b1 = input[curPos + 1] & 0xff;
- int b2 = input[curPos + 2] & 0xff;
- return new BytesNumber(Integer.valueOf((short)(b1 << 8 | b2)), 5);
- } else {
- throw new IllegalArgumentException();
- }
- }
-
- /**
- * A class used to store the last number operand and also it's size in bytes
- */
- static class BytesNumber {
- private int number;
- private int numBytes;
-
- public BytesNumber(int number, int numBytes) {
- this.number = number;
- this.numBytes = numBytes;
- }
-
- public int getNumber() {
- return this.number;
- }
-
- public int getNumBytes() {
- return this.numBytes;
- }
-
- public void clearNumber() {
- this.number = -1;
- this.numBytes = -1;
- }
-
- public String toString() {
- return Integer.toString(number);
- }
-
- @Override
- public boolean equals(Object entry) {
- assert entry instanceof BytesNumber;
- BytesNumber bnEntry = (BytesNumber)entry;
- return this.number == bnEntry.getNumber()
- && this.numBytes == bnEntry.getNumBytes();
- }
-
- @Override
- public int hashCode() {
- int hash = 1;
- hash = hash * 17 + number;
- hash = hash * 31 + numBytes;
- return hash;
- }
- }
-
- private void writeCharsetTable(boolean cidFont) throws IOException {
- writeByte(0);
- for (int gid : gidToSID.keySet()) {
- if (cidFont && gid == 0) {
- continue;
- }
- writeCard16((cidFont) ? gid : gidToSID.get(gid));
- }
- }
-
- protected void writePrivateDict() throws IOException {
- Map<String, DICTEntry> topDICT = cffReader.getTopDictEntries();
-
- DICTEntry privateEntry = topDICT.get("Private");
- if (privateEntry != null) {
- writeBytes(cffReader.getPrivateDictBytes(privateEntry));
- }
- }
-
- protected void updateOffsets(int topDictOffset, int charsetOffset, int charStringOffset,
- int privateDictOffset, int localIndexOffset, int encodingOffset)
- throws IOException {
- Map<String, DICTEntry> topDICT = cffReader.getTopDictEntries();
- Map<String, DICTEntry> privateDICT = null;
-
- DICTEntry privateEntry = topDICT.get("Private");
- if (privateEntry != null) {
- privateDICT = cffReader.getPrivateDict(privateEntry);
- }
-
- int dataPos = 3 + (cffReader.getTopDictIndex().getOffSize()
- * cffReader.getTopDictIndex().getOffsets().length);
- int dataTopDictOffset = topDictOffset + dataPos;
-
- updateFixedOffsets(topDICT, dataTopDictOffset, charsetOffset, charStringOffset, encodingOffset);
-
- if (privateDICT != null) {
- //Private index offset in the top dict
- int oldPrivateOffset = dataTopDictOffset + privateEntry.getOffset();
- output = updateOffset(output, oldPrivateOffset + privateEntry.getOperandLengths().get(0),
- privateEntry.getOperandLengths().get(1), privateDictOffset);
-
- //Update the local subroutine index offset in the private dict
- DICTEntry subroutines = privateDICT.get("Subrs");
- if (subroutines != null) {
- int oldLocalSubrOffset = privateDictOffset + subroutines.getOffset();
- //Value needs to be converted to -139 etc.
- int encodeValue = 0;
- if (subroutines.getOperandLength() == 1) {
- encodeValue = 139;
- }
- output = updateOffset(output, oldLocalSubrOffset, subroutines.getOperandLength(),
- (localIndexOffset - privateDictOffset) + encodeValue);
- }
- }
- }
-
- protected void updateFixedOffsets(Map<String, DICTEntry> topDICT, int dataTopDictOffset,
- int charsetOffset, int charStringOffset, int encodingOffset) {
- //Charset offset in the top dict
- DICTEntry charset = topDICT.get("charset");
- int oldCharsetOffset = dataTopDictOffset + charset.getOffset();
- output = updateOffset(output, oldCharsetOffset, charset.getOperandLength(), charsetOffset);
-
- //Char string index offset in the private dict
- DICTEntry charString = topDICT.get("CharStrings");
- int oldCharStringOffset = dataTopDictOffset + charString.getOffset();
- output = updateOffset(output, oldCharStringOffset, charString.getOperandLength(), charStringOffset);
-
- DICTEntry encodingEntry = topDICT.get("Encoding");
- if (encodingEntry != null && encodingEntry.getOperands().get(0).intValue() != 0
- && encodingEntry.getOperands().get(0).intValue() != 1) {
- int oldEncodingOffset = dataTopDictOffset + encodingEntry.getOffset();
- output = updateOffset(output, oldEncodingOffset, encodingEntry.getOperandLength(), encodingOffset);
- }
- }
-
- protected void updateCIDOffsets(int topDictDataOffset, int fdArrayOffset, int fdSelectOffset,
- int charsetOffset, int charStringOffset, int encodingOffset) {
- LinkedHashMap<String, DICTEntry> topDict = cffReader.getTopDictEntries();
-
- DICTEntry fdArrayEntry = topDict.get("FDArray");
- if (fdArrayEntry != null) {
- output = updateOffset(output, topDictDataOffset + fdArrayEntry.getOffset() - 1,
- fdArrayEntry.getOperandLength(), fdArrayOffset);
- }
-
- DICTEntry fdSelect = topDict.get("FDSelect");
- if (fdSelect != null) {
- output = updateOffset(output, topDictDataOffset + fdSelect.getOffset() - 1,
- fdSelect.getOperandLength(), fdSelectOffset);
- }
-
- updateFixedOffsets(topDict, topDictDataOffset, charsetOffset, charStringOffset, encodingOffset);
- }
-
- protected byte[] updateOffset(byte[] out, int position, int length, int replacement) {
- switch (length) {
- case 1:
- out[position] = (byte)(replacement & 0xFF);
- break;
- case 2:
- if (replacement <= 363) {
- out[position] = (byte)247;
- } else if (replacement <= 619) {
- out[position] = (byte)248;
- } else if (replacement <= 875) {
- out[position] = (byte)249;
- } else {
- out[position] = (byte)250;
- }
- out[position + 1] = (byte)(replacement - 108);
- break;
- case 3:
- out[position] = (byte)28;
- out[position + 1] = (byte)((replacement >> 8) & 0xFF);
- out[position + 2] = (byte)(replacement & 0xFF);
- break;
- case 5:
- out[position] = (byte)29;
- out[position + 1] = (byte)((replacement >> 24) & 0xFF);
- out[position + 2] = (byte)((replacement >> 16) & 0xFF);
- out[position + 3] = (byte)((replacement >> 8) & 0xFF);
- out[position + 4] = (byte)(replacement & 0xFF);
- break;
- default:
- }
- return out;
- }
-
- /**
- * Appends a byte to the output array,
- * updates currentPost but not realSize
- */
- protected void writeByte(int b) {
- output[currentPos++] = (byte)b;
- realSize++;
- }
-
- /**
- * Appends a USHORT to the output array,
- * updates currentPost but not realSize
- */
- protected void writeCard16(int s) {
- byte b1 = (byte)((s >> 8) & 0xff);
- byte b2 = (byte)(s & 0xff);
- writeByte(b1);
- writeByte(b2);
- }
-
- private void writeThreeByteNumber(int s) {
- byte b1 = (byte)((s >> 16) & 0xFF);
- byte b2 = (byte)((s >> 8) & 0xFF);
- byte b3 = (byte)(s & 0xFF);
- writeByte(b1);
- writeByte(b2);
- writeByte(b3);
- }
-
- /**
- * Appends a ULONG to the output array,
- * at the given position
- */
- private void writeULong(int s) {
- byte b1 = (byte)((s >> 24) & 0xff);
- byte b2 = (byte)((s >> 16) & 0xff);
- byte b3 = (byte)((s >> 8) & 0xff);
- byte b4 = (byte)(s & 0xff);
- writeByte(b1);
- writeByte(b2);
- writeByte(b3);
- writeByte(b4);
- }
-
- /**
- * Returns a subset of the fonts (readFont() MUST be called first in order to create the
- * subset).
- * @return byte array
- */
- public byte[] getFontSubset() {
- byte[] ret = new byte[realSize];
- System.arraycopy(output, 0, ret, 0, realSize);
- return ret;
- }
-
- /**
- * Returns the parsed CFF data for the original font.
- * @return The CFFDataReader contaiing the parsed data
- */
- public CFFDataReader getCFFReader() {
- return cffReader;
- }
-}
diff --git a/src/java/org/apache/fop/fonts/truetype/OpenFont.java b/src/java/org/apache/fop/fonts/truetype/OpenFont.java
deleted file mode 100644
index e94f31bb1..000000000
--- a/src/java/org/apache/fop/fonts/truetype/OpenFont.java
+++ /dev/null
@@ -1,2006 +0,0 @@
-/*
- * 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.truetype;
-
-import java.awt.Rectangle;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.BitSet;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.xmlgraphics.fonts.Glyphs;
-
-import org.apache.fop.complexscripts.fonts.AdvancedTypographicTableFormatException;
-import org.apache.fop.complexscripts.fonts.GlyphDefinitionTable;
-import org.apache.fop.complexscripts.fonts.GlyphPositioningTable;
-import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable;
-import org.apache.fop.complexscripts.fonts.OTFAdvancedTypographicTableReader;
-import org.apache.fop.fonts.CMapSegment;
-import org.apache.fop.fonts.FontUtil;
-import org.apache.fop.fonts.MultiByteFont;
-
-public abstract class OpenFont {
-
- static final byte NTABS = 24;
- static final int MAX_CHAR_CODE = 255;
- static final int ENC_BUF_SIZE = 1024;
-
- private static final String[] MAC_GLYPH_ORDERING = {
- /* 0x000 */
- ".notdef", ".null", "nonmarkingreturn", "space",
- "exclam", "quotedbl", "numbersign", "dollar",
- "percent", "ampersand", "quotesingle", "parenleft",
- "parenright", "asterisk", "plus", "comma",
- /* 0x010 */
- "hyphen", "period", "slash", "zero",
- "one", "two", "three", "four",
- "five", "six", "seven", "eight",
- "nine", "colon", "semicolon", "less",
- /* 0x020 */
- "equal", "greater", "question", "at",
- "A", "B", "C", "D",
- "E", "F", "G", "H",
- "I", "J", "K", "L",
- /* 0x030 */
- "M", "N", "O", "P",
- "Q", "R", "S", "T",
- "U", "V", "W", "X",
- "Y", "Z", "bracketleft", "backslash",
- /* 0x040 */
- "bracketright", "asciicircum", "underscore", "grave",
- "a", "b", "c", "d",
- "e", "f", "g", "h",
- "i", "j", "k", "l",
- /* 0x050 */
- "m", "n", "o", "p",
- "q", "r", "s", "t",
- "u", "v", "w", "x",
- "y", "z", "braceleft", "bar",
- /* 0x060 */
- "braceright", "asciitilde", "Adieresis", "Aring",
- "Ccedilla", "Eacute", "Ntilde", "Odieresis",
- "Udieresis", "aacute", "agrave", "acircumflex",
- "adieresis", "atilde", "aring", "ccedilla",
- /* 0x070 */
- "eacute", "egrave", "ecircumflex", "edieresis",
- "iacute", "igrave", "icircumflex", "idieresis",
- "ntilde", "oacute", "ograve", "ocircumflex",
- "odieresis", "otilde", "uacute", "ugrave",
- /* 0x080 */
- "ucircumflex", "udieresis", "dagger", "degree",
- "cent", "sterling", "section", "bullet",
- "paragraph", "germandbls", "registered", "copyright",
- "trademark", "acute", "dieresis", "notequal",
- /* 0x090 */
- "AE", "Oslash", "infinity", "plusminus",
- "lessequal", "greaterequal", "yen", "mu",
- "partialdiff", "summation", "product", "pi",
- "integral", "ordfeminine", "ordmasculine", "Omega",
- /* 0x0A0 */
- "ae", "oslash", "questiondown", "exclamdown",
- "logicalnot", "radical", "florin", "approxequal",
- "Delta", "guillemotleft", "guillemotright", "ellipsis",
- "nonbreakingspace", "Agrave", "Atilde", "Otilde",
- /* 0x0B0 */
- "OE", "oe", "endash", "emdash",
- "quotedblleft", "quotedblright", "quoteleft", "quoteright",
- "divide", "lozenge", "ydieresis", "Ydieresis",
- "fraction", "currency", "guilsinglleft", "guilsinglright",
- /* 0x0C0 */
- "fi", "fl", "daggerdbl", "periodcentered",
- "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex",
- "Ecircumflex", "Aacute", "Edieresis", "Egrave",
- "Iacute", "Icircumflex", "Idieresis", "Igrave",
- /* 0x0D0 */
- "Oacute", "Ocircumflex", "apple", "Ograve",
- "Uacute", "Ucircumflex", "Ugrave", "dotlessi",
- "circumflex", "tilde", "macron", "breve",
- "dotaccent", "ring", "cedilla", "hungarumlaut",
- /* 0x0E0 */
- "ogonek", "caron", "Lslash", "lslash",
- "Scaron", "scaron", "Zcaron", "zcaron",
- "brokenbar", "Eth", "eth", "Yacute",
- "yacute", "Thorn", "thorn", "minus",
- /* 0x0F0 */
- "multiply", "onesuperior", "twosuperior", "threesuperior",
- "onehalf", "onequarter", "threequarters", "franc",
- "Gbreve", "gbreve", "Idotaccent", "Scedilla",
- "scedilla", "Cacute", "cacute", "Ccaron",
- /* 0x100 */
- "ccaron", "dcroat"
- };
-
- /** The FontFileReader used to read this TrueType font. */
- protected FontFileReader fontFile;
-
- /** Set to true to get even more debug output than with level DEBUG */
- public static final boolean TRACE_ENABLED = false;
-
- private static final String ENCODING = "WinAnsiEncoding"; // Default encoding
-
- private static final short FIRST_CHAR = 0;
-
- protected boolean useKerning;
- private boolean isEmbeddable = true;
- private boolean hasSerifs = true;
- /**
- * Table directory
- */
- protected Map<OFTableName, OFDirTabEntry> dirTabs;
-
- private Map<Integer, Map<Integer, Integer>> kerningTab; // for CIDs
- private Map<Integer, Map<Integer, Integer>> ansiKerningTab; // For winAnsiEncoding
- private List<CMapSegment> cmaps;
- protected List<UnicodeMapping> unicodeMappings;
-
- private int upem; // unitsPerEm from "head" table
- protected int nhmtx; // Number of horizontal metrics
- private PostScriptVersion postScriptVersion;
- protected int locaFormat;
- /**
- * Offset to last loca
- */
- protected long lastLoca;
- protected int numberOfGlyphs; // Number of glyphs in font (read from "maxp" table)
-
- /**
- * Contains glyph data
- */
- protected OFMtxEntry[] mtxTab; // Contains glyph data
-
- protected String postScriptName = "";
- protected String fullName = "";
- protected String notice = "";
- protected final Set<String> familyNames = new HashSet<String>();
- protected String subFamilyName = "";
- protected boolean cid = true;
-
- private long italicAngle;
- private long isFixedPitch;
- private int fontBBox1;
- private int fontBBox2;
- private int fontBBox3;
- private int fontBBox4;
- private int capHeight;
- private int os2CapHeight;
- private int underlinePosition;
- private int underlineThickness;
- private int strikeoutPosition;
- private int strikeoutThickness;
- private int xHeight;
- private int os2xHeight;
- //Effective ascender/descender
- private int ascender;
- private int descender;
- //Ascender/descender from hhea table
- private int hheaAscender;
- private int hheaDescender;
- //Ascender/descender from OS/2 table
- private int os2Ascender;
- private int os2Descender;
- private int usWeightClass;
-
- private short lastChar;
-
- private int[] ansiWidth;
- private Map<Integer, List<Integer>> ansiIndex;
-
- // internal mapping of glyph indexes to unicode indexes
- // used for quick mappings in this class
- private final Map<Integer, Integer> glyphToUnicodeMap = new HashMap<Integer, Integer>();
- private final Map<Integer, Integer> unicodeToGlyphMap = new HashMap<Integer, Integer>();
-
- private boolean isCFF;
-
- // advanced typographic table support
- protected boolean useAdvanced;
- protected OTFAdvancedTypographicTableReader advancedTableReader;
-
- /**
- * Version of the PostScript table (<q>post</q>) contained in this font.
- */
- public static enum PostScriptVersion {
- /** PostScript table version 1.0. */
- V1,
- /** PostScript table version 2.0. */
- V2,
- /** PostScript table version 3.0. */
- V3,
- /** Unknown version of the PostScript table. */
- UNKNOWN;
- }
-
- /**
- * logging instance
- */
- protected Log log = LogFactory.getLog(TTFFile.class);
-
- public OpenFont() {
- this(true, false);
- }
-
- /**
- * Constructor
- * @param useKerning true if kerning data should be loaded
- * @param useAdvanced true if advanced typographic tables should be loaded
- */
- public OpenFont(boolean useKerning, boolean useAdvanced) {
- this.useKerning = useKerning;
- this.useAdvanced = useAdvanced;
- }
-
- /**
- * Key-value helper class.
- */
- static final class UnicodeMapping implements Comparable {
-
- private final int unicodeIndex;
- private final int glyphIndex;
-
- UnicodeMapping(OpenFont font, int glyphIndex, int unicodeIndex) {
- this.unicodeIndex = unicodeIndex;
- this.glyphIndex = glyphIndex;
- font.glyphToUnicodeMap.put(new Integer(glyphIndex), new Integer(unicodeIndex));
- font.unicodeToGlyphMap.put(new Integer(unicodeIndex), new Integer(glyphIndex));
- }
-
- /**
- * Returns the glyphIndex.
- * @return the glyph index
- */
- public int getGlyphIndex() {
- return glyphIndex;
- }
-
- /**
- * Returns the unicodeIndex.
- * @return the Unicode index
- */
- public int getUnicodeIndex() {
- return unicodeIndex;
- }
-
-
- /** {@inheritDoc} */
- public int hashCode() {
- int hc = unicodeIndex;
- hc = 19 * hc + (hc ^ glyphIndex);
- return hc;
- }
-
- /** {@inheritDoc} */
- public boolean equals(Object o) {
- if (o instanceof UnicodeMapping) {
- UnicodeMapping m = (UnicodeMapping) o;
- if (unicodeIndex != m.unicodeIndex) {
- return false;
- } else {
- return (glyphIndex == m.glyphIndex);
- }
- } else {
- return false;
- }
- }
-
- /** {@inheritDoc} */
- public int compareTo(Object o) {
- if (o instanceof UnicodeMapping) {
- UnicodeMapping m = (UnicodeMapping) o;
- if (unicodeIndex > m.unicodeIndex) {
- return 1;
- } else if (unicodeIndex < m.unicodeIndex) {
- return -1;
- } else {
- return 0;
- }
- } else {
- return -1;
- }
- }
- }
-
- /**
- * Obtain directory table entry.
- * @param name (tag) of entry
- * @return a directory table entry or null if none found
- */
- public OFDirTabEntry getDirectoryEntry(OFTableName name) {
- return dirTabs.get(name);
- }
-
- /**
- * Position inputstream to position indicated
- * in the dirtab offset + offset
- * @param in font file reader
- * @param tableName (tag) of table
- * @param offset from start of table
- * @return true if seek succeeded
- * @throws IOException if I/O exception occurs during seek
- */
- public boolean seekTab(FontFileReader in, OFTableName tableName,
- long offset) throws IOException {
- OFDirTabEntry dt = dirTabs.get(tableName);
- if (dt == null) {
- log.info("Dirtab " + tableName.getName() + " not found.");
- return false;
- } else {
- in.seekSet(dt.getOffset() + offset);
- }
- return true;
- }
-
- /**
- * Convert from truetype unit to pdf unit based on the
- * unitsPerEm field in the "head" table
- * @param n truetype unit
- * @return pdf unit
- */
- public int convertTTFUnit2PDFUnit(int n) {
- int ret;
- if (n < 0) {
- long rest1 = n % upem;
- long storrest = 1000 * rest1;
- long ledd2 = (storrest != 0 ? rest1 / storrest : 0);
- ret = -((-1000 * n) / upem - (int)ledd2);
- } else {
- ret = (n / upem) * 1000 + ((n % upem) * 1000) / upem;
- }
-
- return ret;
- }
-
- /**
- * Read the cmap table,
- * return false if the table is not present or only unsupported
- * tables are present. Currently only unicode cmaps are supported.
- * Set the unicodeIndex in the TTFMtxEntries and fills in the
- * cmaps vector.
- */
- protected boolean readCMAP() throws IOException {
-
- unicodeMappings = new ArrayList<OpenFont.UnicodeMapping>();
-
- if (!seekTab(fontFile, OFTableName.CMAP, 2)) {
- return true;
- }
- int numCMap = fontFile.readTTFUShort(); // Number of cmap subtables
- long cmapUniOffset = 0;
- long symbolMapOffset = 0;
-
- if (log.isDebugEnabled()) {
- log.debug(numCMap + " cmap tables");
- }
-
- //Read offset for all tables. We are only interested in the unicode table
- for (int i = 0; i < numCMap; i++) {
- int cmapPID = fontFile.readTTFUShort();
- int cmapEID = fontFile.readTTFUShort();
- long cmapOffset = fontFile.readTTFLong();
-
- if (log.isDebugEnabled()) {
- log.debug("Platform ID: " + cmapPID + " Encoding: " + cmapEID);
- }
-
- if (cmapPID == 3 && cmapEID == 1) {
- cmapUniOffset = cmapOffset;
- }
- if (cmapPID == 3 && cmapEID == 0) {
- symbolMapOffset = cmapOffset;
- }
- }
-
- if (cmapUniOffset > 0) {
- return readUnicodeCmap(cmapUniOffset, 1);
- } else if (symbolMapOffset > 0) {
- return readUnicodeCmap(symbolMapOffset, 0);
- } else {
- log.fatal("Unsupported TrueType font: No Unicode or Symbol cmap table"
- + " not present. Aborting");
- return false;
- }
- }
-
- private boolean readUnicodeCmap(long cmapUniOffset, int encodingID)
- throws IOException {
- //Read CMAP table and correct mtxTab.index
- int mtxPtr = 0;
-
- // Read unicode cmap
- seekTab(fontFile, OFTableName.CMAP, cmapUniOffset);
- int cmapFormat = fontFile.readTTFUShort();
- /*int cmap_length =*/ fontFile.readTTFUShort(); //skip cmap length
-
- if (log.isDebugEnabled()) {
- log.debug("CMAP format: " + cmapFormat);
- }
-
- if (cmapFormat == 4) {
- fontFile.skip(2); // Skip version number
- int cmapSegCountX2 = fontFile.readTTFUShort();
- int cmapSearchRange = fontFile.readTTFUShort();
- int cmapEntrySelector = fontFile.readTTFUShort();
- int cmapRangeShift = fontFile.readTTFUShort();
-
- if (log.isDebugEnabled()) {
- log.debug("segCountX2 : " + cmapSegCountX2);
- log.debug("searchRange : " + cmapSearchRange);
- log.debug("entrySelector: " + cmapEntrySelector);
- log.debug("rangeShift : " + cmapRangeShift);
- }
-
-
- int[] cmapEndCounts = new int[cmapSegCountX2 / 2];
- int[] cmapStartCounts = new int[cmapSegCountX2 / 2];
- int[] cmapDeltas = new int[cmapSegCountX2 / 2];
- int[] cmapRangeOffsets = new int[cmapSegCountX2 / 2];
-
- for (int i = 0; i < (cmapSegCountX2 / 2); i++) {
- cmapEndCounts[i] = fontFile.readTTFUShort();
- }
-
- fontFile.skip(2); // Skip reservedPad
-
- for (int i = 0; i < (cmapSegCountX2 / 2); i++) {
- cmapStartCounts[i] = fontFile.readTTFUShort();
- }
-
- for (int i = 0; i < (cmapSegCountX2 / 2); i++) {
- cmapDeltas[i] = fontFile.readTTFShort();
- }
-
- //int startRangeOffset = in.getCurrentPos();
-
- for (int i = 0; i < (cmapSegCountX2 / 2); i++) {
- cmapRangeOffsets[i] = fontFile.readTTFUShort();
- }
-
- int glyphIdArrayOffset = fontFile.getCurrentPos();
-
- BitSet eightBitGlyphs = new BitSet(256);
-
- // Insert the unicode id for the glyphs in mtxTab
- // and fill in the cmaps ArrayList
- for (int i = 0; i < cmapStartCounts.length; i++) {
-
- if (log.isTraceEnabled()) {
- log.trace(i + ": " + cmapStartCounts[i]
- + " - " + cmapEndCounts[i]);
- }
- if (log.isDebugEnabled()) {
- if (isInPrivateUseArea(cmapStartCounts[i], cmapEndCounts[i])) {
- log.debug("Font contains glyphs in the Unicode private use area: "
- + Integer.toHexString(cmapStartCounts[i]) + " - "
- + Integer.toHexString(cmapEndCounts[i]));
- }
- }
-
- for (int j = cmapStartCounts[i]; j <= cmapEndCounts[i]; j++) {
-
- // Update lastChar
- if (j < 256 && j > lastChar) {
- lastChar = (short)j;
- }
-
- if (j < 256) {
- eightBitGlyphs.set(j);
- }
-
- if (mtxPtr < mtxTab.length) {
- int glyphIdx;
- // the last character 65535 = .notdef
- // may have a range offset
- if (cmapRangeOffsets[i] != 0 && j != 65535) {
- int glyphOffset = glyphIdArrayOffset
- + ((cmapRangeOffsets[i] / 2)
- + (j - cmapStartCounts[i])
- + (i)
- - cmapSegCountX2 / 2) * 2;
- fontFile.seekSet(glyphOffset);
- glyphIdx = (fontFile.readTTFUShort() + cmapDeltas[i])
- & 0xffff;
- //mtxTab[glyphIdx].setName(mtxTab[glyphIdx].getName() + " - "+(char)j);
- unicodeMappings.add(new UnicodeMapping(this, glyphIdx, j));
- mtxTab[glyphIdx].getUnicodeIndex().add(new Integer(j));
-
- if (encodingID == 0 && j >= 0xF020 && j <= 0xF0FF) {
- //Experimental: Mapping 0xF020-0xF0FF to 0x0020-0x00FF
- //Tested with Wingdings and Symbol TTF fonts which map their
- //glyphs in the region 0xF020-0xF0FF.
- int mapped = j - 0xF000;
- if (!eightBitGlyphs.get(mapped)) {
- //Only map if Unicode code point hasn't been mapped before
- unicodeMappings.add(new UnicodeMapping(this, glyphIdx, mapped));
- mtxTab[glyphIdx].getUnicodeIndex().add(new Integer(mapped));
- }
- }
-
- // Also add winAnsiWidth
- List<Integer> v = ansiIndex.get(new Integer(j));
- if (v != null) {
- for (Integer aIdx : v) {
- ansiWidth[aIdx.intValue()]
- = mtxTab[glyphIdx].getWx();
-
- if (log.isTraceEnabled()) {
- log.trace("Added width "
- + mtxTab[glyphIdx].getWx()
- + " uni: " + j
- + " ansi: " + aIdx.intValue());
- }
- }
- }
-
- if (log.isTraceEnabled()) {
- log.trace("Idx: "
- + glyphIdx
- + " Delta: " + cmapDeltas[i]
- + " Unicode: " + j
- + " name: " + mtxTab[glyphIdx].getName());
- }
- } else {
- glyphIdx = (j + cmapDeltas[i]) & 0xffff;
-
- if (glyphIdx < mtxTab.length) {
- mtxTab[glyphIdx].getUnicodeIndex().add(new Integer(j));
- } else {
- log.debug("Glyph " + glyphIdx
- + " out of range: "
- + mtxTab.length);
- }
-
- unicodeMappings.add(new UnicodeMapping(this, glyphIdx, j));
- if (glyphIdx < mtxTab.length) {
- mtxTab[glyphIdx].getUnicodeIndex().add(new Integer(j));
- } else {
- log.debug("Glyph " + glyphIdx
- + " out of range: "
- + mtxTab.length);
- }
-
- // Also add winAnsiWidth
- List<Integer> v = ansiIndex.get(new Integer(j));
- if (v != null) {
- for (Integer aIdx : v) {
- ansiWidth[aIdx.intValue()] = mtxTab[glyphIdx].getWx();
- }
- }
-
- //getLogger().debug("IIdx: " +
- // mtxPtr +
- // " Delta: " + cmap_deltas[i] +
- // " Unicode: " + j +
- // " name: " +
- // mtxTab[(j+cmap_deltas[i]) & 0xffff].name);
-
- }
- if (glyphIdx < mtxTab.length) {
- if (mtxTab[glyphIdx].getUnicodeIndex().size() < 2) {
- mtxPtr++;
- }
- }
- }
- }
- }
- } else {
- log.error("Cmap format not supported: " + cmapFormat);
- return false;
- }
- return true;
- }
-
- private boolean isInPrivateUseArea(int start, int end) {
- return (isInPrivateUseArea(start) || isInPrivateUseArea(end));
- }
-
- private boolean isInPrivateUseArea(int unicode) {
- return (unicode >= 0xE000 && unicode <= 0xF8FF);
- }
-
- /**
- *
- * @return mmtx data
- */
- public List<OFMtxEntry> getMtx() {
- return Collections.unmodifiableList(Arrays.asList(mtxTab));
- }
-
- /**
- * Print first char/last char
- */
- /* not used
- private void printMaxMin() {
- int min = 255;
- int max = 0;
- for (int i = 0; i < mtxTab.length; i++) {
- if (mtxTab[i].getIndex() < min) {
- min = mtxTab[i].getIndex();
- }
- if (mtxTab[i].getIndex() > max) {
- max = mtxTab[i].getIndex();
- }
- }
- log.info("Min: " + min);
- log.info("Max: " + max);
- }
- */
-
-
- /**
- * Reads the font using a FontFileReader.
- *
- * @param in The FontFileReader to use
- * @throws IOException In case of an I/O problem
- */
- public void readFont(FontFileReader in, String header) throws IOException {
- readFont(in, header, (String)null);
- }
-
- /**
- * initialize the ansiWidths array (for winAnsiEncoding)
- * and fill with the missingwidth
- */
- protected void initAnsiWidths() {
- ansiWidth = new int[256];
- for (int i = 0; i < 256; i++) {
- ansiWidth[i] = mtxTab[0].getWx();
- }
-
- // Create an index hash to the ansiWidth
- // Can't just index the winAnsiEncoding when inserting widths
- // same char (eg bullet) is repeated more than one place
- ansiIndex = new HashMap<Integer, List<Integer>>();
- for (int i = 32; i < Glyphs.WINANSI_ENCODING.length; i++) {
- Integer ansi = new Integer(i);
- Integer uni = new Integer(Glyphs.WINANSI_ENCODING[i]);
-
- List<Integer> v = ansiIndex.get(uni);
- if (v == null) {
- v = new ArrayList<Integer>();
- ansiIndex.put(uni, v);
- }
- v.add(ansi);
- }
- }
-
- /**
- * Read the font data.
- * If the fontfile is a TrueType Collection (.ttc file)
- * the name of the font to read data for must be supplied,
- * else the name is ignored.
- *
- * @param in The FontFileReader to use
- * @param name The name of the font
- * @return boolean Returns true if the font is valid
- * @throws IOException In case of an I/O problem
- */
- public boolean readFont(FontFileReader in, String header, String name) throws IOException {
- initializeFont(in);
- /*
- * Check if TrueType collection, and that the name
- * exists in the collection
- */
- if (!checkTTC(header, name)) {
- if (name == null) {
- throw new IllegalArgumentException(
- "For TrueType collection you must specify which font "
- + "to select (-ttcname)");
- } else {
- throw new IOException(
- "Name does not exist in the TrueType collection: " + name);
- }
- }
-
- readDirTabs();
- readFontHeader();
- getNumGlyphs();
- if (log.isDebugEnabled()) {
- log.debug("Number of glyphs in font: " + numberOfGlyphs);
- }
- readHorizontalHeader();
- readHorizontalMetrics();
- initAnsiWidths();
- readPostScript();
- readOS2();
- determineAscDesc();
-
- readName();
- boolean pcltFound = readPCLT();
- // Read cmap table and fill in ansiwidths
- boolean valid = readCMAP();
- if (!valid) {
- return false;
- }
-
- // Create cmaps for bfentries
- createCMaps();
- updateBBoxAndOffset();
-
- if (useKerning) {
- readKerning();
- }
- handleCharacterSpacing(in);
-
- guessVerticalMetricsFromGlyphBBox();
- return true;
- }
-
- /**
- * Reads a font.
- *
- * @param in FontFileReader to read from
- * @param name Name to be checked for in the font file
- * @param glyphs Map of glyphs (glyphs has old index as (Integer) key and
- * new index as (Integer) value)
- * @throws IOException in case of an I/O problem
- */
- public void readFont(FontFileReader in, String header, MultiByteFont mbfont) throws IOException {
- readFont(in, header, mbfont.getTTCName());
- }
-
- protected abstract void updateBBoxAndOffset() throws IOException;
-
- protected abstract void readName() throws IOException;
-
- protected abstract void initializeFont(FontFileReader in) throws IOException;
-
- protected void handleCharacterSpacing(FontFileReader in) throws IOException {
- // Read advanced typographic tables.
- if (useAdvanced) {
- try {
- OTFAdvancedTypographicTableReader atr
- = new OTFAdvancedTypographicTableReader(this, in);
- atr.readAll();
- this.advancedTableReader = atr;
- } catch (AdvancedTypographicTableFormatException e) {
- log.warn(
- "Encountered format constraint violation in advanced (typographic) table (AT) "
- + "in font '" + getFullName() + "', ignoring AT data: "
- + e.getMessage()
- );
- }
- }
-
- }
-
- protected void createCMaps() {
- cmaps = new ArrayList<CMapSegment>();
- int unicodeStart;
- int glyphStart;
- int unicodeEnd;
- if (unicodeMappings.isEmpty()) {
- return;
- }
- Iterator<UnicodeMapping> e = unicodeMappings.iterator();
- UnicodeMapping um = e.next();
- UnicodeMapping lastMapping = um;
-
- unicodeStart = um.getUnicodeIndex();
- glyphStart = um.getGlyphIndex();
-
- while (e.hasNext()) {
- um = e.next();
- if (((lastMapping.getUnicodeIndex() + 1) != um.getUnicodeIndex())
- || ((lastMapping.getGlyphIndex() + 1) != um.getGlyphIndex())) {
- unicodeEnd = lastMapping.getUnicodeIndex();
- cmaps.add(new CMapSegment(unicodeStart, unicodeEnd, glyphStart));
- unicodeStart = um.getUnicodeIndex();
- glyphStart = um.getGlyphIndex();
- }
- lastMapping = um;
- }
-
- unicodeEnd = lastMapping.getUnicodeIndex();
- cmaps.add(new CMapSegment(unicodeStart, unicodeEnd, glyphStart));
- }
-
- /**
- * Returns the PostScript name of the font.
- * @return String The PostScript name
- */
- public String getPostScriptName() {
- if (postScriptName.length() == 0) {
- return FontUtil.stripWhiteSpace(getFullName());
- } else {
- return postScriptName;
- }
- }
-
- PostScriptVersion getPostScriptVersion() {
- return postScriptVersion;
- }
-
- /**
- * Returns the font family names of the font.
- * @return Set The family names (a Set of Strings)
- */
- public Set<String> getFamilyNames() {
- return familyNames;
- }
-
- /**
- * Returns the font sub family name of the font.
- * @return String The sub family name
- */
- public String getSubFamilyName() {
- return subFamilyName;
- }
-
- /**
- * Returns the full name of the font.
- * @return String The full name
- */
- public String getFullName() {
- return fullName;
- }
-
- /**
- * Returns the name of the character set used.
- * @return String The caracter set
- */
- public String getCharSetName() {
- return ENCODING;
- }
-
- /**
- * Returns the CapHeight attribute of the font.
- * @return int The CapHeight
- */
- public int getCapHeight() {
- return convertTTFUnit2PDFUnit(capHeight);
- }
-
- /**
- * Returns the XHeight attribute of the font.
- * @return int The XHeight
- */
- public int getXHeight() {
- return convertTTFUnit2PDFUnit(xHeight);
- }
-
- /**
- * Returns the number of bytes necessary to pad the currentPosition so that a table begins
- * on a 4-byte boundary.
- * @param currentPosition the position to pad.
- * @return int the number of bytes to pad.
- */
- protected int getPadSize(int currentPosition) {
- int padSize = 4 - (currentPosition % 4);
- return padSize < 4 ? padSize : 0;
- }
-
- /**
- * Returns the Flags attribute of the font.
- * @return int The Flags
- */
- public int getFlags() {
- int flags = 32; // Use Adobe Standard charset
- if (italicAngle != 0) {
- flags |= 64;
- }
- if (isFixedPitch != 0) {
- flags |= 2;
- }
- if (hasSerifs) {
- flags |= 1;
- }
- return flags;
- }
-
- /**
- * Returns the weight class of this font. Valid values are 100, 200....,800, 900.
- * @return the weight class value (or 0 if there was no OS/2 table in the font)
- */
- public int getWeightClass() {
- return this.usWeightClass;
- }
-
- /**
- * Returns the StemV attribute of the font.
- * @return String The StemV
- */
- public String getStemV() {
- return "0";
- }
-
- /**
- * Returns the ItalicAngle attribute of the font.
- * @return String The ItalicAngle
- */
- public String getItalicAngle() {
- String ia = Short.toString((short)(italicAngle / 0x10000));
-
- // This is the correct italic angle, however only int italic
- // angles are supported at the moment so this is commented out.
- /*
- * if ((italicAngle % 0x10000) > 0 )
- * ia=ia+(comma+Short.toString((short)((short)((italicAngle % 0x10000)*1000)/0x10000)));
- */
- return ia;
- }
-
- /**
- * @return int[] The font bbox
- */
- public int[] getFontBBox() {
- final int[] fbb = new int[4];
- fbb[0] = convertTTFUnit2PDFUnit(fontBBox1);
- fbb[1] = convertTTFUnit2PDFUnit(fontBBox2);
- fbb[2] = convertTTFUnit2PDFUnit(fontBBox3);
- fbb[3] = convertTTFUnit2PDFUnit(fontBBox4);
-
- return fbb;
- }
-
- /**
- * Returns the original bounding box values from the HEAD table
- * @return An array of bounding box values
- */
- public int[] getBBoxRaw() {
- int[] bbox = {fontBBox1, fontBBox2, fontBBox3, fontBBox4};
- return bbox;
- }
-
- /**
- * Returns the LowerCaseAscent attribute of the font.
- * @return int The LowerCaseAscent
- */
- public int getLowerCaseAscent() {
- return convertTTFUnit2PDFUnit(ascender);
- }
-
- /**
- * Returns the LowerCaseDescent attribute of the font.
- * @return int The LowerCaseDescent
- */
- public int getLowerCaseDescent() {
- return convertTTFUnit2PDFUnit(descender);
- }
-
- /**
- * Returns the index of the last character, but this is for WinAnsiEncoding
- * only, so the last char is < 256.
- * @return short Index of the last character (<256)
- */
- public short getLastChar() {
- return lastChar;
- }
-
- /**
- * Returns the index of the first character.
- * @return short Index of the first character
- */
- public short getFirstChar() {
- return FIRST_CHAR;
- }
-
- /**
- * Returns an array of character widths.
- * @return int[] The character widths
- */
- public int[] getWidths() {
- int[] wx = new int[mtxTab.length];
- for (int i = 0; i < wx.length; i++) {
- wx[i] = convertTTFUnit2PDFUnit(mtxTab[i].getWx());
- }
- return wx;
- }
-
- public Rectangle[] getBoundingBoxes() {
- Rectangle[] boundingBoxes = new Rectangle[mtxTab.length];
- for (int i = 0; i < boundingBoxes.length; i++) {
- int[] boundingBox = mtxTab[i].getBoundingBox();
- boundingBoxes[i] = new Rectangle(
- convertTTFUnit2PDFUnit(boundingBox[0]),
- convertTTFUnit2PDFUnit(boundingBox[1]),
- convertTTFUnit2PDFUnit(boundingBox[2] - boundingBox[0]),
- convertTTFUnit2PDFUnit(boundingBox[3] - boundingBox[1]));
- }
- return boundingBoxes;
- }
-
- /**
- * Returns an array (xMin, yMin, xMax, yMax) for a glyph.
- *
- * @param glyphIndex the index of the glyph
- * @return int[] Array defining bounding box.
- */
- public int[] getBBox(int glyphIndex) {
- int[] bboxInTTFUnits = mtxTab[glyphIndex].getBoundingBox();
- int[] bbox = new int[4];
- for (int i = 0; i < 4; i++) {
- bbox[i] = convertTTFUnit2PDFUnit(bboxInTTFUnits[i]);
- }
- return bbox;
- }
-
- /**
- * Returns the width of a given character.
- * @param idx Index of the character
- * @return int Standard width
- */
- public int getCharWidth(int idx) {
- return convertTTFUnit2PDFUnit(ansiWidth[idx]);
- }
-
- /**
- * Returns the width of a given character in raw units
- * @param idx Index of the character
- * @return int Width in it's raw form stored in the font
- */
- public int getCharWidthRaw(int idx) {
- if (ansiWidth != null) {
- return ansiWidth[idx];
- }
- return -1;
- }
-
- /**
- * Returns the kerning table.
- * @return Map The kerning table
- */
- public Map<Integer, Map<Integer, Integer>> getKerning() {
- return kerningTab;
- }
-
- /**
- * Returns the ANSI kerning table.
- * @return Map The ANSI kerning table
- */
- public Map<Integer, Map<Integer, Integer>> getAnsiKerning() {
- return ansiKerningTab;
- }
-
- public int getUnderlinePosition() {
- return convertTTFUnit2PDFUnit(underlinePosition);
- }
-
- public int getUnderlineThickness() {
- return convertTTFUnit2PDFUnit(underlineThickness);
- }
-
- public int getStrikeoutPosition() {
- return convertTTFUnit2PDFUnit(strikeoutPosition);
- }
-
- public int getStrikeoutThickness() {
- return convertTTFUnit2PDFUnit(strikeoutThickness);
- }
-
- /**
- * Indicates if the font may be embedded.
- * @return boolean True if it may be embedded
- */
- public boolean isEmbeddable() {
- return isEmbeddable;
- }
-
- /**
- * Indicates whether or not the font is an OpenType
- * CFF font (rather than a TrueType font).
- * @return true if the font is in OpenType CFF format.
- */
- public boolean isCFF() {
- return this.isCFF;
- }
-
- /**
- * Read Table Directory from the current position in the
- * FontFileReader and fill the global HashMap dirTabs
- * with the table name (String) as key and a TTFDirTabEntry
- * as value.
- * @throws IOException in case of an I/O problem
- */
- protected void readDirTabs() throws IOException {
- int sfntVersion = fontFile.readTTFLong(); // TTF_FIXED_SIZE (4 bytes)
- switch (sfntVersion) {
- case 0x10000:
- log.debug("sfnt version: OpenType 1.0");
- break;
- case 0x4F54544F: //"OTTO"
- this.isCFF = true;
- log.debug("sfnt version: OpenType with CFF data");
- break;
- case 0x74727565: //"true"
- log.debug("sfnt version: Apple TrueType");
- break;
- case 0x74797031: //"typ1"
- log.debug("sfnt version: Apple Type 1 housed in sfnt wrapper");
- break;
- default:
- log.debug("Unknown sfnt version: " + Integer.toHexString(sfntVersion));
- break;
- }
- int ntabs = fontFile.readTTFUShort();
- fontFile.skip(6); // 3xTTF_USHORT_SIZE
-
- dirTabs = new HashMap<OFTableName, OFDirTabEntry>();
- OFDirTabEntry[] pd = new OFDirTabEntry[ntabs];
- log.debug("Reading " + ntabs + " dir tables");
-
- for (int i = 0; i < ntabs; i++) {
- pd[i] = new OFDirTabEntry();
- String tableName = pd[i].read(fontFile);
- dirTabs.put(OFTableName.getValue(tableName), pd[i]);
- }
- dirTabs.put(OFTableName.TABLE_DIRECTORY,
- new OFDirTabEntry(0L, fontFile.getCurrentPos()));
- log.debug("dir tables: " + dirTabs.keySet());
- }
-
- /**
- * Read the "head" table, this reads the bounding box and
- * sets the upem (unitsPerEM) variable
- * @throws IOException in case of an I/O problem
- */
- protected void readFontHeader() throws IOException {
- seekTab(fontFile, OFTableName.HEAD, 2 * 4 + 2 * 4);
- int flags = fontFile.readTTFUShort();
- if (log.isDebugEnabled()) {
- log.debug("flags: " + flags + " - " + Integer.toString(flags, 2));
- }
- upem = fontFile.readTTFUShort();
- if (log.isDebugEnabled()) {
- log.debug("unit per em: " + upem);
- }
-
- fontFile.skip(16);
-
- fontBBox1 = fontFile.readTTFShort();
- fontBBox2 = fontFile.readTTFShort();
- fontBBox3 = fontFile.readTTFShort();
- fontBBox4 = fontFile.readTTFShort();
- if (log.isDebugEnabled()) {
- log.debug("font bbox: xMin=" + fontBBox1
- + " yMin=" + fontBBox2
- + " xMax=" + fontBBox3
- + " yMax=" + fontBBox4);
- }
-
- fontFile.skip(2 + 2 + 2);
-
- locaFormat = fontFile.readTTFShort();
- }
-
- /**
- * Read the number of glyphs from the "maxp" table
- * @throws IOException in case of an I/O problem
- */
- protected void getNumGlyphs() throws IOException {
- seekTab(fontFile, OFTableName.MAXP, 4);
- numberOfGlyphs = fontFile.readTTFUShort();
- }
-
-
- /**
- * Read the "hhea" table to find the ascender and descender and
- * size of "hmtx" table, as a fixed size font might have only
- * one width.
- * @throws IOException in case of an I/O problem
- */
- protected void readHorizontalHeader()
- throws IOException {
- seekTab(fontFile, OFTableName.HHEA, 4);
- hheaAscender = fontFile.readTTFShort();
- hheaDescender = fontFile.readTTFShort();
-
- fontFile.skip(2 + 2 + 3 * 2 + 8 * 2);
- nhmtx = fontFile.readTTFUShort();
-
- if (log.isDebugEnabled()) {
- log.debug("hhea.Ascender: " + formatUnitsForDebug(hheaAscender));
- log.debug("hhea.Descender: " + formatUnitsForDebug(hheaDescender));
- log.debug("Number of horizontal metrics: " + nhmtx);
- }
- }
-
- /**
- * Read "hmtx" table and put the horizontal metrics
- * in the mtxTab array. If the number of metrics is less
- * than the number of glyphs (eg fixed size fonts), extend
- * the mtxTab array and fill in the missing widths
- * @throws IOException in case of an I/O problem
- */
- protected void readHorizontalMetrics()
- throws IOException {
- seekTab(fontFile, OFTableName.HMTX, 0);
-
- int mtxSize = Math.max(numberOfGlyphs, nhmtx);
- mtxTab = new OFMtxEntry[mtxSize];
-
- if (log.isTraceEnabled()) {
- log.trace("*** Widths array: \n");
- }
- for (int i = 0; i < mtxSize; i++) {
- mtxTab[i] = new OFMtxEntry();
- }
- for (int i = 0; i < nhmtx; i++) {
- mtxTab[i].setWx(fontFile.readTTFUShort());
- mtxTab[i].setLsb(fontFile.readTTFUShort());
-
- if (log.isTraceEnabled()) {
- log.trace(" width[" + i + "] = "
- + convertTTFUnit2PDFUnit(mtxTab[i].getWx()) + ";");
- }
- }
-
- if (cid && nhmtx < mtxSize) {
- // Fill in the missing widths
- int lastWidth = mtxTab[nhmtx - 1].getWx();
- for (int i = nhmtx; i < mtxSize; i++) {
- mtxTab[i].setWx(lastWidth);
- mtxTab[i].setLsb(fontFile.readTTFUShort());
- }
- }
- }
-
-
- /**
- * Read the "post" table
- * containing the PostScript names of the glyphs.
- */
- protected void readPostScript() throws IOException {
- seekTab(fontFile, OFTableName.POST, 0);
- int postFormat = fontFile.readTTFLong();
- italicAngle = fontFile.readTTFULong();
- underlinePosition = fontFile.readTTFShort();
- underlineThickness = fontFile.readTTFShort();
- isFixedPitch = fontFile.readTTFULong();
-
- //Skip memory usage values
- fontFile.skip(4 * 4);
-
- log.debug("PostScript format: 0x" + Integer.toHexString(postFormat));
- switch (postFormat) {
- case 0x00010000:
- log.debug("PostScript format 1");
- postScriptVersion = PostScriptVersion.V1;
- for (int i = 0; i < MAC_GLYPH_ORDERING.length; i++) {
- mtxTab[i].setName(MAC_GLYPH_ORDERING[i]);
- }
- break;
- case 0x00020000:
- log.debug("PostScript format 2");
- postScriptVersion = PostScriptVersion.V2;
- int numGlyphStrings = 257;
-
- // Read Number of Glyphs
- int l = fontFile.readTTFUShort();
-
- // Read indexes
- for (int i = 0; i < l; i++) {
- mtxTab[i].setIndex(fontFile.readTTFUShort());
-
- if (mtxTab[i].getIndex() > numGlyphStrings) {
- numGlyphStrings = mtxTab[i].getIndex();
- }
-
- if (log.isTraceEnabled()) {
- log.trace("PostScript index: " + mtxTab[i].getIndexAsString());
- }
- }
-
- // firstChar=minIndex;
- String[] psGlyphsBuffer = new String[numGlyphStrings - 257];
- if (log.isDebugEnabled()) {
- log.debug("Reading " + numGlyphStrings
- + " glyphnames, that are not in the standard Macintosh"
- + " set. Total number of glyphs=" + l);
- }
- for (int i = 0; i < psGlyphsBuffer.length; i++) {
- psGlyphsBuffer[i] = fontFile.readTTFString(fontFile.readTTFUByte());
- }
-
- //Set glyph names
- for (int i = 0; i < l; i++) {
- if (mtxTab[i].getIndex() < MAC_GLYPH_ORDERING.length) {
- mtxTab[i].setName(MAC_GLYPH_ORDERING[mtxTab[i].getIndex()]);
- } else {
- if (!mtxTab[i].isIndexReserved()) {
- int k = mtxTab[i].getIndex() - MAC_GLYPH_ORDERING.length;
-
- if (log.isTraceEnabled()) {
- log.trace(k + " i=" + i + " mtx=" + mtxTab.length
- + " ps=" + psGlyphsBuffer.length);
- }
-
- mtxTab[i].setName(psGlyphsBuffer[k]);
- }
- }
- }
-
- break;
- case 0x00030000:
- // PostScript format 3 contains no glyph names
- log.debug("PostScript format 3");
- postScriptVersion = PostScriptVersion.V3;
- break;
- default:
- log.error("Unknown PostScript format: " + postFormat);
- postScriptVersion = PostScriptVersion.UNKNOWN;
- }
- }
-
-
- /**
- * Read the "OS/2" table
- */
- protected void readOS2() throws IOException {
- // Check if font is embeddable
- OFDirTabEntry os2Entry = dirTabs.get(OFTableName.OS2);
- if (os2Entry != null) {
- seekTab(fontFile, OFTableName.OS2, 0);
- int version = fontFile.readTTFUShort();
- if (log.isDebugEnabled()) {
- log.debug("OS/2 table: version=" + version
- + ", offset=" + os2Entry.getOffset() + ", len=" + os2Entry.getLength());
- }
- fontFile.skip(2); //xAvgCharWidth
- this.usWeightClass = fontFile.readTTFUShort();
-
- // usWidthClass
- fontFile.skip(2);
-
- int fsType = fontFile.readTTFUShort();
- if (fsType == 2) {
- isEmbeddable = false;
- } else {
- isEmbeddable = true;
- }
- fontFile.skip(8 * 2);
- strikeoutThickness = fontFile.readTTFShort();
- strikeoutPosition = fontFile.readTTFShort();
- fontFile.skip(2);
- fontFile.skip(10); //panose array
- fontFile.skip(4 * 4); //unicode ranges
- fontFile.skip(4);
- fontFile.skip(3 * 2);
- int v;
- os2Ascender = fontFile.readTTFShort(); //sTypoAscender
- os2Descender = fontFile.readTTFShort(); //sTypoDescender
- if (log.isDebugEnabled()) {
- log.debug("sTypoAscender: " + os2Ascender
- + " -> internal " + convertTTFUnit2PDFUnit(os2Ascender));
- log.debug("sTypoDescender: " + os2Descender
- + " -> internal " + convertTTFUnit2PDFUnit(os2Descender));
- }
- v = fontFile.readTTFShort(); //sTypoLineGap
- if (log.isDebugEnabled()) {
- log.debug("sTypoLineGap: " + v);
- }
- v = fontFile.readTTFUShort(); //usWinAscent
- if (log.isDebugEnabled()) {
- log.debug("usWinAscent: " + formatUnitsForDebug(v));
- }
- v = fontFile.readTTFUShort(); //usWinDescent
- if (log.isDebugEnabled()) {
- log.debug("usWinDescent: " + formatUnitsForDebug(v));
- }
-
- //version 1 OS/2 table might end here
- if (os2Entry.getLength() >= 78 + (2 * 4) + (2 * 2)) {
- fontFile.skip(2 * 4);
- this.os2xHeight = fontFile.readTTFShort(); //sxHeight
- this.os2CapHeight = fontFile.readTTFShort(); //sCapHeight
- if (log.isDebugEnabled()) {
- log.debug("sxHeight: " + this.os2xHeight);
- log.debug("sCapHeight: " + this.os2CapHeight);
- }
- }
-
- } else {
- isEmbeddable = true;
- }
- }
-
- /**
- * Read the "PCLT" table to find xHeight and capHeight.
- * @throws IOException In case of a I/O problem
- */
- protected boolean readPCLT() throws IOException {
- OFDirTabEntry dirTab = dirTabs.get(OFTableName.PCLT);
- if (dirTab != null) {
- fontFile.seekSet(dirTab.getOffset() + 4 + 4 + 2);
- xHeight = fontFile.readTTFUShort();
- log.debug("xHeight from PCLT: " + formatUnitsForDebug(xHeight));
- fontFile.skip(2 * 2);
- capHeight = fontFile.readTTFUShort();
- log.debug("capHeight from PCLT: " + formatUnitsForDebug(capHeight));
- fontFile.skip(2 + 16 + 8 + 6 + 1 + 1);
-
- int serifStyle = fontFile.readTTFUByte();
- serifStyle = serifStyle >> 6;
- serifStyle = serifStyle & 3;
- if (serifStyle == 1) {
- hasSerifs = false;
- } else {
- hasSerifs = true;
- }
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Determines the right source for the ascender and descender values. The problem here is
- * that the interpretation of these values is not the same for every font. There doesn't seem
- * to be a uniform definition of an ascender and a descender. In some fonts
- * the hhea values are defined after the Apple interpretation, but not in every font. The
- * same problem is in the OS/2 table. FOP needs the ascender and descender to determine the
- * baseline so we need values which add up more or less to the "em box". However, due to
- * accent modifiers a character can grow beyond the em box.
- */
- protected void determineAscDesc() {
- int hheaBoxHeight = hheaAscender - hheaDescender;
- int os2BoxHeight = os2Ascender - os2Descender;
- if (os2Ascender > 0 && os2BoxHeight <= upem) {
- ascender = os2Ascender;
- descender = os2Descender;
- } else if (hheaAscender > 0 && hheaBoxHeight <= upem) {
- ascender = hheaAscender;
- descender = hheaDescender;
- } else {
- if (os2Ascender > 0) {
- //Fall back to info from OS/2 if possible
- ascender = os2Ascender;
- descender = os2Descender;
- } else {
- ascender = hheaAscender;
- descender = hheaDescender;
- }
- }
-
- if (log.isDebugEnabled()) {
- log.debug("Font box height: " + (ascender - descender));
- if (ascender - descender > upem) {
- log.debug("Ascender and descender together are larger than the em box.");
- }
- }
- }
-
- protected void guessVerticalMetricsFromGlyphBBox() {
- // Approximate capHeight from height of "H"
- // It's most unlikely that a font misses the PCLT table
- // This also assumes that postscriptnames exists ("H")
- // Should look it up in the cmap (that wouldn't help
- // for charsets without H anyway...)
- // Same for xHeight with the letter "x"
- int localCapHeight = 0;
- int localXHeight = 0;
- int localAscender = 0;
- int localDescender = 0;
- for (int i = 0; i < mtxTab.length; i++) {
- if ("H".equals(mtxTab[i].getName())) {
- localCapHeight = mtxTab[i].getBoundingBox()[3];
- } else if ("x".equals(mtxTab[i].getName())) {
- localXHeight = mtxTab[i].getBoundingBox()[3];
- } else if ("d".equals(mtxTab[i].getName())) {
- localAscender = mtxTab[i].getBoundingBox()[3];
- } else if ("p".equals(mtxTab[i].getName())) {
- localDescender = mtxTab[i].getBoundingBox()[1];
- } else {
- // OpenType Fonts with a version 3.0 "post" table don't have glyph names.
- // Use Unicode indices instead.
- List unicodeIndex = mtxTab[i].getUnicodeIndex();
- if (unicodeIndex.size() > 0) {
- //Only the first index is used
- char ch = (char)((Integer)unicodeIndex.get(0)).intValue();
- if (ch == 'H') {
- localCapHeight = mtxTab[i].getBoundingBox()[3];
- } else if (ch == 'x') {
- localXHeight = mtxTab[i].getBoundingBox()[3];
- } else if (ch == 'd') {
- localAscender = mtxTab[i].getBoundingBox()[3];
- } else if (ch == 'p') {
- localDescender = mtxTab[i].getBoundingBox()[1];
- }
- }
- }
- }
- if (log.isDebugEnabled()) {
- log.debug("Ascender from glyph 'd': " + formatUnitsForDebug(localAscender));
- log.debug("Descender from glyph 'p': " + formatUnitsForDebug(localDescender));
- }
- if (ascender - descender > upem) {
- log.debug("Replacing specified ascender/descender with derived values to get values"
- + " which fit in the em box.");
- ascender = localAscender;
- descender = localDescender;
- }
-
- if (log.isDebugEnabled()) {
- log.debug("xHeight from glyph 'x': " + formatUnitsForDebug(localXHeight));
- log.debug("CapHeight from glyph 'H': " + formatUnitsForDebug(localCapHeight));
- }
- if (capHeight == 0) {
- capHeight = localCapHeight;
- if (capHeight == 0) {
- capHeight = os2CapHeight;
- }
- if (capHeight == 0) {
- log.debug("capHeight value could not be determined."
- + " The font may not work as expected.");
- }
- }
- if (xHeight == 0) {
- xHeight = localXHeight;
- if (xHeight == 0) {
- xHeight = os2xHeight;
- }
- if (xHeight == 0) {
- log.debug("xHeight value could not be determined."
- + " The font may not work as expected.");
- }
- }
- }
-
- /**
- * Read the kerning table, create a table for both CIDs and
- * winAnsiEncoding.
- * @throws IOException In case of a I/O problem
- */
- protected void readKerning() throws IOException {
- // Read kerning
- kerningTab = new HashMap<Integer, Map<Integer, Integer>>();
- ansiKerningTab = new HashMap<Integer, Map<Integer, Integer>>();
- OFDirTabEntry dirTab = dirTabs.get(OFTableName.KERN);
- if (dirTab != null) {
- seekTab(fontFile, OFTableName.KERN, 2);
- for (int n = fontFile.readTTFUShort(); n > 0; n--) {
- fontFile.skip(2 * 2);
- int k = fontFile.readTTFUShort();
- if (!((k & 1) != 0) || (k & 2) != 0 || (k & 4) != 0) {
- return;
- }
- if ((k >> 8) != 0) {
- continue;
- }
-
- k = fontFile.readTTFUShort();
- fontFile.skip(3 * 2);
- while (k-- > 0) {
- int i = fontFile.readTTFUShort();
- int j = fontFile.readTTFUShort();
- int kpx = fontFile.readTTFShort();
- if (kpx != 0) {
- // CID kerning table entry, using unicode indexes
- final Integer iObj = glyphToUnicode(i);
- final Integer u2 = glyphToUnicode(j);
- if (iObj == null) {
- // happens for many fonts (Ubuntu font set),
- // stray entries in the kerning table??
- log.debug("Ignoring kerning pair because no Unicode index was"
- + " found for the first glyph " + i);
- } else if (u2 == null) {
- log.debug("Ignoring kerning pair because Unicode index was"
- + " found for the second glyph " + i);
- } else {
- Map<Integer, Integer> adjTab = kerningTab.get(iObj);
- if (adjTab == null) {
- adjTab = new HashMap<Integer, Integer>();
- }
- adjTab.put(u2, new Integer(convertTTFUnit2PDFUnit(kpx)));
- kerningTab.put(iObj, adjTab);
- }
- }
- }
- }
-
- // Create winAnsiEncoded kerning table from kerningTab
- // (could probably be simplified, for now we remap back to CID indexes and
- // then to winAnsi)
-
- for (Map.Entry<Integer, Map<Integer, Integer>> e1 : kerningTab.entrySet()) {
- Integer unicodeKey1 = e1.getKey();
- Integer cidKey1 = unicodeToGlyph(unicodeKey1);
- Map<Integer, Integer> akpx = new HashMap<Integer, Integer>();
- Map<Integer, Integer> ckpx = e1.getValue();
-
- for (Map.Entry<Integer, Integer> e : ckpx.entrySet()) {
- Integer unicodeKey2 = e.getKey();
- Integer cidKey2 = unicodeToGlyph(unicodeKey2.intValue());
- Integer kern = e.getValue();
-
- Iterator uniMap = mtxTab[cidKey2.intValue()].getUnicodeIndex().listIterator();
- while (uniMap.hasNext()) {
- Integer unicodeKey = (Integer)uniMap.next();
- Integer[] ansiKeys = unicodeToWinAnsi(unicodeKey.intValue());
- for (int u = 0; u < ansiKeys.length; u++) {
- akpx.put(ansiKeys[u], kern);
- }
- }
- }
-
- if (akpx.size() > 0) {
- Iterator uniMap = mtxTab[cidKey1.intValue()].getUnicodeIndex().listIterator();
- while (uniMap.hasNext()) {
- Integer unicodeKey = (Integer)uniMap.next();
- Integer[] ansiKeys = unicodeToWinAnsi(unicodeKey.intValue());
- for (int u = 0; u < ansiKeys.length; u++) {
- ansiKerningTab.put(ansiKeys[u], akpx);
- }
- }
- }
- }
- }
- }
-
- /**
- * Streams a font.
- * @param ttfOut The interface for streaming TrueType tables.
- * @exception IOException file write error
- */
- public void stream(TTFOutputStream ttfOut) throws IOException {
- SortedSet<Map.Entry<OFTableName, OFDirTabEntry>> sortedDirTabs = sortDirTabMap(dirTabs);
- byte[] file = fontFile.getAllBytes();
- TTFTableOutputStream tableOut = ttfOut.getTableOutputStream();
- TTFGlyphOutputStream glyphOut = ttfOut.getGlyphOutputStream();
- ttfOut.startFontStream();
- for (Map.Entry<OFTableName, OFDirTabEntry> entry : sortedDirTabs) {
- int offset = (int) entry.getValue().getOffset();
- int paddedLength = (int) entry.getValue().getLength();
- paddedLength += getPadSize(offset + paddedLength);
- if (entry.getKey().equals(OFTableName.GLYF)) {
- streamGlyf(glyphOut, file, offset, paddedLength);
- } else {
- tableOut.streamTable(file, offset, paddedLength);
- }
- }
- ttfOut.endFontStream();
- }
-
- private void streamGlyf(TTFGlyphOutputStream glyphOut, byte[] fontFile, int tableOffset,
- int tableLength) throws IOException {
- //Stream all but the last glyph
- int glyphStart = 0;
- int glyphEnd = 0;
- glyphOut.startGlyphStream();
- for (int i = 0; i < mtxTab.length - 1; i++) {
- glyphStart = (int) mtxTab[i].getOffset() + tableOffset;
- glyphEnd = (int) mtxTab[i + 1].getOffset() + tableOffset;
- glyphOut.streamGlyph(fontFile, glyphStart, glyphEnd - glyphStart);
- }
- glyphOut.streamGlyph(fontFile, glyphEnd, (tableOffset + tableLength) - glyphEnd);
- glyphOut.endGlyphStream();
- }
-
- /**
- * Returns the order in which the tables in a TrueType font should be written to file.
- * @param directoryTabs the map that is to be sorted.
- * @return TTFTablesNames[] an array of table names sorted in the order they should appear in
- * the TTF file.
- */
- SortedSet<Map.Entry<OFTableName, OFDirTabEntry>>
- sortDirTabMap(Map<OFTableName, OFDirTabEntry> directoryTabs) {
- SortedSet<Map.Entry<OFTableName, OFDirTabEntry>> sortedSet
- = new TreeSet<Map.Entry<OFTableName, OFDirTabEntry>>(
- new Comparator<Map.Entry<OFTableName, OFDirTabEntry>>() {
-
- public int compare(Entry<OFTableName, OFDirTabEntry> o1,
- Entry<OFTableName, OFDirTabEntry> o2) {
- return (int) (o1.getValue().getOffset() - o2.getValue().getOffset());
- }
- });
- // @SuppressFBWarnings("DMI_ENTRY_SETS_MAY_REUSE_ENTRY_OBJECTS")
- sortedSet.addAll(directoryTabs.entrySet());
- return sortedSet;
- }
-
- /**
- * Returns this font's character to glyph mapping.
- *
- * @return the font's cmap
- */
- public List<CMapSegment> getCMaps() {
- return cmaps;
- }
-
- /**
- * Check if this is a TrueType collection and that the given
- * name exists in the collection.
- * If it does, set offset in fontfile to the beginning of
- * the Table Directory for that font.
- * @param name The name to check
- * @return True if not collection or font name present, false otherwise
- * @throws IOException In case of an I/O problem
- */
- protected final boolean checkTTC(String tag, String name) throws IOException {
- if ("ttcf".equals(tag)) {
- // This is a TrueType Collection
- fontFile.skip(4);
-
- // Read directory offsets
- int numDirectories = (int)fontFile.readTTFULong();
- // int numDirectories=in.readTTFUShort();
- long[] dirOffsets = new long[numDirectories];
- for (int i = 0; i < numDirectories; i++) {
- dirOffsets[i] = fontFile.readTTFULong();
- }
-
- log.info("This is a TrueType collection file with "
- + numDirectories + " fonts");
- log.info("Containing the following fonts: ");
- // Read all the directories and name tables to check
- // If the font exists - this is a bit ugly, but...
- boolean found = false;
-
- // Iterate through all name tables even if font
- // Is found, just to show all the names
- long dirTabOffset = 0;
- for (int i = 0; (i < numDirectories); i++) {
- fontFile.seekSet(dirOffsets[i]);
- readDirTabs();
-
- readName();
-
- if (fullName.equals(name)) {
- found = true;
- dirTabOffset = dirOffsets[i];
- log.info(fullName + " <-- selected");
- } else {
- log.info(fullName);
- }
-
- // Reset names
- notice = "";
- fullName = "";
- familyNames.clear();
- postScriptName = "";
- subFamilyName = "";
- }
-
- fontFile.seekSet(dirTabOffset);
- return found;
- } else {
- fontFile.seekSet(0);
- return true;
- }
- }
-
- /**
- * Return TTC font names
- * @param in FontFileReader to read from
- * @return True if not collection or font name present, false otherwise
- * @throws IOException In case of an I/O problem
- */
- public final List<String> getTTCnames(FontFileReader in) throws IOException {
- this.fontFile = in;
-
- List<String> fontNames = new ArrayList<String>();
- String tag = in.readTTFString(4);
-
- if ("ttcf".equals(tag)) {
- // This is a TrueType Collection
- in.skip(4);
-
- // Read directory offsets
- int numDirectories = (int)in.readTTFULong();
- long[] dirOffsets = new long[numDirectories];
- for (int i = 0; i < numDirectories; i++) {
- dirOffsets[i] = in.readTTFULong();
- }
-
- log.info("This is a TrueType collection file with "
- + numDirectories + " fonts");
- log.info("Containing the following fonts: ");
-
- for (int i = 0; (i < numDirectories); i++) {
- in.seekSet(dirOffsets[i]);
- readDirTabs();
-
- readName();
-
- log.info(fullName);
- fontNames.add(fullName);
-
- // Reset names
- notice = "";
- fullName = "";
- familyNames.clear();
- postScriptName = "";
- subFamilyName = "";
- }
-
- in.seekSet(0);
- return fontNames;
- } else {
- log.error("Not a TTC!");
- return null;
- }
- }
-
- /*
- * Helper classes, they are not very efficient, but that really
- * doesn't matter...
- */
- private Integer[] unicodeToWinAnsi(int unicode) {
- List<Integer> ret = new ArrayList<Integer>();
- for (int i = 32; i < Glyphs.WINANSI_ENCODING.length; i++) {
- if (unicode == Glyphs.WINANSI_ENCODING[i]) {
- ret.add(new Integer(i));
- }
- }
- return ret.toArray(new Integer[ret.size()]);
- }
-
- /**
- * Dumps a few informational values to System.out.
- */
- public void printStuff() {
- System.out.println("Font name: " + postScriptName);
- System.out.println("Full name: " + fullName);
- System.out.println("Family name: " + familyNames);
- System.out.println("Subfamily name: " + subFamilyName);
- System.out.println("Notice: " + notice);
- System.out.println("xHeight: " + convertTTFUnit2PDFUnit(xHeight));
- System.out.println("capheight: " + convertTTFUnit2PDFUnit(capHeight));
-
- int italic = (int)(italicAngle >> 16);
- System.out.println("Italic: " + italic);
- System.out.print("ItalicAngle: " + (short)(italicAngle / 0x10000));
- if ((italicAngle % 0x10000) > 0) {
- System.out.print("."
- + (short)((italicAngle % 0x10000) * 1000)
- / 0x10000);
- }
- System.out.println();
- System.out.println("Ascender: " + convertTTFUnit2PDFUnit(ascender));
- System.out.println("Descender: " + convertTTFUnit2PDFUnit(descender));
- System.out.println("FontBBox: [" + convertTTFUnit2PDFUnit(fontBBox1)
- + " " + convertTTFUnit2PDFUnit(fontBBox2) + " "
- + convertTTFUnit2PDFUnit(fontBBox3) + " "
- + convertTTFUnit2PDFUnit(fontBBox4) + "]");
- }
-
- private String formatUnitsForDebug(int units) {
- return units + " -> " + convertTTFUnit2PDFUnit(units) + " internal units";
- }
-
- /**
- * Map a glyph index to the corresponding unicode code point
- *
- * @param glyphIndex
- * @return unicode code point
- */
- private Integer glyphToUnicode(int glyphIndex) {
- return glyphToUnicodeMap.get(new Integer(glyphIndex));
- }
-
- /**
- * Map a unicode code point to the corresponding glyph index
- *
- * @param unicodeIndex unicode code point
- * @return glyph index
- */
- private Integer unicodeToGlyph(int unicodeIndex) throws IOException {
- final Integer result
- = unicodeToGlyphMap.get(new Integer(unicodeIndex));
- if (result == null) {
- throw new IOException(
- "Glyph index not found for unicode value " + unicodeIndex);
- }
- return result;
- }
-
- String getGlyphName(int glyphIndex) {
- return mtxTab[glyphIndex].getName();
- }
-
- /**
- * Determine if advanced (typographic) table is present.
- * @return true if advanced (typographic) table is present
- */
- public boolean hasAdvancedTable() {
- if (advancedTableReader != null) {
- return advancedTableReader.hasAdvancedTable();
- } else {
- return false;
- }
- }
-
- /**
- * Returns the GDEF table or null if none present.
- * @return the GDEF table
- */
- public GlyphDefinitionTable getGDEF() {
- if (advancedTableReader != null) {
- return advancedTableReader.getGDEF();
- } else {
- return null;
- }
- }
-
- /**
- * Returns the GSUB table or null if none present.
- * @return the GSUB table
- */
- public GlyphSubstitutionTable getGSUB() {
- if (advancedTableReader != null) {
- return advancedTableReader.getGSUB();
- } else {
- return null;
- }
- }
-
- /**
- * Returns the GPOS table or null if none present.
- * @return the GPOS table
- */
- public GlyphPositioningTable getGPOS() {
- if (advancedTableReader != null) {
- return advancedTableReader.getGPOS();
- } else {
- return null;
- }
- }
-
- /**
- * Static main method to get info about a TrueType font.
- * @param args The command line arguments
- */
- public static void main(String[] args) {
- InputStream stream = null;
- try {
- boolean useKerning = true;
- boolean useAdvanced = true;
-
- stream = new FileInputStream(args[0]);
- FontFileReader reader = new FontFileReader(stream);
-
- String name = null;
- if (args.length >= 2) {
- name = args[1];
- }
-
- String header = OFFontLoader.readHeader(reader);
- boolean isCFF = header.equals("OTTO");
- OpenFont otfFile = (isCFF) ? new OTFFile() : new TTFFile(useKerning, useAdvanced);
- otfFile.readFont(reader, header, name);
- otfFile.printStuff();
-
- } catch (IOException ioe) {
- System.err.println("Problem reading font: " + ioe.toString());
- ioe.printStackTrace(System.err);
- } finally {
- IOUtils.closeQuietly(stream);
- }
- }
-
- public String getCopyrightNotice() {
- return notice;
- }
-}
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFFile.java b/src/java/org/apache/fop/fonts/truetype/TTFFile.java
deleted file mode 100644
index 4b0e3d628..000000000
--- a/src/java/org/apache/fop/fonts/truetype/TTFFile.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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.truetype;
-
-import java.io.IOException;
-
-/**
- * Reads a TrueType file or a TrueType Collection.
- * The TrueType spec can be found at the Microsoft.
- * Typography site: http://www.microsoft.com/truetype/
- */
-public class TTFFile extends OpenFont {
-
- public TTFFile() {
- this(true, false);
- }
-
- /**
- * Constructor
- * @param useKerning true if kerning data should be loaded
- * @param useAdvanced true if advanced typographic tables should be loaded
- */
- public TTFFile(boolean useKerning, boolean useAdvanced) {
- super(useKerning, useAdvanced);
- }
-
- /**
- * Read the "name" table.
- * @throws IOException In case of a I/O problem
- */
- protected void readName() throws IOException {
- seekTab(fontFile, OFTableName.NAME, 2);
- int i = fontFile.getCurrentPos();
- int n = fontFile.readTTFUShort();
- int j = fontFile.readTTFUShort() + i - 2;
- i += 2 * 2;
-
- while (n-- > 0) {
- // getLogger().debug("Iteration: " + n);
- fontFile.seekSet(i);
- final int platformID = fontFile.readTTFUShort();
- final int encodingID = fontFile.readTTFUShort();
- final int languageID = fontFile.readTTFUShort();
-
- int k = fontFile.readTTFUShort();
- int l = fontFile.readTTFUShort();
-
- if (((platformID == 1 || platformID == 3)
- && (encodingID == 0 || encodingID == 1))) {
- fontFile.seekSet(j + fontFile.readTTFUShort());
- String txt;
- if (platformID == 3) {
- txt = fontFile.readTTFString(l, encodingID);
- } else {
- txt = fontFile.readTTFString(l);
- }
-
- if (log.isDebugEnabled()) {
- log.debug(platformID + " "
- + encodingID + " "
- + languageID + " "
- + k + " " + txt);
- }
- switch (k) {
- case 0:
- if (notice.length() == 0) {
- notice = txt;
- }
- break;
- case 1: //Font Family Name
- case 16: //Preferred Family
- familyNames.add(txt);
- break;
- case 2:
- if (subFamilyName.length() == 0) {
- subFamilyName = txt;
- }
- break;
- case 4:
- if (fullName.length() == 0 || (platformID == 3 && languageID == 1033)) {
- fullName = txt;
- }
- break;
- case 6:
- if (postScriptName.length() == 0) {
- postScriptName = txt;
- }
- break;
- default:
- break;
- }
- }
- i += 6 * 2;
- }
- }
-
- /**
- * Read the "glyf" table to find the bounding boxes.
- * @throws IOException In case of a I/O problem
- */
- private void readGlyf() throws IOException {
- OFDirTabEntry dirTab = dirTabs.get(OFTableName.GLYF);
- if (dirTab == null) {
- throw new IOException("glyf table not found, cannot continue");
- }
- for (int i = 0; i < (numberOfGlyphs - 1); i++) {
- if (mtxTab[i].getOffset() != mtxTab[i + 1].getOffset()) {
- fontFile.seekSet(dirTab.getOffset() + mtxTab[i].getOffset());
- fontFile.skip(2);
- final int[] bbox = {
- fontFile.readTTFShort(),
- fontFile.readTTFShort(),
- fontFile.readTTFShort(),
- fontFile.readTTFShort()};
- mtxTab[i].setBoundingBox(bbox);
- } else {
- mtxTab[i].setBoundingBox(mtxTab[0].getBoundingBox());
- }
- }
-
- long n = (dirTabs.get(OFTableName.GLYF)).getOffset();
- for (int i = 0; i < numberOfGlyphs; i++) {
- if ((i + 1) >= mtxTab.length
- || mtxTab[i].getOffset() != mtxTab[i + 1].getOffset()) {
- fontFile.seekSet(n + mtxTab[i].getOffset());
- fontFile.skip(2);
- final int[] bbox = {
- fontFile.readTTFShort(),
- fontFile.readTTFShort(),
- fontFile.readTTFShort(),
- fontFile.readTTFShort()};
- mtxTab[i].setBoundingBox(bbox);
- } else {
- /**@todo Verify that this is correct, looks like a copy/paste bug (jm)*/
- final int bbox0 = mtxTab[0].getBoundingBox()[0];
- final int[] bbox = {bbox0, bbox0, bbox0, bbox0};
- mtxTab[i].setBoundingBox(bbox);
- /* Original code
- mtxTab[i].bbox[0] = mtxTab[0].bbox[0];
- mtxTab[i].bbox[1] = mtxTab[0].bbox[0];
- mtxTab[i].bbox[2] = mtxTab[0].bbox[0];
- mtxTab[i].bbox[3] = mtxTab[0].bbox[0]; */
- }
- if (log.isTraceEnabled()) {
- log.trace(mtxTab[i].toString(this));
- }
- }
- }
-
- @Override
- protected void updateBBoxAndOffset() throws IOException {
- readIndexToLocation();
- readGlyf();
- }
-
- /**
- * Read the "loca" table.
- * @throws IOException In case of a I/O problem
- */
- protected final void readIndexToLocation()
- throws IOException {
- if (!seekTab(fontFile, OFTableName.LOCA, 0)) {
- throw new IOException("'loca' table not found, happens when the font file doesn't"
- + " contain TrueType outlines (trying to read an OpenType CFF font maybe?)");
- }
- for (int i = 0; i < numberOfGlyphs; i++) {
- mtxTab[i].setOffset(locaFormat == 1 ? fontFile.readTTFULong()
- : (fontFile.readTTFUShort() << 1));
- }
- lastLoca = (locaFormat == 1 ? fontFile.readTTFULong()
- : (fontFile.readTTFUShort() << 1));
- }
-
- /**
- * Gets the last location of the glyf table
- * @return The last location as a long
- */
- public long getLastGlyfLocation() {
- return lastLoca;
- }
-
- @Override
- protected void initializeFont(FontFileReader in) throws IOException {
- fontFile = in;
- }
-}
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFGlyphOutputStream.java b/src/java/org/apache/fop/fonts/truetype/TTFGlyphOutputStream.java
deleted file mode 100644
index 313d5836d..000000000
--- a/src/java/org/apache/fop/fonts/truetype/TTFGlyphOutputStream.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.truetype;
-
-import java.io.IOException;
-
-/**
- * An interface for writing individual glyphs from the glyf table of a TrueType font to an output stream.
- */
-public interface TTFGlyphOutputStream {
-
- /**
- * Begins the streaming of glyphs.
- */
- void startGlyphStream() throws IOException;
-
- /**
- * Streams an individual glyph from the given byte array.
- *
- * @param glyphData the source of the glyph data to stream from
- * @param offset the position in the glyph data where the glyph starts
- * @param size the size of the glyph data in bytes
- */
- void streamGlyph(byte[] glyphData, int offset, int size) throws IOException;
-
- /**
- * Ends the streaming of glyphs.
- */
- void endGlyphStream() throws IOException;
-
-}
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFOutputStream.java b/src/java/org/apache/fop/fonts/truetype/TTFOutputStream.java
deleted file mode 100644
index 09b5b6f50..000000000
--- a/src/java/org/apache/fop/fonts/truetype/TTFOutputStream.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.truetype;
-
-import java.io.IOException;
-
-/**
- * An interface for writing a TrueType font to an output stream.
- */
-public interface TTFOutputStream {
-
- /**
- * Starts writing the font.
- */
- void startFontStream() throws IOException;
-
- /**
- * Returns an object for streaming TrueType tables.
- */
- TTFTableOutputStream getTableOutputStream();
-
- /**
- * Returns an object for streaming TrueType glyphs in the glyf table.
- */
- TTFGlyphOutputStream getGlyphOutputStream();
-
- /**
- * Ends writing the font.
- */
- void endFontStream() throws IOException;
-
-}
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java b/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java
deleted file mode 100644
index 6d2d68672..000000000
--- a/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java
+++ /dev/null
@@ -1,714 +0,0 @@
-/*
- * 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.truetype;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.SortedSet;
-
-
-/**
- * Reads a TrueType file and generates a subset
- * that can be used to embed a TrueType CID font.
- * TrueType tables needed for embedded CID fonts are:
- * "head", "hhea", "loca", "maxp", "cvt ", "prep", "glyf", "hmtx" and "fpgm".
- * The TrueType spec can be found at the Microsoft
- * Typography site: http://www.microsoft.com/truetype/
- */
-public class TTFSubSetFile extends TTFFile {
-
- protected byte[] output;
- protected int realSize;
- protected int currentPos;
-
- /*
- * Offsets in name table to be filled out by table.
- * The offsets are to the checkSum field
- */
- protected Map<OFTableName, Integer> offsets = new HashMap<OFTableName, Integer>();
-
- private int checkSumAdjustmentOffset;
- protected int locaOffset;
-
- /** Stores the glyph offsets so that we can end strings at glyph boundaries */
- protected int[] glyphOffsets;
-
- /**
- * Default Constructor
- */
- public TTFSubSetFile() {
- }
-
- /**
- * Constructor
- * @param useKerning true if kerning data should be loaded
- * @param useAdvanced true if advanced typographic tables should be loaded
- */
- public TTFSubSetFile(boolean useKerning, boolean useAdvanced) {
- super(useKerning, useAdvanced);
- }
-
- /** The dir tab entries in the new subset font. */
- protected Map<OFTableName, OFDirTabEntry> newDirTabs
- = new HashMap<OFTableName, OFDirTabEntry>();
-
- private int determineTableCount() {
- int numTables = 4; //4 req'd tables: head,hhea,hmtx,maxp
- if (isCFF()) {
- throw new UnsupportedOperationException(
- "OpenType fonts with CFF glyphs are not supported");
- } else {
- numTables += 5; //5 req'd tables: glyf,loca,post,name,OS/2
- if (hasCvt()) {
- numTables++;
- }
- if (hasFpgm()) {
- numTables++;
- }
- if (hasPrep()) {
- numTables++;
- }
- if (!cid) {
- numTables++; //cmap
- }
- }
- return numTables;
- }
-
- /**
- * Create the directory table
- */
- protected void createDirectory() {
- int numTables = determineTableCount();
- // Create the TrueType header
- writeByte((byte)0);
- writeByte((byte)1);
- writeByte((byte)0);
- writeByte((byte)0);
- realSize += 4;
-
- writeUShort(numTables);
- realSize += 2;
-
- // Create searchRange, entrySelector and rangeShift
- int maxPow = maxPow2(numTables);
- int searchRange = (int) Math.pow(2, maxPow) * 16;
- writeUShort(searchRange);
- realSize += 2;
-
- writeUShort(maxPow);
- realSize += 2;
-
- writeUShort((numTables * 16) - searchRange);
- realSize += 2;
- // Create space for the table entries (these must be in ASCII alphabetical order[A-Z] then[a-z])
- writeTableName(OFTableName.OS2);
- if (!cid) {
- writeTableName(OFTableName.CMAP);
- }
- if (hasCvt()) {
- writeTableName(OFTableName.CVT);
- }
- if (hasFpgm()) {
- writeTableName(OFTableName.FPGM);
- }
- writeTableName(OFTableName.GLYF);
- writeTableName(OFTableName.HEAD);
- writeTableName(OFTableName.HHEA);
- writeTableName(OFTableName.HMTX);
- writeTableName(OFTableName.LOCA);
- writeTableName(OFTableName.MAXP);
- writeTableName(OFTableName.NAME);
- writeTableName(OFTableName.POST);
- if (hasPrep()) {
- writeTableName(OFTableName.PREP);
- }
- newDirTabs.put(OFTableName.TABLE_DIRECTORY, new OFDirTabEntry(0, currentPos));
- }
-
- private void writeTableName(OFTableName tableName) {
- writeString(tableName.getName());
- offsets.put(tableName, currentPos);
- currentPos += 12;
- realSize += 16;
- }
-
-
- private boolean hasCvt() {
- return dirTabs.containsKey(OFTableName.CVT);
- }
-
- private boolean hasFpgm() {
- return dirTabs.containsKey(OFTableName.FPGM);
- }
-
- private boolean hasPrep() {
- return dirTabs.containsKey(OFTableName.PREP);
- }
-
- /**
- * Create an empty loca table without updating checksum
- */
- protected void createLoca(int size) throws IOException {
- pad4();
- locaOffset = currentPos;
- int dirTableOffset = offsets.get(OFTableName.LOCA);
- writeULong(dirTableOffset + 4, currentPos);
- writeULong(dirTableOffset + 8, size * 4 + 4);
- currentPos += size * 4 + 4;
- realSize += size * 4 + 4;
- }
-
- private boolean copyTable(FontFileReader in, OFTableName tableName) throws IOException {
- OFDirTabEntry entry = dirTabs.get(tableName);
- if (entry != null) {
- pad4();
- seekTab(in, tableName, 0);
- writeBytes(in.getBytes((int) entry.getOffset(), (int) entry.getLength()));
-
- updateCheckSum(currentPos, (int) entry.getLength(), tableName);
- currentPos += (int) entry.getLength();
- realSize += (int) entry.getLength();
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Copy the cvt table as is from original font to subset font
- */
- protected boolean createCvt(FontFileReader in) throws IOException {
- return copyTable(in, OFTableName.CVT);
- }
-
- /**
- * Copy the fpgm table as is from original font to subset font
- */
- protected boolean createFpgm(FontFileReader in) throws IOException {
- return copyTable(in, OFTableName.FPGM);
- }
-
- /**
- * Copy the name table as is from the original.
- */
- protected boolean createName(FontFileReader in) throws IOException {
- return copyTable(in, OFTableName.NAME);
- }
-
- /**
- * Copy the OS/2 table as is from the original.
- */
- protected boolean createOS2(FontFileReader in) throws IOException {
- return copyTable(in, OFTableName.OS2);
- }
-
- /**
- * Copy the maxp table as is from original font to subset font
- * and set num glyphs to size
- */
- protected void createMaxp(FontFileReader in, int size) throws IOException {
- OFTableName maxp = OFTableName.MAXP;
- OFDirTabEntry entry = dirTabs.get(maxp);
- if (entry != null) {
- pad4();
- seekTab(in, maxp, 0);
- writeBytes(in.getBytes((int) entry.getOffset(), (int) entry.getLength()));
- writeUShort(currentPos + 4, size);
-
- updateCheckSum(currentPos, (int)entry.getLength(), maxp);
- currentPos += (int)entry.getLength();
- realSize += (int)entry.getLength();
- } else {
- throw new IOException("Can't find maxp table");
- }
- }
-
- protected void createPost(FontFileReader in) throws IOException {
- OFTableName post = OFTableName.POST;
- OFDirTabEntry entry = dirTabs.get(post);
- if (entry != null) {
- pad4();
- seekTab(in, post, 0);
- int newTableSize = 32; // This is the post table size with glyphs truncated
- byte[] newPostTable = new byte[newTableSize];
- // We only want the first 28 bytes (truncate the glyph names);
- System.arraycopy(in.getBytes((int) entry.getOffset(), newTableSize),
- 0, newPostTable, 0, newTableSize);
- // set the post table to Format 3.0
- newPostTable[1] = 0x03;
- writeBytes(newPostTable);
- updateCheckSum(currentPos, newTableSize, post);
- currentPos += newTableSize;
- realSize += newTableSize;
- } else {
-// throw new IOException("Can't find post table");
- }
- }
-
-
- /**
- * Copy the prep table as is from original font to subset font
- */
- protected boolean createPrep(FontFileReader in) throws IOException {
- return copyTable(in, OFTableName.PREP);
- }
-
-
- /**
- * Copy the hhea table as is from original font to subset font
- * and fill in size of hmtx table
- */
- protected void createHhea(FontFileReader in, int size) throws IOException {
- OFDirTabEntry entry = dirTabs.get(OFTableName.HHEA);
- if (entry != null) {
- pad4();
- seekTab(in, OFTableName.HHEA, 0);
- writeBytes(in.getBytes((int) entry.getOffset(), (int) entry.getLength()));
- writeUShort((int) entry.getLength() + currentPos - 2, size);
-
- updateCheckSum(currentPos, (int) entry.getLength(), OFTableName.HHEA);
- currentPos += (int) entry.getLength();
- realSize += (int) entry.getLength();
- } else {
- throw new IOException("Can't find hhea table");
- }
- }
-
-
- /**
- * Copy the head table as is from original font to subset font
- * and set indexToLocaFormat to long and set
- * checkSumAdjustment to 0, store offset to checkSumAdjustment
- * in checkSumAdjustmentOffset
- */
- protected void createHead(FontFileReader in) throws IOException {
- OFTableName head = OFTableName.HEAD;
- OFDirTabEntry entry = dirTabs.get(head);
- if (entry != null) {
- pad4();
- seekTab(in, head, 0);
- writeBytes(in.getBytes((int) entry.getOffset(), (int) entry.getLength()));
-
- checkSumAdjustmentOffset = currentPos + 8;
- output[currentPos + 8] = 0; // Set checkSumAdjustment to 0
- output[currentPos + 9] = 0;
- output[currentPos + 10] = 0;
- output[currentPos + 11] = 0;
- output[currentPos + 50] = 0; // long locaformat
- if (cid) {
- output[currentPos + 51] = 1; // long locaformat
- }
- updateCheckSum(currentPos, (int)entry.getLength(), head);
- currentPos += (int)entry.getLength();
- realSize += (int)entry.getLength();
- } else {
- throw new IOException("Can't find head table");
- }
- }
-
-
- /**
- * Create the glyf table and fill in loca table
- */
- private void createGlyf(FontFileReader in,
- Map<Integer, Integer> glyphs) throws IOException {
- OFTableName glyf = OFTableName.GLYF;
- OFDirTabEntry entry = dirTabs.get(glyf);
- int size = 0;
- int startPos = 0;
- int endOffset = 0; // Store this as the last loca
- if (entry != null) {
- pad4();
- startPos = currentPos;
-
- /* Loca table must be in order by glyph index, so build
- * an array first and then write the glyph info and
- * location offset.
- */
- int[] origIndexes = buildSubsetIndexToOrigIndexMap(glyphs);
- glyphOffsets = new int[origIndexes.length];
-
- for (int i = 0; i < origIndexes.length; i++) {
- int nextOffset = 0;
- int origGlyphIndex = origIndexes[i];
- if (origGlyphIndex >= (mtxTab.length - 1)) {
- nextOffset = (int)lastLoca;
- } else {
- nextOffset = (int)mtxTab[origGlyphIndex + 1].getOffset();
- }
- int glyphOffset = (int)mtxTab[origGlyphIndex].getOffset();
- int glyphLength = nextOffset - glyphOffset;
-
- byte[] glyphData = in.getBytes(
- (int)entry.getOffset() + glyphOffset,
- glyphLength);
- int endOffset1 = endOffset;
- // Copy glyph
- writeBytes(glyphData);
-
-
- // Update loca table
- writeULong(locaOffset + i * 4, currentPos - startPos);
- if ((currentPos - startPos + glyphLength) > endOffset1) {
- endOffset1 = (currentPos - startPos + glyphLength);
- }
-
- // Store the glyph boundary positions relative to the start of the font
- glyphOffsets[i] = currentPos;
- currentPos += glyphLength;
- realSize += glyphLength;
-
-
- endOffset = endOffset1;
- }
-
-
- size = currentPos - startPos;
-
- currentPos += 12;
- realSize += 12;
- updateCheckSum(startPos, size + 12, glyf);
-
- // Update loca checksum and last loca index
- writeULong(locaOffset + glyphs.size() * 4, endOffset);
- int locaSize = glyphs.size() * 4 + 4;
- int checksum = getCheckSum(output, locaOffset, locaSize);
- writeULong(offsets.get(OFTableName.LOCA), checksum);
- int padSize = (locaOffset + locaSize) % 4;
- newDirTabs.put(OFTableName.LOCA,
- new OFDirTabEntry(locaOffset, locaSize + padSize));
- } else {
- throw new IOException("Can't find glyf table");
- }
- }
-
- protected int[] buildSubsetIndexToOrigIndexMap(Map<Integer, Integer> glyphs) {
- int[] origIndexes = new int[glyphs.size()];
- for (Map.Entry<Integer, Integer> glyph : glyphs.entrySet()) {
- int origIndex = glyph.getKey();
- int subsetIndex = glyph.getValue();
- if (origIndexes.length > subsetIndex) {
- origIndexes[subsetIndex] = origIndex;
- }
- }
- return origIndexes;
- }
-
- /**
- * Create the hmtx table by copying metrics from original
- * font to subset font. The glyphs Map contains an
- * Integer key and Integer value that maps the original
- * metric (key) to the subset metric (value)
- */
- protected void createHmtx(FontFileReader in,
- Map<Integer, Integer> glyphs) throws IOException {
- OFTableName hmtx = OFTableName.HMTX;
- OFDirTabEntry entry = dirTabs.get(hmtx);
-
- int longHorMetricSize = glyphs.size() * 2;
- int leftSideBearingSize = glyphs.size() * 2;
- int hmtxSize = longHorMetricSize + leftSideBearingSize;
-
- if (entry != null) {
- pad4();
- //int offset = (int)entry.offset;
- for (Map.Entry<Integer, Integer> glyph : glyphs.entrySet()) {
- Integer origIndex = glyph.getKey();
- Integer subsetIndex = glyph.getValue();
-
- writeUShort(currentPos + subsetIndex.intValue() * 4,
- mtxTab[origIndex.intValue()].getWx());
- writeUShort(currentPos + subsetIndex.intValue() * 4 + 2,
- mtxTab[origIndex.intValue()].getLsb());
- }
-
- updateCheckSum(currentPos, hmtxSize, hmtx);
- currentPos += hmtxSize;
- realSize += hmtxSize;
- } else {
- throw new IOException("Can't find hmtx table");
- }
- }
-
- /**
- * Reads a font and creates a subset of the font.
- *
- * @param in FontFileReader to read from
- * @param name Name to be checked for in the font file
- * @param glyphs Map of glyphs (glyphs has old index as (Integer) key and
- * new index as (Integer) value)
- * @throws IOException in case of an I/O problem
- */
- public void readFont(FontFileReader in, String name, String header,
- Map<Integer, Integer> glyphs) throws IOException {
- fontFile = in;
- //Check if TrueType collection, and that the name exists in the collection
- if (!checkTTC(header, name)) {
- throw new IOException("Failed to read font");
- }
-
- //Copy the Map as we're going to modify it
- Map<Integer, Integer> subsetGlyphs = new HashMap<Integer, Integer>(glyphs);
-
- output = new byte[in.getFileSize()];
-
- readDirTabs();
- readFontHeader();
- getNumGlyphs();
- readHorizontalHeader();
- readHorizontalMetrics();
- readIndexToLocation();
-
- scanGlyphs(in, subsetGlyphs);
-
- createDirectory(); // Create the TrueType header and directory
-
- boolean optionalTableFound;
- optionalTableFound = createCvt(in); // copy the cvt table
- if (!optionalTableFound) {
- // cvt is optional (used in TrueType fonts only)
- log.debug("TrueType: ctv table not present. Skipped.");
- }
-
- optionalTableFound = createFpgm(in); // copy fpgm table
- if (!optionalTableFound) {
- // fpgm is optional (used in TrueType fonts only)
- log.debug("TrueType: fpgm table not present. Skipped.");
- }
- createLoca(subsetGlyphs.size()); // create empty loca table
- createGlyf(in, subsetGlyphs); //create glyf table and update loca table
-
- createOS2(in); // copy the OS/2 table
- createHead(in);
- createHhea(in, subsetGlyphs.size()); // Create the hhea table
- createHmtx(in, subsetGlyphs); // Create hmtx table
- createMaxp(in, subsetGlyphs.size()); // copy the maxp table
- createName(in); // copy the name table
- createPost(in); // copy the post table
-
- optionalTableFound = createPrep(in); // copy prep table
- if (!optionalTableFound) {
- // prep is optional (used in TrueType fonts only)
- log.debug("TrueType: prep table not present. Skipped.");
- }
-
- pad4();
- createCheckSumAdjustment();
- }
-
- /**
- * Returns a subset of the fonts (readFont() MUST be called first in order to create the
- * subset).
- * @return byte array
- */
- public byte[] getFontSubset() {
- byte[] ret = new byte[realSize];
- System.arraycopy(output, 0, ret, 0, realSize);
- return ret;
- }
-
- private void handleGlyphSubset(TTFGlyphOutputStream glyphOut) throws IOException {
- glyphOut.startGlyphStream();
- // Stream all but the last glyph
- for (int i = 0; i < glyphOffsets.length - 1; i++) {
- glyphOut.streamGlyph(output, glyphOffsets[i],
- glyphOffsets[i + 1] - glyphOffsets[i]);
- }
- // Stream the last glyph
- OFDirTabEntry glyf = newDirTabs.get(OFTableName.GLYF);
- long lastGlyphLength = glyf.getLength()
- - (glyphOffsets[glyphOffsets.length - 1] - glyf.getOffset());
- glyphOut.streamGlyph(output, glyphOffsets[glyphOffsets.length - 1],
- (int) lastGlyphLength);
- glyphOut.endGlyphStream();
- }
-
- @Override
- public void stream(TTFOutputStream ttfOut) throws IOException {
- SortedSet<Map.Entry<OFTableName, OFDirTabEntry>> sortedDirTabs
- = sortDirTabMap(newDirTabs);
- TTFTableOutputStream tableOut = ttfOut.getTableOutputStream();
- TTFGlyphOutputStream glyphOut = ttfOut.getGlyphOutputStream();
-
- ttfOut.startFontStream();
- for (Map.Entry<OFTableName, OFDirTabEntry> entry : sortedDirTabs) {
- if (entry.getKey().equals(OFTableName.GLYF)) {
- handleGlyphSubset(glyphOut);
- } else {
- tableOut.streamTable(output, (int) entry.getValue().getOffset(),
- (int) entry.getValue().getLength());
- }
- }
- ttfOut.endFontStream();
- }
-
- protected void scanGlyphs(FontFileReader in, Map<Integer, Integer> subsetGlyphs)
- throws IOException {
- OFDirTabEntry glyfTableInfo = dirTabs.get(OFTableName.GLYF);
- if (glyfTableInfo == null) {
- throw new IOException("Glyf table could not be found");
- }
-
- GlyfTable glyfTable = new GlyfTable(in, mtxTab, glyfTableInfo, subsetGlyphs);
- glyfTable.populateGlyphsWithComposites();
- }
-
- /**
- * writes a ISO-8859-1 string at the currentPosition
- * updates currentPosition but not realSize
- * @return number of bytes written
- */
- private int writeString(String str) {
- int length = 0;
- try {
- byte[] buf = str.getBytes("ISO-8859-1");
- writeBytes(buf);
- length = buf.length;
- currentPos += length;
- } catch (java.io.UnsupportedEncodingException e) {
- // This should never happen!
- }
-
- return length;
- }
-
- /**
- * Appends a byte to the output array,
- * updates currentPost but not realSize
- */
- private void writeByte(byte b) {
- output[currentPos++] = b;
- }
-
- protected void writeBytes(byte[] b) {
- if (b.length + currentPos > output.length) {
- byte[] newoutput = new byte[output.length * 2];
- System.arraycopy(output, 0, newoutput, 0, output.length);
- output = newoutput;
- }
- System.arraycopy(b, 0, output, currentPos, b.length);
- }
-
- /**
- * Appends a USHORT to the output array,
- * updates currentPost but not realSize
- */
- protected void writeUShort(int s) {
- byte b1 = (byte)((s >> 8) & 0xff);
- byte b2 = (byte)(s & 0xff);
- writeByte(b1);
- writeByte(b2);
- }
-
- /**
- * Appends a USHORT to the output array,
- * at the given position without changing currentPos
- */
- protected void writeUShort(int pos, int s) {
- byte b1 = (byte)((s >> 8) & 0xff);
- byte b2 = (byte)(s & 0xff);
- output[pos] = b1;
- output[pos + 1] = b2;
- }
-
-
- /**
- * Appends a ULONG to the output array,
- * at the given position without changing currentPos
- */
- protected void writeULong(int pos, int s) {
- byte b1 = (byte)((s >> 24) & 0xff);
- byte b2 = (byte)((s >> 16) & 0xff);
- byte b3 = (byte)((s >> 8) & 0xff);
- byte b4 = (byte)(s & 0xff);
- output[pos] = b1;
- output[pos + 1] = b2;
- output[pos + 2] = b3;
- output[pos + 3] = b4;
- }
-
- /**
- * Create a padding in the fontfile to align
- * on a 4-byte boundary
- */
- protected void pad4() {
- int padSize = getPadSize(currentPos);
- if (padSize < 4) {
- for (int i = 0; i < padSize; i++) {
- output[currentPos++] = 0;
- realSize++;
- }
- }
- }
-
- /**
- * Returns the maximum power of 2 <= max
- */
- private int maxPow2(int max) {
- int i = 0;
- while (Math.pow(2, i) <= max) {
- i++;
- }
-
- return (i - 1);
- }
-
-
- protected void updateCheckSum(int tableStart, int tableSize, OFTableName tableName) {
- int checksum = getCheckSum(output, tableStart, tableSize);
- int offset = offsets.get(tableName);
- int padSize = getPadSize(tableStart + tableSize);
- newDirTabs.put(tableName, new OFDirTabEntry(tableStart, tableSize + padSize));
- writeULong(offset, checksum);
- writeULong(offset + 4, tableStart);
- writeULong(offset + 8, tableSize);
- }
-
- protected static int getCheckSum(byte[] data, int start, int size) {
- // All the tables here are aligned on four byte boundaries
- // Add remainder to size if it's not a multiple of 4
- int remainder = size % 4;
- if (remainder != 0) {
- size += remainder;
- }
-
- long sum = 0;
-
- for (int i = 0; i < size; i += 4) {
- long l = 0;
- for (int j = 0; j < 4; j++) {
- l <<= 8;
- if (data.length > (start + i + j)) {
- l |= data[start + i + j] & 0xff;
- }
- }
- sum += l;
- }
- return (int) sum;
- }
-
- protected void createCheckSumAdjustment() {
- long sum = getCheckSum(output, 0, realSize);
- int checksum = (int)(0xb1b0afba - sum);
- writeULong(checkSumAdjustmentOffset, checksum);
- }
-}
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFTableOutputStream.java b/src/java/org/apache/fop/fonts/truetype/TTFTableOutputStream.java
deleted file mode 100644
index d0d2007f5..000000000
--- a/src/java/org/apache/fop/fonts/truetype/TTFTableOutputStream.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.truetype;
-
-import java.io.IOException;
-
-/**
- * An interface for writing a TrueType table to an output stream.
- */
-public interface TTFTableOutputStream {
-
- /**
- * Streams a table from the given byte array.
- *
- * @param ttfData the source of the table to stream from
- * @param offset the position in the byte array where the table starts
- * @param size the size of the table in bytes
- */
- void streamTable(byte[] ttfData, int offset, int size) throws IOException;
-}
diff --git a/src/java/org/apache/fop/fonts/truetype/package.html b/src/java/org/apache/fop/fonts/truetype/package.html
deleted file mode 100644
index 6517f9889..000000000
--- a/src/java/org/apache/fop/fonts/truetype/package.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<HTML>
-<TITLE>org.apache.fop.fonts.truetype Package</TITLE>
-<BODY>
-<P>Classes for TrueType fonts.</P>
-</BODY>
-</HTML> \ No newline at end of file
diff --git a/src/java/org/apache/fop/fonts/type1/AFMCharMetrics.java b/src/java/org/apache/fop/fonts/type1/AFMCharMetrics.java
deleted file mode 100644
index 8d9f4238b..000000000
--- a/src/java/org/apache/fop/fonts/type1/AFMCharMetrics.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * 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.awt.Rectangle;
-
-import org.apache.fop.fonts.NamedCharacter;
-
-
-/**
- * Holds the metrics of a single character from an AFM file.
- */
-public class AFMCharMetrics {
-
- private int charCode = -1;
- private NamedCharacter character;
- private double widthX;
- private double widthY;
- private Rectangle bBox;
-
- /**
- * Returns the character code.
- * @return the charCode (-1 if not part of the encoding)
- */
- public int getCharCode() {
- return charCode;
- }
-
- /**
- * Indicates whether the character has a character code, i.e. is part of the default encoding.
- * @return true if there is a character code.
- */
- public boolean hasCharCode() {
- return charCode >= 0;
- }
-
- /**
- * Sets the character code.
- * @param charCode the charCode to set
- */
- public void setCharCode(int charCode) {
- this.charCode = charCode;
- }
-
- /**
- * Returns the named character represented by this instance.
- * @return the named character (or null if no named character is associated)
- */
- public NamedCharacter getCharacter() {
- return this.character;
- }
-
- /**
- * Sets the named character represented by this instance.
- * @param ch the named character
- */
- public void setCharacter(NamedCharacter ch) {
- this.character = ch;
- }
-
- /**
- * Sets the named character represented by this instance.
- * @param charName the character name (as defined in the Adobe glyph list)
- * @param unicodeSequence the Unicode sequence
- */
- public void setCharacter(String charName, String unicodeSequence) {
- setCharacter(new NamedCharacter(charName, unicodeSequence));
- }
-
- /**
- * Returns the Unicode sequence for this character.
- * @return the Unicode characters
- * (or null if no such Unicode sequence exists for this character)
- */
- public String getUnicodeSequence() {
- return (getCharacter() != null ? getCharacter().getUnicodeSequence() : null);
- }
-
- /**
- * Returns the PostScript character name.
- * @return the charName (or null if no character name is associated)
- */
- public String getCharName() {
- return (getCharacter() != null ? getCharacter().getName() : null);
- }
-
- /**
- * Returns the progression dimension in x-direction.
- * @return the widthX
- */
- public double getWidthX() {
- return widthX;
- }
-
- /**
- * Sets the progression dimension in x-direction
- * @param widthX the widthX to set
- */
- public void setWidthX(double widthX) {
- this.widthX = widthX;
- }
-
- /**
- * Returns the progression dimension in y-direction.
- * @return the widthY
- */
- public double getWidthY() {
- return widthY;
- }
-
- /**
- * Sets the progression dimension in y-direction
- * @param widthY the widthY to set
- */
- public void setWidthY(double widthY) {
- this.widthY = widthY;
- }
-
- /**
- * Returns the character's bounding box.
- * @return the bounding box (or null if it isn't available)
- */
- public Rectangle getBBox() {
- return bBox;
- }
-
- /**
- * Sets the character's bounding box.
- * @param box the bounding box
- */
- public void setBBox(Rectangle box) {
- bBox = box;
- }
-
- /** {@inheritDoc} */
- public String toString() {
- StringBuffer sb = new StringBuffer("AFM Char: ");
- sb.append(getCharCode());
- sb.append(" (");
- if (getUnicodeSequence() != null) {
- for (int i = 0, c = getUnicodeSequence().length(); i < c; i++) {
- sb.append("0x").append(Integer.toHexString(getUnicodeSequence().charAt(i)));
- sb.append(", ");
- }
- }
- sb.append(getCharName()).append(')');
- return sb.toString();
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/type1/AFMFile.java b/src/java/org/apache/fop/fonts/type1/AFMFile.java
deleted file mode 100644
index 2aa718ea0..000000000
--- a/src/java/org/apache/fop/fonts/type1/AFMFile.java
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * 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.awt.geom.Dimension2D;
-import java.awt.geom.RectangularShape;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.xmlgraphics.java2d.Dimension2DDouble;
-
-import org.apache.fop.fonts.NamedCharacter;
-import org.apache.fop.fonts.SingleByteEncoding;
-
-/**
- * Represents the contents of a Type 1 AFM font metrics file.
- */
-public class AFMFile {
-
- /** logging instance */
- private static final Log LOG = LogFactory.getLog(AFMFile.class);
-
- private String fontName;
- private String fullName;
- private String familyName;
-
- private String weight;
- private RectangularShape fontBBox;
-
- private String encodingScheme;
- private String characterSet;
-
- private Number capHeight;
- private Number xHeight;
- private Number ascender;
- private Number descender;
- private Number stdHW;
- private Number stdVW;
-
- private AFMWritingDirectionMetrics[] writingDirectionMetrics
- = new AFMWritingDirectionMetrics[3];
-
- private List<AFMCharMetrics> charMetrics = new java.util.ArrayList<AFMCharMetrics>();
- private Map<String, AFMCharMetrics> charNameToMetrics
- = new java.util.HashMap<String, AFMCharMetrics>();
- private int firstChar = -1;
- private int lastChar = -1;
-
- private Map<String, Map<String, Dimension2D>> kerningMap;
-
- /**
- * Default constructor.
- */
- public AFMFile() {
- //nop
- }
-
- /**
- * Returns the FontName value.
- * @return the font name
- */
- public String getFontName() {
- return fontName;
- }
-
- /**
- * Sets the FontName value.
- * @param fontName the font name to set
- */
- public void setFontName(String fontName) {
- this.fontName = fontName;
- }
-
- /**
- * Returns the FullName value.
- * @return the full name of the font
- */
- public String getFullName() {
- return fullName;
- }
-
- /**
- * Sets the FullName value.
- * @param fullName the full name to set
- */
- public void setFullName(String fullName) {
- this.fullName = fullName;
- }
-
- /**
- * Returns the FamilyName value.
- * @return the family name of the font
- */
- public String getFamilyName() {
- return familyName;
- }
-
- /**
- * Sets the FamilyName value.
- * @param familyName the family name to set
- */
- public void setFamilyName(String familyName) {
- this.familyName = familyName;
- }
-
- /**
- * Returns the Weight value.
- * @return the weight
- */
- public String getWeight() {
- return weight;
- }
-
- /**
- * Sets the Weight value.
- * @param weight the weight to set
- */
- public void setWeight(String weight) {
- this.weight = weight;
- }
-
- /**
- * Returns the FontBBox value.
- * @return the font's bounding box
- */
- public RectangularShape getFontBBox() {
- return fontBBox;
- }
-
- /**
- * Returns the FontBBox value as integer array.
- * @return the font's bounding box
- */
- public int[] getFontBBoxAsIntArray() {
- RectangularShape rect = getFontBBox();
- return new int[] {
- (int)Math.floor(rect.getMinX()), (int)Math.floor(rect.getMinY()),
- (int)Math.ceil(rect.getMaxX()), (int)Math.ceil(rect.getMaxY())};
- }
-
- /**
- * Sets the FontBBox value.
- * @param fontBBox the fontBBox to set
- */
- public void setFontBBox(RectangularShape fontBBox) {
- this.fontBBox = fontBBox;
- }
-
- /**
- * Returns the EncodingScheme value.
- * @return the encoding scheme
- */
- public String getEncodingScheme() {
- return encodingScheme;
- }
-
- /**
- * Sets the EncodingScheme value
- * @param encodingScheme the encodingScheme to set
- */
- public void setEncodingScheme(String encodingScheme) {
- this.encodingScheme = encodingScheme;
- }
-
- /**
- * Returns the CharacterSet value.
- * @return the characterSet
- */
- public String getCharacterSet() {
- return characterSet;
- }
-
- /**
- * Sets the CharacterSet value.
- * @param characterSet the characterSet to set
- */
- public void setCharacterSet(String characterSet) {
- this.characterSet = characterSet;
- }
-
- /**
- * Returns the CapHeight value.
- * @return the capHeight
- */
- public Number getCapHeight() {
- return capHeight;
- }
-
- /**
- * Sets the CapHeight value.
- * @param capHeight the capHeight to set
- */
- public void setCapHeight(Number capHeight) {
- this.capHeight = capHeight;
- }
-
- /**
- * Returns the XHeight value.
- * @return the xHeight
- */
- public Number getXHeight() {
- return xHeight;
- }
-
- /**
- * Sets the XHeight value.
- * @param height the xHeight to set
- */
- public void setXHeight(Number height) {
- xHeight = height;
- }
-
- /**
- * Returns the Ascender value.
- * @return the ascender
- */
- public Number getAscender() {
- return ascender;
- }
-
- /**
- * Sets the Ascender value.
- * @param ascender the ascender to set
- */
- public void setAscender(Number ascender) {
- this.ascender = ascender;
- }
-
- /**
- * Returns the Descender value.
- * @return the descender
- */
- public Number getDescender() {
- return descender;
- }
-
- /**
- * Sets the Descender value.
- * @param descender the descender to set
- */
- public void setDescender(Number descender) {
- this.descender = descender;
- }
-
- /**
- * Returns the StdHW value.
- * @return the descender
- */
- public Number getStdHW() {
- return stdHW;
- }
-
- /**
- * Sets the StdHW value.
- * @param stdHW the StdHW to set
- */
- public void setStdHW(Number stdHW) {
- this.stdHW = stdHW;
- }
-
- /**
- * Returns the StdVW value.
- * @return the descender
- */
- public Number getStdVW() {
- return stdVW;
- }
-
- /**
- * Sets the StdVW value.
- * @param stdVW the StdVW to set
- */
- public void setStdVW(Number stdVW) {
- this.stdVW = stdVW;
- }
-
- /**
- * Gets writing direction metrics.
- * @param index the writing direction (0, 1 or 2)
- * @return the writing direction metrics
- */
- public AFMWritingDirectionMetrics getWritingDirectionMetrics(int index) {
- return this.writingDirectionMetrics[index];
- }
-
- /**
- * Sets writing direction metrics.
- * @param index the writing direction (0, 1 or 2)
- * @param metrics the writing direction metrics
- */
- public void setWritingDirectionMetrics(int index, AFMWritingDirectionMetrics metrics) {
- this.writingDirectionMetrics[index] = metrics;
- }
-
- /**
- * Adds new character metrics.
- * @param metrics the character metrics
- */
- public void addCharMetrics(AFMCharMetrics metrics) {
- String name = metrics.getCharName();
- if (metrics.getUnicodeSequence() == null && name.equals(".notdef")) {
- //Ignore as no Unicode assignment is possible
- return;
- }
- this.charMetrics.add(metrics);
- if (name != null) {
- this.charNameToMetrics.put(name, metrics);
- }
- int idx = metrics.getCharCode();
- if (idx >= 0) { //Only if the character is part of the encoding
- if (firstChar < 0 || idx < firstChar) {
- firstChar = idx;
- }
- if (lastChar < 0 || idx > lastChar) {
- lastChar = idx;
- }
- }
- }
-
- /**
- * Returns the number of character available for this font.
- * @return the number of character
- */
- public int getCharCount() {
- return this.charMetrics.size();
- }
-
- /**
- * Returns the first character index in the encoding that has a glyph.
- * @return the first character index with a glyph
- */
- public int getFirstChar() {
- return this.firstChar;
- }
-
- /**
- * Returns the last character index in the encoding that has a glyph.
- * @return the last character index with a glyph
- */
- public int getLastChar() {
- return this.lastChar;
- }
-
- /**
- * Returns the character metrics associated with the character name.
- * @param name the character name
- * @return the character metrics or null if there's no such character
- */
- public AFMCharMetrics getChar(String name) {
- return this.charNameToMetrics.get(name);
- }
-
- /**
- * Returns the list of AFMCharMetrics instances representing all the available characters.
- * @return a List of AFMCharMetrics instances
- */
- public List<AFMCharMetrics> getCharMetrics() {
- return Collections.unmodifiableList(this.charMetrics);
- }
-
- /**
- * Adds a X-kerning entry.
- * @param name1 the name of the first character
- * @param name2 the name of the second character
- * @param kx kerning value in x-direction
- */
- public void addXKerning(String name1, String name2, double kx) {
- if (this.kerningMap == null) {
- this.kerningMap = new java.util.HashMap<String, Map<String, Dimension2D>>();
- }
- Map<String, Dimension2D> entries = this.kerningMap.get(name1);
- if (entries == null) {
- entries = new java.util.HashMap<String, Dimension2D>();
- this.kerningMap.put(name1, entries);
- }
- entries.put(name2, new Dimension2DDouble(kx, 0));
- }
-
- /**
- * Indicates whether the font has kerning information.
- * @return true if there is kerning information
- */
- public boolean hasKerning() {
- return this.kerningMap != null;
- }
-
- /**
- * Creates and returns a kerning map for writing mode 0 (ltr) with character codes.
- * @return the kerning map or null if there is no kerning information.
- */
- public Map<Integer, Map<Integer, Integer>> createXKerningMapEncoded() {
- if (!hasKerning()) {
- return null;
- }
- Map<Integer, Map<Integer, Integer>> m
- = new java.util.HashMap<Integer, Map<Integer, Integer>>();
- for (Map.Entry<String, Map<String, Dimension2D>> entryFrom : this.kerningMap.entrySet()) {
- String name1 = entryFrom.getKey();
- AFMCharMetrics chm1 = getChar(name1);
- if (chm1 == null || !chm1.hasCharCode()) {
- continue;
- }
- Map<Integer, Integer> container = null;
- Map<String, Dimension2D> entriesTo = entryFrom.getValue();
- for (Map.Entry<String, Dimension2D> entryTo : entriesTo.entrySet()) {
- String name2 = entryTo.getKey();
- AFMCharMetrics chm2 = getChar(name2);
- if (chm2 == null || !chm2.hasCharCode()) {
- continue;
- }
- if (container == null) {
- Integer k1 = Integer.valueOf(chm1.getCharCode());
- container = m.get(k1);
- if (container == null) {
- container = new java.util.HashMap<Integer, Integer>();
- m.put(k1, container);
- }
- }
- Dimension2D dim = entryTo.getValue();
- container.put(Integer.valueOf(chm2.getCharCode()),
- Integer.valueOf((int)Math.round(dim.getWidth())));
- }
- }
- return m;
- }
-
- /**
- * The character codes in an AFM cannot always be trusted to be the same values as in the
- * font's primary encoding. Therefore, we provide a way to override this primary encoding.
- * @param encoding the encoding to replace the one given in the AFM
- */
- public void overridePrimaryEncoding(SingleByteEncoding encoding) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Overriding primary encoding of " + getFontName() + " with: " + encoding);
- }
- AFMCharMetrics[] mapped = new AFMCharMetrics[256];
- for (AFMCharMetrics cm : this.charMetrics) {
- NamedCharacter nc = cm.getCharacter();
- if (nc.hasSingleUnicodeValue()) {
- int codePoint = encoding.mapChar(nc.getSingleUnicodeValue());
- if (codePoint > 0) {
- if (mapped[codePoint] != null) {
- if (LOG.isDebugEnabled()) {
- AFMCharMetrics other = mapped[codePoint];
- String msg = "Not mapping character " + nc + " to code point "
- + codePoint + " (" + Integer.toHexString(codePoint) + ") in "
- + encoding + ". "
- + other + " has already been assigned that code point.";
- if (other.getUnicodeSequence()
- .equals(nc.getUnicodeSequence())) {
- msg += " This is a specialized glyph for the"
- + " same Unicode character.";
- //TODO should these be mapped to a private Unicode area to make
- //them accessible?
- } else {
- msg += " This is a similar character.";
- }
- if (cm.getWidthX() != other.getWidthX()) {
- msg += " They have differing widths: "
- + cm.getWidthX() + " vs. " + other.getWidthX();
- }
- LOG.debug(msg);
- }
- } else {
- cm.setCharCode(codePoint);
- mapped[codePoint] = cm;
- }
- } else {
- cm.setCharCode(-1);
- }
- } else {
- //No Unicode equivalent
- cm.setCharCode(-1);
- }
- }
- }
-
- /** {@inheritDoc} */
- @Override
- public String toString() {
- return "AFM: " + getFullName();
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/type1/AFMParser.java b/src/java/org/apache/fop/fonts/type1/AFMParser.java
deleted file mode 100644
index ecc9196ed..000000000
--- a/src/java/org/apache/fop/fonts/type1/AFMParser.java
+++ /dev/null
@@ -1,597 +0,0 @@
-/*
- * 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.awt.Rectangle;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Stack;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.fonts.NamedCharacter;
-
-/**
- * Parses the contents of a Type 1 AFM font metrics file into an object structure ({@link AFMFile}).
- */
-public class AFMParser {
-
- private static Log log = LogFactory.getLog(AFMParser.class);
-
- private static final String START_FONT_METRICS = "StartFontMetrics";
- //private static final String END_FONT_METRICS = "EndFontMetrics";
- private static final String FONT_NAME = "FontName";
- private static final String FULL_NAME = "FullName";
- private static final String FAMILY_NAME = "FamilyName";
- private static final String WEIGHT = "Weight";
- private static final String FONT_BBOX = "FontBBox";
- private static final String ENCODING_SCHEME = "EncodingScheme";
- private static final String CHARACTER_SET = "CharacterSet";
- private static final String IS_BASE_FONT = "IsBaseFont";
- private static final String IS_CID_FONT = "IsCIDFont";
- private static final String CAP_HEIGHT = "CapHeight";
- private static final String X_HEIGHT = "XHeight";
- private static final String ASCENDER = "Ascender";
- private static final String DESCENDER = "Descender";
- private static final String STDHW = "StdHW";
- private static final String STDVW = "StdVW";
- private static final String UNDERLINE_POSITION = "UnderlinePosition";
- private static final String UNDERLINE_THICKNESS = "UnderlineThickness";
- private static final String ITALIC_ANGLE = "ItalicAngle";
- private static final String IS_FIXED_PITCH = "IsFixedPitch";
- private static final String START_DIRECTION = "StartDirection";
- private static final String END_DIRECTION = "EndDirection";
- private static final String START_CHAR_METRICS = "StartCharMetrics";
- private static final String END_CHAR_METRICS = "EndCharMetrics";
- private static final String C = "C";
- private static final String CH = "CH";
- private static final String WX = "WX";
- private static final String W0X = "W0X";
- private static final String W1X = "W1X";
- private static final String WY = "WY";
- private static final String W0Y = "W0Y";
- private static final String W1Y = "W1Y";
- private static final String W = "W";
- private static final String W0 = "W0";
- private static final String W1 = "W1";
- private static final String N = "N";
- private static final String B = "B";
- private static final String START_TRACK_KERN = "StartTrackKern";
- private static final String END_TRACK_KERN = "EndTrackKern";
- //private static final String START_KERN_PAIRS = "StartKernPairs";
- //private static final String START_KERN_PAIRS0 = "StartKernPairs0";
- private static final String START_KERN_PAIRS1 = "StartKernPairs1";
- //private static final String END_KERN_PAIRS = "EndKernPairs";
- private static final String START_COMPOSITES = "StartComposites";
- private static final String START_COMP_FONT_METRICS = "StartCompFontMetrics";
-
- private static final String KP = "KP";
- private static final String KPH = "KPH";
- private static final String KPX = "KPX";
- private static final String KPY = "KPY";
-
- private static final int PARSE_NORMAL = 0;
- private static final int PARSE_CHAR_METRICS = 1;
-
- private static final Map<String, ValueHandler> VALUE_PARSERS;
- private static final Map<String, Integer> PARSE_MODE_CHANGES;
-
- static {
- VALUE_PARSERS = new HashMap<String, ValueHandler>();
- VALUE_PARSERS.put(START_FONT_METRICS, new StartFontMetrics());
- VALUE_PARSERS.put(FONT_NAME, new StringSetter(FONT_NAME));
- VALUE_PARSERS.put(FULL_NAME, new StringSetter(FULL_NAME));
- VALUE_PARSERS.put(FAMILY_NAME, new StringSetter(FAMILY_NAME));
- VALUE_PARSERS.put(WEIGHT, new StringSetter(WEIGHT));
- VALUE_PARSERS.put(ENCODING_SCHEME, new StringSetter(ENCODING_SCHEME));
- VALUE_PARSERS.put(FONT_BBOX, new FontBBox());
- VALUE_PARSERS.put(CHARACTER_SET, new StringSetter(CHARACTER_SET));
- VALUE_PARSERS.put(IS_BASE_FONT, new IsBaseFont());
- VALUE_PARSERS.put(IS_CID_FONT, new IsCIDFont());
- VALUE_PARSERS.put(CAP_HEIGHT, new NumberSetter(CAP_HEIGHT));
- VALUE_PARSERS.put(X_HEIGHT, new NumberSetter(X_HEIGHT));
- VALUE_PARSERS.put(ASCENDER, new NumberSetter(ASCENDER));
- VALUE_PARSERS.put(DESCENDER, new NumberSetter(DESCENDER));
- VALUE_PARSERS.put(STDHW, new NumberSetter(STDHW));
- VALUE_PARSERS.put(STDVW, new NumberSetter(STDVW));
- VALUE_PARSERS.put(START_DIRECTION, new StartDirection());
- VALUE_PARSERS.put(END_DIRECTION, new EndDirection());
- VALUE_PARSERS.put(UNDERLINE_POSITION, new WritingDirNumberSetter(UNDERLINE_POSITION));
- VALUE_PARSERS.put(UNDERLINE_THICKNESS, new WritingDirNumberSetter(UNDERLINE_THICKNESS));
- VALUE_PARSERS.put(ITALIC_ANGLE, new WritingDirDoubleSetter(ITALIC_ANGLE));
- VALUE_PARSERS.put(IS_FIXED_PITCH, new WritingDirBooleanSetter(IS_FIXED_PITCH));
- VALUE_PARSERS.put(C, new IntegerSetter("CharCode"));
- VALUE_PARSERS.put(CH, new NotImplementedYet(CH));
- VALUE_PARSERS.put(WX, new DoubleSetter("WidthX"));
- VALUE_PARSERS.put(W0X, new DoubleSetter("WidthX"));
- VALUE_PARSERS.put(W1X, new NotImplementedYet(W1X));
- VALUE_PARSERS.put(WY, new DoubleSetter("WidthY"));
- VALUE_PARSERS.put(W0Y, new DoubleSetter("WidthY"));
- VALUE_PARSERS.put(W1Y, new NotImplementedYet(W1Y));
- VALUE_PARSERS.put(W, new NotImplementedYet(W));
- VALUE_PARSERS.put(W0, new NotImplementedYet(W0));
- VALUE_PARSERS.put(W1, new NotImplementedYet(W1));
- VALUE_PARSERS.put(N, new NamedCharacterSetter("Character"));
- VALUE_PARSERS.put(B, new CharBBox());
- VALUE_PARSERS.put(START_TRACK_KERN, new NotImplementedYet(START_TRACK_KERN));
- VALUE_PARSERS.put(START_KERN_PAIRS1, new NotImplementedYet(START_KERN_PAIRS1));
- VALUE_PARSERS.put(START_COMPOSITES, new NotImplementedYet(START_COMPOSITES));
- VALUE_PARSERS.put(START_COMP_FONT_METRICS, new NotImplementedYet(START_COMP_FONT_METRICS));
- VALUE_PARSERS.put(KP, new NotImplementedYet(KP));
- VALUE_PARSERS.put(KPH, new NotImplementedYet(KPH));
- VALUE_PARSERS.put(KPX, new KPXHandler());
- VALUE_PARSERS.put(KPY, new NotImplementedYet(KPY));
-
- PARSE_MODE_CHANGES = new HashMap<String, Integer>();
- PARSE_MODE_CHANGES.put(START_CHAR_METRICS, new Integer(PARSE_CHAR_METRICS));
- PARSE_MODE_CHANGES.put(END_CHAR_METRICS, new Integer(PARSE_NORMAL));
- }
-
- /**
- * Main constructor.
- */
- public AFMParser() {
- }
-
- /**
- * Parses an AFM file from a stream.
- * @param in the stream to read from
- * @param afmFileName the name of the AFM file
- * @return the parsed AFM file
- * @throws IOException if an I/O error occurs
- */
- public AFMFile parse(InputStream in, String afmFileName) throws IOException {
- Reader reader = new java.io.InputStreamReader(in, "US-ASCII");
- try {
- return parse(new BufferedReader(reader), afmFileName);
- } finally {
- IOUtils.closeQuietly(reader);
- }
- }
-
- /**
- * Parses an AFM file from a BufferedReader.
- * @param reader the BufferedReader instance to read from
- * @param afmFileName the name of the AFM file
- * @return the parsed AFM file
- * @throws IOException if an I/O error occurs
- */
- public AFMFile parse(BufferedReader reader, String afmFileName) throws IOException {
- Stack<Object> stack = new Stack<Object>();
- int parseMode = PARSE_NORMAL;
- while (true) {
- String line = reader.readLine();
- if (line == null) {
- break;
- }
- String key = null;
- switch (parseMode) {
- case PARSE_NORMAL:
- key = parseLine(line, stack);
- break;
- case PARSE_CHAR_METRICS:
- key = parseCharMetrics(line, stack, afmFileName);
- break;
- default:
- throw new IllegalStateException("Invalid parse mode");
- }
- Integer newParseMode = PARSE_MODE_CHANGES.get(key);
- if (newParseMode != null) {
- parseMode = newParseMode.intValue();
- }
- }
- return (AFMFile)stack.pop();
- }
-
- private String parseLine(String line, Stack<Object> stack) throws IOException {
- int startpos = 0;
- //Find key
- startpos = skipToNonWhiteSpace(line, startpos);
- int endpos = skipToWhiteSpace(line, startpos);
- String key = line.substring(startpos, endpos);
-
- //Parse value
- startpos = skipToNonWhiteSpace(line, endpos);
- ValueHandler vp = VALUE_PARSERS.get(key);
- if (vp != null) {
- vp.parse(line, startpos, stack);
- }
- return key;
- }
-
- private String parseCharMetrics(String line, Stack<Object> stack, String afmFileName)
- throws IOException {
- String trimmedLine = line.trim();
- if (END_CHAR_METRICS.equals(trimmedLine)) {
- return trimmedLine;
- }
- AFMFile afm = (AFMFile) stack.peek();
- String encoding = afm.getEncodingScheme();
- CharMetricsHandler charMetricsHandler = CharMetricsHandler.getHandler(VALUE_PARSERS,
- encoding);
- AFMCharMetrics chm = charMetricsHandler.parse(trimmedLine, stack, afmFileName);
- afm.addCharMetrics(chm);
- return null;
- }
-
- private static int skipToNonWhiteSpace(String line, int startpos) {
- int pos = startpos;
- while (pos < line.length() && isWhitespace(line.charAt(pos))) {
- pos++;
- }
- return pos;
- }
-
- private static int skipToWhiteSpace(String line, int startpos) {
- int pos = startpos;
- while (pos < line.length() && !isWhitespace(line.charAt(pos))) {
- pos++;
- }
- return pos;
- }
-
- private static boolean isWhitespace(char ch) {
- return ch == ' '
- || ch == '\t';
- }
-
- // ---------------- Value Handlers ---------------------------
-
- interface ValueHandler {
- void parse(String line, int startpos, Stack<Object> stack) throws IOException;
- }
-
- private abstract static class AbstractValueHandler implements ValueHandler {
-
- protected int findValue(String line, int startpos) {
- return skipToWhiteSpace(line, startpos);
- }
-
- protected String getStringValue(String line, int startpos) {
- return line.substring(startpos);
- }
-
- protected Number getNumberValue(String line, int startpos) {
- try {
- return new Integer(getIntegerValue(line, startpos));
- } catch (NumberFormatException nfe) {
- return new Double(getDoubleValue(line, startpos));
- }
- }
-
- protected int getIntegerValue(String line, int startpos) {
- int endpos = findValue(line, startpos);
- return Integer.parseInt(line.substring(startpos, endpos));
- }
-
- protected double getDoubleValue(String line, int startpos) {
- int endpos = findValue(line, startpos);
- return Double.parseDouble(line.substring(startpos, endpos));
- }
-
- protected Boolean getBooleanValue(String line, int startpos) {
- return Boolean.valueOf(getStringValue(line, startpos));
- }
-
- }
-
- private static class StartFontMetrics extends AbstractValueHandler {
- public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
- int endpos = findValue(line, startpos);
- double version = Double.parseDouble(line.substring(startpos, endpos));
- if (version < 2) {
- throw new IOException(
- "AFM version must be at least 2.0 but it is " + version + "!");
- }
- AFMFile afm = new AFMFile();
- stack.push(afm);
- }
- }
-
- private abstract static class BeanSetter extends AbstractValueHandler {
- protected String method;
-
- public BeanSetter(String variable) {
- this.method = "set" + variable;
- }
-
- protected void setValue(Object target, Class<?> argType, Object value) {
- Class<?> c = target.getClass();
-
- try {
- Method mth = c.getMethod(method, argType);
- mth.invoke(target, value);
- } catch (NoSuchMethodException e) {
- throw new RuntimeException("Bean error: " + e.getMessage(), e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException("Bean error: " + e.getMessage(), e);
- } catch (InvocationTargetException e) {
- throw new RuntimeException("Bean error: " + e.getMessage(), e);
- }
- }
- }
-
- private static class StringSetter extends BeanSetter {
-
- public StringSetter(String variable) {
- super(variable);
- }
-
- public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
- String s = getStringValue(line, startpos);
- Object obj = stack.peek();
- setValue(obj, String.class, s);
- }
- }
-
- private static class NamedCharacterSetter extends BeanSetter {
-
- public NamedCharacterSetter(String variable) {
- super(variable);
- }
-
- public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
- NamedCharacter ch = new NamedCharacter(getStringValue(line, startpos));
- Object obj = stack.peek();
- setValue(obj, NamedCharacter.class, ch);
- }
- }
-
- private static class NumberSetter extends BeanSetter {
- public NumberSetter(String variable) {
- super(variable);
- }
-
- protected Object getContextObject(Stack<Object> stack) {
- return stack.peek();
- }
-
- public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
- Number num = getNumberValue(line, startpos);
- setValue(getContextObject(stack), Number.class, num);
- }
- }
-
- private static class IntegerSetter extends NumberSetter {
- public IntegerSetter(String variable) {
- super(variable);
- }
-
- public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
- int value = getIntegerValue(line, startpos);
- setValue(getContextObject(stack), int.class, new Integer(value));
- }
- }
-
- private static class DoubleSetter extends NumberSetter {
- public DoubleSetter(String variable) {
- super(variable);
- }
-
- public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
- double value = getDoubleValue(line, startpos);
- setValue(getContextObject(stack), double.class, new Double(value));
- }
- }
-
- private static class WritingDirNumberSetter extends NumberSetter {
-
- public WritingDirNumberSetter(String variable) {
- super(variable);
- }
-
- protected Object getContextObject(Stack<Object> stack) {
- if (stack.peek() instanceof AFMWritingDirectionMetrics) {
- return (AFMWritingDirectionMetrics)stack.peek();
- } else {
- AFMFile afm = (AFMFile)stack.peek();
- AFMWritingDirectionMetrics wdm = afm.getWritingDirectionMetrics(0);
- if (wdm == null) {
- wdm = new AFMWritingDirectionMetrics();
- afm.setWritingDirectionMetrics(0, wdm);
- }
- return wdm;
- }
- }
-
- }
-
- private static class WritingDirDoubleSetter extends WritingDirNumberSetter {
-
- public WritingDirDoubleSetter(String variable) {
- super(variable);
- }
-
- public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
- double value = getDoubleValue(line, startpos);
- setValue(getContextObject(stack), double.class, new Double(value));
- }
- }
-
- private static class BooleanSetter extends AbstractValueHandler {
- private String method;
-
- public BooleanSetter(String variable) {
- this.method = "set" + variable.substring(2); //Cut "Is" in front
- }
-
- protected Object getContextObject(Stack<Object> stack) {
- return (AFMFile)stack.peek();
- }
-
- public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
- Boolean b = getBooleanValue(line, startpos);
-
- Object target = getContextObject(stack);
- Class<?> c = target.getClass();
- try {
- Method mth = c.getMethod(method, boolean.class);
- mth.invoke(target, b);
- } catch (NoSuchMethodException e) {
- throw new RuntimeException("Bean error: " + e.getMessage(), e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException("Bean error: " + e.getMessage(), e);
- } catch (InvocationTargetException e) {
- throw new RuntimeException("Bean error: " + e.getMessage(), e);
- }
- }
- }
-
- private static class WritingDirBooleanSetter extends BooleanSetter {
-
- public WritingDirBooleanSetter(String variable) {
- super(variable);
- }
-
- protected Object getContextObject(Stack<Object> stack) {
- if (stack.peek() instanceof AFMWritingDirectionMetrics) {
- return (AFMWritingDirectionMetrics)stack.peek();
- } else {
- AFMFile afm = (AFMFile)stack.peek();
- AFMWritingDirectionMetrics wdm = afm.getWritingDirectionMetrics(0);
- if (wdm == null) {
- wdm = new AFMWritingDirectionMetrics();
- afm.setWritingDirectionMetrics(0, wdm);
- }
- return wdm;
- }
- }
-
- }
-
- private static class FontBBox extends AbstractValueHandler {
- public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
- Rectangle rect = parseBBox(line, startpos);
-
- AFMFile afm = (AFMFile)stack.peek();
- afm.setFontBBox(rect);
- }
-
- protected Rectangle parseBBox(String line, int startpos) {
- Rectangle rect = new Rectangle();
- int endpos;
-
- endpos = findValue(line, startpos);
- rect.x = Integer.parseInt(line.substring(startpos, endpos));
- startpos = skipToNonWhiteSpace(line, endpos);
-
- endpos = findValue(line, startpos);
- rect.y = Integer.parseInt(line.substring(startpos, endpos));
- startpos = skipToNonWhiteSpace(line, endpos);
-
- endpos = findValue(line, startpos);
- int v = Integer.parseInt(line.substring(startpos, endpos));
- rect.width = v - rect.x;
- startpos = skipToNonWhiteSpace(line, endpos);
-
- endpos = findValue(line, startpos);
- v = Integer.parseInt(line.substring(startpos, endpos));
- rect.height = v - rect.y;
- startpos = skipToNonWhiteSpace(line, endpos);
- return rect;
- }
- }
-
- private static class CharBBox extends FontBBox {
- public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
- Rectangle rect = parseBBox(line, startpos);
-
- AFMCharMetrics metrics = (AFMCharMetrics)stack.peek();
- metrics.setBBox(rect);
- }
- }
-
- private static class IsBaseFont extends AbstractValueHandler {
- public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
- if (getBooleanValue(line, startpos).booleanValue()) {
- throw new IOException("Only base fonts are currently supported!");
- }
- }
- }
-
- private static class IsCIDFont extends AbstractValueHandler {
- public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
- if (getBooleanValue(line, startpos).booleanValue()) {
- throw new IOException("CID fonts are currently not supported!");
- }
- }
- }
-
- private static class NotImplementedYet extends AbstractValueHandler {
- private String key;
-
- public NotImplementedYet(String key) {
- this.key = key;
- }
-
- public void parse(String line, int startpos, Stack stack) throws IOException {
- log.warn("Support for '" + key + "' has not been implemented, yet!"
- + " Some font data in the AFM file will be ignored.");
- }
- }
-
- private static class StartDirection extends AbstractValueHandler {
- public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
- int index = getIntegerValue(line, startpos);
- AFMWritingDirectionMetrics wdm = new AFMWritingDirectionMetrics();
- AFMFile afm = (AFMFile)stack.peek();
- afm.setWritingDirectionMetrics(index, wdm);
- stack.push(wdm);
- }
- }
-
- private static class EndDirection extends AbstractValueHandler {
- public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
- if (!(stack.pop() instanceof AFMWritingDirectionMetrics)) {
- throw new IOException("AFM format error: nesting incorrect");
- }
- }
- }
-
- private static class KPXHandler extends AbstractValueHandler {
- public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
- AFMFile afm = (AFMFile)stack.peek();
- int endpos;
-
- endpos = findValue(line, startpos);
- String name1 = line.substring(startpos, endpos);
- startpos = skipToNonWhiteSpace(line, endpos);
-
- endpos = findValue(line, startpos);
- String name2 = line.substring(startpos, endpos);
- startpos = skipToNonWhiteSpace(line, endpos);
-
- endpos = findValue(line, startpos);
- double kx = Double.parseDouble(line.substring(startpos, endpos));
- startpos = skipToNonWhiteSpace(line, endpos);
-
- afm.addXKerning(name1, name2, kx);
- }
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/type1/AFMWritingDirectionMetrics.java b/src/java/org/apache/fop/fonts/type1/AFMWritingDirectionMetrics.java
deleted file mode 100644
index 07d522bd9..000000000
--- a/src/java/org/apache/fop/fonts/type1/AFMWritingDirectionMetrics.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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;
-
-/**
- * Represents a writing direction metrics section from an AFM file.
- */
-public class AFMWritingDirectionMetrics {
-
- private Number underlinePosition;
- private Number underlineThickness;
- private double italicAngle;
- private boolean isFixedPitch;
-
- /**
- * Returns the UnderlinePosition value.
- * @return the underlinePosition
- */
- public Number getUnderlinePosition() {
- return underlinePosition;
- }
-
- /**
- * Sets the UnderlinePosition value.
- * @param underlinePosition the underlinePosition to set
- */
- public void setUnderlinePosition(Number underlinePosition) {
- this.underlinePosition = underlinePosition;
- }
-
- /**
- * Returns the UnderlineThickness value.
- * @return the underlineThickness
- */
- public Number getUnderlineThickness() {
- return underlineThickness;
- }
-
- /**
- * Sets the UnderlineThickness value.
- * @param underlineThickness the underlineThickness to set
- */
- public void setUnderlineThickness(Number underlineThickness) {
- this.underlineThickness = underlineThickness;
- }
-
- /**
- * Returns the ItalicAngle value.
- * @return the italicAngle
- */
- public double getItalicAngle() {
- return italicAngle;
- }
-
- /**
- * Sets the ItalicAngle value.
- * @param italicAngle the italicAngle to set
- */
- public void setItalicAngle(double italicAngle) {
- this.italicAngle = italicAngle;
- }
-
- /**
- * Returns the IsFixedPitch value.
- * @return the isFixedPitch
- */
- public boolean isFixedPitch() {
- return isFixedPitch;
- }
-
- /**
- * Set the IsFixedPitch value.
- * @param value the isFixedPitch to set
- */
- public void setFixedPitch(boolean value) {
- this.isFixedPitch = value;
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/type1/AdobeStandardEncoding.java b/src/java/org/apache/fop/fonts/type1/AdobeStandardEncoding.java
deleted file mode 100644
index d3d5a969d..000000000
--- a/src/java/org/apache/fop/fonts/type1/AdobeStandardEncoding.java
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * 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.
- */
-public 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;
- }
-
- public static String getCharFromCodePoint(int codePoint) {
- for (AdobeStandardEncoding encoding : CACHE.values()) {
- if (encoding.getAdobeCodePoint() == codePoint) {
- return encoding.getAdobeName();
- }
- }
- return "";
- }
-}
diff --git a/src/java/org/apache/fop/fonts/type1/CharMetricsHandler.java b/src/java/org/apache/fop/fonts/type1/CharMetricsHandler.java
deleted file mode 100644
index 79753f3f8..000000000
--- a/src/java/org/apache/fop/fonts/type1/CharMetricsHandler.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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.xmlgraphics.fonts.Glyphs;
-
-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) {
- String charName = namedChar.getName();
- int codePoint = AdobeStandardEncoding.getAdobeCodePoint(charName);
- if (chm.getCharCode() != codePoint && !Glyphs.NOTDEF.equals(charName)) {
- LOG.info(afmFileName + ": named character '" + charName + "'"
- + " has an incorrect code point: " + chm.getCharCode()
- + ". Changed to " + codePoint);
- chm.setCharCode(codePoint);
- }
- }
- return chm;
- }
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/type1/PFBData.java b/src/java/org/apache/fop/fonts/type1/PFBData.java
deleted file mode 100644
index 05f0ec78f..000000000
--- a/src/java/org/apache/fop/fonts/type1/PFBData.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * 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.io.OutputStream;
-
-/**
- * Class that represents the contents of a PFB file.
- *
- * @see PFBParser
- */
-public class PFBData {
-
- /**
- * Raw format, no special file structure
- */
- public static final int PFB_RAW = 0;
-
- /**
- * PC format
- */
- public static final int PFB_PC = 1;
-
- /**
- * MAC Format (unsupported, yet)
- */
- public static final int PFB_MAC = 2;
-
- private int pfbFormat; //One of the PFB_* constants
- private byte[] headerSegment;
- private byte[] encryptedSegment;
- private byte[] trailerSegment;
-
-
- /**
- * Sets the PFB format the font was loaded with.
- * @param format one of the PFB_* constants
- */
- public void setPFBFormat(int format) {
- switch (format) {
- case PFB_RAW:
- case PFB_PC:
- this.pfbFormat = format;
- break;
- case PFB_MAC:
- throw new UnsupportedOperationException("Mac format is not yet implemented");
- default:
- throw new IllegalArgumentException("Invalid value for PFB format: " + format);
- }
- }
-
-
- /**
- * Returns the format the font was loaded with.
- * @return int one of the PFB_* constants
- */
- public int getPFBFormat() {
- return this.pfbFormat;
- }
-
- /**
- * Sets the header segment of the font file.
- * @param headerSeg the header segment
- */
- public void setHeaderSegment(byte[] headerSeg) {
- this.headerSegment = headerSeg;
- }
-
- /**
- * Gets the header segment of the font file
- * @return Header segment as a byte array
- */
- public byte[] getHeaderSegment() {
- return this.headerSegment.clone();
- }
-
- /**
- * Sets the encrypted segment of the font file.
- * @param encryptedSeg the encrypted segment
- */
- public void setEncryptedSegment(byte[] encryptedSeg) {
- this.encryptedSegment = encryptedSeg;
- }
-
- /**
- * Gets the encrypted segment of the font file
- * @return The encrypted segment as a byte array
- */
- public byte[] getEncryptedSegment() {
- return this.encryptedSegment.clone();
- }
-
- /**
- * Sets the trailer segment of the font file.
- * @param trailerSeg the trailer segment
- */
- public void setTrailerSegment(byte[] trailerSeg) {
- this.trailerSegment = trailerSeg;
- }
-
- /**
- * Gets the trailer segment of the font file
- * @return The trailer segment as a byte array
- */
- public byte[] getTrailerSegment() {
- return this.trailerSegment.clone();
- }
-
- /**
- * Returns the full length of the raw font file.
- * @return int the raw file length
- */
- public int getLength() {
- return getLength1() + getLength2() + getLength3();
- }
-
-
- /**
- * Returns the Length1 (length of the header segment).
- * @return int Length1
- */
- public int getLength1() {
- return this.headerSegment.length;
- }
-
-
- /**
- * Returns the Length2 (length of the encrypted segment).
- * @return int Length2
- */
- public int getLength2() {
- return this.encryptedSegment.length;
- }
-
-
- /**
- * Returns the Length3 (length of the trailer segment).
- * @return int Length3
- */
- public int getLength3() {
- return this.trailerSegment.length;
- }
-
-
- /**
- * Writes the PFB file in raw format to an OutputStream.
- * @param out the OutputStream to write to
- * @throws IOException In case of an I/O problem
- */
- public void outputAllParts(OutputStream out) throws IOException {
- out.write(this.headerSegment);
- out.write(this.encryptedSegment);
- out.write(this.trailerSegment);
- }
-
-
- /**
- * {@inheritDoc}
- */
- public String toString() {
- return "PFB: format=" + getPFBFormat()
- + " len1=" + getLength1()
- + " len2=" + getLength2()
- + " len3=" + getLength3();
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/type1/PFBParser.java b/src/java/org/apache/fop/fonts/type1/PFBParser.java
deleted file mode 100644
index 339a9e141..000000000
--- a/src/java/org/apache/fop/fonts/type1/PFBParser.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.BufferedInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.commons.io.IOUtils;
-
-/**
- * This class represents a parser for Adobe Type 1 PFB files.
- *
- * @see PFBData
- */
-public class PFBParser {
-
- private static final byte[] CURRENTFILE_EEXEC;
- private static final byte[] CLEARTOMARK;
-
- static {
- try {
- CURRENTFILE_EEXEC = "currentfile eexec".getBytes("US-ASCII");
- CLEARTOMARK = "cleartomark".getBytes("US-ASCII");
- } catch (java.io.UnsupportedEncodingException e) {
- throw new RuntimeException("Incompatible VM. It doesn't support the US-ASCII encoding");
- }
- }
-
-
- /**
- * Parses a PFB file into a PFBData object.
- * @param in InputStream to load the PFB file from
- * @return PFBData memory representation of the font
- * @throws IOException In case of an I/O problem
- */
- public PFBData parsePFB(InputStream in) throws IOException {
- PFBData pfb = new PFBData();
- BufferedInputStream bin = new BufferedInputStream(in);
- DataInputStream din = new DataInputStream(bin);
- din.mark(32);
- int firstByte = din.readUnsignedByte();
- din.reset();
- if (firstByte == 128) {
- pfb.setPFBFormat(PFBData.PFB_PC);
- parsePCFormat(pfb, din);
- } else {
- pfb.setPFBFormat(PFBData.PFB_RAW);
- parseRAWFormat(pfb, bin);
- }
- return pfb;
- }
-
-
- private static int swapInteger(final int value) {
- return (((value >> 0) & 0xff) << 24)
- + (((value >> 8) & 0xff) << 16)
- + (((value >> 16) & 0xff) << 8)
- + (((value >> 24) & 0xff) << 0);
- }
-
-
- private void parsePCFormat(PFBData pfb, DataInputStream din) throws IOException {
- int segmentHead;
- int segmentType;
-
- //Read first segment
- segmentHead = din.readUnsignedByte();
- if (segmentHead != 128) {
- throw new IOException("Invalid file format. Expected ASCII 80hex");
- }
- segmentType = din.readUnsignedByte(); //Read
- int len1 = swapInteger(din.readInt());
- byte[] headerSegment = new byte[len1];
- din.readFully(headerSegment);
- pfb.setHeaderSegment(headerSegment);
-
- //Read second segment
- segmentHead = din.readUnsignedByte();
- if (segmentHead != 128) {
- throw new IOException("Invalid file format. Expected ASCII 80hex");
- }
- segmentType = din.readUnsignedByte();
- int len2 = swapInteger(din.readInt());
- byte[] encryptedSegment = new byte[len2];
- din.readFully(encryptedSegment);
- pfb.setEncryptedSegment(encryptedSegment);
-
- //Read third segment
- segmentHead = din.readUnsignedByte();
- if (segmentHead != 128) {
- throw new IOException("Invalid file format. Expected ASCII 80hex");
- }
- segmentType = din.readUnsignedByte();
- int len3 = swapInteger(din.readInt());
- byte[] trailerSegment = new byte[len3];
- din.readFully(trailerSegment);
- pfb.setTrailerSegment(trailerSegment);
-
- //Read EOF indicator
- segmentHead = din.readUnsignedByte();
- if (segmentHead != 128) {
- throw new IOException("Invalid file format. Expected ASCII 80hex");
- }
- segmentType = din.readUnsignedByte();
- if (segmentType != 3) {
- throw new IOException("Expected segment type 3, but found: " + segmentType);
- }
- }
-
-
- private static boolean byteCmp(byte[] src, int srcOffset, byte[] cmp) {
- for (int i = 0; i < cmp.length; i++) {
- // System.out.println("Compare: " + src[srcOffset + i] + " " + cmp[i]);
- if (src[srcOffset + i] != cmp[i]) {
- return false;
- }
- }
- return true;
- }
-
- private void calcLengths(PFBData pfb, byte[] originalData) {
- // Calculate length 1 and 3
- // System.out.println ("Checking font, size = "+originalData.length);
-
- // Length1 is the size of the initial ascii portion
- // search for "currentfile eexec"
- // Get the first binary number and search backwards for "eexec"
- int len1 = 30;
-
- // System.out.println("Length1="+len1);
- while (!byteCmp(originalData, len1 - CURRENTFILE_EEXEC.length, CURRENTFILE_EEXEC)) {
- len1++;
- }
-
- // Skip newline
- len1++;
-
- // Length3 is length of the last portion of the file
- int len3 = 0;
- len3 -= CLEARTOMARK.length;
- while (!byteCmp(originalData, originalData.length + len3, CLEARTOMARK)) {
- len3--;
- // System.out.println("Len3="+len3);
- }
- len3 = -len3;
- len3++;
- // Eat 512 zeroes
- int numZeroes = 0;
- byte[] ws1 = new byte[]{0x0D}; //CR
- byte[] ws2 = new byte[]{0x0A}; //LF
- byte[] ws3 = new byte[]{0x30}; //"0"
- while ((originalData[originalData.length - len3] == ws1[0]
- || originalData[originalData.length - len3] == ws2[0]
- || originalData[originalData.length - len3] == ws3[0])
- && numZeroes < 512) {
- len3++;
- if (originalData[originalData.length - len3] == ws3[0]) {
- numZeroes++;
- }
- }
- // System.out.println("Length3="+len3);
-
- //Create the 3 segments
- byte[] buffer = new byte[len1];
- System.arraycopy(originalData, 0, buffer, 0, len1);
- pfb.setHeaderSegment(buffer);
-
- int len2 = originalData.length - len3 - len1;
- buffer = new byte[len2];
- System.arraycopy(originalData, len1, buffer, 0, len2);
- pfb.setEncryptedSegment(buffer);
-
- buffer = new byte[len3];
- System.arraycopy(originalData, len1 + len2, buffer, 0, len3);
- pfb.setTrailerSegment(buffer);
- }
-
- private void parseRAWFormat(PFBData pfb, BufferedInputStream bin)
- throws IOException {
- calcLengths(pfb, IOUtils.toByteArray(bin));
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/type1/PFMFile.java b/src/java/org/apache/fop/fonts/type1/PFMFile.java
deleted file mode 100644
index 8856fdb7f..000000000
--- a/src/java/org/apache/fop/fonts/type1/PFMFile.java
+++ /dev/null
@@ -1,521 +0,0 @@
-/*
- * 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;
-
-// Java
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.xmlgraphics.fonts.Glyphs;
-
-/**
- * This class represents a PFM file (or parts of it) as a Java object.
- */
-public class PFMFile {
-
- // Header stuff
- private String windowsName;
- private String postscriptName;
- private short dfItalic;
- //private int dfWeight;
- private short dfCharSet;
- private short dfPitchAndFamily;
- private int dfAvgWidth;
- private int dfMaxWidth;
- private int dfMinWidth;
- private short dfFirstChar;
- private short dfLastChar;
-
- // Extension stuff
- // ---
-
- // Extend Text Metrics
- private int etmCapHeight;
- private int etmXHeight;
- private int etmLowerCaseAscent;
- private int etmLowerCaseDescent;
-
- // Extent table
- private int[] extentTable;
-
- private Map<Integer, Map<Integer, Integer>> kerningTab = new HashMap<Integer, Map<Integer, Integer>>();
-
- /**
- * logging instance
- */
- protected Log log = LogFactory.getLog(PFMFile.class);
-
- /**
- * Parses a PFM file
- *
- * @param inStream The stream from which to read the PFM file.
- * @throws IOException In case of an I/O problem
- */
- public void load(InputStream inStream) throws IOException {
- byte[] pfmBytes = IOUtils.toByteArray(inStream);
- InputStream bufin = inStream;
- bufin = new ByteArrayInputStream(pfmBytes);
- PFMInputStream in = new PFMInputStream(bufin);
- bufin.mark(512);
- short sh1 = in.readByte();
- short sh2 = in.readByte();
- if (sh1 == 128 && sh2 == 1) {
- //Found the first section header of a PFB file!
- IOUtils.closeQuietly(in);
- throw new IOException("Cannot parse PFM file. You probably specified the PFB file"
- + " of a Type 1 font as parameter instead of the PFM.");
- }
- bufin.reset();
- byte[] b = new byte[16];
- if ((bufin.read(b) == b.length) && new String(b, "US-ASCII").equalsIgnoreCase("StartFontMetrics")) {
- //Found the header of a AFM file!
- IOUtils.closeQuietly(in);
- throw new IOException("Cannot parse PFM file. You probably specified the AFM file"
- + " of a Type 1 font as parameter instead of the PFM.");
- }
- bufin.reset();
- final int version = in.readShort();
- if (version != 256) {
- log.warn("PFM version expected to be '256' but got '" + version + "'."
- + " Please make sure you specify the PFM as parameter"
- + " and not the PFB or the AFM.");
- }
- //final long filesize = in.readInt();
- bufin.reset();
-
- loadHeader(in);
- loadExtension(in);
- }
-
- /**
- * Parses the header of the PFM file.
- *
- * @param inStream The stream from which to read the PFM file.
- * @throws IOException In case of an I/O problem
- */
- private void loadHeader(PFMInputStream inStream) throws IOException {
- if (inStream.skip(80) != 80) {
- throw new IOException("premature EOF when skipping 80 bytes");
- }
- dfItalic = inStream.readByte();
- if (inStream.skip(2) != 2) {
- throw new IOException("premature EOF when skipping 2 bytes");
- }
- inStream.readShort(); // dfWeight =
- dfCharSet = inStream.readByte();
- if (inStream.skip(4) != 4) {
- throw new IOException("premature EOF when skipping 4 bytes");
- }
- dfPitchAndFamily = inStream.readByte();
- dfAvgWidth = inStream.readShort();
- dfMaxWidth = inStream.readShort();
- dfFirstChar = inStream.readByte();
- dfLastChar = inStream.readByte();
- if (inStream.skip(8) != 8) {
- throw new IOException("premature EOF when skipping 8 bytes");
- }
- long faceOffset = inStream.readInt();
-
- inStream.reset();
- if (inStream.skip(faceOffset) != faceOffset) {
- throw new IOException("premature EOF when skipping faceOffset bytes");
- }
- windowsName = inStream.readString();
-
- inStream.reset();
- if (inStream.skip(117) != 117) {
- throw new IOException("premature EOF when skipping 117 bytes");
- }
- }
-
- /**
- * Parses the extension part of the PFM file.
- *
- * @param inStream The stream from which to read the PFM file.
- */
- private void loadExtension(PFMInputStream inStream) throws IOException {
- final int size = inStream.readShort();
- if (size != 30) {
- log.warn("Size of extension block was expected to be "
- + "30 bytes, but was " + size + " bytes.");
- }
- final long extMetricsOffset = inStream.readInt();
- final long extentTableOffset = inStream.readInt();
- if (inStream.skip(4) != 4) { //Skip dfOriginTable
- throw new IOException("premature EOF when skipping dfOriginTable bytes");
- }
- final long kernPairOffset = inStream.readInt();
- if (inStream.skip(4) != 4) { //Skip dfTrackKernTable
- throw new IOException("premature EOF when skipping dfTrackKernTable bytes");
- }
- long driverInfoOffset = inStream.readInt();
-
- if (kernPairOffset > 0) {
- inStream.reset();
- if (inStream.skip(kernPairOffset) != kernPairOffset) {
- throw new IOException("premature EOF when skipping kernPairOffset bytes");
- }
- loadKernPairs(inStream);
- }
-
- inStream.reset();
- if (inStream.skip(driverInfoOffset) != driverInfoOffset) {
- throw new IOException("premature EOF when skipping driverInfoOffset bytes");
- }
- postscriptName = inStream.readString();
-
- if (extMetricsOffset != 0) {
- inStream.reset();
- if (inStream.skip(extMetricsOffset) != extMetricsOffset) {
- throw new IOException("premature EOF when skipping extMetricsOffset bytes");
- }
- loadExtMetrics(inStream);
- }
- if (extentTableOffset != 0) {
- inStream.reset();
- if (inStream.skip(extentTableOffset) != extentTableOffset) {
- throw new IOException("premature EOF when skipping extentTableOffset bytes");
- }
- loadExtentTable(inStream);
- }
-
- }
-
- /**
- * Parses the kernPairs part of the pfm file
- *
- * @param inStream The stream from which to read the PFM file.
- */
- private void loadKernPairs(PFMInputStream inStream) throws IOException {
- int i = inStream.readShort();
-
-
- if (log.isTraceEnabled()) {
- log.trace(i + " kerning pairs");
- }
- while (i > 0) {
- int g1 = (int) inStream.readByte();
- i--;
-
- int g2 = (int) inStream.readByte();
-
- int adj = inStream.readShort();
- if (adj > 0x8000) {
- adj = -(0x10000 - adj);
- }
-
- if (log.isTraceEnabled()) {
- log.trace("Char no: (" + g1 + ", " + g2 + ") kern: " + adj);
- final String glyph1 = Glyphs.TEX8R_GLYPH_NAMES[g1];
- final String glyph2 = Glyphs.TEX8R_GLYPH_NAMES[g2];
- log.trace("glyphs: " + glyph1 + ", " + glyph2);
- }
-
- Map<Integer, Integer> adjTab = kerningTab.get(Integer.valueOf(g1));
- if (adjTab == null) {
- adjTab = new HashMap<Integer, Integer>();
- }
- adjTab.put(Integer.valueOf(g2), Integer.valueOf(adj));
- kerningTab.put(Integer.valueOf(g1), adjTab);
- }
- }
-
- /**
- * Parses the extended metrics part of the PFM file.
- *
- * @param inStream The stream from which to read the PFM file.
- */
- private void loadExtMetrics(PFMInputStream inStream) throws IOException {
- final int size = inStream.readShort();
- if (size != 52) {
- log.warn("Size of extension block was expected to be "
- + "52 bytes, but was " + size + " bytes.");
- }
- if (inStream.skip(12) != 12) { //Skip etmPointSize, etmOrientation, etmMasterHeight,
- //etmMinScale, etmMaxScale, emtMasterUnits
- throw new IOException("premature EOF when skipping etmPointSize, ... bytes");
- }
- etmCapHeight = inStream.readShort();
- etmXHeight = inStream.readShort();
- etmLowerCaseAscent = inStream.readShort();
- etmLowerCaseDescent = -(inStream.readShort());
- //Ignore the rest of the values
- }
-
- /**
- * Parses the extent table of the PFM file.
- *
- * @param inStream The stream from which to read the PFM file.
- */
- private void loadExtentTable(PFMInputStream inStream) throws IOException {
- extentTable = new int[dfLastChar - dfFirstChar + 1];
- dfMinWidth = dfMaxWidth;
- for (short i = dfFirstChar; i <= dfLastChar; i++) {
- extentTable[i - dfFirstChar] = inStream.readShort();
- if (extentTable[i - dfFirstChar] < dfMinWidth) {
- dfMinWidth = extentTable[i - dfFirstChar];
- }
- }
- }
-
- /**
- * Returns the Windows name of the font.
- *
- * @return The Windows name.
- */
- public String getWindowsName() {
- return windowsName;
- }
-
- /**
- * Return the kerning table. The kerning table is a Map with
- * strings with glyphnames as keys, containing Maps as value.
- * The value map contains a glyph name string key and an Integer value
- *
- * @return A Map containing the kerning table
- */
- public Map<Integer, Map<Integer, Integer>> getKerning() {
- return kerningTab;
- }
-
- /**
- * Returns the Postscript name of the font.
- *
- * @return The Postscript name.
- */
- public String getPostscriptName() {
- return postscriptName;
- }
-
- /**
- * Returns the charset used for the font.
- *
- * @return The charset (0=WinAnsi).
- */
- public short getCharSet() {
- return dfCharSet;
- }
-
- /**
- * Returns the charset of the font as a string.
- *
- * @return The name of the charset.
- */
- public String getCharSetName() {
- //TODO Had to remove the detection for Expert(Subset) encoding. The PFM is not suitable
- //for detecting these character sets. We have to parse the AFM for that.
- switch (dfCharSet) {
- case 0:
- return "WinAnsi"; // AKA ISOAdobe
- case 2:
- if ("Symbol".equals(getPostscriptName())) {
- return "Symbol";
- }
- break;
- case 128:
- return "Shift-JIS (Japanese)";
- default:
- log.warn("Unknown charset detected (" + dfCharSet
- + ", 0x" + Integer.toHexString(dfCharSet)
- + "). Trying fallback to WinAnsi.");
- }
- return "WinAnsi";
- }
-
- /**
- * Returns the number of the character that defines
- * the first entry in the widths list.
- *
- * @return The number of the first character.
- */
- public short getFirstChar() {
- return dfFirstChar;
- }
-
- /**
- * Returns the number of the character that defines
- * the last entry in the widths list.
- *
- * @return The number of the last character.
- */
- public short getLastChar() {
- return dfLastChar;
- }
-
- /**
- * Returns the CapHeight parameter for the font (height of uppercase H).
- *
- * @return The CapHeight parameter.
- */
- public int getCapHeight() {
- return etmCapHeight;
- }
-
- /**
- * Returns the XHeight parameter for the font (height of lowercase x).
- *
- * @return The CapHeight parameter.
- */
- public int getXHeight() {
- return etmXHeight;
- }
-
- /**
- * Returns the LowerCaseAscent parameter for the font (height of lowercase d).
- *
- * @return The LowerCaseAscent parameter.
- */
- public int getLowerCaseAscent() {
- return etmLowerCaseAscent;
- }
-
- /**
- * Returns the LowerCaseDescent parameter for the font (height of lowercase p).
- *
- * @return The LowerCaseDescent parameter.
- */
- public int getLowerCaseDescent() {
- return etmLowerCaseDescent;
- }
-
- /**
- * Tells whether the font has proportional character spacing.
- *
- * @return ex. true for Times, false for Courier.
- */
- public boolean getIsProportional() {
- return ((dfPitchAndFamily & 1) == 1);
- }
-
- /**
- * Returns the bounding box for the font.
- * Note: this value is just an approximation,
- * it does not really exist in the PFM file.
- *
- * @return The calculated Font BBox.
- */
- public int[] getFontBBox() {
- int[] bbox = new int[4];
-
- // Just guessing....
- if (!getIsProportional() && (dfAvgWidth == dfMaxWidth)) {
- bbox[0] = -20;
- } else {
- bbox[0] = -100;
- }
- bbox[1] = getLowerCaseDescent() - 5;
- bbox[2] = dfMaxWidth + 10;
- bbox[3] = getLowerCaseAscent() + 5;
- return bbox;
- }
-
- /**
- * Indicates whether the font is non-symbolic (Font uses the Adobe standard Latin character
- * set or a subset of it).
- * @return true if the font is non-symbolic
- */
- public boolean isNonSymbolic() {
- return (dfCharSet != 2); //!= Symbol fonts
- }
-
- /**
- * Returns the characteristics flags for the font as
- * needed for a PDF font descriptor (See PDF specs).
- *
- * @return The characteristics flags.
- */
- public int getFlags() {
- int flags = 0;
- if (!getIsProportional()) {
- flags |= 1; //bit 1: FixedPitch
- }
- if (isNonSymbolic()) {
- flags |= 32; //bit 6: Nonsymbolic
- } else {
- flags |= 4; //bit 3: Symbolic
- }
- //int serif = dfPitchAndFamily & 0xFFFE;
- if ((dfPitchAndFamily & 16) != 0) {
- flags |= 2; //bit 2: Serif
- }
- if ((dfPitchAndFamily & 64) != 0) {
- flags |= 8; //bit 4: Script
- }
- if (dfItalic != 0) {
- flags |= 64; //bit 7: Italic
- }
- return flags;
- }
-
- /**
- * Returns the width of the dominant vertical stems of the font.
- * Note: this value is just an approximation,
- * it does not really exist in the PFM file.
- *
- * @return The vertical stem width.
- */
- public int getStemV() {
- // Just guessing....
- if (dfItalic != 0) {
- return (int) Math.round(dfMinWidth * 0.25);
- } else {
- return (int) Math.round(dfMinWidth * 0.6);
- }
- }
-
- /**
- * Returns the italic angle of the font.
- * Note: this value is just an approximation,
- * it does not really exist in the PFM file.
- *
- * @return The italic angle.
- */
- public int getItalicAngle() {
- if (dfItalic != 0) {
- return -16; // Just guessing....
- } else {
- return 0;
- }
- }
-
- /**
- * Returns the width of a character
- *
- * @param which The number of the character for which the width is requested.
- * @return The width of a character.
- */
- public int getCharWidth(short which) {
- if (extentTable != null) {
- return extentTable[which - dfFirstChar];
- } else {
- //Fixed-width font (PFM may have no extent table)
- //we'll just use the average width
- return this.dfAvgWidth;
- }
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/type1/PFMInputStream.java b/src/java/org/apache/fop/fonts/type1/PFMInputStream.java
deleted file mode 100644
index e8f0cb705..000000000
--- a/src/java/org/apache/fop/fonts/type1/PFMInputStream.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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.DataInputStream;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-
-/**
- * This is a helper class for reading PFM files. It defines functions for
- * extracting specific values out of the stream.
- */
-public class PFMInputStream extends java.io.FilterInputStream {
-
- private final DataInputStream datain;
-
- /**
- * Constructs a PFMInputStream based on an InputStream representing the
- * PFM file.
- *
- * @param in The stream from which to read the PFM file
- */
- public PFMInputStream(InputStream in) {
- super(in);
- datain = new DataInputStream(in);
- }
-
- /**
- * Parses a one byte value out of the stream.
- *
- * @return The value extracted
- * @throws IOException In case of an I/O problem
- */
- public short readByte() throws IOException {
- short s = datain.readByte();
- // Now, we've got to trick Java into forgetting the sign
- int s1 = (((s & 0xF0) >>> 4) << 4) + (s & 0x0F);
- return (short)s1;
- }
-
- /**
- * Parses a two byte value out of the stream.
- *
- * @return The value extracted
- * @throws IOException In case of an I/O problem
- */
- public int readShort() throws IOException {
- int i = datain.readShort();
-
- // Change byte order
- int high = (i & 0xFF00) >>> 8;
- int low = (i & 0x00FF) << 8;
- return low + high;
- }
-
- /**
- * Parses a four byte value out of the stream.
- *
- * @return The value extracted
- * @throws IOException In case of an I/O problem
- */
- public long readInt() throws IOException {
- int i = datain.readInt();
-
- // Change byte order
- int i1 = (i & 0xFF000000) >>> 24;
- int i2 = (i & 0x00FF0000) >>> 8;
- int i3 = (i & 0x0000FF00) << 8;
- int i4 = (i & 0x000000FF) << 24;
- return i1 + i2 + i3 + i4;
- }
-
- /**
- * Parses a zero-terminated string out of the stream.
- *
- * @return The value extracted
- * @throws IOException In case of an I/O problem
- */
- public String readString() throws IOException {
- InputStreamReader reader = new InputStreamReader(in, "ISO-8859-1");
- StringBuffer buf = new StringBuffer();
-
- int ch = reader.read();
- while (ch > 0) {
- buf.append((char)ch);
- ch = reader.read();
- }
- if (ch == -1) {
- throw new EOFException("Unexpected end of stream reached");
- }
- return buf.toString();
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/type1/PostscriptParser.java b/src/java/org/apache/fop/fonts/type1/PostscriptParser.java
deleted file mode 100644
index bc984fecd..000000000
--- a/src/java/org/apache/fop/fonts/type1/PostscriptParser.java
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * 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.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Scanner;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-public class PostscriptParser {
-
- protected static final Log LOG = LogFactory.getLog(PostscriptParser.class);
- /* Patterns used to identify Postscript elements */
- private static final String DICTIONARY = "dict";
- private static final String FIXED_ARRAY = "array";
- private static final String VARIABLE_ARRAY = "[";
- private static final String SUBROUTINE = "{";
- /* A list of parsed subroutines so if they are encountered during the parsing
- * phase of another element, they can be read and pattern matched. */
- private HashMap<String, PSSubroutine> subroutines = new HashMap<String, PSSubroutine>();
-
- /**
- * Parses the postscript document and returns a list of elements
- * @param segment The byte array containing the postscript data
- * @return A list of found Postscript elements
- * @throws IOException
- */
- public List<PSElement> parse(byte[] segment) throws IOException {
- List<PSElement> parsedElements = new ArrayList<PSElement>();
- /* Currently only scan and store the top level element. For deeper
- * Postscript parsing you can push and pop elements from a stack */
- PSElement foundElement = null;
- String operator = null;
- StringBuilder token = new StringBuilder();
- List<String> tokens = new ArrayList<String>();
- int startPoint = -1;
- boolean specialDelimiter = false;
- boolean lastWasSpecial = false;
- for (int i = 0; i < segment.length; i++) {
- byte cur = segment[i];
- if (foundElement != null && foundElement.hasMore()) {
- foundElement.parse(cur, i);
- continue;
- } else {
- char c = (char)cur;
- if (!lastWasSpecial) {
- specialDelimiter = (c == '{' || c == '}' || c == '[' || c == ']'
- || (!token.toString().equals("") && c == '/'));
- boolean isNotBreak = !(c == ' ' || c == '\r' || cur == 15 || cur == 12
- || cur == 10);
- if (isNotBreak && !specialDelimiter) {
- token.append(c);
- continue;
- }
- } else {
- lastWasSpecial = false;
- token.append(c);
- if (token.toString().equals("/")) {
- continue;
- }
- }
- }
- try {
- boolean setOp = false;
- if ((foundElement == null || !foundElement.hasMore()) && token.length() > 1
- && token.charAt(0) == '/' && tokens.size() != 1 || hasEndToken(token.toString())) {
- operator = token.toString();
- setOp = true;
- if (tokens.size() > 2 && tokens.get(tokens.size() - 1).equals("def")) {
- PSVariable newVar = new PSVariable(tokens.get(0), startPoint);
- newVar.setValue(tokens.get(1));
- newVar.setEndPoint(i - operator.length());
- parsedElements.add(newVar);
- }
- tokens.clear();
- startPoint = i - token.length();
- }
- if (operator != null) {
- if (foundElement instanceof PSSubroutine) {
- PSSubroutine sub = (PSSubroutine)foundElement;
- subroutines.put(sub.getOperator(), sub);
- parsedElements.add(sub);
- if (!setOp) {
- operator = "";
- }
- } else {
- if (foundElement != null) {
- if (!hasMatch(foundElement.getOperator(), parsedElements)) {
- parsedElements.add(foundElement);
- } else {
- LOG.warn("Duplicate " + foundElement.getOperator()
- + " in font file, Ignoring.");
- }
- }
- }
- //Compare token against patterns and create an element if matched
- foundElement = createElement(operator, token.toString(), startPoint);
- }
- } finally {
- tokens.add(token.toString());
- token = new StringBuilder();
- if (specialDelimiter) {
- specialDelimiter = false;
- lastWasSpecial = true;
- //Retrace special postscript character so it can be processed separately
- i--;
- }
- }
- }
- return parsedElements;
- }
-
- private boolean hasEndToken(String token) {
- return token.equals("currentdict");
- }
-
- private boolean hasMatch(String operator, List<PSElement> elements) {
- for (PSElement element : elements) {
- if (element.getOperator().equals(operator)) {
- return true;
- }
- }
- return false;
- }
-
- public PSElement createElement(String operator, String elementID, int startPoint) {
- if (operator.equals("")) {
- return null;
- }
- if (elementID.equals(FIXED_ARRAY)) {
- return new PSFixedArray(operator, startPoint);
- } else if (elementID.equals(VARIABLE_ARRAY)) {
- return new PSVariableArray(operator, startPoint);
- } else if (elementID.equals(SUBROUTINE)) {
- return new PSSubroutine(operator, startPoint);
- } else if (!operator.equals("/Private") && elementID.equals(DICTIONARY)) {
- return new PSDictionary(operator, startPoint);
- }
- return null;
- }
-
- /**
- * A base Postscript element class
- */
- public abstract class PSElement {
- /* The identifying operator for this element */
- protected String operator;
- private List<Byte> token;
- /* Determines whether there is any more data to be read whilst parsing */
- protected boolean hasMore = true;
- /* The locations of any entries containing binary data (e.g. arrays) */
- protected LinkedHashMap<String, int[]> binaryEntries;
- /* The tokens parsed from the current element */
- protected List<String> tokens;
- /* Determines whether binary data is currently being read / parsed */
- protected boolean readBinary;
- /* The location of the element within the binary data */
- private int startPoint = -1;
- protected int endPoint = -1;
- /* A flag to determine if unexpected postscript has been found in the element */
- private boolean foundUnexpected;
-
- public PSElement(String operator, int startPoint) {
- this.operator = operator;
- this.startPoint = startPoint;
- token = new ArrayList<Byte>();
- binaryEntries = new LinkedHashMap<String, int[]>();
- tokens = new ArrayList<String>();
- }
-
- /**
- * Gets the Postscript element operator
- * @return The operator returned as a string
- */
- public String getOperator() {
- return operator;
- }
-
- /**
- * The start location of the element within the source binary data
- * @return The start location returned as an integer
- */
- public int getStartPoint() {
- return startPoint;
- }
-
- /**
- * The end location of the element within the source binary data
- * @return The end location returned as an integer
- */
- public int getEndPoint() {
- return endPoint;
- }
-
- /**
- * Takes over the task of tokenizing the byte data
- * @param cur The current byte being read
- */
- public void parse(byte cur, int pos) throws UnsupportedEncodingException {
- if (!readBinary) {
- char c = (char)cur;
- boolean specialDelimiter = (c == '{' || c == '}' || c == '[' || c == ']'
- || c == '(' || c == ')');
- boolean isNotValidBreak = !(c == ' ' || cur == 15 || cur == 12 || c == '\r'
- || c == 10);
- if (isNotValidBreak && !specialDelimiter) {
- token.add(cur);
- } else {
- parseToken(pos);
- }
- if (specialDelimiter) {
- token.add(cur);
- parseToken(pos);
- }
- } else {
- parseByte(cur, pos);
- }
- }
-
- private void parseToken(int pos) throws UnsupportedEncodingException {
- byte[] bytesToken = new byte[token.size()];
- for (int i = 0; i < token.size(); i++) {
- bytesToken[i] = token.get(i).byteValue();
- }
- parseToken(new String(bytesToken, "ASCII"), pos);
- token.clear();
- }
-
- /**
- * Passes responsibility for processing the byte stream to the PostScript object
- * @param cur The byte currently being read
- * @param pos The position of the given byte
- */
- public abstract void parseByte(byte cur, int pos);
-
- /**
- * Delegates the parse routine to a sub class
- * @param token The token which to parse
- */
- public abstract void parseToken(String token, int curPos);
-
- protected boolean isInteger(String intValue) {
- try {
- Integer.parseInt(intValue);
- return true;
- } catch (NumberFormatException ex) {
- return false;
- }
- }
-
- public LinkedHashMap<String, int[]> getBinaryEntries() {
- return binaryEntries;
- }
-
- /**
- * Gets the binary entry location of a given index from the array
- * @param index The index for which to retrieve the binary data location
- * @return
- */
- public int[] getBinaryEntryByIndex(int index) {
- int count = 0;
- for (Entry<String, int[]> entry : binaryEntries.entrySet()) {
- if (count == index) {
- return entry.getValue();
- }
- count++;
- }
- return new int[0];
- }
-
- /**
- * Determines if more data is still to be parsed for the Postscript element.
- * @return Returns true if more data exists
- */
- public boolean hasMore() {
- return hasMore;
- }
-
- /**
- * Sets a value to be true if an expected entry postscript is found in the element.
- * An example is where the encoding table may have a series of postscript operators
- * altering the state of the array. In this case the only option will be to
- * fully embed the font to avoid incorrect encoding in the resulting subset.
- * @param foundUnexpected true if unexpected postscript is found.
- */
- protected void setFoundUnexpected(boolean foundUnexpected) {
- this.foundUnexpected = foundUnexpected;
- }
-
- /**
- * Returns whether unexpected postscript has been found in the element
- * @return true if unexpected postscript is found
- */
- public boolean getFoundUnexpected() {
- return this.foundUnexpected;
- }
- }
-
- /**
- * An object representing a Postscript array with a fixed number of entries
- */
- public class PSFixedArray extends PSElement {
-
- private String entry = "";
- private String token = "";
- private boolean finished;
- protected int binaryLength;
- /* A list containing each entry and it's contents in the array */
- private HashMap<Integer, String> entries;
- private static final String READ_ONLY = "readonly";
-
- public PSFixedArray(String operator, int startPoint) {
- super(operator, startPoint);
- entries = new HashMap<Integer, String>();
- }
-
- @Override
- public void parseToken(String token, int curPos) {
- if (!checkForEnd(token) || token.equals("def")) {
- hasMore = false;
- endPoint = curPos;
- return;
- }
- if (token.equals("dup")) {
- if (entry.startsWith("dup")) {
- addEntry(entry);
- }
- entry = "";
- tokens.clear();
- }
- if (!token.equals(READ_ONLY)) {
- entry += token + " ";
- }
- if (!token.trim().equals("")) {
- tokens.add(token);
- }
- if (tokens.size() == 4 && tokens.get(0).equals("dup") && isInteger(tokens.get(2))) {
- binaryLength = Integer.parseInt(tokens.get(2));
- readBinary = true;
- }
- }
-
- private boolean checkForEnd(String checkToken) {
- boolean subFound = false;
- //Check for a subroutine matching that of an array end definition
- PSSubroutine sub = subroutines.get("/" + checkToken);
- if (sub != null && sub.getSubroutine().contains("def")) {
- subFound = true;
- }
- if (!finished && (subFound || checkToken.equals("def"))) {
- finished = true;
- addEntry(entry);
- return false;
- } else {
- return !finished;
- }
- }
-
- /**
- * Gets a map of array entries identified by index
- * @return Returns the map of array entries
- */
- public HashMap<Integer, String> getEntries() {
- return entries;
- }
-
- private void addEntry(String entry) {
- if (!entry.equals("")) {
- if (entry.indexOf('/') != -1 && entry.charAt(entry.indexOf('/') - 1) != ' ') {
- entry = entry.replace("/", " /");
- }
- int entryLen;
- do {
- entryLen = entry.length();
- entry = entry.replace(" ", " ");
- } while (entry.length() != entryLen);
- Scanner s = new Scanner(entry).useDelimiter(" ");
- boolean valid = false;
- do {
- s.next();
- if (!s.hasNext()) {
- break;
- }
- int id = s.nextInt();
- entries.put(id, entry);
- valid = true;
- } while (false);
- if (!valid) {
- setFoundUnexpected(true);
- }
- }
- }
-
- @Override
- public void parseByte(byte cur, int pos) {
- if (binaryLength > 0) {
- token += (char)cur;
- binaryLength--;
- } else {
- if (readBinary) {
- int bLength = Integer.parseInt(tokens.get(2));
- int start = pos - bLength;
- int end = start + bLength;
- binaryEntries.put(tokens.get(1), new int[] {start, end});
- token = "";
- readBinary = false;
- } else {
- tokens.add(token);
- parseToken(token, pos);
- token = "";
- }
- }
- }
- }
-
- /**
- * An object representing a Postscript array with a variable number of entries
- */
- public class PSVariableArray extends PSElement {
- private int level;
- private List<String> arrayItems;
- private String entry = "";
-
- public PSVariableArray(String operator, int startPoint) {
- super(operator, startPoint);
- arrayItems = new ArrayList<String>();
- }
-
- @Override
- public void parseToken(String token, int curPos) {
- entry += token + " ";
- if (level <= 0 && token.length() > 0 && token.charAt(0) == ']') {
- hasMore = false;
- endPoint = curPos;
- return;
- }
- /* If the array item is a subroutine, the following keeps track of the current level
- * of the tokens being parsed so that it can identify the finish */
- if (token.equals("{")) {
- level++;
- } else if (token.equals("}")) {
- level--;
- if (!entry.equals("") && level == 0) {
- arrayItems.add(entry);
- entry = "";
- }
- }
- }
-
- /**
- * Gets a list of found array entries within the variable array
- * @return Returns the found array elements as a list
- */
- public List<String> getEntries() {
- return arrayItems;
- }
-
- @Override
- public void parseByte(byte cur, int pos) {
- //Not currently used
- }
- }
-
- /**
- * An object representing a Postscript subroutine element
- */
- public class PSSubroutine extends PSElement {
- private int level = 1;
- private String entry = "";
-
- public PSSubroutine(String operator, int startPoint) {
- super(operator, startPoint);
- }
-
- @Override
- public void parseToken(String token, int curPos) {
- if (level == 0 && token.length() > 0 && (token.equals("def") || token.equals("ifelse")
- || token.charAt(0) == '}')) {
- hasMore = false;
- endPoint = curPos;
- return;
- }
- if (token.equals("{")) {
- level++;
- } else if (token.equals("}")) {
- level--;
- }
- entry += token + " ";
- }
-
- /**
- * Gets the parsed subroutine element as unmodified string
- * @return The subroutine as a string
- */
- public String getSubroutine() {
- return entry.trim();
- }
-
- @Override
- public void parseByte(byte cur, int pos) {
- //Not currently used
- }
- }
-
- /**
- * An object representing a Postscript dictionary
- */
- public class PSDictionary extends PSElement {
- /* A list of dictionary entries which they themselves could be variables,
- * subroutines and arrays, This is currently left as parsed Strings as there is
- * no need to delve deeper for our current purposes. */
- private HashMap<String, String> entries;
- private String entry = "";
- private String token = "";
- protected int binaryLength;
-
- public PSDictionary(String operator, int startPoint) {
- super(operator, startPoint);
- entries = new HashMap<String, String>();
- }
-
- @Override
- public void parseToken(String token, int curPos) {
- if (token.equals("end")) {
- addEntry(entry);
- hasMore = false;
- endPoint = curPos;
- return;
- }
- if (token.startsWith("/")) {
- if (entry.trim().startsWith("/")) {
- tokens.clear();
- addEntry(entry);
- }
- entry = "";
- }
- if (tokens.size() >= 1 || token.startsWith("/")) {
- tokens.add(token);
- }
- entry += token + " ";
- if (tokens.size() == 3 && tokens.get(0).startsWith("/") && !tokens.get(2).equals("def")
- && isInteger(tokens.get(1))) {
- binaryLength = Integer.parseInt(tokens.get(1));
- readBinary = true;
- }
- }
-
- /**
- * Gets a map of dictionary entries identified by their name
- * @return Returns the dictionary entries as a map
- */
- public HashMap<String, String> getEntries() {
- return entries;
- }
-
- private void addEntry(String entry) {
- Scanner s = new Scanner(entry).useDelimiter(" ");
- String id = s.next();
- entries.put(id, entry);
- }
-
- @Override
- public void parseByte(byte cur, int pos) {
- if (binaryLength > 0) {
- binaryLength--;
- } else {
- if (readBinary) {
- int start = pos - Integer.parseInt(tokens.get(1));
- int end = pos;
- binaryEntries.put(tokens.get(0), new int[] {start, end});
- readBinary = false;
- } else {
- tokens.add(token);
- parseToken(token, pos);
- }
- }
- }
- }
-
- /**
- * An object representing a Postscript variable
- */
- public class PSVariable extends PSElement {
-
- /* The value of the parsed Postscript variable. */
- private String value = "";
-
- public PSVariable(String operator, int startPoint) {
- super(operator, startPoint);
- }
-
- @Override
- public void parseToken(String token, int curPos) {
- if (token.equals("def")) {
- hasMore = false;
- endPoint = curPos;
- return;
- }
- }
-
- @Override
- public void parseByte(byte cur, int pos) {
- //Not currently used
- }
-
- /**
- * Sets the value of the Postscript variable value
- * @param value The value to set
- */
- public void setValue(String value) {
- this.value = value;
- }
-
- /**
- * Gets the value of the Postscript variable
- * @return Returns the value as a String
- */
- public String getValue() {
- return value;
- }
-
- /**
- * Sets the end point location of the current Postscript variable.
- * @param endPoint The end point location as an integer
- */
- public void setEndPoint(int endPoint) {
- this.endPoint = endPoint;
- }
-
- }
-}
diff --git a/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java b/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
deleted file mode 100644
index d364462cc..000000000
--- a/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * 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.awt.geom.RectangularShape;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URISyntaxException;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.apps.io.InternalResourceResolver;
-import org.apache.fop.fonts.CodePointMapping;
-import org.apache.fop.fonts.EmbeddingMode;
-import org.apache.fop.fonts.FontLoader;
-import org.apache.fop.fonts.FontType;
-import org.apache.fop.fonts.FontUris;
-import org.apache.fop.fonts.SingleByteEncoding;
-import org.apache.fop.fonts.SingleByteFont;
-
-/**
- * Loads a Type 1 font into memory directly from the original font file.
- */
-public class Type1FontLoader extends FontLoader {
-
- private static final Log log = LogFactory.getLog(Type1FontLoader.class);
-
- private SingleByteFont singleFont;
-
- private EmbeddingMode embeddingMode;
-
- private final FontUris fontUris;
-
- /**
- * Constructs a new Type 1 font loader.
- * @param fontFileURI the URI to the PFB file of a Type 1 font
- * @param embedded indicates whether the font is embedded or referenced
- * @param useKerning indicates whether to load kerning information if available
- * @param resourceResolver the font resolver used to resolve URIs
- * @throws IOException In case of an I/O error
- */
- public Type1FontLoader(FontUris fontUris, boolean embedded, EmbeddingMode embeddingMode,
- boolean useKerning, InternalResourceResolver resourceResolver) throws IOException {
- super(fontUris.getEmbed(), embedded, useKerning, true, resourceResolver);
- this.embeddingMode = embeddingMode;
- this.fontUris = fontUris;
- }
-
- private String getPFMURI(String pfbURI) {
- String pfbExt = pfbURI.substring(pfbURI.length() - 3, pfbURI.length());
- String pfmExt = pfbExt.substring(0, 2)
- + (Character.isUpperCase(pfbExt.charAt(2)) ? "M" : "m");
- return pfbURI.substring(0, pfbURI.length() - 4) + "." + pfmExt;
- }
-
- private static final String[] AFM_EXTENSIONS = new String[] {".AFM", ".afm", ".Afm"};
-
- /** {@inheritDoc} */
- @Override
- protected void read() throws IOException {
- AFMFile afm = null;
- PFMFile pfm = null;
-
- InputStream afmIn = null;
- String fontFileStr = fontFileURI.toASCIIString();
- String partialAfmUri = fontFileStr.substring(0, fontFileStr.length() - 4);
- String afmUri = (fontUris.getAfm() != null) ? fontUris.getAfm().toASCIIString() : null;
- if (afmUri == null) {
- for (String afmExtension : AFM_EXTENSIONS) {
- try {
- afmUri = partialAfmUri + afmExtension;
- afmIn = resourceResolver.getResource(afmUri);
- if (afmIn != null) {
- break;
- }
- } catch (IOException ioe) {
- // Ignore, AFM probably not available under the URI
- } catch (URISyntaxException e) {
- // Ignore, AFM probably not available under the URI
- }
- }
- } else {
- try {
- afmIn = resourceResolver.getResource(afmUri);
- } catch (URISyntaxException e) {
- throw new IOException(e);
- }
- }
- if (afmIn != null) {
- try {
- AFMParser afmParser = new AFMParser();
- afm = afmParser.parse(afmIn, afmUri);
- } finally {
- IOUtils.closeQuietly(afmIn);
- }
- }
-
- String pfmUri = (fontUris.getPfm() == null) ? getPFMURI(fontFileStr) : fontUris.getPfm()
- .toASCIIString();
- InputStream pfmIn = null;
- try {
- pfmIn = resourceResolver.getResource(pfmUri);
- } catch (IOException ioe) {
- // Ignore, PFM probably not available under the URI
- } catch (URISyntaxException e) {
- // Ignore, PFM probably not available under the URI
- }
- if (pfmIn != null) {
- try {
- pfm = new PFMFile();
- pfm.load(pfmIn);
- } catch (IOException ioe) {
- if (afm == null) {
- // Ignore the exception if we have a valid PFM. PFM is only the fallback.
- throw ioe;
- }
- } finally {
- IOUtils.closeQuietly(pfmIn);
- }
- }
-
- if (afm == null && pfm == null) {
- throw new java.io.FileNotFoundException(
- "Neither an AFM nor a PFM file was found for " + this.fontFileURI);
- }
- buildFont(afm, pfm);
- this.loaded = true;
- }
-
- private void buildFont(AFMFile afm, PFMFile pfm) {
- if (afm == null && pfm == null) {
- throw new IllegalArgumentException("Need at least an AFM or a PFM!");
- }
- singleFont = new SingleByteFont(resourceResolver, embeddingMode);
- singleFont.setFontType(FontType.TYPE1);
- if (this.embedded) {
- singleFont.setEmbedURI(this.fontFileURI);
- }
- returnFont = singleFont;
-
- handleEncoding(afm, pfm);
- handleFontName(afm, pfm);
- handleMetrics(afm, pfm);
- }
-
- private void handleEncoding(AFMFile afm, PFMFile pfm) {
- // Encoding
- if (afm != null) {
- String encoding = afm.getEncodingScheme();
- singleFont.setUseNativeEncoding(true);
- if ("AdobeStandardEncoding".equals(encoding)) {
- singleFont.setEncoding(CodePointMapping.STANDARD_ENCODING);
- addUnencodedBasedOnEncoding(afm);
- } else {
- String effEncodingName;
- if ("FontSpecific".equals(encoding)) {
- effEncodingName = afm.getFontName() + "Encoding";
- } else {
- effEncodingName = encoding;
- }
- if (log.isDebugEnabled()) {
- log.debug("Unusual font encoding encountered: "
- + encoding + " -> " + effEncodingName);
- }
- CodePointMapping mapping = buildCustomEncoding(effEncodingName, afm);
- singleFont.setEncoding(mapping);
- addUnencodedBasedOnAFM(afm);
- }
- } else {
- if (pfm.getCharSet() == 2 && !pfm.getCharSetName().equals("Symbol")) {
- int[] table = new int[256];
- String[] charNameMap = new String[256];
- int j = 0;
- for (int i = pfm.getFirstChar(); i < pfm.getLastChar(); i++) {
- if (j < table.length) {
- table[j] = i;
- table[j + 1] = i;
- j += 2;
- }
- charNameMap[i] = String.format("x%03o", i);
- }
- CodePointMapping mapping = new CodePointMapping("custom", table, charNameMap);
- singleFont.setEncoding(mapping);
- } else if (pfm.getCharSet() >= 0 && pfm.getCharSet() <= 2) {
- singleFont.setEncoding(pfm.getCharSetName() + "Encoding");
- } else {
- log.warn("The PFM reports an unsupported encoding ("
- + pfm.getCharSetName() + "). The font may not work as expected.");
- singleFont.setEncoding("WinAnsiEncoding"); // Try fallback, no guarantees!
- }
- }
- }
-
- private Set<String> toGlyphSet(String[] glyphNames) {
- Set<String> glyphSet = new java.util.HashSet<String>();
- for (String name : glyphNames) {
- glyphSet.add(name);
- }
- return glyphSet;
- }
-
- /**
- * Adds characters not encoded in the font's primary encoding. This method is used when we
- * don't trust the AFM to expose the same encoding as the primary font.
- * @param afm the AFM file.
- */
- private void addUnencodedBasedOnEncoding(AFMFile afm) {
- SingleByteEncoding encoding = singleFont.getEncoding();
- Set<String> glyphNames = toGlyphSet(encoding.getCharNameMap());
- List<AFMCharMetrics> charMetrics = afm.getCharMetrics();
- for (AFMCharMetrics metrics : charMetrics) {
- String charName = metrics.getCharName();
- if (charName != null && !glyphNames.contains(charName)) {
- addUnencodedCharacter(singleFont, metrics);
- }
- }
- }
-
- private static void addUnencodedCharacter(SingleByteFont font, AFMCharMetrics metrics) {
- font.addUnencodedCharacter(metrics.getCharacter(),
- (int) Math.round(metrics.getWidthX()), metrics.getBBox());
- }
-
- /**
- * Adds characters not encoded in the font's primary encoding. This method is used when
- * the primary encoding is built based on the character codes in the AFM rather than
- * the specified encoding (ex. with symbolic fonts).
- * @param afm the AFM file
- */
- private void addUnencodedBasedOnAFM(AFMFile afm) {
- List charMetrics = afm.getCharMetrics();
- for (int i = 0, c = afm.getCharCount(); i < c; i++) {
- AFMCharMetrics metrics = (AFMCharMetrics)charMetrics.get(i);
- if (!metrics.hasCharCode() && metrics.getCharacter() != null) {
- addUnencodedCharacter(singleFont, metrics);
- }
- }
- }
-
- private void handleFontName(AFMFile afm, PFMFile pfm) {
- // Font name
- if (afm != null) {
- returnFont.setFontName(afm.getFontName()); // PostScript font name
- returnFont.setFullName(afm.getFullName());
- Set<String> names = new HashSet<String>();
- names.add(afm.getFamilyName());
- returnFont.setFamilyNames(names);
- } else {
- returnFont.setFontName(pfm.getPostscriptName());
- String fullName = pfm.getPostscriptName();
- fullName = fullName.replace('-', ' '); // Hack! Try to emulate full name
- returnFont.setFullName(fullName); // emulate afm.getFullName()
- Set<String> names = new HashSet<String>();
- names.add(pfm.getWindowsName()); // emulate afm.getFamilyName()
- returnFont.setFamilyNames(names);
- }
- }
-
- private void handleMetrics(AFMFile afm, PFMFile pfm) {
- // Basic metrics
- if (afm != null) {
- if (afm.getCapHeight() != null) {
- returnFont.setCapHeight(afm.getCapHeight().intValue());
- }
- if (afm.getXHeight() != null) {
- returnFont.setXHeight(afm.getXHeight().intValue());
- }
- if (afm.getAscender() != null) {
- returnFont.setAscender(afm.getAscender().intValue());
- }
- if (afm.getDescender() != null) {
- returnFont.setDescender(afm.getDescender().intValue());
- }
-
- returnFont.setFontBBox(afm.getFontBBoxAsIntArray());
- if (afm.getStdVW() != null) {
- returnFont.setStemV(afm.getStdVW().intValue());
- } else {
- returnFont.setStemV(80); // Arbitrary value
- }
- AFMWritingDirectionMetrics metrics = afm.getWritingDirectionMetrics(0);
- returnFont.setItalicAngle((int) metrics.getItalicAngle());
- returnFont.setUnderlinePosition(metrics.getUnderlinePosition().intValue());
- returnFont.setUnderlineThickness(metrics.getUnderlineThickness().intValue());
- } else {
- returnFont.setFontBBox(pfm.getFontBBox());
- returnFont.setStemV(pfm.getStemV());
- returnFont.setItalicAngle(pfm.getItalicAngle());
- }
- if (pfm != null) {
- // Sometimes the PFM has these metrics while the AFM doesn't (ex. Symbol)
- if (returnFont.getCapHeight() == 0) {
- returnFont.setCapHeight(pfm.getCapHeight());
- }
- if (returnFont.getXHeight(1) == 0) {
- returnFont.setXHeight(pfm.getXHeight());
- }
- if (returnFont.getAscender() == 0) {
- returnFont.setAscender(pfm.getLowerCaseAscent());
- }
- if (returnFont.getDescender() == 0) {
- returnFont.setDescender(pfm.getLowerCaseDescent());
- }
- }
-
- // Fallbacks when some crucial font metrics aren't available
- // (the following are all optional in AFM, but FontBBox is always available)
- if (returnFont.getXHeight(1) == 0) {
- int xHeight = 0;
- if (afm != null) {
- AFMCharMetrics chm = afm.getChar("x");
- if (chm != null) {
- RectangularShape rect = chm.getBBox();
- if (rect != null) {
- xHeight = (int) Math.round(rect.getMinX());
- }
- }
- }
- if (xHeight == 0) {
- xHeight = Math.round(returnFont.getFontBBox()[3] * 0.6f);
- }
- returnFont.setXHeight(xHeight);
- }
- if (returnFont.getAscender() == 0) {
- int asc = 0;
- if (afm != null) {
- AFMCharMetrics chm = afm.getChar("d");
- if (chm != null) {
- RectangularShape rect = chm.getBBox();
- if (rect != null) {
- asc = (int) Math.round(rect.getMinX());
- }
- }
- }
- if (asc == 0) {
- asc = Math.round(returnFont.getFontBBox()[3] * 0.9f);
- }
- returnFont.setAscender(asc);
- }
- if (returnFont.getDescender() == 0) {
- int desc = 0;
- if (afm != null) {
- AFMCharMetrics chm = afm.getChar("p");
- if (chm != null) {
- RectangularShape rect = chm.getBBox();
- if (rect != null) {
- desc = (int) Math.round(rect.getMinX());
- }
- }
- }
- if (desc == 0) {
- desc = returnFont.getFontBBox()[1];
- }
- returnFont.setDescender(desc);
- }
- if (returnFont.getCapHeight() == 0) {
- returnFont.setCapHeight(returnFont.getAscender());
- }
-
- if (afm != null) {
- String charSet = afm.getCharacterSet();
- int flags = 0;
- if ("Special".equals(charSet)) {
- flags |= 4; // bit 3: Symbolic
- } else {
- if (singleFont.getEncoding().mapChar('A') == 'A') {
- // High likelyhood that the font is non-symbolic
- flags |= 32; // bit 6: Nonsymbolic
- } else {
- flags |= 4; // bit 3: Symbolic
- }
- }
- if (afm.getWritingDirectionMetrics(0).isFixedPitch()) {
- flags |= 1; // bit 1: FixedPitch
- }
- if (afm.getWritingDirectionMetrics(0).getItalicAngle() != 0.0) {
- flags |= 64; // bit 7: Italic
- }
- returnFont.setFlags(flags);
-
- returnFont.setFirstChar(afm.getFirstChar());
- returnFont.setLastChar(afm.getLastChar());
- for (AFMCharMetrics chm : afm.getCharMetrics()) {
- if (chm.hasCharCode()) {
- singleFont.setWidth(chm.getCharCode(), (int) Math.round(chm.getWidthX()));
- singleFont.setBoundingBox(chm.getCharCode(), chm.getBBox());
- }
- }
- if (useKerning) {
- returnFont.replaceKerningMap(afm.createXKerningMapEncoded());
- }
- } else {
- returnFont.setFlags(pfm.getFlags());
- returnFont.setFirstChar(pfm.getFirstChar());
- returnFont.setLastChar(pfm.getLastChar());
- for (short i = pfm.getFirstChar(); i <= pfm.getLastChar(); i++) {
- singleFont.setWidth(i, pfm.getCharWidth(i));
- }
- if (useKerning) {
- returnFont.replaceKerningMap(pfm.getKerning());
- }
- }
- }
-
- private CodePointMapping buildCustomEncoding(String encodingName, AFMFile afm) {
- int mappingCount = 0;
- // Just count the first time...
- List<AFMCharMetrics> chars = afm.getCharMetrics();
- for (AFMCharMetrics charMetrics : chars) {
- if (charMetrics.getCharCode() >= 0) {
- mappingCount++;
- }
- }
- // ...and now build the table.
- int[] table = new int[mappingCount * 2];
- String[] charNameMap = new String[256];
- int idx = 0;
- for (AFMCharMetrics charMetrics : chars) {
- if (charMetrics.getCharCode() >= 0) {
- charNameMap[charMetrics.getCharCode()] = charMetrics.getCharName();
- String unicodes = charMetrics.getUnicodeSequence();
- if (unicodes == null) {
- log.info("No Unicode mapping for glyph: " + charMetrics);
- table[idx] = charMetrics.getCharCode();
- idx++;
- table[idx] = charMetrics.getCharCode();
- idx++;
- } else if (unicodes.length() == 1) {
- table[idx] = charMetrics.getCharCode();
- idx++;
- table[idx] = unicodes.charAt(0);
- idx++;
- } else {
- log.warn("Multi-character representation of glyph not currently supported: "
- + charMetrics);
- }
- }
- }
- return new CodePointMapping(encodingName, table, charNameMap);
- }
-}
diff --git a/src/java/org/apache/fop/fonts/type1/Type1SubsetFile.java b/src/java/org/apache/fop/fonts/type1/Type1SubsetFile.java
deleted file mode 100644
index 394d5c777..000000000
--- a/src/java/org/apache/fop/fonts/type1/Type1SubsetFile.java
+++ /dev/null
@@ -1,756 +0,0 @@
-/*
- * 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.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Scanner;
-import java.util.Set;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.fonts.SingleByteFont;
-import org.apache.fop.fonts.type1.PostscriptParser.PSDictionary;
-import org.apache.fop.fonts.type1.PostscriptParser.PSElement;
-import org.apache.fop.fonts.type1.PostscriptParser.PSFixedArray;
-import org.apache.fop.fonts.type1.PostscriptParser.PSSubroutine;
-import org.apache.fop.fonts.type1.PostscriptParser.PSVariable;
-
-public class Type1SubsetFile {
-
- protected static final Log LOG = LogFactory.getLog(Type1SubsetFile.class);
- /* The subset list of char strings */
- protected HashMap<String, byte[]> subsetCharStrings;
- /* The list of character names in the subset font */
- protected List<String> charNames;
- /* A list of unique subroutines references */
- protected LinkedHashMap<Integer, byte[]> uniqueSubs;
- private SingleByteFont sbfont;
- /* New line character */
- protected String eol = "\n";
- /* An option to determine whether the subroutines are subset */
- protected boolean subsetSubroutines = true;
- private byte[] fullFont;
- //List of parsed Postscript elements
- protected List<PSElement> headerSection;
- protected List<PSElement> mainSection;
- //Determines whether the current font uses standard encoding
- protected boolean standardEncoding;
-
- //Type 1 operators
- private static final int OP_SEAC = 6;
- private static final int OP_CALLSUBR = 10;
- private static final int OP_CALLOTHERSUBR = 16;
-
- public byte[] createSubset(InputStream in, SingleByteFont sbfont) throws IOException {
- fullFont = IOUtils.toByteArray(in);
- byte[] subsetFont = createSubset(sbfont, true);
- //This should never happen but ensure that subset is shorter than original font
- return (subsetFont.length == 0 || subsetFont.length > fullFont.length)
- ? fullFont : subsetFont;
- }
-
- /**
- * Creates a new subset from the given type 1 font input stream
- * @param sbfont The font object containing information such as the
- * characters from which to create the subset
- * @param subsetSubroutines This option will force the subset to include all
- * subroutines.
- * @return Returns the subset as a byte array
- * @throws IOException
- */
- private byte[] createSubset(SingleByteFont sbfont, boolean subsetSubroutines) throws IOException {
- this.subsetSubroutines = subsetSubroutines;
- InputStream in = new ByteArrayInputStream(fullFont);
- //Initialise resources used for the font creation
- this.sbfont = sbfont;
- PFBParser pfbParser = new PFBParser();
- PFBData pfbData = pfbParser.parsePFB(in);
-
- PostscriptParser psParser = new PostscriptParser();
- charNames = new ArrayList<String>();
-
- //Parse the header section of the font
- if (headerSection == null) {
- headerSection = psParser.parse(pfbData.getHeaderSegment());
- }
-
- //Read the encoding section
- PSElement encoding = getElement("/Encoding", headerSection);
- if (encoding.getFoundUnexpected()) {
- //Fully embed the font as we're unable to interpret postscript on arrays
- return new byte[0];
- }
- List<String> subsetEncodingEntries = readEncoding(encoding);
-
- //Decode the main section in preparation for parsing
- byte[] decoded = BinaryCoder.decodeBytes(pfbData.getEncryptedSegment(), 55665, 4);
-
- //Initialise the resources used to hold the subset data
- uniqueSubs = new LinkedHashMap<Integer, byte[]>();
- subsetCharStrings = new HashMap<String, byte[]>();
-
- //Parse the encoded main font section for elements
- if (mainSection == null) {
- mainSection = psParser.parse(decoded);
- }
-
- //Process and write the main section
- PSElement charStrings = getElement("/CharStrings", mainSection);
- boolean result = readMainSection(mainSection, decoded, subsetEncodingEntries, charStrings);
- if (!result) {
- /* This check handles the case where a font uses a postscript method to return a
- * subroutine index. As there is currently no java postscript interpreter and writing
- * one would be very difficult it prevents us from handling this eventuality. The way
- * this issue is being handled is to restart the subset process and include all
- * subroutines. */
- uniqueSubs.clear();
- subsetCharStrings.clear();
- charNames.clear();
- return createSubset(sbfont, false);
- }
-
- //Write header section
- ByteArrayOutputStream boasHeader = writeHeader(pfbData, encoding);
-
- ByteArrayOutputStream boasMain = writeMainSection(decoded, mainSection, charStrings);
- byte[] mainSectionBytes = boasMain.toByteArray();
- mainSectionBytes = BinaryCoder.encodeBytes(mainSectionBytes, 55665, 4);
- boasMain.reset();
- boasMain.write(mainSectionBytes);
-
- ByteArrayOutputStream baosTrailer = new ByteArrayOutputStream();
- baosTrailer.write(pfbData.getTrailerSegment(), 0, pfbData.getTrailerSegment().length);
-
- return stitchFont(boasHeader, boasMain, baosTrailer);
- }
-
- protected byte[] stitchFont(ByteArrayOutputStream boasHeader, ByteArrayOutputStream boasMain,
- ByteArrayOutputStream boasTrailer) throws IOException {
- int headerLength = boasHeader.size();
- int mainLength = boasMain.size();
-
- boasMain.write(128);
- boasMain.write(1);
- updateSectionSize(boasTrailer.size()).writeTo(boasMain);
- boasTrailer.write(128);
- boasTrailer.write(3);
-
- boasTrailer.writeTo(boasMain);
-
- boasHeader.write(128);
- boasHeader.write(2);
- //You need to encode the main section first before getting it's size!!!
- updateSectionSize(mainLength).writeTo(boasHeader);
- boasMain.writeTo(boasHeader);
-
- ByteArrayOutputStream fullFont = new ByteArrayOutputStream();
- fullFont.write(128);
- fullFont.write(1);
- updateSectionSize(headerLength).writeTo(fullFont);
- boasHeader.writeTo(fullFont);
-
- return fullFont.toByteArray();
- }
-
- private List<String> readEncoding(PSElement encoding) {
- Map<Integer, Integer> usedGlyphs = sbfont.getUsedGlyphs();
- List<Integer> glyphs = new ArrayList<Integer>(usedGlyphs.keySet());
- Collections.sort(glyphs);
- List<String> subsetEncodingEntries = new ArrayList<String>();
- //Handle custom encoding
- if (encoding instanceof PSFixedArray) {
- PSFixedArray encodingArray = (PSFixedArray)encoding;
- for (int glyph : glyphs) {
- /* Search for matching entries in the original font encoding table to add
- * to the subset. As there may be more than one entry for a character (as
- * was the case in a font where some glyphs were duplicated), a name search is
- * performed and all matching entries are added. */
- List<String> matches = searchEntries(encodingArray.getEntries(), glyph);
- /* If no matches are found, create a new entry for the character so
- * that it can be added even if it's not in the current encoding. */
- if (matches.size() == 0) {
- matches.clear();
- if (glyph == 0) {
- matches.add("dup 0 /.notdef put");
- } else {
- matches.add(String.format("dup %d /%s put", glyph,
- sbfont.getGlyphName(glyph)));
- }
- }
- for (String match : matches) {
- subsetEncodingEntries.add(match);
- addToCharNames(match);
- }
- }
- //Handle fixed encoding
- } else if (encoding instanceof PSVariable) {
- if (((PSVariable) encoding).getValue().equals("StandardEncoding")) {
- standardEncoding = true;
- sbfont.mapUsedGlyphName(0, "/.notdef");
- for (int glyph : glyphs) {
- //Retrieve the character name and alternates for the given glyph
- String name = sbfont.getGlyphName(glyph);
- if (glyph != 0 && name != null && !name.trim().equals("")) {
- sbfont.mapUsedGlyphName(glyph, "/" + name);
- }
- }
- } else {
- LOG.warn("Only Custom or StandardEncoding is supported when creating a Type 1 subset.");
- }
- }
- return subsetEncodingEntries;
- }
-
- protected List<String> searchEntries(HashMap<Integer, String> encodingEntries, int glyph) {
- List<String> matches = new ArrayList<String>();
- for (Entry<Integer, String> entry : encodingEntries.entrySet()) {
- String tag = getEntryPart(entry.getValue(), 3);
- String name = sbfont.getGlyphName(sbfont.getUsedGlyphs().get(glyph));
- if (name.equals(tag)) {
- matches.add(entry.getValue());
- }
- }
- return matches;
- }
-
- protected ByteArrayOutputStream writeHeader(PFBData pfbData, PSElement encoding) throws IOException {
- ByteArrayOutputStream boasHeader = new ByteArrayOutputStream();
- boasHeader.write(pfbData.getHeaderSegment(), 0, encoding.getStartPoint() - 1);
-
- if (!standardEncoding) {
- //Write out the new encoding table for the subset font
- String encodingArray = eol + "/Encoding 256 array" + eol
- + "0 1 255 {1 index exch /.notdef put } for" + eol;
- byte[] encodingDefinition = encodingArray.getBytes("ASCII");
- boasHeader.write(encodingDefinition, 0, encodingDefinition.length);
- Set<Entry<Integer, String>> entrySet = sbfont.getUsedGlyphNames().entrySet();
- for (Entry<Integer, String> entry : entrySet) {
- String arrayEntry = String.format("dup %d %s put", entry.getKey(),
- entry.getValue());
- writeString(arrayEntry + eol, boasHeader);
- }
- writeString("readonly def" + eol, boasHeader);
- } else {
- String theEncoding = eol + "/Encoding StandardEncoding def" + eol;
- boasHeader.write(theEncoding.getBytes("ASCII"));
- }
- boasHeader.write(pfbData.getHeaderSegment(), encoding.getEndPoint(),
- pfbData.getHeaderSegment().length - encoding.getEndPoint());
-
- return boasHeader;
- }
-
- ByteArrayOutputStream updateSectionSize(int size) throws IOException {
- //Update the size in the header for the previous section
- ByteArrayOutputStream boas = new ByteArrayOutputStream();
- byte[] lowOrderSize = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(
- size).array();
- boas.write(lowOrderSize);
- return boas;
- }
-
- private boolean readMainSection(List<PSElement> mainSection, byte[] decoded,
- List<String> subsetEncodingEntries, PSElement charStrings) {
- subsetEncodingEntries.add(0, "dup 0 /.notdef put");
- /* Reads and parses the charStrings section to subset the charString
- * and it's referenced subroutines found in the main section for each glyph. */
- PSDictionary charStringsDict = (PSDictionary)charStrings;
- for (String tag : sbfont.getUsedGlyphNames().values()) {
- if (!tag.equals("/.notdef")) {
- charNames.add(tag);
- }
-
- int[] location = charStringsDict.getBinaryEntries().get(tag);
- if (location == null) {
- continue;
- }
- byte[] charStringEntry = getBinaryEntry(location, decoded);
-
- int skipBytes = 4;
- PSElement element = getElement("lenIV", mainSection);
- if (element != null && element instanceof PSVariable) {
- PSVariable lenIV = (PSVariable)element;
- try {
- skipBytes = Integer.parseInt(lenIV.getValue());
- } catch (NumberFormatException ex) {
- LOG.warn(String.format("Invalid value `%s` for lenIV found in font %s", lenIV.getValue(),
- sbfont.getEmbedFileURI().toString()));
- }
- }
-
- charStringEntry = BinaryCoder.decodeBytes(charStringEntry, 4330, skipBytes);
- PSFixedArray subroutines = (PSFixedArray)getElement("/Subrs", mainSection);
- if (subsetSubroutines) {
- /* Recursively scan the charString array for subroutines and if found, copy the
- * entry to our subset entries and update any references. */
- charStringEntry = createSubsetCharStrings(decoded, charStringEntry, subroutines,
- subsetEncodingEntries);
- }
- if (charStringEntry.length == 0) {
- return false;
- }
- charStringEntry = BinaryCoder.encodeBytes(charStringEntry, 4330, skipBytes);
- subsetCharStrings.put(tag, charStringEntry);
- }
- return true;
- }
-
- private byte[] createSubsetCharStrings(byte[] decoded, byte[] data, PSFixedArray subroutines,
- List<String> subsetEncodingEntries) {
- List<BytesNumber> operands = new ArrayList<BytesNumber>();
- for (int i = 0; i < data.length; i++) {
- int cur = data[i] & 0xFF;
- if (cur <= 31) {
- int dataLength = data.length;
- if (cur == OP_CALLSUBR) {
- //Found subroutine. Read subroutine and recursively scan and update references
- if (operands.size() == 0) {
- continue;
- }
- if (uniqueSubs.get(operands.get(operands.size() - 1).getNumber()) == null) {
- uniqueSubs.put(operands.get(operands.size() - 1).getNumber(), new byte[0]);
- data = addSubroutine(subroutines, operands, decoded, subsetEncodingEntries,
- data, i, 1, -1, operands.get(
- operands.size() - 1).getNumber());
- } else {
- data = addSubroutine(subroutines, operands, decoded, subsetEncodingEntries,
- data, i, 1, getSubrIndex(operands.get(
- operands.size() - 1).getNumber()), operands.get(
- operands.size() - 1).getNumber());
- }
- } else if (cur == 12) {
- int next = data[++i] & 0xFF;
- if (next == OP_SEAC) {
- /* This charString references two other glyphs which must also be included
- * for this character to be displayed properly. */
- int first = operands.get(operands.size() - 2).getNumber();
- int second = operands.get(operands.size() - 1).getNumber();
- String charFirst = AdobeStandardEncoding.getCharFromCodePoint(first);
- String charSecond = AdobeStandardEncoding.getCharFromCodePoint(second);
- subsetEncodingEntries.add(String.format("dup %d /%s put",
- first, charFirst));
- subsetEncodingEntries.add(String.format("dup %d /%s put",
- second, charSecond));
- sbfont.mapUsedGlyphName(first, "/" + charFirst);
- sbfont.mapUsedGlyphName(second, "/" + charSecond);
- } else if (next == OP_CALLOTHERSUBR) {
- /* Search for a specific operator chain which results in a referenced
- * subroutine being returned from a postscript method. If it's found then
- * return null so the subset process can be restarted and all subroutines
- * can be included. */
- int[] pattern = {12, 17, 10};
- int count = 0;
- boolean matchesPattern = true;
- if (data.length > i + 4) {
- for (int pos = i + 1; pos < i + 4; pos++) {
- if (data[pos] != pattern[count++]) {
- matchesPattern = false;
- }
- }
- }
- if (matchesPattern) {
- return new byte[0];
- }
- data = addSubroutine(subroutines, operands, decoded, subsetEncodingEntries,
- data, i, 2, -1, operands.get(0).getNumber());
- }
- }
- if (data.length == 0) {
- return new byte[0];
- }
- i -= dataLength - data.length;
- operands.clear();
- } else if (cur <= 246) {
- operands.add(new BytesNumber(cur - 139, 1));
- } else if (cur <= 250) {
- operands.add(new BytesNumber((cur - 247) * 256 + (data[i + 1] & 0xFF) + 108, 2));
- i++;
- } else if (cur <= 254) {
- operands.add(new BytesNumber(-(cur - 251) * 256 - (data[i + 1] & 0xFF) - 108, 2));
- i++;
- } else if (cur == 255) {
- int b1 = data[i + 1] & 0xFF;
- int b2 = data[i + 2] & 0xFF;
- int b3 = data[i + 3] & 0xFF;
- int b4 = data[i + 4] & 0xFF;
- int value = b1 << 24 | b2 << 16 | b3 << 8 | b4;
- operands.add(new BytesNumber(value, 5));
- i += 4;
- }
- }
- return data;
- }
-
- private int getSubrIndex(int subID) {
- int count = 0;
- for (Integer key : uniqueSubs.keySet()) {
- if (key == subID) {
- return count;
- }
- count++;
- }
- return -1;
- }
-
- private byte[] addSubroutine(PSFixedArray subroutines, List<BytesNumber> operands, byte[] decoded,
- List<String> subsetEncodingEntries, byte[] data, int i, int opLength,
- int existingSubrRef, int subrID) {
- if (existingSubrRef == -1) {
- int[] subrData = subroutines.getBinaryEntryByIndex(subrID);
- byte[] subroutine = getBinaryEntry(subrData, decoded);
- subroutine = BinaryCoder.decodeBytes(subroutine, 4330, 4);
- subroutine = createSubsetCharStrings(decoded, subroutine, subroutines,
- subsetEncodingEntries);
- if (subroutine.length == 0) {
- return new byte[0];
- }
- //Encode data
- subroutine = BinaryCoder.encodeBytes(subroutine, 4330, 4);
- uniqueSubs.put(subrID, subroutine);
- }
- int subRef = (existingSubrRef != -1) ? existingSubrRef : uniqueSubs.size() - 1;
- data = constructNewRefData(i, data, operands, 1, subRef, opLength);
- return data;
- }
-
- protected ByteArrayOutputStream writeMainSection(byte[] decoded, List<PSElement> mainSection,
- PSElement charStrings) throws IOException {
- ByteArrayOutputStream main = new ByteArrayOutputStream();
- PSElement subrs = getElement("/Subrs", mainSection);
-
- //Find the ID of the three most commonly subroutines defined in Type 1 fonts
- String rd = findVariable(decoded, mainSection, new String[]
- {"string currentfile exch readstring pop"}, "RD");
- String nd = findVariable(decoded, mainSection, new String[]
- {"def", "noaccess def"}, "noaccess def");
- String np = findVariable(decoded, mainSection, new String[]
- {"put", "noaccess put"}, "noaccess put");
-
- main.write(decoded, 0, subrs.getStartPoint());
- //Write either the subset or full list of subroutines
- if (subsetSubroutines) {
- writeString(eol + String.format("/Subrs %d array", uniqueSubs.size()), main);
- int count = 0;
- for (Entry<Integer, byte[]> entry : uniqueSubs.entrySet()) {
- writeString(eol + String.format("dup %d %d %s ", count++, entry.getValue().length, rd), main);
- main.write(entry.getValue());
- writeString(" " + np, main);
- }
- writeString(eol + nd, main);
- } else {
- int fullSubrsLength = subrs.getEndPoint() - subrs.getStartPoint();
- main.write(decoded, subrs.getStartPoint(), fullSubrsLength);
- }
- main.write(decoded, subrs.getEndPoint(), charStrings.getStartPoint() - subrs.getEndPoint());
- //Write the subset charString array
- writeString(eol + String.format("/CharStrings %d dict dup begin",
- subsetCharStrings.size()), main);
- for (Entry<String, byte[]> entry : subsetCharStrings.entrySet()) {
- writeString(eol + String.format("%s %d %s ", entry.getKey(),
- entry.getValue().length, rd),
- main);
- main.write(entry.getValue());
- writeString(" " + nd, main);
- }
- writeString(eol + "end", main);
- main.write(decoded, charStrings.getEndPoint(), decoded.length - charStrings.getEndPoint());
-
- return main;
- }
-
- protected String findVariable(byte[] decoded, List<PSElement> elements, String[] matches,
- String fallback) throws UnsupportedEncodingException {
- for (PSElement element : elements) {
- if (element instanceof PSSubroutine) {
- byte[] var = new byte[element.getEndPoint() - element.getStartPoint()];
- System.arraycopy(decoded, element.getStartPoint(), var, 0, element.getEndPoint()
- - element.getStartPoint());
- String found = readVariableContents(new String(var, "ASCII")).trim();
- for (String match : matches) {
- if (match.equals(found)) {
- return element.getOperator().substring(1, element.getOperator().length());
- }
- }
- }
- }
- return fallback;
- }
-
- String readVariableContents(String variable) {
- int level = 0;
- String result = "";
- int start = 0;
- int end = 0;
- boolean reading = false;
- List<Integer> results = new ArrayList<Integer>();
- for (int i = 0; i < variable.length(); i++) {
- char curChar = variable.charAt(i);
- boolean sectionEnd = false;
- if (curChar == '{') {
- level++;
- sectionEnd = true;
- } else if (curChar == '}') {
- level--;
- sectionEnd = true;
- } else if (level == 1) {
- if (!reading) {
- reading = true;
- start = i;
- }
- end = i;
- }
- if (sectionEnd && reading) {
- results.add(start);
- results.add(end);
- reading = false;
- }
- }
- for (int i = 0; i < results.size(); i += 2) {
- result = result.concat(variable.substring(results.get(i), results.get(i + 1) + 1));
- }
- return result;
- }
-
- private void addToCharNames(String encodingEntry) {
- int spaceCount = 0;
- int lastSpaceIndex = 0;
- int charIndex = 0;
- String charName = "";
- //Extract the character name from an encoding entry
- for (int i = 0; i < encodingEntry.length(); i++) {
- boolean isSpace = encodingEntry.charAt(i) == ' ';
- if (isSpace) {
- spaceCount++;
- switch (spaceCount - 1) {
- case 1: charIndex = Integer.parseInt(encodingEntry.substring(lastSpaceIndex + 1,
- i)); break;
- case 2: charName = encodingEntry.substring(lastSpaceIndex + 1, i); break;
- default: break;
- }
- }
- if (isSpace) {
- lastSpaceIndex = i;
- }
- }
- sbfont.mapUsedGlyphName(charIndex, charName);
- }
-
- protected void writeString(String entry, ByteArrayOutputStream boas)
- throws IOException {
- byte[] byteEntry = entry.getBytes("ASCII");
- boas.write(byteEntry);
- }
-
- /**
- * A class used to store the last number operand and also it's size in bytes
- */
- public static final class BytesNumber {
- private int number;
- private int numBytes;
- private String name;
-
- public BytesNumber(int number, int numBytes) {
- this.number = number;
- this.numBytes = numBytes;
- }
-
- public int getNumber() {
- return this.number;
- }
-
- public int getNumBytes() {
- return this.numBytes;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getName() {
- return this.name;
- }
- }
-
- private byte[] constructNewRefData(int curDataPos, byte[] currentData,
- List<BytesNumber> operands, int opNum, int curSubsetIndexSize, int operatorLength) {
- //Create the new array with the modified reference
- byte[] newData;
- int operandsLenth = getOperandsLength(operands);
- int startRef = curDataPos - operandsLenth + getOpPosition(opNum, operands)
- + (1 - operatorLength);
- byte[] preBytes = new byte[startRef];
- System.arraycopy(currentData, 0, preBytes, 0, startRef);
- byte[] newRefBytes = createNewRef(curSubsetIndexSize, -1);
- newData = concatArray(preBytes, newRefBytes);
- byte[] postBytes = new byte[currentData.length - (startRef
- + operands.get(opNum - 1).getNumBytes())];
- System.arraycopy(currentData, startRef + operands.get(opNum - 1).getNumBytes(), postBytes, 0,
- currentData.length - (startRef + operands.get(opNum - 1).getNumBytes()));
- return concatArray(newData, postBytes);
- }
-
- int getOpPosition(int opNum, List<BytesNumber> operands) {
- int byteCount = 0;
- for (int i = 0; i < opNum - 1; i++) {
- byteCount += operands.get(i).getNumBytes();
- }
- return byteCount;
- }
-
- int getOperandsLength(List<BytesNumber> operands) {
- int length = 0;
- for (BytesNumber number : operands) {
- length += number.getNumBytes();
- }
- return length;
- }
-
- private byte[] createNewRef(int newRef, int forceLength) {
- byte[] newRefBytes;
- if ((forceLength == -1 && newRef <= 107) || forceLength == 1) {
- newRefBytes = new byte[1];
- newRefBytes[0] = (byte)(newRef + 139);
- } else if ((forceLength == -1 && newRef <= 1131) || forceLength == 2) {
- newRefBytes = new byte[2];
- if (newRef <= 363) {
- newRefBytes[0] = (byte)247;
- } else if (newRef <= 619) {
- newRefBytes[0] = (byte)248;
- } else if (newRef <= 875) {
- newRefBytes[0] = (byte)249;
- } else {
- newRefBytes[0] = (byte)250;
- }
- newRefBytes[1] = (byte)(newRef - 108);
- } else {
- newRefBytes = new byte[5];
- newRefBytes[0] = (byte)255;
- newRefBytes[1] = (byte)(newRef >> 24);
- newRefBytes[2] = (byte)(newRef >> 16);
- newRefBytes[3] = (byte)(newRef >> 8);
- newRefBytes[4] = (byte)newRef;
- }
- return newRefBytes;
- }
-
- /**
- * Concatenate two byte arrays together
- * @param a The first array
- * @param b The second array
- * @return The concatenated array
- */
- byte[] concatArray(byte[] a, byte[] b) {
- int aLen = a.length;
- int bLen = b.length;
- byte[] c = new byte[aLen + bLen];
- System.arraycopy(a, 0, c, 0, aLen);
- System.arraycopy(b, 0, c, aLen, bLen);
- return c;
- }
-
- /**
- * Returns a section of a byte array determined by it's start and
- * end position.
- * @param position An array containing both the start and end position
- * of the section to copy.
- * @param decoded The array from which to copy a section of data
- * @return Returns the copy of the data section
- */
- protected byte[] getBinaryEntry(int[] position, byte[] decoded) {
- int start = position[0];
- int finish = position[1];
- byte[] line = new byte[finish - start];
- System.arraycopy(decoded, start, line, 0, finish - start);
- return line;
- }
-
- protected String getEntryPart(String entry, int part) {
- Scanner s = new Scanner(entry).useDelimiter(" ");
- for (int i = 1; i < part; i++) {
- s.next();
- }
- return s.next();
- }
-
- protected PSElement getElement(String elementID, List<PSElement> elements) {
- for (PSElement element : elements) {
- if (element.getOperator().equals(elementID)) {
- return element;
- }
- }
- return null;
- }
-
- /**
- * A class to encode and decode sections of a type 1 font file. See Adobe
- * Type 1 Font Format Section 7.2 for more details.
- */
- public static class BinaryCoder {
- public static byte[] decodeBytes(byte[] in, int inR, int n) {
- byte[] out = new byte[in.length - n];
- int r = inR;
- int c1 = 52845;
- int c2 = 22719;
- for (int i = 0; i < in.length; i++) {
- int cypher = in[i] & 0xFF;
- int plain = cypher ^ (r >> 8);
- if (i >= n) {
- out[i - n] = (byte)plain;
- }
- r = (cypher + r) * c1 + c2 & 0xFFFF;
- }
- return out;
- }
-
- public static byte[] encodeBytes(byte[] in, int inR, int n) {
- byte[] buffer = new byte[in.length + n];
- for (int i = 0; i < n; i++) {
- buffer[i] = 0;
- }
- int r = inR;
- int c1 = 52845;
- int c2 = 22719;
- System.arraycopy(in, 0, buffer, n, buffer.length - n);
- byte[] out = new byte[buffer.length];
- for (int i = 0; i < buffer.length; i++) {
- int plain = buffer[i] & 0xff;
- int cipher = plain ^ r >> 8;
- out[i] = (byte) cipher;
- r = (cipher + r) * c1 + c2 & 0xffff;
- }
- return out;
- }
- }
-}
diff --git a/src/java/org/apache/fop/fonts/type1/package.html b/src/java/org/apache/fop/fonts/type1/package.html
deleted file mode 100644
index 0c492fc4d..000000000
--- a/src/java/org/apache/fop/fonts/type1/package.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<HTML>
-<TITLE>org.apache.fop.fonts.type1 Package</TITLE>
-<BODY>
-<P>Classes for Adobe Type 1 fonts.</P>
-</BODY>
-</HTML> \ No newline at end of file