Author: lehmi
Date: Mon Apr 9 16:05:55 2012
New Revision: 1311300
URL: http://svn.apache.org/viewvc?rev=1311300&view=rev
Log:
PDFBOX-490: improved TTFParser to read glyph information based on Apache Batik
code
Added:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfCompositeComp.java
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfCompositeDescript.java
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfDescript.java
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfSimpleDescript.java
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphDescription.java
Modified:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphData.java
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphTable.java
Added:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfCompositeComp.java
URL:
http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfCompositeComp.java?rev=1311300&view=auto
==============================================================================
---
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfCompositeComp.java
(added)
+++
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfCompositeComp.java
Mon Apr 9 16:05:55 2012
@@ -0,0 +1,293 @@
+/*
+
+ 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.ttf;
+
+import java.io.IOException;
+
+/**
+ * This class is based on code from Apache Batik a subproject of Apache
XMLGraphics.
+ * see http://xmlgraphics.apache.org/batik/ for further details.
+ */
+public class GlyfCompositeComp
+{
+
+ // Flags for composite glyphs.
+
+ /**
+ * If set, the arguments are words; otherwise, they are bytes.
+ */
+ protected static final short ARG_1_AND_2_ARE_WORDS = 0x0001;
+ /**
+ * If set, the arguments are xy values; otherwise they are points.
+ */
+ protected static final short ARGS_ARE_XY_VALUES = 0x0002;
+ /**
+ * If set, xy values are rounded to those of the closest grid lines.
+ */
+ protected static final short ROUND_XY_TO_GRID = 0x0004;
+ /**
+ * If set, there is a simple scale; otherwise, scale = 1.0.
+ */
+ protected static final short WE_HAVE_A_SCALE = 0x0008;
+ /**
+ * Indicates at least one more glyph after this one.
+ */
+ protected static final short MORE_COMPONENTS = 0x0020;
+ /**
+ * The x direction will use a different scale from the y direction.
+ */
+ protected static final short WE_HAVE_AN_X_AND_Y_SCALE = 0x0040;
+ /**
+ * There is a 2 by2 transformation that will be used to scale the
component.
+ */
+ protected static final short WE_HAVE_A_TWO_BY_TWO = 0x0080;
+ /**
+ * Following the last component are instructions for the composite
character.
+ */
+ protected static final short WE_HAVE_INSTRUCTIONS = 0x0100;
+ /**
+ * If set, this forces the aw and lsb (and rsb) for the composite to be
equal to
+ * those from this original glyph.
+ */
+ protected static final short USE_MY_METRICS = 0x0200;
+
+ private int firstIndex;
+ private int firstContour;
+ private short argument1;
+ private short argument2;
+ private short flags;
+ private int glyphIndex;
+ private double xscale = 1.0;
+ private double yscale = 1.0;
+ private double scale01 = 0.0;
+ private double scale10 = 0.0;
+ private int xtranslate = 0;
+ private int ytranslate = 0;
+ private int point1 = 0;
+ private int point2 = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param bais the stream to be read
+ * @throws IOException is thrown if something went wrong
+ */
+ protected GlyfCompositeComp(TTFDataStream bais) throws IOException
+ {
+ flags = bais.readSignedShort();
+ glyphIndex = bais.readSignedShort();
+
+ // Get the arguments as just their raw values
+ if ((flags & ARG_1_AND_2_ARE_WORDS) != 0)
+ {
+ argument1 = bais.readSignedShort();
+ argument2 = bais.readSignedShort();
+ }
+ else
+ {
+ argument1 = (short) bais.read();
+ argument2 = (short) bais.read();
+ }
+
+ // Assign the arguments according to the flags
+ if ((flags & ARGS_ARE_XY_VALUES) != 0)
+ {
+ xtranslate = argument1;
+ ytranslate = argument2;
+ }
+ else
+ {
+ point1 = argument1;
+ point2 = argument2;
+ }
+
+ // Get the scale values (if any)
+ if ((flags & WE_HAVE_A_SCALE) != 0)
+ {
+ int i = bais.readSignedShort();
+ xscale = yscale = (double) i / (double) 0x4000;
+ }
+ else if ((flags & WE_HAVE_AN_X_AND_Y_SCALE) != 0)
+ {
+ short i = bais.readSignedShort();
+ xscale = (double) i / (double) 0x4000;
+ i = bais.readSignedShort();
+ yscale = (double) i / (double) 0x4000;
+ }
+ else if ((flags & WE_HAVE_A_TWO_BY_TWO) != 0)
+ {
+ int i = bais.readSignedShort();
+ xscale = (double) i / (double) 0x4000;
+ i = bais.readSignedShort();
+ scale01 = (double) i / (double) 0x4000;
+ i = bais.readSignedShort();
+ scale10 = (double) i / (double) 0x4000;
+ i = bais.readSignedShort();
+ yscale = (double) i / (double) 0x4000;
+ }
+ }
+
+ /**
+ * Sets the first index.
+ * @param idx the first index
+ */
+ public void setFirstIndex(int idx)
+ {
+ firstIndex = idx;
+ }
+
+ /**
+ * Returns the first index.
+ * @return the first index.
+ */
+ public int getFirstIndex()
+ {
+ return firstIndex;
+ }
+
+ /**
+ * Sets the index for the first contour.
+ * @param idx the index of the first contour
+ */
+ public void setFirstContour(int idx)
+ {
+ firstContour = idx;
+ }
+
+ /**
+ * Returns the index of the first contour.
+ * @return the index of the first contour.
+ */
+ public int getFirstContour()
+ {
+ return firstContour;
+ }
+
+ /**
+ * Returns argument 1.
+ * @return argument 1.
+ */
+ public short getArgument1()
+ {
+ return argument1;
+ }
+
+ /**
+ * Returns argument 2.
+ * @return argument 2.
+ */
+ public short getArgument2()
+ {
+ return argument2;
+ }
+
+ /**
+ * Returns the flags of the glyph.
+ * @return the flags.
+ */
+ public short getFlags()
+ {
+ return flags;
+ }
+
+ /**
+ * Returns the index of the first contour.
+ * @return index of the first contour.
+ */
+ public int getGlyphIndex()
+ {
+ return glyphIndex;
+ }
+
+ /**
+ * Returns the scale-01 value.
+ * @return the scale-01 value.
+ */
+ public double getScale01()
+ {
+ return scale01;
+ }
+
+ /**
+ * Returns the scale-10 value.
+ * @return the scale-10 value.
+ */
+ public double getScale10()
+ {
+ return scale10;
+ }
+
+ /**
+ * Returns the x-scaling value.
+ * @return the x-scaling value.
+ */
+ public double getXScale()
+ {
+ return xscale;
+ }
+
+ /**
+ * Returns the y-scaling value.
+ * @return the y-scaling value.
+ */
+ public double getYScale()
+ {
+ return yscale;
+ }
+
+ /**
+ * Returns the x-translation value.
+ * @return the x-translation value.
+ */
+ public int getXTranslate()
+ {
+ return xtranslate;
+ }
+
+ /**
+ * Returns the y-translation value.
+ * @return the y-translation value.
+ */
+ public int getYTranslate()
+ {
+ return ytranslate;
+ }
+
+ /**
+ * Transforms an x-coordinate of a point for this component.
+ * @param x The x-coordinate of the point to transform
+ * @param y The y-coordinate of the point to transform
+ * @return The transformed x-coordinate
+ */
+ public int scaleX(int x, int y)
+ {
+ return Math.round((float)(x * xscale + y * scale10));
+ }
+
+ /**
+ * Transforms a y-coordinate of a point for this component.
+ * @param x The x-coordinate of the point to transform
+ * @param y The y-coordinate of the point to transform
+ * @return The transformed y-coordinate
+ */
+ public int scaleY(int x, int y)
+ {
+ return Math.round((float)(x * scale01 + y * yscale));
+ }
+}
Added:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfCompositeDescript.java
URL:
http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfCompositeDescript.java?rev=1311300&view=auto
==============================================================================
---
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfCompositeDescript.java
(added)
+++
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfCompositeDescript.java
Mon Apr 9 16:05:55 2012
@@ -0,0 +1,252 @@
+/*
+
+ 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.ttf;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+/**
+ * Glyph description for composite glyphs. Composite glyphs are made up of one
+ * or more simple glyphs, usually with some sort of transformation applied to
each.
+ *
+ * This class is based on code from Apache Batik a subproject of Apache
XMLGraphics.
+ * see http://xmlgraphics.apache.org/batik/ for further details.
+ */
+public class GlyfCompositeDescript extends GlyfDescript
+{
+
+ private List<GlyfCompositeComp> components = new
ArrayList<GlyfCompositeComp>();
+ private GlyphData[] glyphs = null;
+ private boolean beingResolved = false;
+ private boolean resolved = false;
+
+ /**
+ * Constructor.
+ *
+ * @param bais the stream to be read
+ * @param glyphTable the Glyphtable containing all glyphs
+ * @throws IOException is thrown if something went wrong
+ */
+ public GlyfCompositeDescript(TTFDataStream bais, GlyphTable glyphTable)
throws IOException
+ {
+ super((short) -1, bais);
+
+ glyphs = glyphTable.getGlyphs();
+
+ // Get all of the composite components
+ GlyfCompositeComp comp;
+ do
+ {
+ comp = new GlyfCompositeComp(bais);
+ components.add(comp);
+ }
+ while ((comp.getFlags() & GlyfCompositeComp.MORE_COMPONENTS) != 0);
+
+ // Are there hinting instructions to read?
+ if ((comp.getFlags() & GlyfCompositeComp.WE_HAVE_INSTRUCTIONS) != 0)
+ {
+ readInstructions(bais, (bais.read()<<8 | bais.read()));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void resolve()
+ {
+ if (resolved)
+ {
+ return;
+ }
+ if (beingResolved)
+ {
+ System.err.println("Circular reference in GlyfCompositeDesc");
+ return;
+ }
+ beingResolved = true;
+
+ int firstIndex = 0;
+ int firstContour = 0;
+
+ Iterator<GlyfCompositeComp> i = components.iterator();
+ while (i.hasNext())
+ {
+ GlyfCompositeComp comp = (GlyfCompositeComp)i.next();
+ comp.setFirstIndex(firstIndex);
+ comp.setFirstContour(firstContour);
+
+ GlyphDescription desc;
+ desc = getGlypDescription(comp.getGlyphIndex());
+ if (desc != null)
+ {
+ desc.resolve();
+ firstIndex += desc.getPointCount();
+ firstContour += desc.getContourCount();
+ }
+ }
+ resolved = true;
+ beingResolved = false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getEndPtOfContours(int i)
+ {
+ GlyfCompositeComp c = getCompositeCompEndPt(i);
+ if (c != null)
+ {
+ GlyphDescription gd = getGlypDescription(c.getGlyphIndex());
+ return gd.getEndPtOfContours(i - c.getFirstContour()) +
c.getFirstIndex();
+ }
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public byte getFlags(int i)
+ {
+ GlyfCompositeComp c = getCompositeComp(i);
+ if (c != null)
+ {
+ GlyphDescription gd = getGlypDescription(c.getGlyphIndex());
+ return gd.getFlags(i - c.getFirstIndex());
+ }
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public short getXCoordinate(int i)
+ {
+ GlyfCompositeComp c = getCompositeComp(i);
+ if (c != null)
+ {
+ GlyphDescription gd = getGlypDescription(c.getGlyphIndex());
+ int n = i - c.getFirstIndex();
+ int x = gd.getXCoordinate(n);
+ int y = gd.getYCoordinate(n);
+ short x1 = (short) c.scaleX(x, y);
+ x1 += c.getXTranslate();
+ return x1;
+ }
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public short getYCoordinate(int i)
+ {
+ GlyfCompositeComp c = getCompositeComp(i);
+ if (c != null)
+ {
+ GlyphDescription gd = getGlypDescription(c.getGlyphIndex());
+ int n = i - c.getFirstIndex();
+ int x = gd.getXCoordinate(n);
+ int y = gd.getYCoordinate(n);
+ short y1 = (short) c.scaleY(x, y);
+ y1 += c.getYTranslate();
+ return y1;
+ }
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isComposite()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getPointCount()
+ {
+ if (!resolved)
+ {
+ System.err.println("getPointCount called on unresolved
GlyfCompositeDescript");
+ }
+ GlyfCompositeComp c = (GlyfCompositeComp)
components.get(components.size()-1);
+ return c.getFirstIndex() +
getGlypDescription(c.getGlyphIndex()).getPointCount();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getContourCount()
+ {
+ if (!resolved)
+ {
+ System.err.println("getContourCount called on unresolved
GlyfCompositeDescript");
+ }
+ GlyfCompositeComp c = (GlyfCompositeComp)
components.get(components.size()-1);
+ return c.getFirstContour() +
getGlypDescription(c.getGlyphIndex()).getContourCount();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getComponentCount()
+ {
+ return components.size();
+ }
+
+ private GlyfCompositeComp getCompositeComp(int i)
+ {
+ GlyfCompositeComp c;
+ for (int n = 0; n < components.size(); n++)
+ {
+ c = (GlyfCompositeComp) components.get(n);
+ GlyphDescription gd = getGlypDescription(c.getGlyphIndex());
+ if (c.getFirstIndex() <= i && i < (c.getFirstIndex() +
gd.getPointCount()))
+ {
+ return c;
+ }
+ }
+ return null;
+ }
+
+ private GlyfCompositeComp getCompositeCompEndPt(int i)
+ {
+ GlyfCompositeComp c;
+ for (int j = 0; j < components.size(); j++)
+ {
+ c = (GlyfCompositeComp) components.get(j);
+ GlyphDescription gd = getGlypDescription(c.getGlyphIndex());
+ if (c.getFirstContour() <= i && i < (c.getFirstContour() +
gd.getContourCount()))
+ {
+ return c;
+ }
+ }
+ return null;
+ }
+
+ private GlyphDescription getGlypDescription(int index)
+ {
+ return glyphs[index].getDescription();
+ }
+}
Added:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfDescript.java
URL:
http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfDescript.java?rev=1311300&view=auto
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfDescript.java
(added)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfDescript.java
Mon Apr 9 16:05:55 2012
@@ -0,0 +1,122 @@
+/*
+
+ 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.ttf;
+
+import java.io.IOException;
+
+/**
+ * This class is based on code from Apache Batik a subproject of Apache
XMLGraphics.
+ * see http://xmlgraphics.apache.org/batik/ for further details.
+ *
+ */
+public abstract class GlyfDescript implements GlyphDescription
+{
+
+ // Flags describing a coordinate of a glyph.
+ /**
+ * if set, the point is on the curve.
+ */
+ public static final byte ON_CURVE = 0x01;
+ /**
+ * if set, the x-coordinate is 1 byte long.
+ */
+ public static final byte X_SHORT_VECTOR = 0x02;
+ /**
+ * if set, the y-coordinate is 1 byte long.
+ */
+ public static final byte Y_SHORT_VECTOR = 0x04;
+ /**
+ * if set, the next byte specifies the number of additional
+ * times this set of flags is to be repeated.
+ */
+ public static final byte REPEAT = 0x08;
+ /**
+ * This flag as two meanings, depending on how the
+ * x-short vector flags is set.
+ * If the x-short vector is set, this bit describes the sign
+ * of the value, with 1 equaling positive and 0 positive.
+ * If the x-short vector is not set and this bit is also not
+ * set, the current x-coordinate is a signed 16-bit delta vector.
+ */
+ public static final byte X_DUAL = 0x10;
+ /**
+ * This flag as two meanings, depending on how the
+ * y-short vector flags is set.
+ * If the y-short vector is set, this bit describes the sign
+ * of the value, with 1 equaling positive and 0 positive.
+ * If the y-short vector is not set and this bit is also not
+ * set, the current y-coordinate is a signed 16-bit delta vector.
+ */
+ public static final byte Y_DUAL = 0x20;
+
+ private short[] instructions;
+ private int contourCount;
+
+ /**
+ * Constructor.
+ *
+ * @param numberOfContours the number of contours
+ * @param bais the stream to be read
+ * @throws IOException is thrown if something went wrong
+ */
+ protected GlyfDescript(short numberOfContours, TTFDataStream bais) throws
IOException
+ {
+ contourCount = numberOfContours;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void resolve()
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getContourCount()
+ {
+ return contourCount;
+ }
+
+ /**
+ * Returns the hinting instructions.
+ * @return an array containing the hinting instructions.
+ */
+ public short[] getInstructions()
+ {
+ return instructions;
+ }
+
+ /**
+ * Read the hinting instructions.
+ * @param bais the stream to be read
+ * @param count the number of instructions to be read
+ * @throws IOException is thrown if something went wrong
+ */
+ protected void readInstructions(TTFDataStream bais, int count) throws
IOException
+ {
+ instructions = new short[count];
+ for (int i = 0; i < count; i++)
+ {
+ instructions[i] = (short) bais.read();
+ }
+ }
+
+}
Added:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfSimpleDescript.java
URL:
http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfSimpleDescript.java?rev=1311300&view=auto
==============================================================================
---
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfSimpleDescript.java
(added)
+++
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyfSimpleDescript.java
Mon Apr 9 16:05:55 2012
@@ -0,0 +1,194 @@
+/*
+
+ 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.ttf;
+
+import java.io.IOException;
+
+/**
+ * This class is based on code from Apache Batik a subproject of Apache
XMLGraphics.
+ * see http://xmlgraphics.apache.org/batik/ for further details.
+ */
+public class GlyfSimpleDescript extends GlyfDescript
+{
+
+ private int[] endPtsOfContours;
+ private byte[] flags;
+ private short[] xCoordinates;
+ private short[] yCoordinates;
+ private int pointCount;
+
+ /**
+ * Constructor.
+ *
+ * @param numberOfContours number of contours
+ * @param bais the stream to be read
+ * @throws IOException is thrown if something went wrong
+ */
+ public GlyfSimpleDescript(short numberOfContours, TTFDataStream bais)
throws IOException
+ {
+ super(numberOfContours, bais);
+
+ // Simple glyph description
+ endPtsOfContours = new int[numberOfContours];
+ for (int i = 0; i < numberOfContours; i++)
+ {
+ endPtsOfContours[i] = bais.readSignedShort();
+ }
+
+ // The last end point index reveals the total number of points
+ pointCount = endPtsOfContours[numberOfContours-1] + 1;
+ flags = new byte[pointCount];
+ xCoordinates = new short[pointCount];
+ yCoordinates = new short[pointCount];
+
+ int instructionCount = bais.readSignedShort();
+ readInstructions(bais, instructionCount);
+ readFlags(pointCount, bais);
+ readCoords(pointCount, bais);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getEndPtOfContours(int i)
+ {
+ return endPtsOfContours[i];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public byte getFlags(int i)
+ {
+ return flags[i];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public short getXCoordinate(int i)
+ {
+ return xCoordinates[i];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public short getYCoordinate(int i)
+ {
+ return yCoordinates[i];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isComposite()
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getPointCount()
+ {
+ return pointCount;
+ }
+
+ /**
+ * The table is stored as relative values, but we'll store them as
absolutes.
+ */
+ private void readCoords(int count, TTFDataStream bais) throws IOException
+ {
+ short x = 0;
+ short y = 0;
+ for (int i = 0; i < count; i++)
+ {
+ if ((flags[i] & X_DUAL) != 0)
+ {
+ if ((flags[i] & X_SHORT_VECTOR) != 0)
+ {
+ x += (short) bais.read();
+ }
+ }
+ else
+ {
+ if ((flags[i] & X_SHORT_VECTOR) != 0)
+ {
+ x += (short) -((short) bais.read());
+ }
+ else
+ {
+ x += bais.readSignedShort();
+ }
+ }
+ xCoordinates[i] = x;
+ }
+
+ for (int i = 0; i < count; i++)
+ {
+ if ((flags[i] & Y_DUAL) != 0)
+ {
+ if ((flags[i] & Y_SHORT_VECTOR) != 0)
+ {
+ y += (short) bais.read();
+ }
+ }
+ else
+ {
+ if ((flags[i] & Y_SHORT_VECTOR) != 0)
+ {
+ y += (short) -((short) bais.read());
+ }
+ else
+ {
+ y += bais.readSignedShort();
+ }
+ }
+ yCoordinates[i] = y;
+ }
+ }
+
+ /**
+ * The flags are run-length encoded.
+ */
+ private void readFlags(int flagCount, TTFDataStream bais) throws
IOException
+ {
+ try
+ {
+ for (int index = 0; index < flagCount; index++)
+ {
+ flags[index] = (byte) bais.read();
+ if ((flags[index] & REPEAT) != 0)
+ {
+ int repeats = bais.read();
+ for (int i = 1; i <= repeats; i++)
+ {
+ flags[index + i] = flags[index];
+ }
+ index += repeats;
+ }
+ }
+ }
+ catch (ArrayIndexOutOfBoundsException e)
+ {
+ System.out.println("error: array index out of bounds");
+ }
+ }
+}
Modified:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphData.java
URL:
http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphData.java?rev=1311300&r1=1311299&r2=1311300&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphData.java
(original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphData.java
Mon Apr 9 16:05:55 2012
@@ -28,19 +28,13 @@ import org.apache.fontbox.util.BoundingB
*/
public class GlyphData
{
- private static final int FLAG_ON_CURVE = 1;
- private static final int FLAG_SHORT_X = 1<<1;
- private static final int FLAG_SHORT_Y = 1<<2;
- private static final int FLAG_X_MAGIC = 1<<3;
- private static final int FLAG_Y_MAGIC = 1<<4;
-
- private BoundingBox boundingBox = new BoundingBox();
+ private short xMin;
+ private short yMin;
+ private short xMax;
+ private short yMax;
+ private BoundingBox boundingBox = null;
private short numberOfContours;
- private int[] endPointsOfContours;
- private byte[] instructions;
- private int[] flags;
- private short[] xCoordinates;
- private short[] yCoordinates;
+ private GlyfDescript glyphDescription = null;
/**
* This will read the required data from the stream.
@@ -52,32 +46,22 @@ public class GlyphData
public void initData( TrueTypeFont ttf, TTFDataStream data ) throws
IOException
{
numberOfContours = data.readSignedShort();
- boundingBox.setLowerLeftX( data.readSignedShort() );
- boundingBox.setLowerLeftY( data.readSignedShort() );
- boundingBox.setUpperRightX( data.readSignedShort() );
- boundingBox.setUpperRightY( data.readSignedShort() );
- /**if( numberOfContours > 0 )
+ xMin = data.readSignedShort();
+ yMin = data.readSignedShort();
+ xMax = data.readSignedShort();
+ yMax = data.readSignedShort();
+ boundingBox = new BoundingBox(xMin, yMin, xMax, yMax);
+
+ if (numberOfContours >= 0)
+ {
+ // create a simple glyph
+ glyphDescription = new GlyfSimpleDescript(numberOfContours, data);
+ }
+ else
{
- endPointsOfContours = new int[ numberOfContours ];
- for( int i=0; i<numberOfContours; i++ )
- {
- endPointsOfContours[i] = data.readUnsignedShort();
- }
- int instructionLength = data.readUnsignedShort();
- instructions = data.read( instructionLength );
-
- //BJL It is possible to read some more information here but PDFBox
- //does not need it at this time so just ignore it.
-
- //not sure if the length of the flags is the number of contours??
- //flags = new int[numberOfContours];
- //first read the flags, and just so the TTF can save a couples
bytes
- //we need to check some bit masks to see if there are more bytes
or not.
- //int currentFlagIndex = 0;
- //int currentFlag =
-
-
- }*/
+ // create a composite glyph
+ glyphDescription = new GlyfCompositeDescript(data, ttf.getGlyph());
+ }
}
/**
@@ -108,4 +92,50 @@ public class GlyphData
{
this.numberOfContours = numberOfContoursValue;
}
+
+ /**
+ * Returns the description of the glyph.
+ * @return the glyph description
+ */
+ public GlyphDescription getDescription()
+ {
+ return glyphDescription;
+ }
+
+ /**
+ * Returns the xMax value.
+ * @return the XMax value
+ */
+ public short getXMaximum()
+ {
+ return xMax;
+ }
+
+ /**
+ * Returns the xMin value.
+ * @return the xMin value
+ */
+ public short getXMinimum()
+ {
+ return xMin;
+ }
+
+ /**
+ * Returns the yMax value.
+ * @return the yMax value
+ */
+ public short getYMaximum()
+ {
+ return yMax;
+ }
+
+ /**
+ * Returns the yMin value.
+ * @return the yMin value
+ */
+ public short getYMinimum()
+ {
+ return yMin;
+ }
+
}
Added:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphDescription.java
URL:
http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphDescription.java?rev=1311300&view=auto
==============================================================================
---
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphDescription.java
(added)
+++
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphDescription.java
Mon Apr 9 16:05:55 2012
@@ -0,0 +1,81 @@
+/*
+
+ 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.ttf;
+
+/**
+ * Specifies access to glyph description classes, simple and composite.
+ *
+ * This class is based on code from Apache Batik a subproject of Apache
XMLGraphics.
+ * see http://xmlgraphics.apache.org/batik/ for further details.
+ *
+ */
+public interface GlyphDescription
+{
+ /**
+ * Returns the index of the ending point of the given contour.
+ *
+ * @param i the number of the contour
+ * @return the index of the ending point of the given contour
+ */
+ public int getEndPtOfContours(int i);
+
+ /**
+ * Returns the flags of the given point.
+ * @param i the given point
+ * @return the flags value for the given point
+ */
+ public byte getFlags(int i);
+
+ /**
+ * Returns the x coordinate of the given point.
+ * @param i the given point
+ * @return the x coordinate value for the given point
+ */
+ public short getXCoordinate(int i);
+
+ /**
+ * Returns the y coordinate of the given point.
+ * @param i the given point
+ * @return the y coordinate value for the given point
+ */
+ public short getYCoordinate(int i);
+
+ /**
+ * Returns whether this point is a composite or not.
+ * @return true if this point is a composite
+ */
+ public boolean isComposite();
+
+ /**
+ * Returns the number of points.
+ * @return the number of points
+ */
+ public int getPointCount();
+
+ /**
+ * Returns the number of contours.
+ * @return the number of contours
+ */
+ public int getContourCount();
+
+ /**
+ * Resolve all parts of an composite glyph.
+ */
+ public void resolve();
+}
Modified:
pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphTable.java
URL:
http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphTable.java?rev=1311300&r1=1311299&r2=1311300&view=diff
==============================================================================
--- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphTable.java
(original)
+++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/ttf/GlyphTable.java
Mon Apr 9 16:05:55 2012
@@ -54,7 +54,17 @@ public class GlyphTable extends TTFTable
glyph.initData( ttf, data );
glyphs[i] = glyph;
}
+ for( int i=0; i<numGlyphs-1; i++ )
+ {
+ GlyphData glyph = glyphs[i];
+ // resolve composite glyphs
+ if (glyph != null && glyph.getDescription().isComposite())
+ {
+ glyph.getDescription().resolve();
+ }
+ }
}
+
/**
* @return Returns the glyphs.
*/
@@ -62,11 +72,12 @@ public class GlyphTable extends TTFTable
{
return glyphs;
}
+
/**
* @param glyphsValue The glyphs to set.
*/
public void setGlyphs(GlyphData[] glyphsValue)
{
- this.glyphs = glyphsValue;
+ glyphs = glyphsValue;
}
}