Browse Source

replaced fontbox snapshot jar by a patched released jar (patch files added to lib)

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1547340 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-2_0
Luis Bernardo 10 years ago
parent
commit
9a7c9f11ff
3 changed files with 1133 additions and 0 deletions
  1. BIN
      lib/fontbox-1.8.3-patched.jar
  2. 395
    0
      lib/pdfbox-1645.patch
  3. 738
    0
      lib/pdfbox-1646.patch

BIN
lib/fontbox-1.8.0-SNAPSHOT.jar → lib/fontbox-1.8.3-patched.jar View File


+ 395
- 0
lib/pdfbox-1645.patch View File

@@ -0,0 +1,395 @@
Index: fontbox/src/test/java/org/apache/fontbox/cff/CharStringRendererTest.java
===================================================================
--- fontbox/src/test/java/org/apache/fontbox/cff/CharStringRendererTest.java (revision 0)
+++ fontbox/src/test/java/org/apache/fontbox/cff/CharStringRendererTest.java (revision 0)
@@ -0,0 +1,28 @@
+package org.apache.fontbox.cff;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+public class CharStringRendererTest {
+
+ @Test
+ public void testArgumentValidation() {
+ CharStringRenderer renderer = new CharStringRenderer();
+ List<Integer> numbers = new ArrayList<Integer>();
+ for (int i = 0;i < 4;i++) {
+ numbers.add(1);
+ }
+ assertTrue(renderer.hasValidArguments("vhcurveto", numbers));
+ numbers.add(1);
+ assertTrue(renderer.hasValidArguments("vvcurveto", numbers));
+ for (int i = 0;i < 3;i++) {
+ numbers.add(1);
+ }
+ assertTrue(renderer.hasValidArguments("rcurveline", numbers));
+ }
+
+}
Index: fontbox/src/main/java/org/apache/fontbox/cff/AFMFormatter.java
===================================================================
--- fontbox/src/main/java/org/apache/fontbox/cff/AFMFormatter.java (revision 1546564)
+++ fontbox/src/main/java/org/apache/fontbox/cff/AFMFormatter.java (working copy)
@@ -27,7 +27,7 @@
/**
* This class creates all needed AFM font metric data from a CFFFont ready to be read from a AFMPaser.
- *
+ *
* @author Villu Ruusmann
* @version $Revision$
*/
@@ -125,7 +125,7 @@
metric.name = mapping.getName();
renderer.render(mapping.toType1Sequence());
metric.width = renderer.getWidth();
- metric.bounds = renderer.getBounds();
+ metric.bounds = renderer.getBounds2D();
metrics.add(metric);
}
return metrics;
@@ -150,7 +150,7 @@
}
/**
- * This class represents the metric of one single character.
+ * This class represents the metric of one single character.
*
*/
private static class CharMetric implements Comparable<CharMetric>
Index: fontbox/src/main/java/org/apache/fontbox/cff/CharStringRenderer.java
===================================================================
--- fontbox/src/main/java/org/apache/fontbox/cff/CharStringRenderer.java (revision 1546564)
+++ fontbox/src/main/java/org/apache/fontbox/cff/CharStringRenderer.java (working copy)
@@ -16,9 +16,11 @@
*/
package org.apache.fontbox.cff;
+import java.awt.Point;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
+import java.util.HashMap;
import java.util.List;
import org.apache.commons.logging.Log;
@@ -33,7 +35,7 @@
{
// TODO CharStringRenderer as abstract Class with two inherited classes according to the Charsstring type....
private static final Log LOG = LogFactory.getLog(CharStringRenderer.class);
-
+
private boolean isCharstringType1 = true;
private boolean isFirstCommand = true;
@@ -42,6 +44,8 @@
private Point2D referencePoint = null;
private int width = 0;
private boolean hasNonEndCharOp = false;
+ private int[] bbox = {0,0,0,0};
+ private HashMap<String, String> vStrings;
/**
* Constructor for the char string renderer.
@@ -100,7 +104,7 @@
private void handleCommandType2(List<Integer> numbers, CharStringCommand command)
{
String name = CharStringCommand.TYPE2_VOCABULARY.get(command.getKey());
-
+ checkArguments(name, numbers);
if (!hasNonEndCharOp)
{
hasNonEndCharOp = !"endchar".equals(name);
@@ -176,7 +180,7 @@
setWidth(numbers.get(0));
rmoveTo(numbers.get(1), numbers.get(2));
}
- else
+ else if (numbers.size() == 2)
{
rmoveTo(numbers.get(0), numbers.get(1));
}
@@ -192,7 +196,7 @@
setWidth(numbers.get(0));
rmoveTo(numbers.get(1), Integer.valueOf(0));
}
- else
+ else if (numbers.size() == 1)
{
rmoveTo(numbers.get(0), Integer.valueOf(0));
}
@@ -284,6 +288,61 @@
}
}
+ void checkArguments(String name, List<Integer> numbers) {
+ if (name == null) {
+ return;
+ }
+ boolean valid = hasValidArguments(name, numbers);
+ if (!valid) {
+ //Initialize the validation strings if not already done
+ if (vStrings == null) {
+ vStrings = new HashMap<String, String>();
+ vStrings.put("vmoveto", "1 || 2");
+ vStrings.put("rlineto", "3 || % 2");
+ vStrings.put("rrcurveto", "7 || % 6");
+ vStrings.put("rlinecurve", "% 2 || 6 + % 2");
+ vStrings.put("rcurveline", "% 6 || 2 + % 6");
+ vStrings.put("rmoveto", "2 || 3");
+ vStrings.put("hmoveto", "1 || 2");
+ vStrings.put("vhcurveto", "% 4 || 1 + % 4");
+ vStrings.put("hvcurveto", "% 4 || 1 + % 4");
+ vStrings.put("vvcurveto", "% 4 || 1 + % 4");
+ }
+ LOG.info(String.format("Font has an unexpected number of parameters for operator '%s'. Arguments "+
+ "size %d did not match pattern '%s'", name, numbers.size(),
+ vStrings.get(name)));
+ }
+ }
+
+ boolean hasValidArguments(String name, List<Integer> numbers) {
+ boolean valid = true;
+ if (name.equals("vmoveto")) {
+ valid = (numbers.size() == 1 || numbers.size() == 2);
+ }
+ if (name.equals("rlineto")) {
+ valid = (numbers.size() == 3 || numbers.size() % 2 == 0);
+ }
+ if (name.equals("rrcurveto")) {
+ valid = (numbers.size() == 7 || numbers.size() % 6 == 0);
+ }
+ if (name.equals("rlinecurve")) {
+ valid = (numbers.size() % 2 == 0 || (numbers.size() - 6) % 2 == 0);
+ }
+ if (name.equals("rcurveline")) {
+ valid = (numbers.size() % 6 == 0 || (numbers.size() - 2) % 6 == 0);
+ }
+ if (name.equals("rmoveto")) {
+ valid = (numbers.size() == 2 || numbers.size() == 3);
+ }
+ if (name.equals("hmoveto")) {
+ valid = (numbers.size() == 1 || numbers.size() == 2);
+ }
+ if (name.equals("vvcurveto") || name.equals("vhcurveto") || name.equals("hvcurveto")) {
+ valid = (numbers.size() % 4 == 0 || (numbers.size() - 1) % 4 == 0);
+ }
+ return valid;
+ }
+
/**
*
* @param numbers
@@ -353,11 +412,14 @@
Point2D point = referencePoint;
if (point == null)
{
- point = path.getCurrentPoint();
- if (point == null)
+ if (path.getCurrentPoint() == null)
{
point = sidebearingPoint;
}
+ else
+ {
+ point = path.getCurrentPoint();
+ }
}
referencePoint = null;
path.moveTo((float)(point.getX() + dx.doubleValue()),
@@ -397,15 +459,20 @@
private void rlineTo(Number dx, Number dy)
{
Point2D point = path.getCurrentPoint();
- path.lineTo((float)(point.getX() + dx.doubleValue()),
- (float)(point.getY() + dy.doubleValue()));
+ if (point != null) {
+ updateBBox(dx.intValue(), dy.intValue());
+ path.lineTo((float)(point.getX() + dx.doubleValue()),
+ (float)(point.getY() + dy.doubleValue()));
+ }
}
private void rrlineTo(List<Integer> numbers)
{
for (int i = 0;i < numbers.size();i += 2)
{
- rlineTo(numbers.get(i), numbers.get(i + 1));
+ if (numbers.size() - i >= 2) {
+ rlineTo(numbers.get(i), numbers.get(i + 1));
+ }
}
}
@@ -415,13 +482,15 @@
{
for (int i = 0;i < numbers.size();i += 6)
{
- float x1 = numbers.get(i);
- float y1 = numbers.get(i + 1);
- float x2 = numbers.get(i + 2);
- float y2 = numbers.get(i + 3);
- float x3 = numbers.get(i + 4);
- float y3 = numbers.get(i + 5);
- rrcurveTo(x1, y1, x2, y2, x3, y3);
+ if (numbers.size() - i >= 6) {
+ float x1 = numbers.get(i);
+ float y1 = numbers.get(i + 1);
+ float x2 = numbers.get(i + 2);
+ float y2 = numbers.get(i + 3);
+ float x3 = numbers.get(i + 4);
+ float y3 = numbers.get(i + 5);
+ rrcurveTo(x1, y1, x2, y2, x3, y3);
+ }
}
}
}
@@ -429,14 +498,42 @@
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);
+ Point2D p0 = path.getCurrentPoint();
+ if (p0 != null) {
+ float x1 = (float) p0.getX() + dx1.floatValue();
+ float y1 = (float) p0.getY() + dy1.floatValue();
+ float x2 = x1 + dx2.floatValue();
+ float y2 = y1 + dy2.floatValue();
+ float x3 = x2 + dx3.floatValue();
+ float y3 = y2 + dy3.floatValue( );
+
+ Point p1 = new Point((int)x1, (int)y1);
+ Point p2 = new Point((int)x2, (int)y2);
+ Point p3 = new Point((int)x3, (int)y3);
+
+ updateBBox((int)p0.getX(), (int)p0.getY());
+ updateBBox((int)p3.getX(), (int)p3.getY());
+
+ int[] abc = calculateABC((int)p0.getX(), p1.x, p2.x, p3.x);
+ double[] txs = getT(abc);
+ for (double tx : txs) {
+ if (tx > 0 && tx < 1) {
+ int[] XandY = getXandY(tx, new Point((int)p0.getX(), (int)p0.getY()), p1, p2, p3);
+ updateBBox(XandY[0], XandY[1]);
+ }
+ }
+
+ abc = calculateABC((int)p0.getY(), p1.y, p2.y, p3.y);
+ double[] tys = getT(abc);
+ for (double ty : tys) {
+ if (ty > 0 && ty < 1) {
+ int[] XandY = getXandY(ty, new Point((int)p0.getX(), (int)p0.getY()), p1, p2, p3);
+ updateBBox(XandY[0], XandY[1]);
+ }
+ }
+
+ path.curveTo(x1, y1, x2, y2, x3, y3);
+ }
}
@@ -646,7 +743,9 @@
private void closePath()
{
referencePoint = path.getCurrentPoint();
- path.closePath();
+ if (referencePoint != null) {
+ path.closePath();
+ }
}
private void pointSb(Number x, Number y)
@@ -658,11 +757,15 @@
* Returns the bounds of the renderer path.
* @return the bounds as Rectangle2D
*/
- public Rectangle2D getBounds()
+ public int[] getBounds()
{
- return path.getBounds2D();
+ return bbox;
}
+ public Rectangle2D getBounds2D() {
+ return path.getBounds2D();
+ }
+
/**
* Returns the width of the current command.
* @return the width
@@ -676,4 +779,61 @@
{
this.width = aWidth;
}
-}
\ No newline at end of file
+
+ private int[] calculateABC(int p0, int p1, int p2, int p3) {
+ int[] abc = new int[3];
+ abc[0] = p0 - 3 * p1 + 3 * p2 - p3;
+ abc[1] = 2 * (-p0 + 2 * p1 - p2);
+ abc[2] = p0 - p1;
+ return abc;
+ }
+
+ private double[] getT(int[] abc) {
+ double[] t = {-1, -1};
+ int a = abc[0];
+ int b = abc[1];
+ int c = abc[2];
+ double s = Math.pow(b, 2) - 4 * a * c;
+ if (a == 0) {
+ if (b != 0) {
+ t[0] = -c / b;
+ }
+ return t;
+ } else if (s > 0) {
+ t[0] = (-b + Math.sqrt(s)) / 2 / a;
+ t[1] = (-b - Math.sqrt(s)) / 2 / a;
+ return t;
+ } else if (s == 0) {
+ t[0] = -b / 2 / a;
+ return t;
+ } else {
+ return t;
+ }
+ }
+
+ private int[] getXandY(double t, Point p0, Point p1, Point p2, Point p3) {
+ int[] XandY = new int[2];
+ double p0Coeff = Math.pow(1 - t, 3);
+ double p1Coeff = 3 * t * Math.pow(1 - t, 2);
+ double p2Coeff = 3 * Math.pow(t, 2) * (1 - t);
+ double p3Coeff = Math.pow(t, 3);
+ double x = p0Coeff * p0.x + p1Coeff * p1.x + p2Coeff * p2.x + p3Coeff * p3.x;
+ double y = p0Coeff * p0.y + p1Coeff * p1.y + p2Coeff * p2.y + p3Coeff * p3.y;
+ XandY[0] = (int)x;
+ XandY[1] = (int)y;
+ return XandY;
+ }
+
+ private void updateBBox(int x, int y) {
+ if (x < bbox[0]) {
+ bbox[0] = x;
+ } else if (x > bbox[2]) {
+ bbox[2] = x;
+ }
+ if (y < bbox[1]) {
+ bbox[1] = y;
+ } else if (y > bbox[3]) {
+ bbox[3] = y;
+ }
+ }
+}

+ 738
- 0
lib/pdfbox-1646.patch View File

@@ -0,0 +1,738 @@
Index: fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java
===================================================================
--- fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java (revision 1546564)
+++ fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java (working copy)
@@ -36,7 +36,7 @@
import org.apache.fontbox.cff.encoding.CFFStandardEncoding;
/**
- * This class represents a parser for a CFF font.
+ * This class represents a parser for a CFF font.
* @author Villu Ruusmann
* @version $Revision: 1.0 $
*/
@@ -107,7 +107,11 @@
{
input.setPosition(0);
}
+ return parse(input);
+ }
+ public List<CFFFont> parse(CFFDataInput input) throws IOException {
+ this.input = input;
header = readHeader(input);
nameIndex = readIndexData(input);
topDictIndex = readIndexData(input);
@@ -119,6 +123,7 @@
{
CFFFont font = parseFont(i);
font.setGlobalSubrIndex(globalSubrIndex);
+ font.constructMappings();
fonts.add(font);
}
return fonts;
@@ -145,7 +150,7 @@
return cffHeader;
}
- private static IndexData readIndexData(CFFDataInput input) throws IOException
+ public static IndexData readIndexData(CFFDataInput input) throws IOException
{
int count = input.readCard16();
IndexData index = new IndexData(count);
@@ -179,7 +184,8 @@
return dict;
}
- private static DictData.Entry readEntry(CFFDataInput input) throws IOException
+ private static DictData.Entry readEntry(CFFDataInput input)
+ throws IOException
{
DictData.Entry entry = new DictData.Entry();
while (true)
@@ -211,13 +217,15 @@
return entry;
}
- private static CFFOperator readOperator(CFFDataInput input, int b0) throws IOException
+ private static CFFOperator readOperator(CFFDataInput input, int b0)
+ throws IOException
{
CFFOperator.Key key = readOperatorKey(input, b0);
return CFFOperator.getOperator(key);
}
- private static CFFOperator.Key readOperatorKey(CFFDataInput input, int b0) throws IOException
+ private static CFFOperator.Key readOperatorKey(CFFDataInput input, int b0)
+ throws IOException
{
if (b0 == 12)
{
@@ -227,7 +235,8 @@
return new CFFOperator.Key(b0);
}
- private static Integer readIntegerNumber(CFFDataInput input, int b0) throws IOException
+ private static Integer readIntegerNumber(CFFDataInput input, int b0)
+ throws IOException
{
if (b0 == 28)
{
@@ -263,7 +272,8 @@
}
}
- private static Double readRealNumber(CFFDataInput input, int b0) throws IOException
+ private static Double readRealNumber(CFFDataInput input, int b0)
+ throws IOException
{
StringBuffer sb = new StringBuffer();
boolean done = false;
@@ -446,9 +456,9 @@
throw new IOException("FDArray is missing for a CIDKeyed Font.");
}
- int fontDictOffset = fdArrayEntry.getNumber(0).intValue();
- input.setPosition(fontDictOffset);
- IndexData fdIndex = readIndexData(input);
+ int fontDictOffset = fdArrayEntry.getNumber(0).intValue();
+ input.setPosition(fontDictOffset);
+ IndexData fdIndex = readIndexData(input);
List<Map<String, Object>> privateDictionaries = new LinkedList<Map<String, Object>>();
List<Map<String, Object>> fontDictionaries = new LinkedList<Map<String, Object>>();
@@ -577,8 +587,8 @@
{
return CFFStandardString.getName(index);
}
- if (index - 391 <= stringIndex.getCount())
- {
+ if (index - 391 < stringIndex.getCount())
+ {
DataInput dataInput = new DataInput(stringIndex.getBytes(index - 391));
return dataInput.getString();
}
@@ -620,7 +630,8 @@
return entry != null ? entry.getArray() : defaultValue;
}
- private CFFEncoding readEncoding(CFFDataInput dataInput, int[] gids) throws IOException
+ private CFFEncoding readEncoding(CFFDataInput dataInput, int[] gids)
+ throws IOException
{
int format = dataInput.readCard8();
int baseFormat = format & 0x7f;
@@ -639,7 +650,8 @@
}
}
- private Format0Encoding readFormat0Encoding(CFFDataInput dataInput, int format, int[] gids) throws IOException
+ private Format0Encoding readFormat0Encoding(CFFDataInput dataInput, int format,
+ int[] gids) throws IOException
{
Format0Encoding encoding = new Format0Encoding();
encoding.format = format;
@@ -657,7 +669,8 @@
return encoding;
}
- private Format1Encoding readFormat1Encoding(CFFDataInput dataInput, int format, int[] gids) throws IOException
+ private Format1Encoding readFormat1Encoding(CFFDataInput dataInput, int format,
+ int[] gids) throws IOException
{
Format1Encoding encoding = new Format1Encoding();
encoding.format = format;
@@ -683,7 +696,8 @@
return encoding;
}
- private void readSupplement(CFFDataInput dataInput, EmbeddedEncoding encoding) throws IOException
+ private void readSupplement(CFFDataInput dataInput, EmbeddedEncoding encoding)
+ throws IOException
{
encoding.nSups = dataInput.readCard8();
encoding.supplement = new EmbeddedEncoding.Supplement[encoding.nSups];
@@ -738,15 +752,14 @@
fdselect.fds = new int[nGlyphs];
for (int i = 0; i < fdselect.fds.length; i++)
{
- fdselect.fds[i] = dataInput.readCard8();
-
+ fdselect.fds[i] = dataInput.readCard8();
}
return fdselect;
}
/**
* Read the Format 3 of the FDSelect data structure.
- *
+ *
* @param dataInput
* @param format
* @param nGlyphs
@@ -768,7 +781,6 @@
r3.first = dataInput.readCard16();
r3.fd = dataInput.readCard8();
fdselect.range3[i] = r3;
-
}
fdselect.sentinel = dataInput.readCard16();
@@ -902,7 +914,8 @@
}
}
- private CFFCharset readCharset(CFFDataInput dataInput, int nGlyphs) throws IOException
+ private CFFCharset readCharset(CFFDataInput dataInput, int nGlyphs)
+ throws IOException
{
int format = dataInput.readCard8();
if (format == 0)
@@ -923,7 +936,8 @@
}
}
- private Format0Charset readFormat0Charset(CFFDataInput dataInput, int format, int nGlyphs) throws IOException
+ private Format0Charset readFormat0Charset(CFFDataInput dataInput, int format,
+ int nGlyphs) throws IOException
{
Format0Charset charset = new Format0Charset();
charset.format = format;
@@ -936,7 +950,8 @@
return charset;
}
- private Format1Charset readFormat1Charset(CFFDataInput dataInput, int format, int nGlyphs) throws IOException
+ private Format1Charset readFormat1Charset(CFFDataInput dataInput, int format,
+ int nGlyphs) throws IOException
{
Format1Charset charset = new Format1Charset();
charset.format = format;
@@ -957,7 +972,8 @@
return charset;
}
- private Format2Charset readFormat2Charset(CFFDataInput dataInput, int format, int nGlyphs) throws IOException
+ private Format2Charset readFormat2Charset(CFFDataInput dataInput, int format,
+ int nGlyphs) throws IOException
{
Format2Charset charset = new Format2Charset();
charset.format = format;
@@ -981,7 +997,7 @@
}
/**
- * Inner class holding the header of a CFF font.
+ * Inner class holding the header of a CFF font.
*/
private static class Header
{
@@ -999,7 +1015,7 @@
}
/**
- * Inner class holding the DictData of a CFF font.
+ * Inner class holding the DictData of a CFF font.
*/
private static class DictData
{
@@ -1030,7 +1046,7 @@
}
/**
- * {@inheritDoc}
+ * {@inheritDoc}
*/
public String toString()
{
@@ -1038,7 +1054,7 @@
}
/**
- * Inner class holding an operand of a CFF font.
+ * Inner class holding an operand of a CFF font.
*/
private static class Entry
{
@@ -1100,7 +1116,7 @@
}
/**
- * Inner class representing an embedded CFF encoding.
+ * Inner class representing an embedded CFF encoding.
*/
abstract static class EmbeddedEncoding extends CFFEncoding
{
@@ -1124,7 +1140,7 @@
}
/**
- * Inner class representing a supplement for an encoding.
+ * Inner class representing a supplement for an encoding.
*/
static class Supplement
{
@@ -1150,7 +1166,7 @@
}
/**
- * Inner class representing a Format0 encoding.
+ * Inner class representing a Format0 encoding.
*/
private static class Format0Encoding extends EmbeddedEncoding
{
@@ -1167,7 +1183,7 @@
}
/**
- * Inner class representing a Format1 encoding.
+ * Inner class representing a Format1 encoding.
*/
private static class Format1Encoding extends EmbeddedEncoding
{
@@ -1183,7 +1199,7 @@
}
/**
- * Inner class representing a range of an encoding.
+ * Inner class representing a range of an encoding.
*/
private static class Range1
{
@@ -1193,13 +1209,20 @@
@Override
public String toString()
{
- return getClass().getName() + "[first=" + first + ", nLeft=" + nLeft + "]";
+ return getClass().getName() + "[first=" + first + ", nLeft="
+ + nLeft + "]";
}
+
+ @Override
+ public boolean equals(Object obj) {
+ Range1 r = (Range1)obj;
+ return (first == r.first && nLeft == r.nLeft);
+ }
}
}
/**
- * Inner class representing an embedded CFF charset.
+ * Inner class representing an embedded CFF charset.
*/
abstract static class EmbeddedCharset extends CFFCharset
{
@@ -1211,7 +1234,7 @@
}
/**
- * Inner class representing a Format0 charset.
+ * Inner class representing a Format0 charset.
*/
private static class Format0Charset extends EmbeddedCharset
{
@@ -1226,7 +1249,7 @@
}
/**
- * Inner class representing a Format1 charset.
+ * Inner class representing a Format1 charset.
*/
private static class Format1Charset extends EmbeddedCharset
{
@@ -1240,7 +1263,7 @@
}
/**
- * Inner class representing a range of a charset.
+ * Inner class representing a range of a charset.
*/
private static class Range1
{
@@ -1256,7 +1279,7 @@
}
/**
- * Inner class representing a Format2 charset.
+ * Inner class representing a Format2 charset.
*/
private static class Format2Charset extends EmbeddedCharset
{
@@ -1270,7 +1293,7 @@
}
/**
- * Inner class representing a range of a charset.
+ * Inner class representing a range of a charset.
*/
private static class Range2
{
@@ -1284,4 +1307,8 @@
}
}
}
+
+ public IndexData getStringIndex() {
+ return stringIndex;
+ }
}
Index: fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java
===================================================================
--- fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java (revision 1546564)
+++ fontbox/src/main/java/org/apache/fontbox/cff/CFFFont.java (working copy)
@@ -31,7 +31,7 @@
/**
* This class represents a CFF/Type2 Font.
- *
+ *
* @author Villu Ruusmann
* @version $Revision$
*/
@@ -44,6 +44,8 @@
private CFFEncoding fontEncoding = null;
private CFFCharset fontCharset = null;
private Map<String, byte[]> charStringsDict = new LinkedHashMap<String, byte[]>();
+ Map<Integer, Mapping> sidMappings = null;
+ ArrayList<Mapping> gidMappings = null;
private IndexData globalSubrIndex = null;
private IndexData localSubrIndex = null;
@@ -97,6 +99,7 @@
topDict.put(name, value);
}
}
+
/**
* Returns the top dictionary.
* @return the dictionary
@@ -107,7 +110,7 @@
}
/**
- * Adds the given key/value pair to the private dictionary.
+ * Adds the given key/value pair to the private dictionary.
* @param name the given key
* @param value the given value
*/
@@ -118,7 +121,8 @@
privateDict.put(name, value);
}
}
- /**
+
+ /**
* Returns the private dictionary.
* @return the dictionary
*/
@@ -127,14 +131,60 @@
return privateDict;
}
+ /**
+ * Returns a mapping for a given GID
+ * @param GID The given GID
+ * @return The found mapping
+ */
+ public Mapping getMapping(int GID) {
+ return sidMappings.get(GID);
+ }
+
/**
- * Get the mapping (code/SID/charname/bytes) for this font.
- * @return mappings for codes < 256 and for codes > = 256
- */
- public Collection<Mapping> getMappings()
+ * Get the mapping (code/SID/charname/bytes) for this font.
+ * @return mappings for codes < 256 and for codes > = 256
+ */
+ public Collection<Mapping> getMappings() {
+ constructMappings();
+ return sidMappings.values();
+ }
+
+ /**
+ * Gets the GID mappings list.
+ */
+ public ArrayList<Mapping> getGIDMappings() {
+ return gidMappings;
+ }
+
+ private void constructGIDMap() {
+ gidMappings = new ArrayList<Mapping>();
+ Mapping notdef = new Mapping();
+ notdef.setName(".notdef");
+ gidMappings.add(notdef);
+ for (CFFCharset.Entry entry : fontCharset.getEntries())
+ {
+ String name = entry.getName();
+ byte[] bytes = this.charStringsDict.get(name);
+ if (bytes == null)
+ {
+ continue;
+ }
+ Mapping mapping = new Mapping();
+ mapping.setSID(entry.getSID());
+ mapping.setName(name);
+ mapping.setBytes(bytes);
+ gidMappings.add(mapping);
+ }
+ }
+
+ /**
+ * Construct the mappings.
+ */
+ public void constructMappings()
{
- List<Mapping> mappings = new ArrayList<Mapping>();
- Set<String> mappedNames = new HashSet<String>();
+ constructGIDMap();
+ sidMappings = new LinkedHashMap<Integer, Mapping>();
+ Set<String> mappedNames = new HashSet<String>();
for (CFFEncoding.Entry entry : fontEncoding.getEntries())
{
String charName = fontCharset.getName(entry.getSID());
@@ -153,7 +203,7 @@
mapping.setSID(entry.getSID());
mapping.setName(charName);
mapping.setBytes(bytes);
- mappings.add(mapping);
+ sidMappings.put(mapping.getSID(), mapping);
mappedNames.add(charName);
}
if (fontEncoding instanceof CFFParser.EmbeddedEncoding)
@@ -177,7 +227,7 @@
mapping.setSID(supplement.getGlyph());
mapping.setName(charName);
mapping.setBytes(bytes);
- mappings.add(mapping);
+ sidMappings.put(mapping.getSID(), mapping);
mappedNames.add(charName);
}
}
@@ -185,7 +235,7 @@
int code = 256;
for (CFFCharset.Entry entry : fontCharset.getEntries())
{
- String name = entry.getName();
+ String name = entry.getName();
if (mappedNames.contains(name))
{
continue;
@@ -201,11 +251,10 @@
mapping.setName(name);
mapping.setBytes(bytes);
- mappings.add(mapping);
+ sidMappings.put(mapping.getSID(), mapping);
mappedNames.add(name);
}
- return mappings;
}
/**
@@ -215,34 +264,43 @@
* @return -1 if the SID is missing from the Font.
* @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) {
+ 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;
+ Mapping m = sidMappings.get(SID);
+ if (m != null) {
+ CharStringRenderer csr = getRendererForMapping(m);
+ // ---- If the CharString has a Width nominalWidthX must be added,
+ // otherwise it is the default width.
+ return csr.getWidth() != 0 ? csr.getWidth() + nominalWidth : defaultWidth;
+ }
- 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);
- }
+ // ---- SID Width not found, return the nodef width
+ return getNotDefWidth(defaultWidth, nominalWidth);
+ }
- // ---- If the CharString has a Width nominalWidthX must be added,
- // otherwise it is the default width.
- return csr.getWidth() != 0 ? csr.getWidth() + nominalWidth : defaultWidth;
- }
- }
+ private CharStringRenderer getRendererForMapping(Mapping m) throws IOException {
+ 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);
+ }
+ return csr;
+ }
- // ---- SID Width not found, return the nodef width
- return getNotDefWidth(defaultWidth, nominalWidth);
- }
-
+ /**
+ * Returns the witdth of the .notdef character.
+ *
+ * @param defaultWidth default width
+ * @param nominalWidth nominal width
+ * @return the calculated width for the .notdef character
+ * @throws IOException if something went wrong
+ */
protected int getNotDefWidth(int defaultWidth, int nominalWidth) throws IOException {
CharStringRenderer csr;
byte[] glyphDesc = this.getCharStringsDict().get(".notdef");
@@ -260,6 +318,36 @@
return csr.getWidth() != 0 ? csr.getWidth() + nominalWidth : defaultWidth;
}
+ /**
+ * Return the Width value of the given Glyph identifier
+ *
+ * @param SID
+ * @return -1 if the SID is missing from the Font.
+ * @throws IOException
+ */
+ public int[] getBoundingBox(int SID) throws IOException {
+ Mapping m = sidMappings.get(SID);
+ if (m != null) {
+ CharStringRenderer csr = getRendererForMapping(m);
+ return csr.getBounds();
+ }
+ // ---- SID Width not found, return the nodef width
+ return new int[4];
+ }
+
+ /**
+ * Gets the name of a character from the given SID
+ * @param SID The given SID
+ * @return The name of the found character
+ */
+ public String getNameOfCharFromCode(int SID) {
+ if (sidMappings.get(SID) != null) {
+ return sidMappings.get(SID).getName();
+ } else {
+ return "";
+ }
+ }
+
/**
* Returns the CFFEncoding of the font.
* @return the encoding
@@ -336,50 +424,51 @@
+ charStringsDict + "]";
}
+ /**
+ * Sets the global subroutine index data.
+ * @param globalSubrIndex the IndexData object containing the global subroutines
+ */
+ public void setGlobalSubrIndex(IndexData globalSubrIndexValue) {
+ globalSubrIndex = globalSubrIndexValue;
+ }
- /**
- * Sets the global subroutine index data.
- * @param globalSubrIndex the IndexData object containing the global subroutines
- */
- public void setGlobalSubrIndex(IndexData globalSubrIndex) {
- this.globalSubrIndex = globalSubrIndex;
- }
+ /**
+ * Returns the global subroutine index data.
+ * @return the dictionary
+ */
+ public IndexData getGlobalSubrIndex()
+ {
+ return globalSubrIndex;
+ }
- /**
- * Returns the global subroutine index data.
- * @return the dictionary
- */
- public IndexData getGlobalSubrIndex() {
- return globalSubrIndex;
- }
+ /**
+ * Returns the local subroutine index data.
+ * @return the dictionary
+ */
+ public IndexData getLocalSubrIndex()
+ {
+ return localSubrIndex;
+ }
- /**
- * Returns the local subroutine index data.
- * @return the dictionary
- */
- public IndexData getLocalSubrIndex() {
- return localSubrIndex;
- }
+ /**
+ * Sets the local subroutine index data.
+ * @param localSubrIndexValue the IndexData object containing the local subroutines
+ */
+ public void setLocalSubrIndex(IndexData localSubrIndexValue) {
+ localSubrIndex = localSubrIndexValue;
+ }
- /**
- * Sets the local subroutine index data.
- * @param localSubrIndex the IndexData object containing the local subroutines
- */
- public void setLocalSubrIndex(IndexData localSubrIndex) {
- this.localSubrIndex = localSubrIndex;
- }
+ /**
+ * This class is used for the font mapping.
+ *
+ */
+ public class Mapping
+ {
+ private int mappedCode;
+ private int mappedSID;
+ private String mappedName;
+ private byte[] mappedBytes;
- /**
- * This class is used for the font mapping.
- *
- */
- public class Mapping
- {
- private int mappedCode;
- private int mappedSID;
- private String mappedName;
- private byte[] mappedBytes;
-
/**
* Converts the mapping into a Type1-sequence.
* @return the Type1-sequence
@@ -458,4 +547,4 @@
this.mappedBytes = bytes;
}
}
-}
\ No newline at end of file
+}

Loading…
Cancel
Save