You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2014/01/05 16:37:49 UTC
svn commit: r1555529 - in /pdfbox/trunk:
fontbox/src/main/java/org/apache/fontbox/cff/
fontbox/src/main/java/org/apache/fontbox/encoding/
pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/
Author: lehmi
Date: Sun Jan 5 15:37:49 2014
New Revision: 1555529
URL: http://svn.apache.org/r1555529
Log:
PDFBOX-1831: rearranged/improved code to support composite glyphs as proposed by John Hewson
Added:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharString.java (with props)
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharString.java (with props)
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/StandardEncoding.java (with props)
Removed:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringConverter.java
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringRenderer.java
Modified:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/AFMFormatter.java
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFontROS.java
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringHandler.java
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1FontFormatter.java
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/Encoding.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/CFFGlyph2D.java
Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/AFMFormatter.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/AFMFormatter.java?rev=1555529&r1=1555528&r2=1555529&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/AFMFormatter.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/AFMFormatter.java Sun Jan 5 15:37:49 2014
@@ -29,7 +29,7 @@ import org.apache.fontbox.cff.encoding.C
* This class creates all needed AFM font metric data from a CFFFont ready to be read from a AFMPaser.
*
* @author Villu Ruusmann
- * @version $Revision$
+ *
*/
public class AFMFormatter
{
@@ -116,16 +116,14 @@ public class AFMFormatter
private static List<CharMetric> renderFont(CFFFont font) throws IOException
{
List<CharMetric> metrics = new ArrayList<CharMetric>();
- CharStringRenderer renderer = font.createRenderer();
Collection<CFFFont.Mapping> mappings = font.getMappings();
for (CFFFont.Mapping mapping : mappings)
{
CharMetric metric = new CharMetric();
metric.code = mapping.getCode();
metric.name = mapping.getName();
- renderer.render(mapping.toType1Sequence());
- metric.width = renderer.getWidth();
- metric.bounds = renderer.getBounds();
+ metric.width = mapping.getType1CharString().getWidth();
+ metric.bounds = mapping.getType1CharString().getBounds();
metrics.add(metric);
}
return metrics;
Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java?rev=1555529&r1=1555528&r2=1555529&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java Sun Jan 5 15:37:49 2014
@@ -17,13 +17,7 @@
package org.apache.fontbox.cff;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
import org.apache.fontbox.cff.charset.CFFCharset;
import org.apache.fontbox.cff.encoding.CFFEncoding;
@@ -32,11 +26,10 @@ import org.apache.fontbox.cff.encoding.C
* This class represents a CFF/Type2 Font.
*
* @author Villu Ruusmann
- *
+ * @author John Hewson
*/
public class CFFFont
{
-
private String fontname = null;
private Map<String, Object> topDict = new LinkedHashMap<String, Object>();
private Map<String, Object> privateDict = new LinkedHashMap<String, Object>();
@@ -45,6 +38,7 @@ public class CFFFont
private Map<String, byte[]> charStringsDict = new LinkedHashMap<String, byte[]>();
private IndexData globalSubrIndex = null;
private IndexData localSubrIndex = null;
+ private Map<String, Type2CharString> charStringCache = new HashMap<String, Type2CharString>();
/**
* The name of the font.
@@ -220,44 +214,25 @@ public class CFFFont
/**
* Return the Width value of the given Glyph identifier.
*
- * @param SID
+ * @param sid SID
* @return -1 if the SID is missing from the Font.
* @throws IOException if something went wrong
*
*/
- public int getWidth(int SID) throws IOException
+ public int getWidth(int sid) throws IOException
{
- int nominalWidth = privateDict.containsKey("nominalWidthX") ? ((Number) privateDict.get("nominalWidthX"))
- .intValue() : 0;
- int defaultWidth = privateDict.containsKey("defaultWidthX") ? ((Number) privateDict.get("defaultWidthX"))
- .intValue() : 1000;
-
for (Mapping m : getMappings())
{
- if (m.getSID() == SID)
+ if (m.getSID() == sid)
{
-
- CharStringRenderer csr = null;
- if (((Number) getProperty("CharstringType")).intValue() == 2)
- {
- List<Object> lSeq = m.toType2Sequence();
- csr = new CharStringRenderer(false);
- csr.render(lSeq);
- }
- else
- {
- List<Object> lSeq = m.toType1Sequence();
- csr = new CharStringRenderer();
- csr.render(lSeq);
- }
-
- // ---- If the CharString has a Width nominalWidthX must be added,
- // otherwise it is the default width.
- return csr.getWidth() != 0 ? csr.getWidth() + nominalWidth : defaultWidth;
+ Type1CharString charstring = m.getType1CharString();
+ return charstring.getWidth();
}
}
- // ---- SID Width not found, return the nodef width
+ // SID not found, return the nodef width
+ int nominalWidth = getNominalWidthX(sid);
+ int defaultWidth = getDefaultWidthX(sid);
return getNotDefWidth(defaultWidth, nominalWidth);
}
@@ -271,23 +246,8 @@ public class CFFFont
*/
protected int getNotDefWidth(int defaultWidth, int nominalWidth) throws IOException
{
- CharStringRenderer csr;
- byte[] glyphDesc = this.getCharStringsDict().get(".notdef");
- if (((Number) getProperty("CharstringType")).intValue() == 2)
- {
- Type2CharStringParser parser = new Type2CharStringParser();
- List<Object> lSeq = parser.parse(glyphDesc, getGlobalSubrIndex(), getLocalSubrIndex());
- csr = new CharStringRenderer(false);
- csr.render(lSeq);
- }
- else
- {
- Type1CharStringParser parser = new Type1CharStringParser();
- List<Object> lSeq = parser.parse(glyphDesc, getLocalSubrIndex());
- csr = new CharStringRenderer();
- csr.render(lSeq);
- }
- return csr.getWidth() != 0 ? csr.getWidth() + nominalWidth : defaultWidth;
+ Type1CharString charstring = getType1CharString(".notdef");
+ return charstring.getWidth() != 0 ? charstring.getWidth() + nominalWidth : defaultWidth;
}
/**
@@ -331,6 +291,25 @@ public class CFFFont
}
/**
+ * Returns the SID for a given glyph name.
+ * @param name glyph name
+ * @return SID
+ */
+ private int getSIDForName(String name)
+ {
+ int sid = 0; // .notdef
+ for (Mapping m : getMappings())
+ {
+ if (m.getName().equals(name))
+ {
+ sid = m.getSID();
+ break;
+ }
+ }
+ return sid;
+ }
+
+ /**
* Returns the character strings dictionary.
*
* @return the dictionary
@@ -341,25 +320,65 @@ public class CFFFont
}
/**
- * Creates a CharStringConverter for this font.
- *
- * @return the new CharStringConverter
+ * Returns the Type 1 CharString for the character with the given name.
+ *
+ * @return Type 1 CharString
+ * @throws IOException if something went wrong
+ *
*/
- public CharStringConverter createConverter()
+ public Type1CharString getType1CharString(String name) throws IOException
{
- Number defaultWidthX = (Number) getProperty("defaultWidthX");
- Number nominalWidthX = (Number) getProperty("nominalWidthX");
- return new CharStringConverter(defaultWidthX.intValue(), nominalWidthX.intValue());
+ return getType1CharString(name, getSIDForName(name));
}
/**
- * Creates a CharStringRenderer for this font.
- *
- * @return the new CharStringRenderer
+ * Returns the Type 1 CharString for the character with the given name and SID.
+ *
+ * @return Type 1 CharString
+ */
+ private Type1CharString getType1CharString(String name, int sid) throws IOException
+ {
+ Type2CharString type2 = charStringCache.get(name);
+ if (type2 == null)
+ {
+ Type2CharStringParser parser = new Type2CharStringParser();
+ List<Object> type2seq = parser.parse(charStringsDict.get(name), globalSubrIndex, localSubrIndex);
+ type2 = new Type2CharString(this, type2seq, getDefaultWidthX(sid), getNominalWidthX(sid));
+ charStringCache.put(name, type2);
+ }
+ return type2;
+ }
+
+ /**
+ * Returns the defaultWidthX for the given SID.
+ *
+ * @param sid SID
+ * @return defaultWidthX
+ */
+ protected int getDefaultWidthX(int sid)
+ {
+ Number num = (Number)getProperty("defaultWidthX");
+ if (num == null)
+ {
+ return 1000;
+ }
+ return num.intValue();
+ }
+
+ /**
+ * Returns the nominalWidthX for the given SID.
+ *
+ * @param sid SID
+ * @return defaultWidthX
*/
- public CharStringRenderer createRenderer()
+ protected int getNominalWidthX(int sid)
{
- return new CharStringRenderer();
+ Number num = (Number)getProperty("nominalWidthX");
+ if (num == null)
+ {
+ return 0;
+ }
+ return num.intValue();
}
/**
@@ -414,7 +433,6 @@ public class CFFFont
/**
* This class is used for the font mapping.
- *
*/
public class Mapping
{
@@ -424,27 +442,14 @@ public class CFFFont
private byte[] mappedBytes;
/**
- * Converts the mapping into a Type1-sequence.
- *
- * @return the Type1-sequence
+ * Returns the Type 1 CharString for the character.
+ *
+ * @return the Type 1 CharString
* @throws IOException if an error occurs during reading
*/
- public List<Object> toType1Sequence() throws IOException
+ public Type1CharString getType1CharString() throws IOException
{
- CharStringConverter converter = createConverter();
- return converter.convert(toType2Sequence());
- }
-
- /**
- * Converts the mapping into a Type2-sequence.
- *
- * @return the Type2-sequence
- * @throws IOException if an error occurs during reading
- */
- public List<Object> toType2Sequence() throws IOException
- {
- Type2CharStringParser parser = new Type2CharStringParser();
- return parser.parse(getBytes(), getGlobalSubrIndex(), getLocalSubrIndex());
+ return CFFFont.this.getType1CharString(mappedName, mappedSID);
}
/**
Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFontROS.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFontROS.java?rev=1555529&r1=1555528&r2=1555529&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFontROS.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFontROS.java Sun Jan 5 15:37:49 2014
@@ -22,168 +22,209 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-public class CFFFontROS extends CFFFont {
- private String registry;
- private String ordering;
- private int supplement;
-
- private List<Map<String, Object>> fontDictionaries = new LinkedList<Map<String,Object>>();
- private List<Map<String, Object>> privateDictionaries = new LinkedList<Map<String,Object>>();
- private CIDKeyedFDSelect fdSelect = null;
-
- /**
- * Returns the registry value.
- * @return the registry
- */
- public String getRegistry() {
- return registry;
- }
-
- /**
- * Sets the registry value.
- *
- * @param registry the registry to set
- */
- public void setRegistry(String registry) {
- this.registry = registry;
- }
-
- /**
- * Returns the ordering value.
- *
- * @return the ordering
- */
- public String getOrdering() {
- return ordering;
- }
-
- /**
- * Sets the ordering value.
- *
- * @param ordering the ordering to set
- */
- public void setOrdering(String ordering) {
- this.ordering = ordering;
- }
-
- /**
- * Returns the supplement value.
- *
- * @return the supplement
- */
- public int getSupplement() {
- return supplement;
- }
-
- /**
- * Sets the supplement value.
- *
- * @param supplement the supplement to set
- */
- public void setSupplement(int supplement) {
- this.supplement = supplement;
- }
-
- /**
- * Returns the font dictionaries.
- *
- * @return the fontDict
- */
- public List<Map<String, Object>> getFontDict() {
- return fontDictionaries;
- }
-
- /**
- * Sets the font dictionaries.
- *
- * @param fontDict the fontDict to set
- */
- public void setFontDict(List<Map<String, Object>> fontDict) {
- this.fontDictionaries = fontDict;
- }
-
- /**
- * Returns the private dictionary.
- *
- * @return the privDict
- */
- public List<Map<String, Object>> getPrivDict() {
- return privateDictionaries;
- }
-
- /**
- * Sets the private dictionary.
- *
- * @param privDict the privDict to set
- */
- public void setPrivDict(List<Map<String, Object>> privDict) {
- this.privateDictionaries = privDict;
- }
-
- /**
- * Returns the fdSelect value.
- *
- * @return the fdSelect
- */
- public CIDKeyedFDSelect getFdSelect() {
- return fdSelect;
- }
-
- /**
- * Sets the fdSelect value.
- *
- * @param fdSelect the fdSelect to set
- */
- public void setFdSelect(CIDKeyedFDSelect fdSelect) {
- this.fdSelect = fdSelect;
- }
-
- /**
- * Returns the Width value of the given Glyph identifier
- *
- * @param CID
- * @return -1 if the SID is missing from the Font.
- * @throws IOException
- */
- public int getWidth(int CID) throws IOException {
- // ---- search the right FDArray index in the FDSelect according to the Character identifier
- // this index will be used to access the private dictionary which contains useful values
- // to compute width.
- int fdArrayIndex = this.fdSelect.getFd(CID);
- if (fdArrayIndex == -1 && CID == 0 ) { // --- notdef char
- return super.getWidth(CID);
- } else if (fdArrayIndex == -1) {
- return 1000;
- }
-
- Map<String, Object> fontDict = this.fontDictionaries.get(fdArrayIndex);
- Map<String, Object> privDict = this.privateDictionaries.get(fdArrayIndex);
-
- int nominalWidth = privDict.containsKey("nominalWidthX") ? ((Number)privDict.get("nominalWidthX")).intValue() : 0;
- int defaultWidth = privDict.containsKey("defaultWidthX") ? ((Number)privDict.get("defaultWidthX")).intValue() : 1000 ;
-
- for (Mapping m : getMappings() ){
- if (m.getSID() == CID) {
-
- CharStringRenderer csr = null;
- Number charStringType = (Number)getProperty("CharstringType");
- if ( charStringType.intValue() == 2 ) {
- List<Object> lSeq = m.toType2Sequence();
- csr = new CharStringRenderer(false);
- csr.render(lSeq);
- } else {
- List<Object> lSeq = m.toType1Sequence();
- csr = new CharStringRenderer();
- csr.render(lSeq);
- }
-
- // ---- If the CharString has a Width nominalWidthX must be added,
- // otherwise it is the default width.
- return csr.getWidth() != 0 ? csr.getWidth() + nominalWidth : defaultWidth;
- }
- }
-
- // ---- CID Width not found, return the notdef width
- return getNotDefWidth(defaultWidth, nominalWidth);
- }
-}
+/**
+ * This class represents a CID-Keyed CFF/Type2 Font.
+ *
+ * @author Villu Ruusmann
+ * @author John Hewson
+ */
+public class CFFFontROS extends CFFFont
+{
+ private String registry;
+ private String ordering;
+ private int supplement;
+
+ private List<Map<String, Object>> fontDictionaries = new LinkedList<Map<String,Object>>();
+ private List<Map<String, Object>> privateDictionaries = new LinkedList<Map<String,Object>>();
+ private CIDKeyedFDSelect fdSelect = null;
+
+ /**
+ * Returns the registry value.
+ * * @return the registry
+ */
+ public String getRegistry()
+ {
+ return registry;
+ }
+
+ /**
+ * Sets the registry value.
+ *
+ * @param registry the registry to set
+ */
+ public void setRegistry(String registry)
+ {
+ this.registry = registry;
+ }
+
+ /**
+ * Returns the ordering value.
+ *
+ * @return the ordering
+ */
+ public String getOrdering()
+ {
+ return ordering;
+ }
+
+ /**
+ * Sets the ordering value.
+ *
+ * @param ordering the ordering to set
+ */
+ public void setOrdering(String ordering)
+ {
+ this.ordering = ordering;
+ }
+
+ /**
+ * Returns the supplement value.
+ *
+ * @return the supplement
+ */
+ public int getSupplement()
+ {
+ return supplement;
+ }
+
+ /**
+ * Sets the supplement value.
+ *
+ * @param supplement the supplement to set
+ */
+ public void setSupplement(int supplement)
+ {
+ this.supplement = supplement;
+ }
+
+ /**
+ * Returns the font dictionaries.
+ *
+ * @return the fontDict
+ */
+ public List<Map<String, Object>> getFontDict()
+ {
+ return fontDictionaries;
+ }
+
+ /**
+ * Sets the font dictionaries.
+ *
+ * @param fontDict the fontDict to set
+ */
+ public void setFontDict(List<Map<String, Object>> fontDict)
+ {
+ this.fontDictionaries = fontDict;
+ }
+
+ /**
+ * Returns the private dictionary.
+ *
+ * @return the privDict
+ */
+ public List<Map<String, Object>> getPrivDict()
+ {
+ return privateDictionaries;
+ }
+
+ /**
+ * Sets the private dictionary.
+ *
+ * @param privDict the privDict to set
+ */
+ public void setPrivDict(List<Map<String, Object>> privDict)
+ {
+ this.privateDictionaries = privDict;
+ }
+
+ /**
+ * Returns the fdSelect value.
+ *
+ * @return the fdSelect
+ */
+ public CIDKeyedFDSelect getFdSelect()
+ {
+ return fdSelect;
+ }
+
+ /**
+ * Sets the fdSelect value.
+ *
+ * @param fdSelect the fdSelect to set
+ */
+ public void setFdSelect(CIDKeyedFDSelect fdSelect)
+ {
+ this.fdSelect = fdSelect;
+ }
+
+ /**
+ * Returns the Width value of the given Glyph identifier
+ *
+ * @param cid CID
+ * @return -1 if the CID is missing from the Font.
+ * @throws IOException
+ */
+ public int getWidth(int cid) throws IOException
+ {
+ // search the right FDArray index in the FDSelect according to the Character identifier
+ // this index will be used to access the private dictionary which contains useful values
+ // to compute width.
+ int fdArrayIndex = this.fdSelect.getFd(cid);
+ if (fdArrayIndex == -1 && cid == 0 ) // notdef char
+ {
+ return super.getWidth(cid);
+ }
+ else if (fdArrayIndex == -1)
+ {
+ return 1000;
+ }
+
+ for (Mapping m : getMappings())
+ {
+ if (m.getSID() == cid)
+ {
+ Type1CharString charstring = m.getType1CharString();
+ return charstring.getWidth();
+ }
+ }
+
+ // CID not found, return the notdef width
+ int nominalWidth = getNominalWidthX(cid);
+ int defaultWidth = getDefaultWidthX(cid);
+ return getNotDefWidth(defaultWidth, nominalWidth);
+ }
+
+ /**
+ * Returns the defaultWidthX for the given CID.
+ *
+ * @param cid CID
+ * @return defaultWidthX
+ */
+ protected int getDefaultWidthX(int cid)
+ {
+ int fdArrayIndex = this.fdSelect.getFd(cid);
+ if (fdArrayIndex == -1)
+ {
+ return 1000;
+ }
+ Map<String, Object> privDict = this.privateDictionaries.get(fdArrayIndex);
+ return privDict.containsKey("defaultWidthX") ? ((Number)privDict.get("defaultWidthX")).intValue() : 1000;
+ }
+
+ /**
+ * Returns the nominalWidthX for the given CID.
+ *
+ * @param cid CID
+ * @return defaultWidthX
+ */
+ protected int getNominalWidthX(int cid)
+ {
+ int fdArrayIndex = this.fdSelect.getFd(cid);
+ if (fdArrayIndex == -1)
+ {
+ return 0;
+ }
+ Map<String, Object> privDict = this.privateDictionaries.get(fdArrayIndex);
+ return privDict.containsKey("nominalWidthX") ? ((Number)privDict.get("nominalWidthX")).intValue() : 0;
+ }
+}
\ No newline at end of file
Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringHandler.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringHandler.java?rev=1555529&r1=1555528&r2=1555529&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringHandler.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringHandler.java Sun Jan 5 15:37:49 2014
@@ -21,24 +21,21 @@ import java.util.List;
/**
* A Handler for CharStringCommands.
- *
+ *
* @author Villu Ruusmann
- * @version $Revision$
+ *
*/
public abstract class CharStringHandler
{
-
/**
* Handler for a sequence of CharStringCommands.
- *
+ *
* @param sequence of CharStringCommands
- *
- * @return may return a command sequence of a subroutine
+ *
*/
@SuppressWarnings(value = { "unchecked" })
- public List<Integer> handleSequence(List<Object> sequence)
+ public void handleSequence(List<Object> sequence)
{
- List<Integer> numbers = null;
int offset = 0;
int size = sequence.size();
for (int i = 0; i < size; i++)
@@ -46,30 +43,18 @@ public abstract class CharStringHandler
Object object = sequence.get(i);
if (object instanceof CharStringCommand)
{
- if (numbers == null)
- numbers = (List) sequence.subList(offset, i);
- else
- numbers.addAll((List) sequence.subList(offset, i));
- List<Integer> stack = handleCommand(numbers, (CharStringCommand) object);
- if (stack != null && !stack.isEmpty())
- numbers = stack;
- else
- numbers = null;
+ List<Integer> numbers = (List) sequence.subList(offset, i);
+ handleCommand(numbers, (CharStringCommand) object);
offset = i + 1;
}
}
- if (numbers != null && !numbers.isEmpty())
- return numbers;
- else
- return null;
}
+
/**
* Handler for CharStringCommands.
- *
+ *
* @param numbers a list of numbers
* @param command the CharStringCommand
- *
- * @return may return a command sequence of a subroutine
*/
- public abstract List<Integer> handleCommand(List<Integer> numbers, CharStringCommand command);
+ public abstract void handleCommand(List<Integer> numbers, CharStringCommand command);
}
\ No newline at end of file
Added: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharString.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharString.java?rev=1555529&view=auto
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharString.java (added)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharString.java Sun Jan 5 15:37:49 2014
@@ -0,0 +1,290 @@
+/*
+ * 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.
+ */
+package org.apache.fontbox.cff;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fontbox.encoding.StandardEncoding;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * This class represents and renders a Type 1 CharString.
+ *
+ * @author Villu Ruusmann
+ * @author John Hewson
+ */
+public class Type1CharString
+{
+ private static final Log LOG = LogFactory.getLog(Type1CharString.class);
+
+ private CFFFont cffFont;
+ private GeneralPath path = null;
+ private int width = 0;
+ private Point2D leftSideBearing = null;
+ private Point2D referencePoint = null;
+ protected List<Object> type1Sequence;
+
+ /**
+ * Constructs a new Type1CharString object.
+ * @param font Parent CFF font
+ * @param sequence Type 1 char string sequence
+ */
+ public Type1CharString(CFFFont font, List<Object> sequence)
+ {
+ this(font);
+ type1Sequence = sequence;
+ }
+
+ /**
+ * Constructor for use in subclasses.
+ * @param font Parent CFF font
+ */
+ protected Type1CharString(CFFFont font)
+ {
+ cffFont = font;
+ }
+
+ /**
+ * Returns the bounds of the renderer path.
+ * @return the bounds as Rectangle2D
+ */
+ public Rectangle2D getBounds()
+ {
+ if (path == null)
+ {
+ render();
+ }
+ return path.getBounds2D();
+ }
+
+ /**
+ * Returns the advance width of the glyph.
+ * @return the width
+ */
+ public int getWidth()
+ {
+ if (path == null)
+ {
+ render();
+ }
+ return width;
+ }
+
+ /**
+ * Returns the path of the character.
+ * @return the path
+ */
+ public GeneralPath getPath()
+ {
+ //TODO does not need to be lazy anymore?
+ if (path == null)
+ {
+ render();
+ }
+ return path;
+ }
+
+ /**
+ * Returns the Type 1 char string sequence.
+ * @return the Type 1 sequence
+ */
+ public List<Object> getType1Sequence()
+ {
+ return type1Sequence;
+ }
+
+ /**
+ * Renders the Type 1 char string sequence to a GeneralPath.
+ */
+ private void render()
+ {
+ path = new GeneralPath();
+ leftSideBearing = new Point2D.Float(0, 0);
+ referencePoint = null;
+ width = 0;
+ CharStringHandler handler = new CharStringHandler() {
+ public void handleCommand(List<Integer> numbers, CharStringCommand command)
+ {
+ Type1CharString.this.handleCommand(numbers, command);
+ }
+ };
+ handler.handleSequence(type1Sequence);
+ }
+
+ private void handleCommand(List<Integer> numbers, CharStringCommand command)
+ {
+ String name = CharStringCommand.TYPE1_VOCABULARY.get(command.getKey());
+
+ if ("vmoveto".equals(name))
+ {
+ rmoveTo(0, numbers.get(0));
+ }
+ else if ("rlineto".equals(name))
+ {
+ rlineTo(numbers.get(0), numbers.get(1));
+ }
+ else if ("hlineto".equals(name))
+ {
+ rlineTo(numbers.get(0), 0);
+ }
+ else if ("vlineto".equals(name))
+ {
+ rlineTo(0, numbers.get(0));
+ }
+ else if ("rrcurveto".equals(name))
+ {
+ rrcurveTo(numbers.get(0), numbers.get(1), numbers.get(2), numbers
+ .get(3), numbers.get(4), numbers.get(5));
+ }
+ else if ("closepath".equals(name))
+ {
+ closepath();
+ }
+ else if ("sbw".equals(name))
+ {
+ leftSideBearing = new Point2D.Float(numbers.get(0), numbers.get(1));
+ width = numbers.get(2);
+ }
+ else if ("hsbw".equals(name))
+ {
+ leftSideBearing = new Point2D.Float(numbers.get(0), 0);
+ width = numbers.get(1);
+ }
+ else if ("rmoveto".equals(name))
+ {
+ rmoveTo(numbers.get(0), numbers.get(1));
+ }
+ else if ("hmoveto".equals(name))
+ {
+ rmoveTo(numbers.get(0), 0);
+ }
+ else if ("vhcurveto".equals(name))
+ {
+ rrcurveTo(0, numbers.get(0), numbers.get(1),
+ numbers.get(2), numbers.get(3), 0);
+ }
+ else if ("hvcurveto".equals(name))
+ {
+ rrcurveTo(numbers.get(0), 0, numbers.get(1),
+ numbers.get(2), 0, numbers.get(3));
+ }
+ else if ("seac".equals(name))
+ {
+ seac(numbers.get(0), numbers.get(1), numbers.get(2), numbers.get(3), numbers.get(4));
+ }
+ }
+
+ /**
+ * Relative moveto.
+ */
+ private void rmoveTo(Number dx, Number dy)
+ {
+ Point2D point = referencePoint;
+ if (point == null)
+ {
+ point = path.getCurrentPoint();
+ if (point == null)
+ {
+ point = leftSideBearing;
+ }
+ }
+ referencePoint = null;
+ path.moveTo((float)(point.getX() + dx.doubleValue()),
+ (float)(point.getY() + dy.doubleValue()));
+ }
+
+ /**
+ * Relative lineto.
+ */
+ private void rlineTo(Number dx, Number dy)
+ {
+ Point2D point = path.getCurrentPoint();
+ path.lineTo((float)(point.getX() + dx.doubleValue()),
+ (float)(point.getY() + dy.doubleValue()));
+ }
+
+ /**
+ * Relative curveto.
+ */
+ private void rrcurveTo(Number dx1, Number dy1, Number dx2, Number dy2,
+ Number dx3, Number dy3)
+ {
+ Point2D point = path.getCurrentPoint();
+ float x1 = (float) point.getX() + dx1.floatValue();
+ float y1 = (float) point.getY() + dy1.floatValue();
+ float x2 = x1 + dx2.floatValue();
+ float y2 = y1 + dy2.floatValue();
+ float x3 = x2 + dx3.floatValue();
+ float y3 = y2 + dy3.floatValue();
+ path.curveTo(x1, y1, x2, y2, x3, y3);
+ }
+
+ /**
+ * Close path.
+ */
+ private void closepath()
+ {
+ referencePoint = path.getCurrentPoint();
+ path.closePath();
+ }
+
+ /**
+ * Standard Encoding Accented Character
+ *
+ * Makes an accented character from two other characters.
+ */
+ private void seac(Number asb, Number adx, Number ady, Number bchar, Number achar)
+ {
+ // base character
+ String baseName = StandardEncoding.INSTANCE.getName(bchar.intValue());
+ if (baseName != null)
+ {
+ try
+ {
+ Type1CharString base = cffFont.getType1CharString(baseName);
+ path.append(base.getPath().getPathIterator(null), false);
+ }
+ catch (IOException e)
+ {
+ LOG.warn("invalid character in seac command");
+ }
+ }
+ // accent character
+ String accentName = StandardEncoding.INSTANCE.getName(achar.intValue());
+ if (accentName != null)
+ {
+ try
+ {
+ Type1CharString accent = cffFont.getType1CharString(accentName);
+ AffineTransform at = AffineTransform.getTranslateInstance(
+ leftSideBearing.getX() + adx.floatValue(),
+ leftSideBearing.getY() + ady.floatValue());
+ path.append(accent.getPath().getPathIterator(at), false);
+ }
+ catch (IOException e)
+ {
+ LOG.warn("invalid character in seac command");
+ }
+ }
+ }
+}
\ No newline at end of file
Propchange: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharString.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1FontFormatter.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1FontFormatter.java?rev=1555529&r1=1555528&r2=1555529&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1FontFormatter.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1FontFormatter.java Sun Jan 5 15:37:49 2014
@@ -174,7 +174,7 @@ public class Type1FontFormatter
for (CFFFont.Mapping mapping : mappings)
{
- byte[] type1Bytes = formatter.format(mapping.toType1Sequence());
+ byte[] type1Bytes = formatter.format(mapping.getType1CharString().getType1Sequence());
byte[] charstringBytes = Type1FontUtil.charstringEncrypt(
type1Bytes, 4);
Added: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharString.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharString.java?rev=1555529&view=auto
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharString.java (added)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharString.java Sun Jan 5 15:37:49 2014
@@ -0,0 +1,383 @@
+/*
+ * 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.
+ */
+package org.apache.fontbox.cff;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Represents a Type 2 CharString by converting it into an equivalent Type 1 CharString.
+ *
+ * @author Villu Ruusmann
+ * @author John Hewson
+ */
+public class Type2CharString extends Type1CharString
+{
+ private int defWidthX = 0;
+ private int nominalWidthX = 0;
+ private int pathCount = 0;
+ private List<Object> type2sequence;
+
+ /**
+ * Constructor.
+ * @param font Parent CFF font
+ * @param sequence Type 2 char string sequence
+ * @param defaultWidthX default width
+ * @param nomWidthX nominal width width
+ */
+ public Type2CharString(CFFFont font, List<Object> sequence, int defaultWidthX, int nomWidthX)
+ {
+ super(font);
+ type2sequence = sequence;
+ defWidthX = defaultWidthX;
+ nominalWidthX = nomWidthX;
+ convertType1ToType2(sequence);
+ }
+
+ /**
+ * Returns the advance width of the glyph.
+ * @return the width
+ */
+ public int getWidth()
+ {
+ int width = super.getWidth();
+ if (width == 0)
+ {
+ return defWidthX;
+ }
+ else
+ {
+ return nominalWidthX + width;
+ }
+ }
+
+ /**
+ * Returns the Type 2 char string sequence.
+ * @return the Type 2 sequence
+ */
+ public List<Object> getType2Sequence()
+ {
+ return type2sequence;
+ }
+
+ /**
+ * Converts a sequence of Type 2 commands into a sequence of Type 1 commands.
+ * @param sequence the Type 2 char string sequence
+ */
+ private void convertType1ToType2(List<Object> sequence)
+ {
+ type1Sequence = new ArrayList<Object>();
+ pathCount = 0;
+ CharStringHandler handler = new CharStringHandler() {
+ public void handleCommand(List<Integer> numbers, CharStringCommand command)
+ {
+ Type2CharString.this.handleCommand(numbers, command);
+ }
+ };
+ handler.handleSequence(sequence);
+ }
+
+ @SuppressWarnings(value = { "unchecked" })
+ private void handleCommand(List<Integer> numbers, CharStringCommand command)
+ {
+ String name = CharStringCommand.TYPE2_VOCABULARY.get(command.getKey());
+
+ if ("hstem".equals(name))
+ {
+ numbers = clearStack(numbers, numbers.size() % 2 != 0);
+ expandStemHints(numbers, true);
+ }
+ else if ("vstem".equals(name))
+ {
+ numbers = clearStack(numbers, numbers.size() % 2 != 0);
+ expandStemHints(numbers, false);
+ }
+ else if ("vmoveto".equals(name))
+ {
+ numbers = clearStack(numbers, numbers.size() > 1);
+ markPath();
+ addCommand(numbers, command);
+ }
+ else if ("rlineto".equals(name))
+ {
+ addCommandList(split(numbers, 2), command);
+ }
+ else if ("hlineto".equals(name))
+ {
+ drawAlternatingLine(numbers, true);
+ }
+ else if ("vlineto".equals(name))
+ {
+ drawAlternatingLine(numbers, false);
+ }
+ else if ("rrcurveto".equals(name))
+ {
+ addCommandList(split(numbers, 6), command);
+ }
+ else if ("endchar".equals(name))
+ {
+ numbers = clearStack(numbers, numbers.size() == 5);
+ closePath();
+ if (numbers.size() == 4)
+ {
+ // deprecated "seac" operator
+ numbers.add(0, 0);
+ addCommand(numbers, new CharStringCommand(12, 6));
+ }
+ else
+ {
+ addCommand(numbers, command);
+ }
+ }
+ else if ("rmoveto".equals(name))
+ {
+ numbers = clearStack(numbers, numbers.size() > 2);
+ markPath();
+ addCommand(numbers, command);
+ }
+ else if ("hmoveto".equals(name))
+ {
+ numbers = clearStack(numbers, numbers.size() > 1);
+ markPath();
+ addCommand(numbers, command);
+ }
+ else if ("vhcurveto".equals(name))
+ {
+ drawAlternatingCurve(numbers, false);
+ }
+ else if ("hvcurveto".equals(name))
+ {
+ drawAlternatingCurve(numbers, true);
+ }
+ else if ("hflex".equals(name))
+ {
+ List<Integer> first = Arrays.asList(numbers.get(0), 0,
+ numbers.get(1), numbers.get(2), numbers.get(3), 0);
+ List<Integer> second = Arrays.asList(numbers.get(4), 0,
+ numbers.get(5), -numbers.get(2),
+ numbers.get(6), 0);
+ addCommandList(Arrays.asList(first, second), new CharStringCommand(8));
+ }
+ else if ("flex".equals(name))
+ {
+ List<Integer> first = numbers.subList(0, 6);
+ List<Integer> second = numbers.subList(6, 12);
+ addCommandList(Arrays.asList(first, second), new CharStringCommand(8));
+ }
+ else if ("hflex1".equals(name))
+ {
+ List<Integer> first = Arrays.asList(numbers.get(0), numbers.get(1),
+ numbers.get(2), numbers.get(3), numbers.get(4), 0);
+ List<Integer> second = Arrays.asList(numbers.get(5), 0,
+ numbers.get(6), numbers.get(7), numbers.get(8), 0);
+ addCommandList(Arrays.asList(first, second), new CharStringCommand(8));
+ }
+ else if ("flex1".equals(name))
+ {
+ int dx = 0;
+ int dy = 0;
+ for(int i = 0; i < 5; i++)
+ {
+ dx += numbers.get(i * 2);
+ dy += numbers.get(i * 2 + 1);
+ }
+ List<Integer> first = numbers.subList(0, 6);
+ List<Integer> second = Arrays.asList(numbers.get(6), numbers.get(7), numbers.get(8),
+ numbers.get(9), (Math.abs(dx) > Math.abs(dy) ? numbers.get(10) : Integer.valueOf(-dx)),
+ (Math.abs(dx) > Math.abs(dy) ? Integer.valueOf(-dy) : numbers.get(10)));
+ addCommandList(Arrays.asList(first, second), new CharStringCommand(8));
+ }
+ else if ("hstemhm".equals(name))
+ {
+ numbers = clearStack(numbers, numbers.size() % 2 != 0);
+ expandStemHints(numbers, true);
+ }
+ else if ("hintmask".equals(name) || "cntrmask".equals(name))
+ {
+ numbers = clearStack(numbers, numbers.size() % 2 != 0);
+ if (numbers.size() > 0)
+ {
+ expandStemHints(numbers, false);
+ }
+ }
+ else if ("vstemhm".equals(name))
+ {
+ numbers = clearStack(numbers, numbers.size() % 2 != 0);
+ expandStemHints(numbers, false);
+ }
+ else if ("rcurveline".equals(name))
+ {
+ addCommandList(split(numbers.subList(0, numbers.size() - 2), 6),
+ new CharStringCommand(8));
+ addCommand(numbers.subList(numbers.size() - 2, numbers.size()),
+ new CharStringCommand(5));
+ }
+ else if ("rlinecurve".equals(name))
+ {
+ addCommandList(split(numbers.subList(0, numbers.size() - 6), 2),
+ new CharStringCommand(5));
+ addCommand(numbers.subList(numbers.size() - 6, numbers.size()),
+ new CharStringCommand(8));
+ }
+ else if ("vvcurveto".equals(name))
+ {
+ drawCurve(numbers, false);
+ }
+ else if ("hhcurveto".equals(name))
+ {
+ drawCurve(numbers, true);
+ }
+ else
+ {
+ addCommand(numbers, command);
+ }
+ }
+
+ private List<Integer> clearStack(List<Integer> numbers, boolean flag)
+ {
+ if (type1Sequence.size() == 0)
+ {
+ if (flag)
+ {
+ addCommand(Arrays.asList(0, numbers.get(0) + nominalWidthX),
+ new CharStringCommand(13));
+
+ numbers = numbers.subList(1, numbers.size());
+ }
+ else
+ {
+ addCommand(Arrays.asList(0, defWidthX),
+ new CharStringCommand(13));
+ }
+ }
+ return numbers;
+ }
+
+ private void expandStemHints(List<Integer> numbers, boolean horizontal)
+ {
+ // TODO
+ }
+
+ private void markPath()
+ {
+ if (pathCount > 0)
+ {
+ closePath();
+ }
+ pathCount++;
+ }
+
+ private void closePath()
+ {
+ CharStringCommand command = pathCount > 0 ? (CharStringCommand) type1Sequence
+ .get(type1Sequence.size() - 1)
+ : null;
+
+ CharStringCommand closepathCommand = new CharStringCommand(9);
+ if (command != null && !closepathCommand.equals(command))
+ {
+ addCommand(Collections.<Integer> emptyList(), closepathCommand);
+ }
+ }
+
+ private void drawAlternatingLine(List<Integer> numbers, boolean horizontal)
+ {
+ while (numbers.size() > 0)
+ {
+ addCommand(numbers.subList(0, 1), new CharStringCommand(
+ horizontal ? 6 : 7));
+ numbers = numbers.subList(1, numbers.size());
+ horizontal = !horizontal;
+ }
+ }
+
+ private void drawAlternatingCurve(List<Integer> numbers, boolean horizontal)
+ {
+ while (numbers.size() > 0)
+ {
+ boolean last = numbers.size() == 5;
+ if (horizontal)
+ {
+ addCommand(Arrays.asList(numbers.get(0), 0,
+ numbers.get(1), numbers.get(2), last ? numbers.get(4)
+ : Integer.valueOf(0), numbers.get(3)),
+ new CharStringCommand(8));
+ }
+ else
+ {
+ addCommand(Arrays.asList(0, numbers.get(0),
+ numbers.get(1), numbers.get(2), numbers.get(3),
+ last ? numbers.get(4) : Integer.valueOf(0)),
+ new CharStringCommand(8));
+ }
+ numbers = numbers.subList(last ? 5 : 4, numbers.size());
+ horizontal = !horizontal;
+ }
+ }
+
+ private void drawCurve(List<Integer> numbers, boolean horizontal)
+ {
+ while (numbers.size() > 0)
+ {
+ boolean first = numbers.size() % 4 == 1;
+
+ if (horizontal)
+ {
+ addCommand(Arrays.asList(numbers.get(first ? 1 : 0),
+ first ? numbers.get(0) : Integer.valueOf(0), numbers
+ .get(first ? 2 : 1),
+ numbers.get(first ? 3 : 2), numbers.get(first ? 4 : 3),
+ 0), new CharStringCommand(8));
+ }
+ else
+ {
+ addCommand(Arrays.asList(first ? numbers.get(0) : Integer
+ .valueOf(0), numbers.get(first ? 1 : 0), numbers
+ .get(first ? 2 : 1), numbers.get(first ? 3 : 2),
+ 0, numbers.get(first ? 4 : 3)),
+ new CharStringCommand(8));
+ }
+ numbers = numbers.subList(first ? 5 : 4, numbers.size());
+ }
+ }
+
+ private void addCommandList(List<List<Integer>> numbers, CharStringCommand command)
+ {
+ for (List<Integer> ns : numbers)
+ {
+ addCommand(ns, command);
+ }
+ }
+
+ private void addCommand(List<Integer> numbers, CharStringCommand command)
+ {
+ type1Sequence.addAll(numbers);
+ type1Sequence.add(command);
+ }
+
+ private static <E> List<List<E>> split(List<E> list, int size)
+ {
+ List<List<E>> result = new ArrayList<List<E>>();
+ for (int i = 0; i < list.size() / size; i++)
+ {
+ result.add(list.subList(i * size, (i + 1) * size));
+ }
+ return result;
+ }
+}
\ No newline at end of file
Propchange: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type2CharString.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/Encoding.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/Encoding.java?rev=1555529&r1=1555528&r2=1555529&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/Encoding.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/Encoding.java Sun Jan 5 15:37:49 2014
@@ -25,8 +25,6 @@ import java.util.Map;
* This is an interface to a text encoder.
*
* @author Ben Litchfield
- * @version $Revision: 1.1 $
- *
*
*/
public abstract class Encoding
@@ -153,10 +151,8 @@ public abstract class Encoding
* @param code The character code.
*
* @return The name of the character.
- *
- * @throws IOException If there is no name for the code.
*/
- public String getName( int code ) throws IOException
+ public String getName( int code )
{
String name = codeToName.get( code );
if( name == null )
Added: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/StandardEncoding.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/StandardEncoding.java?rev=1555529&view=auto
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/StandardEncoding.java (added)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/StandardEncoding.java Sun Jan 5 15:37:49 2014
@@ -0,0 +1,188 @@
+/*
+ * 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.
+ */
+package org.apache.fontbox.encoding;
+
+
+/**
+ * Adobe Standard Encoding
+ *
+ * @author Ben Litchfield
+ *
+ */
+public class StandardEncoding extends Encoding
+{
+ /**
+ * Singleton instance of this class.
+ */
+ public static final StandardEncoding INSTANCE = new StandardEncoding();
+
+ /**
+ * Constructor.
+ */
+ public StandardEncoding()
+ {
+ addCharacterEncoding( 0101, "A" );
+ addCharacterEncoding( 0341, "AE" );
+ addCharacterEncoding( 0102, "B" );
+ addCharacterEncoding( 0103, "C" );
+ addCharacterEncoding( 0104, "D" );
+ addCharacterEncoding( 0105, "E" );
+ addCharacterEncoding( 0106, "F" );
+ addCharacterEncoding( 0107, "G" );
+ addCharacterEncoding( 0110, "H" );
+ addCharacterEncoding( 0111, "I" );
+ addCharacterEncoding( 0112, "J" );
+ addCharacterEncoding( 0113, "K" );
+ addCharacterEncoding( 0114, "L" );
+ addCharacterEncoding( 0350, "Lslash" );
+ addCharacterEncoding( 0115, "M" );
+ addCharacterEncoding( 0116, "N" );
+ addCharacterEncoding( 0117, "O" );
+ addCharacterEncoding( 0352, "OE" );
+ addCharacterEncoding( 0351, "Oslash" );
+ addCharacterEncoding( 0120, "P" );
+ addCharacterEncoding( 0121, "Q" );
+ addCharacterEncoding( 0122, "R" );
+ addCharacterEncoding( 0123, "S" );
+ addCharacterEncoding( 0124, "T" );
+ addCharacterEncoding( 0125, "U" );
+ addCharacterEncoding( 0126, "V" );
+ addCharacterEncoding( 0127, "W" );
+ addCharacterEncoding( 0130, "X" );
+ addCharacterEncoding( 0131, "Y" );
+ addCharacterEncoding( 0132, "Z" );
+ addCharacterEncoding( 0141, "a" );
+ addCharacterEncoding( 0302, "acute" );
+ addCharacterEncoding( 0361, "ae" );
+ addCharacterEncoding( 0046, "ampersand" );
+ addCharacterEncoding( 0136, "asciicircum" );
+ addCharacterEncoding( 0176, "asciitilde" );
+ addCharacterEncoding( 0052, "asterisk" );
+ addCharacterEncoding( 0100, "at" );
+ addCharacterEncoding( 0142, "b" );
+ addCharacterEncoding( 0134, "backslash" );
+ addCharacterEncoding( 0174, "bar" );
+ addCharacterEncoding( 0173, "braceleft" );
+ addCharacterEncoding( 0175, "braceright" );
+ addCharacterEncoding( 0133, "bracketleft" );
+ addCharacterEncoding( 0135, "bracketright" );
+ addCharacterEncoding( 0306, "breve" );
+ addCharacterEncoding( 0267, "bullet" );
+ addCharacterEncoding( 0143, "c" );
+ addCharacterEncoding( 0317, "caron" );
+ addCharacterEncoding( 0313, "cedilla" );
+ addCharacterEncoding( 0242, "cent" );
+ addCharacterEncoding( 0303, "circumflex" );
+ addCharacterEncoding( 0072, "colon" );
+ addCharacterEncoding( 0054, "comma" );
+ addCharacterEncoding( 0250, "currency" );
+ addCharacterEncoding( 0144, "d" );
+ addCharacterEncoding( 0262, "dagger" );
+ addCharacterEncoding( 0263, "daggerdbl" );
+ addCharacterEncoding( 0310, "dieresis" );
+ addCharacterEncoding( 0044, "dollar" );
+ addCharacterEncoding( 0307, "dotaccent" );
+ addCharacterEncoding( 0365, "dotlessi" );
+ addCharacterEncoding( 0145, "e" );
+ addCharacterEncoding( 0070, "eight" );
+ addCharacterEncoding( 0274, "ellipsis" );
+ addCharacterEncoding( 0320, "emdash" );
+ addCharacterEncoding( 0261, "endash" );
+ addCharacterEncoding( 0075, "equal" );
+ addCharacterEncoding( 0041, "exclam" );
+ addCharacterEncoding( 0241, "exclamdown" );
+ addCharacterEncoding( 0146, "f" );
+ addCharacterEncoding( 0256, "fi" );
+ addCharacterEncoding( 0065, "five" );
+ addCharacterEncoding( 0257, "fl" );
+ addCharacterEncoding( 0246, "florin" );
+ addCharacterEncoding( 0064, "four" );
+ addCharacterEncoding( 0244, "fraction" );
+ addCharacterEncoding( 0147, "g" );
+ addCharacterEncoding( 0373, "germandbls" );
+ addCharacterEncoding( 0301, "grave" );
+ addCharacterEncoding( 0076, "greater" );
+ addCharacterEncoding( 0253, "guillemotleft" );
+ addCharacterEncoding( 0273, "guillemotright" );
+ addCharacterEncoding( 0254, "guilsinglleft" );
+ addCharacterEncoding( 0255, "guilsinglright" );
+ addCharacterEncoding( 0150, "h" );
+ addCharacterEncoding( 0315, "hungarumlaut" );
+ addCharacterEncoding( 0055, "hyphen" );
+ addCharacterEncoding( 0151, "i" );
+ addCharacterEncoding( 0152, "j" );
+ addCharacterEncoding( 0153, "k" );
+ addCharacterEncoding( 0154, "l" );
+ addCharacterEncoding( 0074, "less" );
+ addCharacterEncoding( 0370, "lslash" );
+ addCharacterEncoding( 0155, "m" );
+ addCharacterEncoding( 0305, "macron" );
+ addCharacterEncoding( 0156, "n" );
+ addCharacterEncoding( 0071, "nine" );
+ addCharacterEncoding( 0043, "numbersign" );
+ addCharacterEncoding( 0157, "o" );
+ addCharacterEncoding( 0372, "oe" );
+ addCharacterEncoding( 0316, "ogonek" );
+ addCharacterEncoding( 0061, "one" );
+ addCharacterEncoding( 0343, "ordfeminine" );
+ addCharacterEncoding( 0353, "ordmasculine" );
+ addCharacterEncoding( 0371, "oslash" );
+ addCharacterEncoding( 0160, "p" );
+ addCharacterEncoding( 0266, "paragraph" );
+ addCharacterEncoding( 0050, "parenleft" );
+ addCharacterEncoding( 0051, "parenright" );
+ addCharacterEncoding( 0045, "percent" );
+ addCharacterEncoding( 0056, "period" );
+ addCharacterEncoding( 0264, "periodcentered" );
+ addCharacterEncoding( 0275, "perthousand" );
+ addCharacterEncoding( 0053, "plus" );
+ addCharacterEncoding( 0161, "q" );
+ addCharacterEncoding( 0077, "question" );
+ addCharacterEncoding( 0277, "questiondown" );
+ addCharacterEncoding( 0042, "quotedbl" );
+ addCharacterEncoding( 0271, "quotedblbase" );
+ addCharacterEncoding( 0252, "quotedblleft" );
+ addCharacterEncoding( 0272, "quotedblright" );
+ addCharacterEncoding( 0140, "quoteleft" );
+ addCharacterEncoding( 0047, "quoteright" );
+ addCharacterEncoding( 0270, "quotesinglbase" );
+ addCharacterEncoding( 0251, "quotesingle" );
+ addCharacterEncoding( 0162, "r" );
+ addCharacterEncoding( 0312, "ring" );
+ addCharacterEncoding( 0163, "s" );
+ addCharacterEncoding( 0247, "section" );
+ addCharacterEncoding( 0073, "semicolon" );
+ addCharacterEncoding( 0067, "seven" );
+ addCharacterEncoding( 0066, "six" );
+ addCharacterEncoding( 0057, "slash" );
+ addCharacterEncoding( 0040, "space" );
+ addCharacterEncoding( 0243, "sterling" );
+ addCharacterEncoding( 0164, "t" );
+ addCharacterEncoding( 0063, "three" );
+ addCharacterEncoding( 0304, "tilde" );
+ addCharacterEncoding( 0062, "two" );
+ addCharacterEncoding( 0165, "u" );
+ addCharacterEncoding( 0137, "underscore" );
+ addCharacterEncoding( 0166, "v" );
+ addCharacterEncoding( 0167, "w" );
+ addCharacterEncoding( 0170, "x" );
+ addCharacterEncoding( 0171, "y" );
+ addCharacterEncoding( 0245, "yen" );
+ addCharacterEncoding( 0172, "z" );
+ addCharacterEncoding( 0060, "zero" );
+ }
+}
\ No newline at end of file
Propchange: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/encoding/StandardEncoding.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/CFFGlyph2D.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/CFFGlyph2D.java?rev=1555529&r1=1555528&r2=1555529&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/CFFGlyph2D.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdfviewer/font/CFFGlyph2D.java Sun Jan 5 15:37:49 2014
@@ -29,7 +29,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fontbox.cff.CFFFont;
import org.apache.fontbox.cff.CFFFontROS;
-import org.apache.fontbox.cff.CharStringRenderer;
import org.apache.pdfbox.encoding.Encoding;
/**
@@ -80,14 +79,13 @@ public class CFFGlyph2D implements Glyph
codeToName.put(key, encodingCodeToName.get(key));
}
}
- CharStringRenderer renderer = cffFont.createRenderer();
int glyphId = 0;
for (CFFFont.Mapping mapping : mappings)
{
GeneralPath glyph = null;
try
{
- glyph = renderer.render(mapping.toType1Sequence());
+ glyph = mapping.getType1CharString().getPath();
}
catch (IOException exception)
{