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/06/22 15:25:35 UTC
svn commit: r1604572 - in /pdfbox/trunk:
fontbox/src/main/java/org/apache/fontbox/cff/
fontbox/src/main/java/org/apache/fontbox/util/
pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/
Author: lehmi
Date: Sun Jun 22 13:25:34 2014
New Revision: 1604572
URL: http://svn.apache.org/r1604572
Log:
PDFBOX-2157: removed the AFMFormatter class, create FontMetric on the fly when parsing the CFF font
Removed:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/AFMFormatter.java
Modified:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/BoundingBox.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java
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=1604572&r1=1604571&r2=1604572&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 Jun 22 13:25:34 2014
@@ -26,6 +26,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.apache.fontbox.afm.FontMetric;
import org.apache.fontbox.cff.charset.CFFCharset;
import org.apache.fontbox.cff.encoding.CFFEncoding;
import org.apache.fontbox.type1.Type1CharStringReader;
@@ -48,7 +49,8 @@ public class CFFFont implements Type1Cha
private IndexData globalSubrIndex = null;
private IndexData localSubrIndex = null;
private Map<String, Type2CharString> charStringCache = new HashMap<String, Type2CharString>();
-
+ private FontMetric fontMetric = null;
+
/**
* The name of the font.
*
@@ -91,6 +93,54 @@ public class CFFFont implements Type1Cha
}
/**
+ * Returns the string value for the given name from the dictionary.
+ *
+ * @param name the name of the value
+ * @return the string value of the name if available
+ */
+ public String getPropertyAsString(String name)
+ {
+ Object value = getProperty(name);
+ if (value != null && value instanceof String)
+ {
+ return (String)value;
+ }
+ return null;
+ }
+
+ /**
+ * Returns the float value for the given name from the dictionary.
+ *
+ * @param name the name of the value
+ * @return the float value of the name if available
+ */
+ public float getPropertyAsFloat(String name, float defaultValue)
+ {
+ Object value = getProperty(name);
+ if (value != null && value instanceof Float)
+ {
+ return (Float)value;
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Returns the boolean value for the given name from the dictionary.
+ *
+ * @param name the name of the value
+ * @return the boolean value of the name if available
+ */
+ public boolean getPropertyAsBoolean(String name, boolean defaultValue)
+ {
+ Object value = getProperty(name);
+ if (value != null && value instanceof Boolean)
+ {
+ return (Boolean)value;
+ }
+ return defaultValue;
+ }
+
+ /**
* Adds the given key/value pair to the top dictionary.
*
* @param name the given key
@@ -315,6 +365,26 @@ public class CFFFont implements Type1Cha
}
/**
+ * Returns the FontMetric of the font.
+ *
+ * @return the font metrics
+ */
+ public FontMetric getFontMetric()
+ {
+ return fontMetric;
+ }
+
+ /**
+ * Sets the FontMetric of the font.
+ *
+ * @param metric the given FontMetric
+ */
+ public void setFontMetric(FontMetric metric)
+ {
+ fontMetric = metric;
+ }
+
+ /**
* Returns the SID for a given glyph name.
* @param name glyph name
* @return SID
Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java?rev=1604572&r1=1604571&r2=1604572&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java Sun Jun 22 13:25:34 2014
@@ -16,9 +16,11 @@
*/
package org.apache.fontbox.cff;
+import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
@@ -26,6 +28,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.apache.fontbox.afm.CharMetric;
+import org.apache.fontbox.afm.FontMetric;
import org.apache.fontbox.cff.CFFFont.Mapping;
import org.apache.fontbox.cff.charset.CFFCharset;
import org.apache.fontbox.cff.charset.CFFExpertCharset;
@@ -34,6 +38,7 @@ import org.apache.fontbox.cff.charset.CF
import org.apache.fontbox.cff.encoding.CFFEncoding;
import org.apache.fontbox.cff.encoding.CFFExpertEncoding;
import org.apache.fontbox.cff.encoding.CFFStandardEncoding;
+import org.apache.fontbox.util.BoundingBox;
/**
* This class represents a parser for a CFF font.
@@ -119,6 +124,7 @@ public class CFFParser
{
CFFFont font = parseFont(i);
font.setGlobalSubrIndex(globalSubrIndex);
+ createFontMetrics(font);
fonts.add(font);
}
return fonts;
@@ -567,7 +573,6 @@ public class CFFParser
font.setLocalSubrIndex(readIndexData(input));
}
}
-
return font;
}
@@ -1285,4 +1290,75 @@ public class CFFParser
}
}
}
+
+ private void createFontMetrics(CFFFont font) throws IOException
+ {
+ FontMetric fontMetrics = new FontMetric();
+ fontMetrics.setAFMVersion(2.0f);
+ fontMetrics.setFontName( font.getName() );
+ fontMetrics.setFullName( font.getPropertyAsString("FullName") );
+ fontMetrics.setFamilyName( font.getPropertyAsString("FamilyName") );
+ fontMetrics.setWeight( font.getPropertyAsString("Weight") );
+ CFFEncoding encoding = font.getEncoding();
+ if (encoding.isFontSpecific())
+ {
+ fontMetrics.setEncodingScheme("FontSpecific");
+ }
+ fontMetrics.setUnderlinePosition(font.getPropertyAsFloat("UnderlinePosition", -100));
+ fontMetrics.setUnderlineThickness(font.getPropertyAsFloat("UnderlineThickness", 50));
+ fontMetrics.setItalicAngle(font.getPropertyAsFloat("ItalicAngle", 0));
+ fontMetrics.setFixedPitch(font.getPropertyAsBoolean("isFixedPitch",false) );
+
+ List<CharMetricSortable> metrics = createCharMetrics(font);
+ Collections.sort(metrics);
+ BoundingBox bounds = null;
+ for (CharMetric metric : metrics)
+ {
+ fontMetrics.addCharMetric(metric);
+ if(bounds == null)
+ {
+ bounds = metric.getBoundingBox();
+ }
+ else
+ {
+ BoundingBox.union(bounds, metric.getBoundingBox(), bounds);
+ }
+ }
+ fontMetrics.setFontBBox(bounds);
+ font.setFontMetric(fontMetrics);
+ }
+
+ private List<CharMetricSortable> createCharMetrics(CFFFont font) throws IOException
+ {
+ List<CharMetricSortable> metrics = new ArrayList<CharMetricSortable>();
+ Collection<CFFFont.Mapping> mappings = font.getMappings();
+ for (CFFFont.Mapping mapping : mappings)
+ {
+ CharMetricSortable metric = new CharMetricSortable();
+ metric.setCharacterCode(mapping.getCode());
+ metric.setName(mapping.getName());
+ metric.setWx(mapping.getType1CharString().getWidth());
+ metric.setBBox(mapping.getType1CharString().getBounds());
+ metrics.add(metric);
+ }
+ return metrics;
+ }
+
+ /**
+ * This class represents the metric of one single character.
+ */
+ private static class CharMetricSortable extends CharMetric implements Comparable<CharMetric>
+ {
+ public int compareTo(CharMetric that)
+ {
+ return getCharacterCode() - that.getCharacterCode();
+ }
+
+ public void setBBox(Rectangle2D rect)
+ {
+ BoundingBox bBox = new BoundingBox((float)rect.getMinX(), (float)rect.getMinY(), (float)rect.getMaxX(), (float)rect.getMaxY());
+ setBoundingBox(bBox);
+ }
+ }
+
}
Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/BoundingBox.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/BoundingBox.java?rev=1604572&r1=1604571&r2=1604572&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/BoundingBox.java (original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/util/BoundingBox.java Sun Jun 22 13:25:34 2014
@@ -16,14 +16,12 @@
*/
package org.apache.fontbox.util;
-import java.awt.Point;
/**
* This is an implementation of a bounding box. This was originally written for the
* AMF parser.
*
* @author Ben Litchfield (ben@benlitchfield.com)
- * @version $Revision: 1.1 $
*/
public class BoundingBox
{
@@ -171,18 +169,6 @@ public class BoundingBox
}
/**
- * Checks if a point is inside this rectangle.
- *
- * @param point The point to check
- *
- * @return true If the point is on the edge or inside the rectangle bounds.
- */
- public boolean contains( Point point )
- {
- return contains( (float)point.getX(), (float)point.getY() );
- }
-
- /**
* This will return a string representation of this rectangle.
*
* @return This object as a string.
@@ -193,4 +179,33 @@ public class BoundingBox
getUpperRightX() + "," + getUpperRightY() +"]";
}
+ /**
+ * Unions the given bounding boxes and puts the result into the
+ * specified result bounding box.
+ *
+ * @param bBox1 the first bounding box to be combined with each other
+ * @param bBox2 the second bounding box to be combined with each other
+ * @param result the bounding box that holds the results of the union
+ *
+ */
+ public static void union(BoundingBox bBox1, BoundingBox bBox2, BoundingBox result)
+ {
+ float x1 = Math.min(bBox1.getLowerLeftX(), bBox2.getLowerLeftX());
+ float y1 = Math.min(bBox1.getLowerLeftY(), bBox2.getLowerLeftY());
+ float x2 = Math.max(bBox1.getUpperRightX(), bBox2.getUpperRightX());
+ float y2 = Math.max(bBox1.getUpperRightY(), bBox2.getUpperRightY());
+ if (x2 < x1)
+ {
+ float temp = x1;
+ x1 = x2;
+ x2 = temp;
+ }
+ if (y2 < y1)
+ {
+ float temp = y1;
+ y1 = y2;
+ y2 = temp;
+ }
+ result = new BoundingBox(x1, y1, x2, y2);
+ }
}
\ No newline at end of file
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java?rev=1604572&r1=1604571&r2=1604572&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType1CFont.java Sun Jun 22 13:25:34 2014
@@ -17,7 +17,6 @@
package org.apache.pdfbox.pdmodel.font;
-import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -30,12 +29,9 @@ import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.fontbox.afm.AFMParser;
import org.apache.fontbox.afm.FontMetric;
-import org.apache.fontbox.cff.AFMFormatter;
import org.apache.fontbox.cff.CFFFont;
import org.apache.fontbox.cff.CFFParser;
-import org.apache.fontbox.util.BoundingBox;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSFloat;
@@ -251,14 +247,7 @@ public class PDType1CFont extends PDFont
{
if (fontMetric == null)
{
- try
- {
- fontMetric = prepareFontMetric(cffFont);
- }
- catch (IOException exception)
- {
- LOG.error("An error occured while extracting the font metrics!", exception);
- }
+ fontMetric = cffFont.getFontMetric();
}
return fontMetric;
}
@@ -361,31 +350,6 @@ public class PDType1CFont extends PDFont
return null;
}
- private FontMetric prepareFontMetric(CFFFont font) throws IOException
- {
- byte[] afmBytes = AFMFormatter.format(font);
-
- InputStream is = new ByteArrayInputStream(afmBytes);
- try
- {
- AFMParser afmParser = new AFMParser(is);
- FontMetric result = afmParser.parse();
-
- // Replace default FontBBox value with a newly computed one
- BoundingBox bounds = result.getFontBBox();
- List<Integer> numbers = Arrays.asList((int) bounds.getLowerLeftX(),
- (int) bounds.getLowerLeftY(), (int) bounds.getUpperRightX(),
- (int) bounds.getUpperRightY());
- font.addValueToTopDict("FontBBox", numbers);
-
- return result;
- }
- finally
- {
- is.close();
- }
- }
-
/**
* Returns the raw data of the font as CFFFont.
*