aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/pdfbox/ttf
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/pdfbox/ttf')
-rw-r--r--src/main/java/org/pdfbox/ttf/CMAPEncodingEntry.java219
-rw-r--r--src/main/java/org/pdfbox/ttf/CMAPTable.java122
-rw-r--r--src/main/java/org/pdfbox/ttf/DigitalSignatureTable.java45
-rw-r--r--src/main/java/org/pdfbox/ttf/GlyphData.java125
-rw-r--r--src/main/java/org/pdfbox/ttf/GlyphTable.java88
-rw-r--r--src/main/java/org/pdfbox/ttf/HeaderTable.java332
-rw-r--r--src/main/java/org/pdfbox/ttf/HorizontalHeaderTable.java332
-rw-r--r--src/main/java/org/pdfbox/ttf/HorizontalMetricsTable.java95
-rw-r--r--src/main/java/org/pdfbox/ttf/IndexToLocationTable.java96
-rw-r--r--src/main/java/org/pdfbox/ttf/MaximumProfileTable.java300
-rw-r--r--src/main/java/org/pdfbox/ttf/MemoryTTFDataStream.java231
-rw-r--r--src/main/java/org/pdfbox/ttf/NameRecord.java242
-rw-r--r--src/main/java/org/pdfbox/ttf/NamingTable.java112
-rw-r--r--src/main/java/org/pdfbox/ttf/OS2WindowsMetricsTable.java694
-rw-r--r--src/main/java/org/pdfbox/ttf/PostScriptTable.java304
-rw-r--r--src/main/java/org/pdfbox/ttf/RAFDataStream.java193
-rw-r--r--src/main/java/org/pdfbox/ttf/TTFDataStream.java253
-rw-r--r--src/main/java/org/pdfbox/ttf/TTFParser.java219
-rw-r--r--src/main/java/org/pdfbox/ttf/TTFTable.java115
-rw-r--r--src/main/java/org/pdfbox/ttf/TrueTypeFont.java221
-rw-r--r--src/main/java/org/pdfbox/ttf/package.html9
21 files changed, 4347 insertions, 0 deletions
diff --git a/src/main/java/org/pdfbox/ttf/CMAPEncodingEntry.java b/src/main/java/org/pdfbox/ttf/CMAPEncodingEntry.java
new file mode 100644
index 0000000..a740203
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/CMAPEncodingEntry.java
@@ -0,0 +1,219 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.io.IOException;
+
+/**
+ * An encoding entry for a cmap.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class CMAPEncodingEntry
+{
+
+ private int platformId;
+ private int platformEncodingId;
+ private long subTableOffset;
+ private int[] glyphIdToCharacterCode;
+ /**
+ * This will read the required data from the stream.
+ *
+ * @param ttf The font that is being read.
+ * @param data The stream to read the data from.
+ * @throws IOException If there is an error reading the data.
+ */
+ public void initData( TrueTypeFont ttf, TTFDataStream data ) throws IOException
+ {
+ platformId = data.readUnsignedShort();
+ platformEncodingId = data.readUnsignedShort();
+ subTableOffset = data.readUnsignedInt();
+ }
+
+ /**
+ * This will read the required data from the stream.
+ *
+ * @param ttf The font that is being read.
+ * @param data The stream to read the data from.
+ * @throws IOException If there is an error reading the data.
+ */
+ public void initSubtable( TrueTypeFont ttf, TTFDataStream data ) throws IOException
+ {
+ data.seek( ttf.getCMAP().getOffset() + subTableOffset );
+ int subtableFormat = data.readUnsignedShort();
+ int length = data.readUnsignedShort();
+ int version = data.readUnsignedShort();
+ int numGlyphs = ttf.getMaximumProfile().getNumGlyphs();
+ if( subtableFormat == 0 )
+ {
+ byte[] glyphMapping = data.read( 256 );
+ glyphIdToCharacterCode = new int[256];
+ for( int i=0;i<glyphMapping.length; i++ )
+ {
+ glyphIdToCharacterCode[i]=(glyphMapping[i]+256)%256;
+ }
+ }
+ else if( subtableFormat == 2 )
+ {
+ int[] subHeaderKeys = new int[256];
+ for( int i=0; i<256; i++)
+ {
+ subHeaderKeys[i] = data.readUnsignedShort();
+ }
+ int firstCode = data.readUnsignedShort();
+ int entryCount = data.readUnsignedShort();
+ short idDelta = data.readSignedShort();
+ int idRangeOffset = data.readUnsignedShort();
+ //BJL
+ //HMM the TTF spec is not very clear about what is suppose to
+ //happen here. If you know please submit a patch or point
+ //me to some better documentation.
+ throw new IOException( "Not yet implemented:" + subtableFormat );
+ }
+ else if( subtableFormat == 4 )
+ {
+ int segCountX2 = data.readUnsignedShort();
+ int segCount = segCountX2/2;
+ int searchRange = data.readUnsignedShort();
+ int entrySelector = data.readUnsignedShort();
+ int rangeShift = data.readUnsignedShort();
+ int[] endCount = data.readUnsignedShortArray( segCount );
+ int reservedPad = data.readUnsignedShort();
+ int[] startCount = data.readUnsignedShortArray( segCount );
+ int[] idDelta = data.readUnsignedShortArray( segCount );
+ int[] idRangeOffset = data.readUnsignedShortArray( segCount );
+
+ //this is the final result
+ //key=glyphId, value is character codes
+ glyphIdToCharacterCode = new int[numGlyphs];
+
+ long currentPosition = data.getCurrentPosition();
+
+ for( int i=0; i<segCount; i++ )
+ {
+ int start = startCount[i];
+ int end = endCount[i];
+ int delta = idDelta[i];
+ int rangeOffset = idRangeOffset[i];
+ if( start != 65536 && end != 65536 )
+ {
+ for( int j=start; j<=end; j++ )
+ {
+ if( rangeOffset == 0 )
+ {
+ glyphIdToCharacterCode[ ((j+delta)%65536) ]=j;
+ }
+ else
+ {
+ long glyphOffset = currentPosition +
+ ((rangeOffset/2) + //idRangeOffset[i]/2
+ (j-start) + //(c - startCount[i])
+ (i-segCount))*2; //&idRangeOffset[i]);
+ data.seek( glyphOffset );
+ int glyphIndex = data.readUnsignedShort();
+ if( glyphIndex != 0 )
+ {
+ glyphIndex += delta;
+ glyphIndex = glyphIndex % 65536;
+ if( glyphIdToCharacterCode[glyphIndex] == 0 )
+ {
+ glyphIdToCharacterCode[glyphIndex] = j;
+ }
+ }
+
+ }
+ }
+ }
+ }
+ }
+ else if( subtableFormat == 6 )
+ {
+ int firstCode = data.readUnsignedShort();
+ int entryCount = data.readUnsignedShort();
+ glyphIdToCharacterCode = new int[numGlyphs];
+ int[] glyphIdArray = data.readUnsignedShortArray( entryCount );
+ for( int i=0; i<entryCount; i++)
+ {
+ glyphIdToCharacterCode[glyphIdArray[i]] = firstCode+i;
+ }
+ }
+ else
+ {
+ throw new IOException( "Unknown cmap format:" + subtableFormat );
+ }
+ }
+
+
+ /**
+ * @return Returns the glyphIdToCharacterCode.
+ */
+ public int[] getGlyphIdToCharacterCode()
+ {
+ return glyphIdToCharacterCode;
+ }
+ /**
+ * @param glyphIdToCharacterCodeValue The glyphIdToCharacterCode to set.
+ */
+ public void setGlyphIdToCharacterCode(int[] glyphIdToCharacterCodeValue)
+ {
+ this.glyphIdToCharacterCode = glyphIdToCharacterCodeValue;
+ }
+
+ /**
+ * @return Returns the platformEncodingId.
+ */
+ public int getPlatformEncodingId()
+ {
+ return platformEncodingId;
+ }
+ /**
+ * @param platformEncodingIdValue The platformEncodingId to set.
+ */
+ public void setPlatformEncodingId(int platformEncodingIdValue)
+ {
+ this.platformEncodingId = platformEncodingIdValue;
+ }
+ /**
+ * @return Returns the platformId.
+ */
+ public int getPlatformId()
+ {
+ return platformId;
+ }
+ /**
+ * @param platformIdValue The platformId to set.
+ */
+ public void setPlatformId(int platformIdValue)
+ {
+ this.platformId = platformIdValue;
+ }
+}
diff --git a/src/main/java/org/pdfbox/ttf/CMAPTable.java b/src/main/java/org/pdfbox/ttf/CMAPTable.java
new file mode 100644
index 0000000..92a74bc
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/CMAPTable.java
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.io.IOException;
+
+/**
+ * A table in a true type font.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class CMAPTable extends TTFTable
+{
+ /**
+ * A tag used to identify this table.
+ */
+ public static final String TAG = "cmap";
+
+ /**
+ * A constant for the platform.
+ */
+ public static final int PLATFORM_WINDOWS = 3;
+
+ /**
+ * An encoding constant.
+ */
+ public static final int ENCODING_SYMBOL = 0;
+ /**
+ * An encoding constant.
+ */
+ public static final int ENCODING_UNICODE = 1;
+ /**
+ * An encoding constant.
+ */
+ public static final int ENCODING_SHIFT_JIS = 2;
+ /**
+ * An encoding constant.
+ */
+ public static final int ENCODING_BIG5 = 3;
+ /**
+ * An encoding constant.
+ */
+ public static final int ENCODING_PRC = 4;
+ /**
+ * An encoding constant.
+ */
+ public static final int ENCODING_WANSUNG = 5;
+ /**
+ * An encoding constant.
+ */
+ public static final int ENCODING_JOHAB = 6;
+
+ private CMAPEncodingEntry[] cmaps;
+
+ /**
+ * This will read the required data from the stream.
+ *
+ * @param ttf The font that is being read.
+ * @param data The stream to read the data from.
+ * @throws IOException If there is an error reading the data.
+ */
+ public void initData( TrueTypeFont ttf, TTFDataStream data ) throws IOException
+ {
+ int version = data.readUnsignedShort();
+ int numberOfTables = data.readUnsignedShort();
+ cmaps = new CMAPEncodingEntry[ numberOfTables ];
+ for( int i=0; i< numberOfTables; i++ )
+ {
+ CMAPEncodingEntry cmap = new CMAPEncodingEntry();
+ cmap.initData( ttf, data );
+ cmaps[i]=cmap;
+ }
+ for( int i=0; i< numberOfTables; i++ )
+ {
+ cmaps[i].initSubtable( ttf, data );
+ }
+
+ }
+ /**
+ * @return Returns the cmaps.
+ */
+ public CMAPEncodingEntry[] getCmaps()
+ {
+ return cmaps;
+ }
+ /**
+ * @param cmapsValue The cmaps to set.
+ */
+ public void setCmaps(CMAPEncodingEntry[] cmapsValue)
+ {
+ this.cmaps = cmapsValue;
+ }
+}
diff --git a/src/main/java/org/pdfbox/ttf/DigitalSignatureTable.java b/src/main/java/org/pdfbox/ttf/DigitalSignatureTable.java
new file mode 100644
index 0000000..67ae170
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/DigitalSignatureTable.java
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+/**
+ * A table in a true type font.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class DigitalSignatureTable extends TTFTable
+{
+ /**
+ * Tag to identify this table.
+ */
+ public static final String TAG = "DSIG";
+}
diff --git a/src/main/java/org/pdfbox/ttf/GlyphData.java b/src/main/java/org/pdfbox/ttf/GlyphData.java
new file mode 100644
index 0000000..95aed28
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/GlyphData.java
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.io.IOException;
+
+import org.pdfbox.util.BoundingBox;
+
+/**
+ * A glyph data record in the glyf table.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+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 numberOfContours;
+ private int[] endPointsOfContours;
+ private byte[] instructions;
+ private int[] flags;
+ private short[] xCoordinates;
+ private short[] yCoordinates;
+
+ /**
+ * This will read the required data from the stream.
+ *
+ * @param ttf The font that is being read.
+ * @param data The stream to read the data from.
+ * @throws IOException If there is an error reading the data.
+ */
+ 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 )
+ {
+ 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 =
+
+
+ }*/
+ }
+
+ /**
+ * @return Returns the boundingBox.
+ */
+ public BoundingBox getBoundingBox()
+ {
+ return boundingBox;
+ }
+ /**
+ * @param boundingBoxValue The boundingBox to set.
+ */
+ public void setBoundingBox(BoundingBox boundingBoxValue)
+ {
+ this.boundingBox = boundingBoxValue;
+ }
+ /**
+ * @return Returns the numberOfContours.
+ */
+ public short getNumberOfContours()
+ {
+ return numberOfContours;
+ }
+ /**
+ * @param numberOfContoursValue The numberOfContours to set.
+ */
+ public void setNumberOfContours(short numberOfContoursValue)
+ {
+ this.numberOfContours = numberOfContoursValue;
+ }
+}
diff --git a/src/main/java/org/pdfbox/ttf/GlyphTable.java b/src/main/java/org/pdfbox/ttf/GlyphTable.java
new file mode 100644
index 0000000..bbde89a
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/GlyphTable.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.io.IOException;
+
+/**
+ * A table in a true type font.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class GlyphTable extends TTFTable
+{
+ /**
+ * Tag to identify this table.
+ */
+ public static final String TAG = "glyf";
+
+ private GlyphData[] glyphs;
+
+ /**
+ * This will read the required data from the stream.
+ *
+ * @param ttf The font that is being read.
+ * @param data The stream to read the data from.
+ * @throws IOException If there is an error reading the data.
+ */
+ public void initData( TrueTypeFont ttf, TTFDataStream data ) throws IOException
+ {
+ MaximumProfileTable maxp = ttf.getMaximumProfile();
+ IndexToLocationTable loc = ttf.getIndexToLocation();
+ PostScriptTable post = ttf.getPostScript();
+ long[] offsets = loc.getOffsets();
+ int numGlyphs = maxp.getNumGlyphs();
+ glyphs = new GlyphData[numGlyphs];
+ String[] glyphNames = post.getGlyphNames();
+ for( int i=0; i<numGlyphs-1; i++ )
+ {
+ GlyphData glyph = new GlyphData();
+ data.seek( getOffset() + offsets[i] );
+ glyph.initData( ttf, data );
+ glyphs[i] = glyph;
+ }
+ }
+ /**
+ * @return Returns the glyphs.
+ */
+ public GlyphData[] getGlyphs()
+ {
+ return glyphs;
+ }
+ /**
+ * @param glyphsValue The glyphs to set.
+ */
+ public void setGlyphs(GlyphData[] glyphsValue)
+ {
+ this.glyphs = glyphsValue;
+ }
+}
diff --git a/src/main/java/org/pdfbox/ttf/HeaderTable.java b/src/main/java/org/pdfbox/ttf/HeaderTable.java
new file mode 100644
index 0000000..b4a8369
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/HeaderTable.java
@@ -0,0 +1,332 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.io.IOException;
+import java.util.Calendar;
+
+/**
+ * A table in a true type font.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class HeaderTable extends TTFTable
+{
+ /**
+ * Tag to identify this table.
+ */
+ public static final String TAG = "head";
+
+ private float version;
+ private float fontRevision;
+ private long checkSumAdjustment;
+ private long magicNumber;
+ private int flags;
+ private int unitsPerEm;
+ private Calendar created;
+ private Calendar modified;
+ private short xMin;
+ private short yMin;
+ private short xMax;
+ private short yMax;
+ private int macStyle;
+ private int lowestRecPPEM;
+ private short fontDirectionHint;
+ private short indexToLocFormat;
+ private short glyphDataFormat;
+
+ /**
+ * This will read the required data from the stream.
+ *
+ * @param ttf The font that is being read.
+ * @param data The stream to read the data from.
+ * @throws IOException If there is an error reading the data.
+ */
+ public void initData( TrueTypeFont ttf, TTFDataStream data ) throws IOException
+ {
+ version = data.read32Fixed();
+ fontRevision = data.read32Fixed();
+ checkSumAdjustment = data.readUnsignedInt();
+ magicNumber = data.readUnsignedInt();
+ flags = data.readUnsignedShort();
+ unitsPerEm = data.readUnsignedShort();
+ created = data.readInternationalDate();
+ modified = data.readInternationalDate();
+ xMin = data.readSignedShort();
+ yMin = data.readSignedShort();
+ xMax = data.readSignedShort();
+ yMax = data.readSignedShort();
+ macStyle = data.readUnsignedShort();
+ lowestRecPPEM = data.readUnsignedShort();
+ fontDirectionHint = data.readSignedShort();
+ indexToLocFormat = data.readSignedShort();
+ glyphDataFormat = data.readSignedShort();
+ }
+ /**
+ * @return Returns the checkSumAdjustment.
+ */
+ public long getCheckSumAdjustment()
+ {
+ return checkSumAdjustment;
+ }
+ /**
+ * @param checkSumAdjustmentValue The checkSumAdjustment to set.
+ */
+ public void setCheckSumAdjustment(long checkSumAdjustmentValue)
+ {
+ this.checkSumAdjustment = checkSumAdjustmentValue;
+ }
+ /**
+ * @return Returns the created.
+ */
+ public Calendar getCreated()
+ {
+ return created;
+ }
+ /**
+ * @param createdValue The created to set.
+ */
+ public void setCreated(Calendar createdValue)
+ {
+ this.created = createdValue;
+ }
+ /**
+ * @return Returns the flags.
+ */
+ public int getFlags()
+ {
+ return flags;
+ }
+ /**
+ * @param flagsValue The flags to set.
+ */
+ public void setFlags(int flagsValue)
+ {
+ this.flags = flagsValue;
+ }
+ /**
+ * @return Returns the fontDirectionHint.
+ */
+ public short getFontDirectionHint()
+ {
+ return fontDirectionHint;
+ }
+ /**
+ * @param fontDirectionHintValue The fontDirectionHint to set.
+ */
+ public void setFontDirectionHint(short fontDirectionHintValue)
+ {
+ this.fontDirectionHint = fontDirectionHintValue;
+ }
+ /**
+ * @return Returns the fontRevision.
+ */
+ public float getFontRevision()
+ {
+ return fontRevision;
+ }
+ /**
+ * @param fontRevisionValue The fontRevision to set.
+ */
+ public void setFontRevision(float fontRevisionValue)
+ {
+ this.fontRevision = fontRevisionValue;
+ }
+ /**
+ * @return Returns the glyphDataFormat.
+ */
+ public short getGlyphDataFormat()
+ {
+ return glyphDataFormat;
+ }
+ /**
+ * @param glyphDataFormatValue The glyphDataFormat to set.
+ */
+ public void setGlyphDataFormat(short glyphDataFormatValue)
+ {
+ this.glyphDataFormat = glyphDataFormatValue;
+ }
+ /**
+ * @return Returns the indexToLocFormat.
+ */
+ public short getIndexToLocFormat()
+ {
+ return indexToLocFormat;
+ }
+ /**
+ * @param indexToLocFormatValue The indexToLocFormat to set.
+ */
+ public void setIndexToLocFormat(short indexToLocFormatValue)
+ {
+ this.indexToLocFormat = indexToLocFormatValue;
+ }
+ /**
+ * @return Returns the lowestRecPPEM.
+ */
+ public int getLowestRecPPEM()
+ {
+ return lowestRecPPEM;
+ }
+ /**
+ * @param lowestRecPPEMValue The lowestRecPPEM to set.
+ */
+ public void setLowestRecPPEM(int lowestRecPPEMValue)
+ {
+ this.lowestRecPPEM = lowestRecPPEMValue;
+ }
+ /**
+ * @return Returns the macStyle.
+ */
+ public int getMacStyle()
+ {
+ return macStyle;
+ }
+ /**
+ * @param macStyleValue The macStyle to set.
+ */
+ public void setMacStyle(int macStyleValue)
+ {
+ this.macStyle = macStyleValue;
+ }
+ /**
+ * @return Returns the magicNumber.
+ */
+ public long getMagicNumber()
+ {
+ return magicNumber;
+ }
+ /**
+ * @param magicNumberValue The magicNumber to set.
+ */
+ public void setMagicNumber(long magicNumberValue)
+ {
+ this.magicNumber = magicNumberValue;
+ }
+ /**
+ * @return Returns the modified.
+ */
+ public Calendar getModified()
+ {
+ return modified;
+ }
+ /**
+ * @param modifiedValue The modified to set.
+ */
+ public void setModified(Calendar modifiedValue)
+ {
+ this.modified = modifiedValue;
+ }
+ /**
+ * @return Returns the unitsPerEm.
+ */
+ public int getUnitsPerEm()
+ {
+ return unitsPerEm;
+ }
+ /**
+ * @param unitsPerEmValue The unitsPerEm to set.
+ */
+ public void setUnitsPerEm(int unitsPerEmValue)
+ {
+ this.unitsPerEm = unitsPerEmValue;
+ }
+ /**
+ * @return Returns the version.
+ */
+ public float getVersion()
+ {
+ return version;
+ }
+ /**
+ * @param versionValue The version to set.
+ */
+ public void setVersion(float versionValue)
+ {
+ this.version = versionValue;
+ }
+ /**
+ * @return Returns the xMax.
+ */
+ public short getXMax()
+ {
+ return xMax;
+ }
+ /**
+ * @param maxValue The xMax to set.
+ */
+ public void setXMax(short maxValue)
+ {
+ xMax = maxValue;
+ }
+ /**
+ * @return Returns the xMin.
+ */
+ public short getXMin()
+ {
+ return xMin;
+ }
+ /**
+ * @param minValue The xMin to set.
+ */
+ public void setXMin(short minValue)
+ {
+ xMin = minValue;
+ }
+ /**
+ * @return Returns the yMax.
+ */
+ public short getYMax()
+ {
+ return yMax;
+ }
+ /**
+ * @param maxValue The yMax to set.
+ */
+ public void setYMax(short maxValue)
+ {
+ yMax = maxValue;
+ }
+ /**
+ * @return Returns the yMin.
+ */
+ public short getYMin()
+ {
+ return yMin;
+ }
+ /**
+ * @param minValue The yMin to set.
+ */
+ public void setYMin(short minValue)
+ {
+ yMin = minValue;
+ }
+}
diff --git a/src/main/java/org/pdfbox/ttf/HorizontalHeaderTable.java b/src/main/java/org/pdfbox/ttf/HorizontalHeaderTable.java
new file mode 100644
index 0000000..43eff25
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/HorizontalHeaderTable.java
@@ -0,0 +1,332 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.io.IOException;
+
+/**
+ * A table in a true type font.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class HorizontalHeaderTable extends TTFTable
+{
+ /**
+ * A tag that identifies this table type.
+ */
+ public static final String TAG = "hhea";
+
+ private float version;
+ private short ascender;
+ private short descender;
+ private short lineGap;
+ private int advanceWidthMax;
+ private short minLeftSideBearing;
+ private short minRightSideBearing;
+ private short xMaxExtent;
+ private short caretSlopeRise;
+ private short caretSlopeRun;
+ private short reserved1;
+ private short reserved2;
+ private short reserved3;
+ private short reserved4;
+ private short reserved5;
+ private short metricDataFormat;
+ private int numberOfHMetrics;
+
+ /**
+ * This will read the required data from the stream.
+ *
+ * @param ttf The font that is being read.
+ * @param data The stream to read the data from.
+ * @throws IOException If there is an error reading the data.
+ */
+ public void initData( TrueTypeFont ttf, TTFDataStream data ) throws IOException
+ {
+ version = data.read32Fixed();
+ ascender = data.readSignedShort();
+ descender = data.readSignedShort();
+ lineGap = data.readSignedShort();
+ advanceWidthMax = data.readUnsignedShort();
+ minLeftSideBearing = data.readSignedShort();
+ minRightSideBearing = data.readSignedShort();
+ xMaxExtent = data.readSignedShort();
+ caretSlopeRise = data.readSignedShort();
+ caretSlopeRun = data.readSignedShort();
+ reserved1 = data.readSignedShort();
+ reserved2 = data.readSignedShort();
+ reserved3 = data.readSignedShort();
+ reserved4 = data.readSignedShort();
+ reserved5 = data.readSignedShort();
+ metricDataFormat = data.readSignedShort();
+ numberOfHMetrics = data.readUnsignedShort();
+ }
+
+ /**
+ * @return Returns the advanceWidthMax.
+ */
+ public int getAdvanceWidthMax()
+ {
+ return advanceWidthMax;
+ }
+ /**
+ * @param advanceWidthMaxValue The advanceWidthMax to set.
+ */
+ public void setAdvanceWidthMax(int advanceWidthMaxValue)
+ {
+ this.advanceWidthMax = advanceWidthMaxValue;
+ }
+ /**
+ * @return Returns the ascender.
+ */
+ public short getAscender()
+ {
+ return ascender;
+ }
+ /**
+ * @param ascenderValue The ascender to set.
+ */
+ public void setAscender(short ascenderValue)
+ {
+ this.ascender = ascenderValue;
+ }
+ /**
+ * @return Returns the caretSlopeRise.
+ */
+ public short getCaretSlopeRise()
+ {
+ return caretSlopeRise;
+ }
+ /**
+ * @param caretSlopeRiseValue The caretSlopeRise to set.
+ */
+ public void setCaretSlopeRise(short caretSlopeRiseValue)
+ {
+ this.caretSlopeRise = caretSlopeRiseValue;
+ }
+ /**
+ * @return Returns the caretSlopeRun.
+ */
+ public short getCaretSlopeRun()
+ {
+ return caretSlopeRun;
+ }
+ /**
+ * @param caretSlopeRunValue The caretSlopeRun to set.
+ */
+ public void setCaretSlopeRun(short caretSlopeRunValue)
+ {
+ this.caretSlopeRun = caretSlopeRunValue;
+ }
+ /**
+ * @return Returns the descender.
+ */
+ public short getDescender()
+ {
+ return descender;
+ }
+ /**
+ * @param descenderValue The descender to set.
+ */
+ public void setDescender(short descenderValue)
+ {
+ this.descender = descenderValue;
+ }
+ /**
+ * @return Returns the lineGap.
+ */
+ public short getLineGap()
+ {
+ return lineGap;
+ }
+ /**
+ * @param lineGapValue The lineGap to set.
+ */
+ public void setLineGap(short lineGapValue)
+ {
+ this.lineGap = lineGapValue;
+ }
+ /**
+ * @return Returns the metricDataFormat.
+ */
+ public short getMetricDataFormat()
+ {
+ return metricDataFormat;
+ }
+ /**
+ * @param metricDataFormatValue The metricDataFormat to set.
+ */
+ public void setMetricDataFormat(short metricDataFormatValue)
+ {
+ this.metricDataFormat = metricDataFormatValue;
+ }
+ /**
+ * @return Returns the minLeftSideBearing.
+ */
+ public short getMinLeftSideBearing()
+ {
+ return minLeftSideBearing;
+ }
+ /**
+ * @param minLeftSideBearingValue The minLeftSideBearing to set.
+ */
+ public void setMinLeftSideBearing(short minLeftSideBearingValue)
+ {
+ this.minLeftSideBearing = minLeftSideBearingValue;
+ }
+ /**
+ * @return Returns the minRightSideBearing.
+ */
+ public short getMinRightSideBearing()
+ {
+ return minRightSideBearing;
+ }
+ /**
+ * @param minRightSideBearingValue The minRightSideBearing to set.
+ */
+ public void setMinRightSideBearing(short minRightSideBearingValue)
+ {
+ this.minRightSideBearing = minRightSideBearingValue;
+ }
+ /**
+ * @return Returns the numberOfHMetrics.
+ */
+ public int getNumberOfHMetrics()
+ {
+ return numberOfHMetrics;
+ }
+ /**
+ * @param numberOfHMetricsValue The numberOfHMetrics to set.
+ */
+ public void setNumberOfHMetrics(int numberOfHMetricsValue)
+ {
+ this.numberOfHMetrics = numberOfHMetricsValue;
+ }
+ /**
+ * @return Returns the reserved1.
+ */
+ public short getReserved1()
+ {
+ return reserved1;
+ }
+ /**
+ * @param reserved1Value The reserved1 to set.
+ */
+ public void setReserved1(short reserved1Value)
+ {
+ this.reserved1 = reserved1Value;
+ }
+ /**
+ * @return Returns the reserved2.
+ */
+ public short getReserved2()
+ {
+ return reserved2;
+ }
+ /**
+ * @param reserved2Value The reserved2 to set.
+ */
+ public void setReserved2(short reserved2Value)
+ {
+ this.reserved2 = reserved2Value;
+ }
+ /**
+ * @return Returns the reserved3.
+ */
+ public short getReserved3()
+ {
+ return reserved3;
+ }
+ /**
+ * @param reserved3Value The reserved3 to set.
+ */
+ public void setReserved3(short reserved3Value)
+ {
+ this.reserved3 = reserved3Value;
+ }
+ /**
+ * @return Returns the reserved4.
+ */
+ public short getReserved4()
+ {
+ return reserved4;
+ }
+ /**
+ * @param reserved4Value The reserved4 to set.
+ */
+ public void setReserved4(short reserved4Value)
+ {
+ this.reserved4 = reserved4Value;
+ }
+ /**
+ * @return Returns the reserved5.
+ */
+ public short getReserved5()
+ {
+ return reserved5;
+ }
+ /**
+ * @param reserved5Value The reserved5 to set.
+ */
+ public void setReserved5(short reserved5Value)
+ {
+ this.reserved5 = reserved5Value;
+ }
+ /**
+ * @return Returns the version.
+ */
+ public float getVersion()
+ {
+ return version;
+ }
+ /**
+ * @param versionValue The version to set.
+ */
+ public void setVersion(float versionValue)
+ {
+ this.version = versionValue;
+ }
+ /**
+ * @return Returns the xMaxExtent.
+ */
+ public short getXMaxExtent()
+ {
+ return xMaxExtent;
+ }
+ /**
+ * @param maxExtentValue The xMaxExtent to set.
+ */
+ public void setXMaxExtent(short maxExtentValue)
+ {
+ xMaxExtent = maxExtentValue;
+ }
+}
diff --git a/src/main/java/org/pdfbox/ttf/HorizontalMetricsTable.java b/src/main/java/org/pdfbox/ttf/HorizontalMetricsTable.java
new file mode 100644
index 0000000..4dc9081
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/HorizontalMetricsTable.java
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.io.IOException;
+
+/**
+ * A table in a true type font.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class HorizontalMetricsTable extends TTFTable
+{
+ /**
+ * A tag that identifies this table type.
+ */
+ public static final String TAG = "hmtx";
+
+ private int[] advanceWidth;
+ private short[] leftSideBearing;
+ private short[] nonHorizontalLeftSideBearing;
+
+ /**
+ * This will read the required data from the stream.
+ *
+ * @param ttf The font that is being read.
+ * @param data The stream to read the data from.
+ * @throws IOException If there is an error reading the data.
+ */
+ public void initData( TrueTypeFont ttf, TTFDataStream data ) throws IOException
+ {
+ HorizontalHeaderTable hHeader = ttf.getHorizontalHeader();
+ MaximumProfileTable maxp = ttf.getMaximumProfile();
+ int numHMetrics = hHeader.getNumberOfHMetrics();
+ int numGlyphs = maxp.getNumGlyphs();
+
+ advanceWidth = new int[ numHMetrics ];
+ leftSideBearing = new short[ numHMetrics ];
+ for( int i=0; i<numHMetrics; i++ )
+ {
+ advanceWidth[i] = data.readUnsignedShort();
+ leftSideBearing[i] = data.readSignedShort();
+ }
+
+ int numberNonHorizontal = numGlyphs - numHMetrics;
+ nonHorizontalLeftSideBearing = new short[ numberNonHorizontal ];
+ for( int i=0; i<numberNonHorizontal; i++ )
+ {
+ nonHorizontalLeftSideBearing[i] = data.readSignedShort();
+ }
+ }
+ /**
+ * @return Returns the advanceWidth.
+ */
+ public int[] getAdvanceWidth()
+ {
+ return advanceWidth;
+ }
+ /**
+ * @param advanceWidthValue The advanceWidth to set.
+ */
+ public void setAdvanceWidth(int[] advanceWidthValue)
+ {
+ this.advanceWidth = advanceWidthValue;
+ }
+}
diff --git a/src/main/java/org/pdfbox/ttf/IndexToLocationTable.java b/src/main/java/org/pdfbox/ttf/IndexToLocationTable.java
new file mode 100644
index 0000000..a695c73
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/IndexToLocationTable.java
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.io.IOException;
+
+/**
+ * A table in a true type font.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class IndexToLocationTable extends TTFTable
+{
+ private static final short SHORT_OFFSETS = 0;
+ private static final short LONG_OFFSETS = 1;
+
+ /**
+ * A tag that identifies this table type.
+ */
+ public static final String TAG = "loca";
+
+ private long[] offsets;
+
+ /**
+ * This will read the required data from the stream.
+ *
+ * @param ttf The font that is being read.
+ * @param data The stream to read the data from.
+ * @throws IOException If there is an error reading the data.
+ */
+ public void initData( TrueTypeFont ttf, TTFDataStream data ) throws IOException
+ {
+ HeaderTable head = ttf.getHeader();
+ MaximumProfileTable maxp = ttf.getMaximumProfile();
+ int numGlyphs = maxp.getNumGlyphs();
+ offsets = new long[ numGlyphs +1];
+ for( int i=0; i<numGlyphs+1; i++ )
+ {
+ if( head.getIndexToLocFormat() == SHORT_OFFSETS )
+ {
+ offsets[i] = data.readUnsignedShort() * 2;
+ }
+ else if( head.getIndexToLocFormat() == LONG_OFFSETS )
+ {
+ offsets[i] = data.readUnsignedInt();
+ }
+ else
+ {
+ throw new IOException( "Error:TTF.loca unknown offset format.");
+ }
+ }
+ }
+ /**
+ * @return Returns the offsets.
+ */
+ public long[] getOffsets()
+ {
+ return offsets;
+ }
+ /**
+ * @param offsetsValue The offsets to set.
+ */
+ public void setOffsets(long[] offsetsValue)
+ {
+ this.offsets = offsetsValue;
+ }
+}
diff --git a/src/main/java/org/pdfbox/ttf/MaximumProfileTable.java b/src/main/java/org/pdfbox/ttf/MaximumProfileTable.java
new file mode 100644
index 0000000..36cf443
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/MaximumProfileTable.java
@@ -0,0 +1,300 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.io.IOException;
+
+/**
+ * A table in a true type font.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class MaximumProfileTable extends TTFTable
+{
+ /**
+ * A tag that identifies this table type.
+ */
+ public static final String TAG = "maxp";
+
+ private float version;
+ private int numGlyphs;
+ private int maxPoints;
+ private int maxContours;
+ private int maxCompositePoints;
+ private int maxCompositeContours;
+ private int maxZones;
+ private int maxTwilightPoints;
+ private int maxStorage;
+ private int maxFunctionDefs;
+ private int maxInstructionDefs;
+ private int maxStackElements;
+ private int maxSizeOfInstructions;
+ private int maxComponentElements;
+ private int maxComponentDepth;
+
+ /**
+ * @return Returns the maxComponentDepth.
+ */
+ public int getMaxComponentDepth()
+ {
+ return maxComponentDepth;
+ }
+ /**
+ * @param maxComponentDepthValue The maxComponentDepth to set.
+ */
+ public void setMaxComponentDepth(int maxComponentDepthValue)
+ {
+ this.maxComponentDepth = maxComponentDepthValue;
+ }
+ /**
+ * @return Returns the maxComponentElements.
+ */
+ public int getMaxComponentElements()
+ {
+ return maxComponentElements;
+ }
+ /**
+ * @param maxComponentElementsValue The maxComponentElements to set.
+ */
+ public void setMaxComponentElements(int maxComponentElementsValue)
+ {
+ this.maxComponentElements = maxComponentElementsValue;
+ }
+ /**
+ * @return Returns the maxCompositeContours.
+ */
+ public int getMaxCompositeContours()
+ {
+ return maxCompositeContours;
+ }
+ /**
+ * @param maxCompositeContoursValue The maxCompositeContours to set.
+ */
+ public void setMaxCompositeContours(int maxCompositeContoursValue)
+ {
+ this.maxCompositeContours = maxCompositeContoursValue;
+ }
+ /**
+ * @return Returns the maxCompositePoints.
+ */
+ public int getMaxCompositePoints()
+ {
+ return maxCompositePoints;
+ }
+ /**
+ * @param maxCompositePointsValue The maxCompositePoints to set.
+ */
+ public void setMaxCompositePoints(int maxCompositePointsValue)
+ {
+ this.maxCompositePoints = maxCompositePointsValue;
+ }
+ /**
+ * @return Returns the maxContours.
+ */
+ public int getMaxContours()
+ {
+ return maxContours;
+ }
+ /**
+ * @param maxContoursValue The maxContours to set.
+ */
+ public void setMaxContours(int maxContoursValue)
+ {
+ this.maxContours = maxContoursValue;
+ }
+ /**
+ * @return Returns the maxFunctionDefs.
+ */
+ public int getMaxFunctionDefs()
+ {
+ return maxFunctionDefs;
+ }
+ /**
+ * @param maxFunctionDefsValue The maxFunctionDefs to set.
+ */
+ public void setMaxFunctionDefs(int maxFunctionDefsValue)
+ {
+ this.maxFunctionDefs = maxFunctionDefsValue;
+ }
+ /**
+ * @return Returns the maxInstructionDefs.
+ */
+ public int getMaxInstructionDefs()
+ {
+ return maxInstructionDefs;
+ }
+ /**
+ * @param maxInstructionDefsValue The maxInstructionDefs to set.
+ */
+ public void setMaxInstructionDefs(int maxInstructionDefsValue)
+ {
+ this.maxInstructionDefs = maxInstructionDefsValue;
+ }
+ /**
+ * @return Returns the maxPoints.
+ */
+ public int getMaxPoints()
+ {
+ return maxPoints;
+ }
+ /**
+ * @param maxPointsValue The maxPoints to set.
+ */
+ public void setMaxPoints(int maxPointsValue)
+ {
+ this.maxPoints = maxPointsValue;
+ }
+ /**
+ * @return Returns the maxSizeOfInstructions.
+ */
+ public int getMaxSizeOfInstructions()
+ {
+ return maxSizeOfInstructions;
+ }
+ /**
+ * @param maxSizeOfInstructionsValue The maxSizeOfInstructions to set.
+ */
+ public void setMaxSizeOfInstructions(int maxSizeOfInstructionsValue)
+ {
+ this.maxSizeOfInstructions = maxSizeOfInstructionsValue;
+ }
+ /**
+ * @return Returns the maxStackElements.
+ */
+ public int getMaxStackElements()
+ {
+ return maxStackElements;
+ }
+ /**
+ * @param maxStackElementsValue The maxStackElements to set.
+ */
+ public void setMaxStackElements(int maxStackElementsValue)
+ {
+ this.maxStackElements = maxStackElementsValue;
+ }
+ /**
+ * @return Returns the maxStorage.
+ */
+ public int getMaxStorage()
+ {
+ return maxStorage;
+ }
+ /**
+ * @param maxStorageValue The maxStorage to set.
+ */
+ public void setMaxStorage(int maxStorageValue)
+ {
+ this.maxStorage = maxStorageValue;
+ }
+ /**
+ * @return Returns the maxTwilightPoints.
+ */
+ public int getMaxTwilightPoints()
+ {
+ return maxTwilightPoints;
+ }
+ /**
+ * @param maxTwilightPointsValue The maxTwilightPoints to set.
+ */
+ public void setMaxTwilightPoints(int maxTwilightPointsValue)
+ {
+ this.maxTwilightPoints = maxTwilightPointsValue;
+ }
+ /**
+ * @return Returns the maxZones.
+ */
+ public int getMaxZones()
+ {
+ return maxZones;
+ }
+ /**
+ * @param maxZonesValue The maxZones to set.
+ */
+ public void setMaxZones(int maxZonesValue)
+ {
+ this.maxZones = maxZonesValue;
+ }
+ /**
+ * @return Returns the numGlyphs.
+ */
+ public int getNumGlyphs()
+ {
+ return numGlyphs;
+ }
+ /**
+ * @param numGlyphsValue The numGlyphs to set.
+ */
+ public void setNumGlyphs(int numGlyphsValue)
+ {
+ this.numGlyphs = numGlyphsValue;
+ }
+ /**
+ * @return Returns the version.
+ */
+ public float getVersion()
+ {
+ return version;
+ }
+ /**
+ * @param versionValue The version to set.
+ */
+ public void setVersion(float versionValue)
+ {
+ this.version = versionValue;
+ }
+
+ /**
+ * This will read the required data from the stream.
+ *
+ * @param ttf The font that is being read.
+ * @param data The stream to read the data from.
+ * @throws IOException If there is an error reading the data.
+ */
+ public void initData( TrueTypeFont ttf, TTFDataStream data ) throws IOException
+ {
+ version = data.read32Fixed();
+ numGlyphs = data.readUnsignedShort();
+ maxPoints = data.readUnsignedShort();
+ maxContours = data.readUnsignedShort();
+ maxCompositePoints = data.readUnsignedShort();
+ maxCompositeContours = data.readUnsignedShort();
+ maxZones = data.readUnsignedShort();
+ maxTwilightPoints = data.readUnsignedShort();
+ maxStorage = data.readUnsignedShort();
+ maxFunctionDefs = data.readUnsignedShort();
+ maxInstructionDefs = data.readUnsignedShort();
+ maxStackElements = data.readUnsignedShort();
+ maxSizeOfInstructions = data.readUnsignedShort();
+ maxComponentElements = data.readUnsignedShort();
+ maxComponentDepth = data.readUnsignedShort();
+ }
+}
diff --git a/src/main/java/org/pdfbox/ttf/MemoryTTFDataStream.java b/src/main/java/org/pdfbox/ttf/MemoryTTFDataStream.java
new file mode 100644
index 0000000..17f4455
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/MemoryTTFDataStream.java
@@ -0,0 +1,231 @@
+/**
+ * Copyright (c) 2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.pdfbox.pdmodel.common.PDMemoryStream;
+import org.pdfbox.pdmodel.common.PDStream;
+
+/**
+ * An interface into a data stream.
+ *
+ * @author Ben Litchfield (ben@benlitchfield.com)
+ * @version $Revision: 1.3 $
+ */
+public class MemoryTTFDataStream extends TTFDataStream
+{
+ private byte[] data = null;
+ private int currentPosition = 0;
+
+ /**
+ * Constructor from a stream.
+ * @param is The stream of read from.
+ * @throws IOException If an error occurs while reading from the stream.
+ */
+ public MemoryTTFDataStream( InputStream is ) throws IOException
+ {
+ try
+ {
+ ByteArrayOutputStream output = new ByteArrayOutputStream( is.available() );
+ byte[] buffer = new byte[1024];
+ int amountRead = 0;
+ while( (amountRead = is.read( buffer ) ) != -1 )
+ {
+ output.write( buffer, 0, amountRead );
+ }
+ data = output.toByteArray();
+ }
+ finally
+ {
+ if( is != null )
+ {
+ is.close();
+ }
+ }
+ }
+
+
+
+ /**
+ * Read an unsigned byte.
+ * @return An unsigned byte.
+ * @throws IOException If there is an error reading the data.
+ */
+ public long readLong() throws IOException
+ {
+ return ((long)(readSignedInt()) << 32) + (readSignedInt() & 0xFFFFFFFFL);
+ }
+
+ /**
+ * Read a signed integer.
+ *
+ * @return A signed integer.
+ * @throws IOException If there is a problem reading the file.
+ */
+ public int readSignedInt() throws IOException
+ {
+ int ch1 = read();
+ int ch2 = read();
+ int ch3 = read();
+ int ch4 = read();
+ if( (ch1 | ch2 | ch3 | ch4) < 0)
+ {
+ throw new EOFException();
+ }
+ return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
+ }
+
+ /**
+ * Read an unsigned byte.
+ * @return An unsigned byte.
+ * @throws IOException If there is an error reading the data.
+ */
+ public int read() throws IOException
+ {
+ int retval = -1;
+ if( currentPosition < data.length )
+ {
+ retval = data[currentPosition];
+ }
+ currentPosition++;
+ return (retval+256)%256;
+ }
+
+ /**
+ * Read an unsigned short.
+ *
+ * @return An unsigned short.
+ * @throws IOException If there is an error reading the data.
+ */
+ public int readUnsignedShort() throws IOException
+ {
+ int ch1 = this.read();
+ int ch2 = this.read();
+ if ((ch1 | ch2) < 0)
+ {
+ throw new EOFException();
+ }
+ return (ch1 << 8) + (ch2 << 0);
+ }
+
+ /**
+ * Read an signed short.
+ *
+ * @return An signed short.
+ * @throws IOException If there is an error reading the data.
+ */
+ public short readSignedShort() throws IOException
+ {
+ int ch1 = this.read();
+ int ch2 = this.read();
+ if ((ch1 | ch2) < 0)
+ {
+ throw new EOFException();
+ }
+ return (short)((ch1 << 8) + (ch2 << 0));
+ }
+
+ /**
+ * Close the underlying resources.
+ *
+ * @throws IOException If there is an error closing the resources.
+ */
+ public void close() throws IOException
+ {
+ data = null;
+ }
+
+ /**
+ * Seek into the datasource.
+ *
+ * @param pos The position to seek to.
+ * @throws IOException If there is an error seeking to that position.
+ */
+ public void seek(long pos) throws IOException
+ {
+ currentPosition = (int)pos;
+ }
+
+ /**
+ * @see java.io.InputStream#read( byte[], int, int )
+ *
+ * @param b The buffer to write to.
+ * @param off The offset into the buffer.
+ * @param len The length into the buffer.
+ *
+ * @return The number of bytes read.
+ *
+ * @throws IOException If there is an error reading from the stream.
+ */
+ public int read(byte[] b,
+ int off,
+ int len)
+ throws IOException
+ {
+ int amountRead = Math.min( len, data.length-currentPosition );
+ System.arraycopy(data,currentPosition,b, off, amountRead );
+ currentPosition+=amountRead;
+
+ return amountRead;
+ }
+
+ /**
+ * Get the current position in the stream.
+ * @return The current position in the stream.
+ * @throws IOException If an error occurs while reading the stream.
+ */
+ public long getCurrentPosition() throws IOException
+ {
+ return currentPosition;
+ }
+
+ /**
+ * Get a COSStream from this TTFDataStream
+ * This permit to pass the data read from an
+ * external source to the COSObjects to keep
+ * a certain persistence layer between specialized
+ * objects like the TTF package and the pdmodel package.
+ *
+ * Created by Pascal Allain
+ * Vertical7 Inc.
+ *
+ * @return COSStream describing this stream
+ */
+ public PDStream getPDStream()
+ {
+ return new PDMemoryStream( data );
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/ttf/NameRecord.java b/src/main/java/org/pdfbox/ttf/NameRecord.java
new file mode 100644
index 0000000..354fa89
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/NameRecord.java
@@ -0,0 +1,242 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.io.IOException;
+
+/**
+ * A name record in the name table.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class NameRecord
+{
+ /**
+ * A constant for the platform.
+ */
+ public static final int PLATFORM_APPLE_UNICODE = 0;
+ /**
+ * A constant for the platform.
+ */
+ public static final int PLATFORM_MACINTOSH = 1;
+ /**
+ * A constant for the platform.
+ */
+ public static final int PLATFORM_ISO = 2;
+ /**
+ * A constant for the platform.
+ */
+ public static final int PLATFORM_WINDOWS = 3;
+
+ /**
+ * Platform specific encoding.
+ */
+ public static final int PLATFORM_ENCODING_WINDOWS_UNDEFINED = 0;
+ /**
+ * Platform specific encoding.
+ */
+ public static final int PLATFORM_ENCODING_WINDOWS_UNICODE = 1;
+
+ /**
+ * A name id.
+ */
+ public static final int NAME_COPYRIGHT = 0;
+ /**
+ * A name id.
+ */
+ public static final int NAME_FONT_FAMILY_NAME = 1;
+ /**
+ * A name id.
+ */
+ public static final int NAME_FONT_SUB_FAMILY_NAME = 2;
+ /**
+ * A name id.
+ */
+ public static final int NAME_UNIQUE_FONT_ID = 3;
+ /**
+ * A name id.
+ */
+ public static final int NAME_FULL_FONT_NAME = 4;
+ /**
+ * A name id.
+ */
+ public static final int NAME_VERSION = 5;
+ /**
+ * A name id.
+ */
+ public static final int NAME_POSTSCRIPT_NAME = 6;
+ /**
+ * A name id.
+ */
+ public static final int NAME_TRADEMARK = 7;
+
+
+
+ private int platformId;
+ private int platformEncodingId;
+ private int languageId;
+ private int nameId;
+ private int stringLength;
+ private int stringOffset;
+ private String string;
+
+ /**
+ * @return Returns the stringLength.
+ */
+ public int getStringLength()
+ {
+ return stringLength;
+ }
+ /**
+ * @param stringLengthValue The stringLength to set.
+ */
+ public void setStringLength(int stringLengthValue)
+ {
+ this.stringLength = stringLengthValue;
+ }
+ /**
+ * @return Returns the stringOffset.
+ */
+ public int getStringOffset()
+ {
+ return stringOffset;
+ }
+ /**
+ * @param stringOffsetValue The stringOffset to set.
+ */
+ public void setStringOffset(int stringOffsetValue)
+ {
+ this.stringOffset = stringOffsetValue;
+ }
+
+ /**
+ * @return Returns the languageId.
+ */
+ public int getLanguageId()
+ {
+ return languageId;
+ }
+ /**
+ * @param languageIdValue The languageId to set.
+ */
+ public void setLanguageId(int languageIdValue)
+ {
+ this.languageId = languageIdValue;
+ }
+ /**
+ * @return Returns the nameId.
+ */
+ public int getNameId()
+ {
+ return nameId;
+ }
+ /**
+ * @param nameIdValue The nameId to set.
+ */
+ public void setNameId(int nameIdValue)
+ {
+ this.nameId = nameIdValue;
+ }
+ /**
+ * @return Returns the platformEncodingId.
+ */
+ public int getPlatformEncodingId()
+ {
+ return platformEncodingId;
+ }
+ /**
+ * @param platformEncodingIdValue The platformEncodingId to set.
+ */
+ public void setPlatformEncodingId(int platformEncodingIdValue)
+ {
+ this.platformEncodingId = platformEncodingIdValue;
+ }
+ /**
+ * @return Returns the platformId.
+ */
+ public int getPlatformId()
+ {
+ return platformId;
+ }
+ /**
+ * @param platformIdValue The platformId to set.
+ */
+ public void setPlatformId(int platformIdValue)
+ {
+ this.platformId = platformIdValue;
+ }
+
+ /**
+ * This will read the required data from the stream.
+ *
+ * @param ttf The font that is being read.
+ * @param data The stream to read the data from.
+ * @throws IOException If there is an error reading the data.
+ */
+ public void initData( TrueTypeFont ttf, TTFDataStream data ) throws IOException
+ {
+ platformId = data.readUnsignedShort();
+ platformEncodingId = data.readUnsignedShort();
+ languageId = data.readUnsignedShort();
+ nameId = data.readUnsignedShort();
+ stringLength = data.readUnsignedShort();
+ stringOffset = data.readUnsignedShort();
+ }
+
+ /**
+ * Return a string representation of this class.
+ *
+ * @return A string for this class.
+ */
+ public String toString()
+ {
+ return
+ "platform=" + platformId +
+ " pEncoding=" + platformEncodingId +
+ " language=" + languageId +
+ " name=" + nameId;
+ }
+ /**
+ * @return Returns the string.
+ */
+ public String getString()
+ {
+ return string;
+ }
+ /**
+ * @param stringValue The string to set.
+ */
+ public void setString(String stringValue)
+ {
+ this.string = stringValue;
+ }
+}
diff --git a/src/main/java/org/pdfbox/ttf/NamingTable.java b/src/main/java/org/pdfbox/ttf/NamingTable.java
new file mode 100644
index 0000000..5976e47
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/NamingTable.java
@@ -0,0 +1,112 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.io.IOException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A table in a true type font.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class NamingTable extends TTFTable
+{
+ /**
+ * A tag that identifies this table type.
+ */
+ public static final String TAG = "name";
+
+ private List nameRecords = new ArrayList();
+
+ /**
+ * This will read the required data from the stream.
+ *
+ * @param ttf The font that is being read.
+ * @param data The stream to read the data from.
+ * @throws IOException If there is an error reading the data.
+ */
+ public void initData( TrueTypeFont ttf, TTFDataStream data ) throws IOException
+ {
+ int formatSelector = data.readUnsignedShort();
+ int numberOfNameRecords = data.readUnsignedShort();
+ int offsetToStartOfStringStorage = data.readUnsignedShort();
+ for( int i=0; i< numberOfNameRecords; i++ )
+ {
+ NameRecord nr = new NameRecord();
+ nr.initData( ttf, data );
+ nameRecords.add( nr );
+ }
+ for( int i=0; i<numberOfNameRecords; i++ )
+ {
+ NameRecord nr = (NameRecord)nameRecords.get( i );
+ data.seek( getOffset() + (2*3)+numberOfNameRecords*2*6+nr.getStringOffset() );
+ int platform = nr.getPlatformId();
+ int encoding = nr.getPlatformEncodingId();
+ String charset = "ISO-8859-1";
+ if( platform == 3 && encoding == 1 )
+ {
+ charset = "UTF-16";
+ }
+ else if( platform == 2 )
+ {
+ if( encoding == 0 )
+ {
+ charset = "US-ASCII";
+ }
+ else if( encoding == 1 )
+ {
+ //not sure is this is correct??
+ charset = "ISO-10646-1";
+ }
+ else if( encoding == 2 )
+ {
+ charset = "ISO-8859-1";
+ }
+ }
+ String string = data.readString( nr.getStringLength(), charset );
+ nr.setString( string );
+ }
+ }
+
+ /**
+ * This will get the name records for this naming table.
+ *
+ * @return A list of NameRecord objects.
+ */
+ public List getNameRecords()
+ {
+ return nameRecords;
+ }
+}
diff --git a/src/main/java/org/pdfbox/ttf/OS2WindowsMetricsTable.java b/src/main/java/org/pdfbox/ttf/OS2WindowsMetricsTable.java
new file mode 100644
index 0000000..f5c5a90
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/OS2WindowsMetricsTable.java
@@ -0,0 +1,694 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.io.IOException;
+
+/**
+ * A table in a true type font.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class OS2WindowsMetricsTable extends TTFTable
+{
+
+ /**
+ * Weight class constant.
+ */
+ public static final int WEIGHT_CLASS_THIN = 100;
+ /**
+ * Weight class constant.
+ */
+ public static final int WEIGHT_CLASS_ULTRA_LIGHT = 200;
+ /**
+ * Weight class constant.
+ */
+ public static final int WEIGHT_CLASS_LIGHT = 300;
+ /**
+ * Weight class constant.
+ */
+ public static final int WEIGHT_CLASS_NORMAL = 400;
+ /**
+ * Weight class constant.
+ */
+ public static final int WEIGHT_CLASS_MEDIUM = 500;
+ /**
+ * Weight class constant.
+ */
+ public static final int WEIGHT_CLASS_SEMI_BOLD = 600;
+ /**
+ * Weight class constant.
+ */
+ public static final int WEIGHT_CLASS_BOLD = 700;
+ /**
+ * Weight class constant.
+ */
+ public static final int WEIGHT_CLASS_EXTRA_BOLD = 800;
+ /**
+ * Weight class constant.
+ */
+ public static final int WEIGHT_CLASS_BLACK = 900;
+
+ /**
+ * Width class constant.
+ */
+ public static final int WIDTH_CLASS_ULTRA_CONDENSED = 1;
+ /**
+ * Width class constant.
+ */
+ public static final int WIDTH_CLASS_EXTRA_CONDENSED = 2;
+ /**
+ * Width class constant.
+ */
+ public static final int WIDTH_CLASS_CONDENSED = 3;
+ /**
+ * Width class constant.
+ */
+ public static final int WIDTH_CLASS_SEMI_CONDENSED = 4;
+ /**
+ * Width class constant.
+ */
+ public static final int WIDTH_CLASS_MEDIUM = 5;
+ /**
+ * Width class constant.
+ */
+ public static final int WIDTH_CLASS_SEMI_EXPANDED = 6;
+ /**
+ * Width class constant.
+ */
+ public static final int WIDTH_CLASS_EXPANDED = 7;
+ /**
+ * Width class constant.
+ */
+ public static final int WIDTH_CLASS_EXTRA_EXPANDED = 8;
+ /**
+ * Width class constant.
+ */
+ public static final int WIDTH_CLASS_ULTRA_EXPANDED = 9;
+
+ /**
+ * Family class constant.
+ */
+ public static final int FAMILY_CLASS_NO_CLASSIFICATION = 0;
+ /**
+ * Family class constant.
+ */
+ public static final int FAMILY_CLASS_OLDSTYLE_SERIFS = 1;
+ /**
+ * Family class constant.
+ */
+ public static final int FAMILY_CLASS_TRANSITIONAL_SERIFS = 2;
+ /**
+ * Family class constant.
+ */
+ public static final int FAMILY_CLASS_MODERN_SERIFS = 3;
+ /**
+ * Family class constant.
+ */
+ public static final int FAMILY_CLASS_CLAREDON_SERIFS = 4;
+ /**
+ * Family class constant.
+ */
+ public static final int FAMILY_CLASS_SLAB_SERIFS = 5;
+ /**
+ * Family class constant.
+ */
+ public static final int FAMILY_CLASS_FREEFORM_SERIFS = 7;
+ /**
+ * Family class constant.
+ */
+ public static final int FAMILY_CLASS_SANS_SERIF = 8;
+ /**
+ * Family class constant.
+ */
+ public static final int FAMILY_CLASS_ORNAMENTALS = 9;
+ /**
+ * Family class constant.
+ */
+ public static final int FAMILY_CLASS_SCRIPTS = 10;
+ /**
+ * Family class constant.
+ */
+ public static final int FAMILY_CLASS_SYMBOLIC = 12;
+
+ /**
+ * @return Returns the achVendId.
+ */
+ public String getAchVendId()
+ {
+ return achVendId;
+ }
+ /**
+ * @param achVendIdValue The achVendId to set.
+ */
+ public void setAchVendId(String achVendIdValue)
+ {
+ this.achVendId = achVendIdValue;
+ }
+ /**
+ * @return Returns the averageCharWidth.
+ */
+ public short getAverageCharWidth()
+ {
+ return averageCharWidth;
+ }
+ /**
+ * @param averageCharWidthValue The averageCharWidth to set.
+ */
+ public void setAverageCharWidth(short averageCharWidthValue)
+ {
+ this.averageCharWidth = averageCharWidthValue;
+ }
+ /**
+ * @return Returns the codePageRange1.
+ */
+ public long getCodePageRange1()
+ {
+ return codePageRange1;
+ }
+ /**
+ * @param codePageRange1Value The codePageRange1 to set.
+ */
+ public void setCodePageRange1(long codePageRange1Value)
+ {
+ this.codePageRange1 = codePageRange1Value;
+ }
+ /**
+ * @return Returns the codePageRange2.
+ */
+ public long getCodePageRange2()
+ {
+ return codePageRange2;
+ }
+ /**
+ * @param codePageRange2Value The codePageRange2 to set.
+ */
+ public void setCodePageRange2(long codePageRange2Value)
+ {
+ this.codePageRange2 = codePageRange2Value;
+ }
+ /**
+ * @return Returns the familyClass.
+ */
+ public short getFamilyClass()
+ {
+ return familyClass;
+ }
+ /**
+ * @param familyClassValue The familyClass to set.
+ */
+ public void setFamilyClass(short familyClassValue)
+ {
+ this.familyClass = familyClassValue;
+ }
+ /**
+ * @return Returns the firstCharIndex.
+ */
+ public int getFirstCharIndex()
+ {
+ return firstCharIndex;
+ }
+ /**
+ * @param firstCharIndexValue The firstCharIndex to set.
+ */
+ public void setFirstCharIndex(int firstCharIndexValue)
+ {
+ this.firstCharIndex = firstCharIndexValue;
+ }
+ /**
+ * @return Returns the fsSelection.
+ */
+ public int getFsSelection()
+ {
+ return fsSelection;
+ }
+ /**
+ * @param fsSelectionValue The fsSelection to set.
+ */
+ public void setFsSelection(int fsSelectionValue)
+ {
+ this.fsSelection = fsSelectionValue;
+ }
+ /**
+ * @return Returns the fsType.
+ */
+ public short getFsType()
+ {
+ return fsType;
+ }
+ /**
+ * @param fsTypeValue The fsType to set.
+ */
+ public void setFsType(short fsTypeValue)
+ {
+ this.fsType = fsTypeValue;
+ }
+ /**
+ * @return Returns the lastCharIndex.
+ */
+ public int getLastCharIndex()
+ {
+ return lastCharIndex;
+ }
+ /**
+ * @param lastCharIndexValue The lastCharIndex to set.
+ */
+ public void setLastCharIndex(int lastCharIndexValue)
+ {
+ this.lastCharIndex = lastCharIndexValue;
+ }
+ /**
+ * @return Returns the panose.
+ */
+ public byte[] getPanose()
+ {
+ return panose;
+ }
+ /**
+ * @param panoseValue The panose to set.
+ */
+ public void setPanose(byte[] panoseValue)
+ {
+ this.panose = panoseValue;
+ }
+ /**
+ * @return Returns the strikeoutPosition.
+ */
+ public short getStrikeoutPosition()
+ {
+ return strikeoutPosition;
+ }
+ /**
+ * @param strikeoutPositionValue The strikeoutPosition to set.
+ */
+ public void setStrikeoutPosition(short strikeoutPositionValue)
+ {
+ this.strikeoutPosition = strikeoutPositionValue;
+ }
+ /**
+ * @return Returns the strikeoutSize.
+ */
+ public short getStrikeoutSize()
+ {
+ return strikeoutSize;
+ }
+ /**
+ * @param strikeoutSizeValue The strikeoutSize to set.
+ */
+ public void setStrikeoutSize(short strikeoutSizeValue)
+ {
+ this.strikeoutSize = strikeoutSizeValue;
+ }
+ /**
+ * @return Returns the subscriptXOffset.
+ */
+ public short getSubscriptXOffset()
+ {
+ return subscriptXOffset;
+ }
+ /**
+ * @param subscriptXOffsetValue The subscriptXOffset to set.
+ */
+ public void setSubscriptXOffset(short subscriptXOffsetValue)
+ {
+ this.subscriptXOffset = subscriptXOffsetValue;
+ }
+ /**
+ * @return Returns the subscriptXSize.
+ */
+ public short getSubscriptXSize()
+ {
+ return subscriptXSize;
+ }
+ /**
+ * @param subscriptXSizeValue The subscriptXSize to set.
+ */
+ public void setSubscriptXSize(short subscriptXSizeValue)
+ {
+ this.subscriptXSize = subscriptXSizeValue;
+ }
+ /**
+ * @return Returns the subscriptYOffset.
+ */
+ public short getSubscriptYOffset()
+ {
+ return subscriptYOffset;
+ }
+ /**
+ * @param subscriptYOffsetValue The subscriptYOffset to set.
+ */
+ public void setSubscriptYOffset(short subscriptYOffsetValue)
+ {
+ this.subscriptYOffset = subscriptYOffsetValue;
+ }
+ /**
+ * @return Returns the subscriptYSize.
+ */
+ public short getSubscriptYSize()
+ {
+ return subscriptYSize;
+ }
+ /**
+ * @param subscriptYSizeValue The subscriptYSize to set.
+ */
+ public void setSubscriptYSize(short subscriptYSizeValue)
+ {
+ this.subscriptYSize = subscriptYSizeValue;
+ }
+ /**
+ * @return Returns the superscriptXOffset.
+ */
+ public short getSuperscriptXOffset()
+ {
+ return superscriptXOffset;
+ }
+ /**
+ * @param superscriptXOffsetValue The superscriptXOffset to set.
+ */
+ public void setSuperscriptXOffset(short superscriptXOffsetValue)
+ {
+ this.superscriptXOffset = superscriptXOffsetValue;
+ }
+ /**
+ * @return Returns the superscriptXSize.
+ */
+ public short getSuperscriptXSize()
+ {
+ return superscriptXSize;
+ }
+ /**
+ * @param superscriptXSizeValue The superscriptXSize to set.
+ */
+ public void setSuperscriptXSize(short superscriptXSizeValue)
+ {
+ this.superscriptXSize = superscriptXSizeValue;
+ }
+ /**
+ * @return Returns the superscriptYOffset.
+ */
+ public short getSuperscriptYOffset()
+ {
+ return superscriptYOffset;
+ }
+ /**
+ * @param superscriptYOffsetValue The superscriptYOffset to set.
+ */
+ public void setSuperscriptYOffset(short superscriptYOffsetValue)
+ {
+ this.superscriptYOffset = superscriptYOffsetValue;
+ }
+ /**
+ * @return Returns the superscriptYSize.
+ */
+ public short getSuperscriptYSize()
+ {
+ return superscriptYSize;
+ }
+ /**
+ * @param superscriptYSizeValue The superscriptYSize to set.
+ */
+ public void setSuperscriptYSize(short superscriptYSizeValue)
+ {
+ this.superscriptYSize = superscriptYSizeValue;
+ }
+ /**
+ * @return Returns the typeLineGap.
+ */
+ public int getTypeLineGap()
+ {
+ return typeLineGap;
+ }
+ /**
+ * @param typeLineGapValue The typeLineGap to set.
+ */
+ public void setTypeLineGap(int typeLineGapValue)
+ {
+ this.typeLineGap = typeLineGapValue;
+ }
+ /**
+ * @return Returns the typoAscender.
+ */
+ public int getTypoAscender()
+ {
+ return typoAscender;
+ }
+ /**
+ * @param typoAscenderValue The typoAscender to set.
+ */
+ public void setTypoAscender(int typoAscenderValue)
+ {
+ this.typoAscender = typoAscenderValue;
+ }
+ /**
+ * @return Returns the typoDescender.
+ */
+ public int getTypoDescender()
+ {
+ return typoDescender;
+ }
+ /**
+ * @param typoDescenderValue The typoDescender to set.
+ */
+ public void setTypoDescender(int typoDescenderValue)
+ {
+ this.typoDescender = typoDescenderValue;
+ }
+ /**
+ * @return Returns the unicodeRange1.
+ */
+ public long getUnicodeRange1()
+ {
+ return unicodeRange1;
+ }
+ /**
+ * @param unicodeRange1Value The unicodeRange1 to set.
+ */
+ public void setUnicodeRange1(long unicodeRange1Value)
+ {
+ this.unicodeRange1 = unicodeRange1Value;
+ }
+ /**
+ * @return Returns the unicodeRange2.
+ */
+ public long getUnicodeRange2()
+ {
+ return unicodeRange2;
+ }
+ /**
+ * @param unicodeRange2Value The unicodeRange2 to set.
+ */
+ public void setUnicodeRange2(long unicodeRange2Value)
+ {
+ this.unicodeRange2 = unicodeRange2Value;
+ }
+ /**
+ * @return Returns the unicodeRange3.
+ */
+ public long getUnicodeRange3()
+ {
+ return unicodeRange3;
+ }
+ /**
+ * @param unicodeRange3Value The unicodeRange3 to set.
+ */
+ public void setUnicodeRange3(long unicodeRange3Value)
+ {
+ this.unicodeRange3 = unicodeRange3Value;
+ }
+ /**
+ * @return Returns the unicodeRange4.
+ */
+ public long getUnicodeRange4()
+ {
+ return unicodeRange4;
+ }
+ /**
+ * @param unicodeRange4Value The unicodeRange4 to set.
+ */
+ public void setUnicodeRange4(long unicodeRange4Value)
+ {
+ this.unicodeRange4 = unicodeRange4Value;
+ }
+ /**
+ * @return Returns the version.
+ */
+ public int getVersion()
+ {
+ return version;
+ }
+ /**
+ * @param versionValue The version to set.
+ */
+ public void setVersion(int versionValue)
+ {
+ this.version = versionValue;
+ }
+ /**
+ * @return Returns the weightClass.
+ */
+ public int getWeightClass()
+ {
+ return weightClass;
+ }
+ /**
+ * @param weightClassValue The weightClass to set.
+ */
+ public void setWeightClass(int weightClassValue)
+ {
+ this.weightClass = weightClassValue;
+ }
+ /**
+ * @return Returns the widthClass.
+ */
+ public int getWidthClass()
+ {
+ return widthClass;
+ }
+ /**
+ * @param widthClassValue The widthClass to set.
+ */
+ public void setWidthClass(int widthClassValue)
+ {
+ this.widthClass = widthClassValue;
+ }
+ /**
+ * @return Returns the winAscent.
+ */
+ public int getWinAscent()
+ {
+ return winAscent;
+ }
+ /**
+ * @param winAscentValue The winAscent to set.
+ */
+ public void setWinAscent(int winAscentValue)
+ {
+ this.winAscent = winAscentValue;
+ }
+ /**
+ * @return Returns the winDescent.
+ */
+ public int getWinDescent()
+ {
+ return winDescent;
+ }
+ /**
+ * @param winDescentValue The winDescent to set.
+ */
+ public void setWinDescent(int winDescentValue)
+ {
+ this.winDescent = winDescentValue;
+ }
+ private int version;
+ private short averageCharWidth;
+ private int weightClass;
+ private int widthClass;
+ private short fsType;
+ private short subscriptXSize;
+ private short subscriptYSize;
+ private short subscriptXOffset;
+ private short subscriptYOffset;
+ private short superscriptXSize;
+ private short superscriptYSize;
+ private short superscriptXOffset;
+ private short superscriptYOffset;
+ private short strikeoutSize;
+ private short strikeoutPosition;
+ private short familyClass;
+ private byte[] panose = new byte[10];
+ private long unicodeRange1;
+ private long unicodeRange2;
+ private long unicodeRange3;
+ private long unicodeRange4;
+ private String achVendId;
+ private int fsSelection;
+ private int firstCharIndex;
+ private int lastCharIndex;
+ private int typoAscender;
+ private int typoDescender;
+ private int typeLineGap;
+ private int winAscent;
+ private int winDescent;
+ private long codePageRange1 = -1;
+ private long codePageRange2 = -1;
+
+ /**
+ * A tag that identifies this table type.
+ */
+ public static final String TAG = "OS/2";
+
+ /**
+ * This will read the required data from the stream.
+ *
+ * @param ttf The font that is being read.
+ * @param data The stream to read the data from.
+ * @throws IOException If there is an error reading the data.
+ */
+ public void initData( TrueTypeFont ttf, TTFDataStream data ) throws IOException
+ {
+ version = data.readUnsignedShort();
+ averageCharWidth = data.readSignedShort();
+ weightClass = data.readUnsignedShort();
+ widthClass = data.readUnsignedShort();
+ fsType = data.readSignedShort();
+ subscriptXSize = data.readSignedShort();
+ subscriptYSize = data.readSignedShort();
+ subscriptXOffset = data.readSignedShort();
+ subscriptYOffset = data.readSignedShort();
+ superscriptXSize = data.readSignedShort();
+ superscriptYSize = data.readSignedShort();
+ superscriptXOffset = data.readSignedShort();
+ superscriptYOffset = data.readSignedShort();
+ strikeoutSize = data.readSignedShort();
+ strikeoutPosition = data.readSignedShort();
+ familyClass = data.readSignedShort();
+ panose = data.read( 10 );
+ unicodeRange1 = data.readUnsignedInt();
+ unicodeRange2 = data.readUnsignedInt();
+ unicodeRange3 = data.readUnsignedInt();
+ unicodeRange4 = data.readUnsignedInt();
+ achVendId = data.readString( 4 );
+ fsSelection = data.readUnsignedShort();
+ firstCharIndex = data.readUnsignedShort();
+ lastCharIndex = data.readUnsignedShort();
+ typoAscender = data.readSignedShort();
+ typoDescender = data.readSignedShort();
+ typeLineGap = data.readSignedShort();
+ winAscent = data.readUnsignedShort();
+ winDescent = data.readUnsignedShort();
+ if( version >= 1 )
+ {
+ codePageRange1 = data.readUnsignedInt();
+ codePageRange2 = data.readUnsignedInt();
+ }
+ }
+}
diff --git a/src/main/java/org/pdfbox/ttf/PostScriptTable.java b/src/main/java/org/pdfbox/ttf/PostScriptTable.java
new file mode 100644
index 0000000..e7b7822
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/PostScriptTable.java
@@ -0,0 +1,304 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.io.IOException;
+
+import org.pdfbox.cos.COSName;
+
+import org.pdfbox.encoding.MacRomanEncoding;
+
+/**
+ * A table in a true type font.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class PostScriptTable extends TTFTable
+{
+ private float formatType;
+ private float italicAngle;
+ private short underlinePosition;
+ private short underlineThickness;
+ private long isFixedPitch;
+ private long minMemType42;
+ private long maxMemType42;
+ private long mimMemType1;
+ private long maxMemType1;
+ private String[] glyphNames = null;
+
+ /**
+ * A tag that identifies this table type.
+ */
+ public static final String TAG = "post";
+
+ /**
+ * This will read the required data from the stream.
+ *
+ * @param ttf The font that is being read.
+ * @param data The stream to read the data from.
+ * @throws IOException If there is an error reading the data.
+ */
+ public void initData( TrueTypeFont ttf, TTFDataStream data ) throws IOException
+ {
+ MaximumProfileTable maxp = ttf.getMaximumProfile();
+ formatType = data.read32Fixed();
+ italicAngle = data.read32Fixed();
+ underlinePosition = data.readSignedShort();
+ underlineThickness = data.readSignedShort();
+ isFixedPitch = data.readUnsignedInt();
+ minMemType42 = data.readUnsignedInt();
+ maxMemType42 = data.readUnsignedInt();
+ mimMemType1 = data.readUnsignedInt();
+ maxMemType1 = data.readUnsignedInt();
+ MacRomanEncoding encoding = new MacRomanEncoding();
+
+
+ if( formatType == 1.0f )
+ {
+ /*
+ * This TrueType font file contains exactly the 258 glyphs in the standard
+ * Macintosh TrueType.
+ */
+ glyphNames = new String[258];
+ for( int i=0; i<glyphNames.length; i++)
+ {
+ COSName name = encoding.getName( i );
+ if( name != null )
+ {
+ glyphNames[i] = name.getName();
+ }
+ }
+ }
+ else if( formatType == 2.0f )
+ {
+ int numGlyphs = data.readUnsignedShort();
+ int[] glyphNameIndex = new int[numGlyphs];
+ glyphNames = new String[ numGlyphs ];
+ int maxIndex = Integer.MIN_VALUE;
+ for( int i=0; i<numGlyphs; i++ )
+ {
+ int index = data.readUnsignedShort();
+ glyphNameIndex[i] = index;
+ maxIndex = Math.max( maxIndex, index );
+ }
+ String[] nameArray = null;
+ if( maxIndex >= 258 )
+ {
+ nameArray = new String[ maxIndex-258 +1 ];
+ for( int i=0; i<maxIndex-258+1; i++ )
+ {
+ int numberOfChars = data.read();
+ nameArray[i]=data.readString( numberOfChars );
+ }
+ }
+ for( int i=0; i<numGlyphs; i++ )
+ {
+ int index = glyphNameIndex[i];
+ if( index < 258 )
+ {
+ glyphNames[i] = encoding.getName( index ).getName();
+ }
+ else if( index >= 258 && index <= 32767 )
+ {
+ glyphNames[i] = nameArray[index-258];
+ }
+ else
+ {
+ throw new IOException( "Unknown glyph name index:" + index );
+ }
+ }
+ }
+ else if( formatType == 2.5f )
+ {
+ int[] glyphNameIndex = new int[maxp.getNumGlyphs()];
+ for( int i=0; i<glyphNameIndex.length; i++)
+ {
+ int offset = data.readSignedByte();
+ glyphNameIndex[i] = i+1+offset;
+ }
+ glyphNames = new String[glyphNameIndex.length];
+ for( int i=0; i<glyphNames.length; i++)
+ {
+ COSName name = encoding.getName( glyphNameIndex[i] );
+ if( name != null )
+ {
+ glyphNames[i] = name.getName();
+ }
+ }
+
+ }
+ else if( formatType == 3.0f )
+ {
+ //no postscript information is provided.
+ }
+ }
+ /**
+ * @return Returns the formatType.
+ */
+ public float getFormatType()
+ {
+ return formatType;
+ }
+ /**
+ * @param formatTypeValue The formatType to set.
+ */
+ public void setFormatType(float formatTypeValue)
+ {
+ this.formatType = formatTypeValue;
+ }
+ /**
+ * @return Returns the isFixedPitch.
+ */
+ public long getIsFixedPitch()
+ {
+ return isFixedPitch;
+ }
+ /**
+ * @param isFixedPitchValue The isFixedPitch to set.
+ */
+ public void setIsFixedPitch(long isFixedPitchValue)
+ {
+ this.isFixedPitch = isFixedPitchValue;
+ }
+ /**
+ * @return Returns the italicAngle.
+ */
+ public float getItalicAngle()
+ {
+ return italicAngle;
+ }
+ /**
+ * @param italicAngleValue The italicAngle to set.
+ */
+ public void setItalicAngle(float italicAngleValue)
+ {
+ this.italicAngle = italicAngleValue;
+ }
+ /**
+ * @return Returns the maxMemType1.
+ */
+ public long getMaxMemType1()
+ {
+ return maxMemType1;
+ }
+ /**
+ * @param maxMemType1Value The maxMemType1 to set.
+ */
+ public void setMaxMemType1(long maxMemType1Value)
+ {
+ this.maxMemType1 = maxMemType1Value;
+ }
+ /**
+ * @return Returns the maxMemType42.
+ */
+ public long getMaxMemType42()
+ {
+ return maxMemType42;
+ }
+ /**
+ * @param maxMemType42Value The maxMemType42 to set.
+ */
+ public void setMaxMemType42(long maxMemType42Value)
+ {
+ this.maxMemType42 = maxMemType42Value;
+ }
+ /**
+ * @return Returns the mimMemType1.
+ */
+ public long getMimMemType1()
+ {
+ return mimMemType1;
+ }
+ /**
+ * @param mimMemType1Value The mimMemType1 to set.
+ */
+ public void setMimMemType1(long mimMemType1Value)
+ {
+ this.mimMemType1 = mimMemType1Value;
+ }
+ /**
+ * @return Returns the minMemType42.
+ */
+ public long getMinMemType42()
+ {
+ return minMemType42;
+ }
+ /**
+ * @param minMemType42Value The minMemType42 to set.
+ */
+ public void setMinMemType42(long minMemType42Value)
+ {
+ this.minMemType42 = minMemType42Value;
+ }
+ /**
+ * @return Returns the underlinePosition.
+ */
+ public short getUnderlinePosition()
+ {
+ return underlinePosition;
+ }
+ /**
+ * @param underlinePositionValue The underlinePosition to set.
+ */
+ public void setUnderlinePosition(short underlinePositionValue)
+ {
+ this.underlinePosition = underlinePositionValue;
+ }
+ /**
+ * @return Returns the underlineThickness.
+ */
+ public short getUnderlineThickness()
+ {
+ return underlineThickness;
+ }
+ /**
+ * @param underlineThicknessValue The underlineThickness to set.
+ */
+ public void setUnderlineThickness(short underlineThicknessValue)
+ {
+ this.underlineThickness = underlineThicknessValue;
+ }
+ /**
+ * @return Returns the glyphNames.
+ */
+ public String[] getGlyphNames()
+ {
+ return glyphNames;
+ }
+ /**
+ * @param glyphNamesValue The glyphNames to set.
+ */
+ public void setGlyphNames(String[] glyphNamesValue)
+ {
+ this.glyphNames = glyphNamesValue;
+ }
+}
diff --git a/src/main/java/org/pdfbox/ttf/RAFDataStream.java b/src/main/java/org/pdfbox/ttf/RAFDataStream.java
new file mode 100644
index 0000000..14ebfd9
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/RAFDataStream.java
@@ -0,0 +1,193 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import org.pdfbox.cos.COSStream;
+import org.pdfbox.pdmodel.common.PDStream;
+
+/**
+ * An implementation of the TTFDataStream that goes against a RAF.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.4 $
+ */
+public class RAFDataStream extends TTFDataStream
+{
+ private RandomAccessFile raf = null;
+ /**
+ * Constructor.
+ *
+ * @param name The raf file.
+ * @param mode The mode to open the RAF.
+ *
+ * @throws FileNotFoundException If there is a problem creating the RAF.
+ *
+ * @see RandomAccessFile#RandomAccessFile( String, String )
+ */
+ public RAFDataStream(String name, String mode) throws FileNotFoundException
+ {
+ raf = new RandomAccessFile( name, mode );
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param file The raf file.
+ * @param mode The mode to open the RAF.
+ *
+ * @throws FileNotFoundException If there is a problem creating the RAF.
+ *
+ * @see RandomAccessFile#RandomAccessFile( File, String )
+ */
+ public RAFDataStream(File file, String mode) throws FileNotFoundException
+ {
+ raf = new RandomAccessFile( file, mode );
+ }
+
+ /**
+ * Read an signed short.
+ *
+ * @return An signed short.
+ * @throws IOException If there is an error reading the data.
+ */
+ public short readSignedShort() throws IOException
+ {
+ return raf.readShort();
+ }
+
+ /**
+ * Get the current position in the stream.
+ * @return The current position in the stream.
+ * @throws IOException If an error occurs while reading the stream.
+ */
+ public long getCurrentPosition() throws IOException
+ {
+ return raf.getFilePointer();
+ }
+
+ /**
+ * Get a COSStream from this TTFDataStream
+ * This permit to pass the data read from an
+ * external source to the COSObjects to keep
+ * a certain persistence layer between specialized
+ * objects like the TTF package and the pdmodel package.
+ *
+ * Created by Pascal Allain
+ * Vertical7 Inc.
+ *
+ * @return COSStream describing this stream (unfiletred)
+ */
+ public PDStream getPDStream()
+ {
+ COSStream retval = null;
+
+ retval = new COSStream(raf);
+
+ return new PDStream( retval );
+ }
+
+ /**
+ * Close the underlying resources.
+ *
+ * @throws IOException If there is an error closing the resources.
+ */
+ public void close() throws IOException
+ {
+ raf.close();
+ raf = null;
+ }
+
+ /**
+ * Read an unsigned byte.
+ * @return An unsigned byte.
+ * @throws IOException If there is an error reading the data.
+ */
+ public int read() throws IOException
+ {
+ return raf.read();
+ }
+
+ /**
+ * Read an unsigned short.
+ *
+ * @return An unsigned short.
+ * @throws IOException If there is an error reading the data.
+ */
+ public int readUnsignedShort() throws IOException
+ {
+ return raf.readUnsignedShort();
+ }
+
+ /**
+ * Read an unsigned byte.
+ * @return An unsigned byte.
+ * @throws IOException If there is an error reading the data.
+ */
+ public long readLong() throws IOException
+ {
+ return raf.readLong();
+ }
+
+ /**
+ * Seek into the datasource.
+ *
+ * @param pos The position to seek to.
+ * @throws IOException If there is an error seeking to that position.
+ */
+ public void seek(long pos) throws IOException
+ {
+ raf.seek( pos );
+ }
+
+ /**
+ * @see java.io.InputStream#read( byte[], int, int )
+ *
+ * @param b The buffer to write to.
+ * @param off The offset into the buffer.
+ * @param len The length into the buffer.
+ *
+ * @return The number of bytes read.
+ *
+ * @throws IOException If there is an error reading from the stream.
+ */
+ public int read(byte[] b,
+ int off,
+ int len)
+ throws IOException
+ {
+ return raf.read(b,off,len);
+ }
+}
diff --git a/src/main/java/org/pdfbox/ttf/TTFDataStream.java b/src/main/java/org/pdfbox/ttf/TTFDataStream.java
new file mode 100644
index 0000000..c4cf19d
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/TTFDataStream.java
@@ -0,0 +1,253 @@
+/**
+ * Copyright (c) 2004-2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.io.EOFException;
+import java.io.IOException;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+import org.pdfbox.pdmodel.common.PDStream;
+
+/**
+ * An interface into a data stream.
+ *
+ * @author Ben Litchfield (ben@benlitchfield.com)
+ * @version $Revision: 1.5 $
+ */
+public abstract class TTFDataStream
+{
+
+ /**
+ * Read a 16.16 fixed value, where the first 16 bits are the decimal and the last
+ * 16 bits are the fraction.
+ * @return A 32 bit value.
+ * @throws IOException If there is an error reading the data.
+ */
+ public float read32Fixed() throws IOException
+ {
+ float retval = 0;
+ retval = readSignedShort();
+ retval += (readUnsignedShort()/65536);
+ return retval;
+ }
+
+ /**
+ * Read a fixed length ascii string.
+ * @param length The length of the string to read.
+ * @return A string of the desired length.
+ * @throws IOException If there is an error reading the data.
+ */
+ public String readString( int length ) throws IOException
+ {
+ return readString( length, "ISO-8859-1" );
+ }
+
+ /**
+ * Read a fixed length ascii string.
+ * @param length The length of the string to read in bytes.
+ * @param charset The expected character set of the string.
+ * @return A string of the desired length.
+ * @throws IOException If there is an error reading the data.
+ */
+ public String readString( int length, String charset ) throws IOException
+ {
+ byte[] buffer = read( length );
+ return new String(buffer, charset);
+ }
+
+ /**
+ * Read an unsigned byte.
+ * @return An unsigned byte.
+ * @throws IOException If there is an error reading the data.
+ */
+ public abstract int read() throws IOException;
+
+ /**
+ * Read an unsigned byte.
+ * @return An unsigned byte.
+ * @throws IOException If there is an error reading the data.
+ */
+ public abstract long readLong() throws IOException;
+
+
+ /**
+ * Read a signed byte.
+ * @return A signed byte.
+ * @throws IOException If there is an error reading the data.
+ */
+ public int readSignedByte() throws IOException
+ {
+ int signedByte = read();
+ return signedByte < 127 ? signedByte : signedByte-256;
+ }
+
+ /**
+ * Read an unsigned integer.
+ * @return An unsiged integer.
+ * @throws IOException If there is an error reading the data.
+ */
+ public long readUnsignedInt() throws IOException
+ {
+ long byte1 = read();
+ long byte2 = read();
+ long byte3 = read();
+ long byte4 = read();
+ if( byte4 < 0 )
+ {
+ throw new EOFException();
+ }
+ return (byte1 << 24) + (byte2 << 16) + (byte3 << 8) + (byte4 << 0);
+ }
+
+ /**
+ * Read an unsigned short.
+ *
+ * @return An unsigned short.
+ * @throws IOException If there is an error reading the data.
+ */
+ public abstract int readUnsignedShort() throws IOException;
+
+ /**
+ * Read an unsigned short array.
+ *
+ * @param length The length of the array to read.
+ * @return An unsigned short array.
+ * @throws IOException If there is an error reading the data.
+ */
+ public int[] readUnsignedShortArray( int length ) throws IOException
+ {
+ int[] array = new int[ length ];
+ for( int i=0; i<length; i++ )
+ {
+ array[i] = readUnsignedShort();
+ }
+ return array;
+ }
+
+ /**
+ * Read an signed short.
+ *
+ * @return An signed short.
+ * @throws IOException If there is an error reading the data.
+ */
+ public abstract short readSignedShort() throws IOException;
+
+ /**
+ * Read an eight byte international date.
+ *
+ * @return An signed short.
+ * @throws IOException If there is an error reading the data.
+ */
+ public Calendar readInternationalDate() throws IOException
+ {
+ long secondsSince1904 = readLong();
+ GregorianCalendar cal = new GregorianCalendar( 1904, 0, 1 );
+ long millisFor1904 = cal.getTimeInMillis();
+ millisFor1904 += (secondsSince1904*1000);
+ cal.setTimeInMillis( millisFor1904 );
+ return cal;
+ }
+
+ /**
+ * Close the underlying resources.
+ *
+ * @throws IOException If there is an error closing the resources.
+ */
+ public abstract void close() throws IOException;
+
+ /**
+ * Seek into the datasource.
+ *
+ * @param pos The position to seek to.
+ * @throws IOException If there is an error seeking to that position.
+ */
+ public abstract void seek(long pos) throws IOException;
+
+ /**
+ * Read a specific number of bytes from the stream.
+ * @param numberOfBytes The number of bytes to read.
+ * @return The byte buffer.
+ * @throws IOException If there is an error while reading.
+ */
+ public byte[] read( int numberOfBytes ) throws IOException
+ {
+ byte[] data = new byte[ numberOfBytes ];
+ int amountRead = 0;
+ int totalAmountRead = 0;
+ while( (amountRead = read( data, totalAmountRead, numberOfBytes-totalAmountRead ) ) != -1 &&
+ totalAmountRead < numberOfBytes )
+ {
+ totalAmountRead += amountRead;
+ //read at most numberOfBytes bytes from the stream.
+ }
+ return data;
+ }
+
+ /**
+ * @see java.io.InputStream#read( byte[], int, int )
+ *
+ * @param b The buffer to write to.
+ * @param off The offset into the buffer.
+ * @param len The length into the buffer.
+ *
+ * @return The number of bytes read.
+ *
+ * @throws IOException If there is an error reading from the stream.
+ */
+ public abstract int read(byte[] b,
+ int off,
+ int len)
+ throws IOException;
+
+ /**
+ * Get the current position in the stream.
+ * @return The current position in the stream.
+ * @throws IOException If an error occurs while reading the stream.
+ */
+ public abstract long getCurrentPosition() throws IOException;
+
+ /**
+ * Get a COSStream from this TTFDataStream
+ * This permit to pass the data read from an
+ * external source to the COSObjects to keep
+ * a certain persistence layer between specialized
+ * objects like the TTF package and the pdmodel package.
+ *
+ * Created by Pascal Allain
+ * Vertical7 Inc.
+ *
+ * @return COSStream describing this stream
+ */
+ public abstract PDStream getPDStream();
+
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/ttf/TTFParser.java b/src/main/java/org/pdfbox/ttf/TTFParser.java
new file mode 100644
index 0000000..903badb
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/TTFParser.java
@@ -0,0 +1,219 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.io.File;
+import java.io.IOException;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * A true type font file parser.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.3 $
+ */
+public class TTFParser
+{
+ /**
+ * A simple command line program to test parsing of a TTF file. <br/>
+ * usage: java org.pdfbox.ttf.TTFParser &lt;ttf-file&gt;
+ *
+ * @param args The command line arguments.
+ *
+ * @throws IOException If there is an error while parsing the font file.
+ */
+ public static void main( String[] args ) throws IOException
+ {
+ if( args.length != 1 )
+ {
+ System.err.println( "usage: java org.pdfbox.ttf.TTFParser <ttf-file>" );
+ System.exit( -1 );
+ }
+ TTFParser parser = new TTFParser();
+ TrueTypeFont font = parser.parseTTF( args[0] );
+ System.out.println( "Font:" + font );
+ }
+
+ /**
+ * Parse a file and get a true type font.
+ * @param ttfFile The TTF file.
+ * @return A true type font.
+ * @throws IOException If there is an error parsing the true type font.
+ */
+ public TrueTypeFont parseTTF( String ttfFile ) throws IOException
+ {
+ RAFDataStream raf = new RAFDataStream( ttfFile, "r" );
+ return parseTTF( raf );
+ }
+
+ /**
+ * Parse a file and get a true type font.
+ * @param ttfFile The TTF file.
+ * @return A true type font.
+ * @throws IOException If there is an error parsing the true type font.
+ */
+ public TrueTypeFont parseTTF( File ttfFile ) throws IOException
+ {
+ RAFDataStream raf = new RAFDataStream( ttfFile, "r" );
+ return parseTTF( raf );
+ }
+
+ /**
+ * Parse a file and get a true type font.
+ * @param raf The TTF file.
+ * @return A true type font.
+ * @throws IOException If there is an error parsing the true type font.
+ */
+ public TrueTypeFont parseTTF( TTFDataStream raf ) throws IOException
+ {
+ TrueTypeFont font = new TrueTypeFont( raf );
+ font.setVersion( raf.read32Fixed() );
+ int numberOfTables = raf.readUnsignedShort();
+ int searchRange = raf.readUnsignedShort();
+ int entrySelector = raf.readUnsignedShort();
+ int rangeShift = raf.readUnsignedShort();
+ for( int i=0; i<numberOfTables; i++ )
+ {
+ TTFTable table = readTableDirectory( raf );
+ font.addTable( table );
+ }
+ List initialized = new ArrayList();
+ //need to initialize a couple tables in a certain order
+ HeaderTable head = font.getHeader();
+ raf.seek( head.getOffset() );
+ head.initData( font, raf );
+ initialized.add( head );
+
+
+ HorizontalHeaderTable hh = font.getHorizontalHeader();
+ raf.seek( hh.getOffset() );
+ hh.initData( font, raf );
+ initialized.add( hh );
+
+ MaximumProfileTable maxp = font.getMaximumProfile();
+ raf.seek( maxp.getOffset() );
+ maxp.initData( font, raf );
+ initialized.add( maxp );
+
+ PostScriptTable post = font.getPostScript();
+ raf.seek( post.getOffset() );
+ post.initData( font, raf );
+ initialized.add( post );
+
+ IndexToLocationTable loc = font.getIndexToLocation();
+ raf.seek( loc.getOffset() );
+ loc.initData( font, raf );
+ initialized.add( loc );
+
+ Iterator iter = font.getTables().iterator();
+ while( iter.hasNext() )
+ {
+ TTFTable table = (TTFTable)iter.next();
+ if( !initialized.contains( table ) )
+ {
+ raf.seek( table.getOffset() );
+ table.initData( font, raf );
+ }
+ }
+ return font;
+ }
+
+ private TTFTable readTableDirectory( TTFDataStream raf ) throws IOException
+ {
+ TTFTable retval = null;
+ String tag = raf.readString( 4 );
+ if( tag.equals( CMAPTable.TAG ) )
+ {
+ retval = new CMAPTable();
+ }
+ else if( tag.equals( GlyphTable.TAG ) )
+ {
+ retval = new GlyphTable();
+ }
+ else if( tag.equals( HeaderTable.TAG ) )
+ {
+ retval = new HeaderTable();
+ }
+ else if( tag.equals( HorizontalHeaderTable.TAG ) )
+ {
+ retval = new HorizontalHeaderTable();
+ }
+ else if( tag.equals( HorizontalMetricsTable.TAG ) )
+ {
+ retval = new HorizontalMetricsTable();
+ }
+ else if( tag.equals( IndexToLocationTable.TAG ) )
+ {
+ retval = new IndexToLocationTable();
+ }
+ else if( tag.equals( MaximumProfileTable.TAG ) )
+ {
+ retval = new MaximumProfileTable();
+ }
+ else if( tag.equals( NamingTable.TAG ) )
+ {
+ retval = new NamingTable();
+ }
+ else if( tag.equals( OS2WindowsMetricsTable.TAG ) )
+ {
+ retval = new OS2WindowsMetricsTable();
+ }
+ else if( tag.equals( PostScriptTable.TAG ) )
+ {
+ retval = new PostScriptTable();
+ }
+ else if( tag.equals( GlyphTable.TAG ) )
+ {
+ retval = new GlyphTable();
+ }
+ else if( tag.equals( GlyphTable.TAG ) )
+ {
+ retval = new GlyphTable();
+ }
+ else if( tag.equals( DigitalSignatureTable.TAG ) )
+ {
+ retval = new DigitalSignatureTable();
+ }
+ else
+ {
+ //unknown table type but read it anyway.
+ retval = new TTFTable();
+ }
+ retval.setTag( tag );
+ retval.setCheckSum( raf.readUnsignedInt() );
+ retval.setOffset( raf.readUnsignedInt() );
+ retval.setLength( raf.readUnsignedInt() );
+ return retval;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/org/pdfbox/ttf/TTFTable.java b/src/main/java/org/pdfbox/ttf/TTFTable.java
new file mode 100644
index 0000000..fdc03ea
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/TTFTable.java
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2004, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.io.IOException;
+
+/**
+ * A table in a true type font.
+ *
+ * @author Ben Litchfield (ben@csh.rit.edu)
+ * @version $Revision: 1.1 $
+ */
+public class TTFTable
+{
+ private String tag;
+ private long checkSum;
+ private long offset;
+ private long length;
+
+ /**
+ * @return Returns the checkSum.
+ */
+ public long getCheckSum()
+ {
+ return checkSum;
+ }
+ /**
+ * @param checkSumValue The checkSum to set.
+ */
+ public void setCheckSum(long checkSumValue)
+ {
+ this.checkSum = checkSumValue;
+ }
+ /**
+ * @return Returns the length.
+ */
+ public long getLength()
+ {
+ return length;
+ }
+ /**
+ * @param lengthValue The length to set.
+ */
+ public void setLength(long lengthValue)
+ {
+ this.length = lengthValue;
+ }
+ /**
+ * @return Returns the offset.
+ */
+ public long getOffset()
+ {
+ return offset;
+ }
+ /**
+ * @param offsetValue The offset to set.
+ */
+ public void setOffset(long offsetValue)
+ {
+ this.offset = offsetValue;
+ }
+ /**
+ * @return Returns the tag.
+ */
+ public String getTag()
+ {
+ return tag;
+ }
+ /**
+ * @param tagValue The tag to set.
+ */
+ public void setTag(String tagValue)
+ {
+ this.tag = tagValue;
+ }
+
+ /**
+ * This will read the required data from the stream.
+ *
+ * @param ttf The font that is being read.
+ * @param data The stream to read the data from.
+ * @throws IOException If there is an error reading the data.
+ */
+ public void initData( TrueTypeFont ttf, TTFDataStream data ) throws IOException
+ {
+ }
+}
diff --git a/src/main/java/org/pdfbox/ttf/TrueTypeFont.java b/src/main/java/org/pdfbox/ttf/TrueTypeFont.java
new file mode 100644
index 0000000..bbe6392
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/TrueTypeFont.java
@@ -0,0 +1,221 @@
+/**
+ * Copyright (c) 2004-2005, www.pdfbox.org
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of pdfbox; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://www.pdfbox.org
+ *
+ */
+package org.pdfbox.ttf;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import java.io.IOException;
+
+import org.pdfbox.pdmodel.common.PDStream;
+
+/**
+ * A class to hold true type font information.
+ *
+ * @author Ben Litchfield (ben@benlitchfield.com)
+ * @version $Revision: 1.4 $
+ */
+public class TrueTypeFont
+{
+ private float version;
+
+ private Map tables = new HashMap();
+
+ private TTFDataStream data;
+
+ /**
+ * Constructor. Clients should use the TTFParser to create a new TrueTypeFont object.
+ *
+ * @param fontData The font data.
+ */
+ TrueTypeFont( TTFDataStream fontData )
+ {
+ data = fontData;
+ }
+
+ /**
+ * Close the underlying resources.
+ *
+ * @throws IOException If there is an error closing the resources.
+ */
+ public void close() throws IOException
+ {
+ data.close();
+ }
+
+ /**
+ * @return Returns the version.
+ */
+ public float getVersion()
+ {
+ return version;
+ }
+ /**
+ * @param versionValue The version to set.
+ */
+ public void setVersion(float versionValue)
+ {
+ version = versionValue;
+ }
+
+ /**
+ * Add a table definition.
+ *
+ * @param table The table to add.
+ */
+ public void addTable( TTFTable table )
+ {
+ tables.put( table.getTag(), table );
+ }
+
+ /**
+ * Get all of the tables.
+ *
+ * @return All of the tables.
+ */
+ public Collection getTables()
+ {
+ return tables.values();
+ }
+
+ /**
+ * This will get the naming table for the true type font.
+ *
+ * @return The naming table.
+ */
+ public NamingTable getNaming()
+ {
+ return (NamingTable)tables.get( NamingTable.TAG );
+ }
+
+ /**
+ * Get the postscript table for this TTF.
+ *
+ * @return The postscript table.
+ */
+ public PostScriptTable getPostScript()
+ {
+ return (PostScriptTable)tables.get( PostScriptTable.TAG );
+ }
+
+ /**
+ * Get the OS/2 table for this TTF.
+ *
+ * @return The OS/2 table.
+ */
+ public OS2WindowsMetricsTable getOS2Windows()
+ {
+ return (OS2WindowsMetricsTable)tables.get( OS2WindowsMetricsTable.TAG );
+ }
+
+ /**
+ * Get the maxp table for this TTF.
+ *
+ * @return The maxp table.
+ */
+ public MaximumProfileTable getMaximumProfile()
+ {
+ return (MaximumProfileTable)tables.get( MaximumProfileTable.TAG );
+ }
+
+ /**
+ * Get the head table for this TTF.
+ *
+ * @return The head table.
+ */
+ public HeaderTable getHeader()
+ {
+ return (HeaderTable)tables.get( HeaderTable.TAG );
+ }
+
+ /**
+ * Get the hhea table for this TTF.
+ *
+ * @return The hhea table.
+ */
+ public HorizontalHeaderTable getHorizontalHeader()
+ {
+ return (HorizontalHeaderTable)tables.get( HorizontalHeaderTable.TAG );
+ }
+
+ /**
+ * Get the hmtx table for this TTF.
+ *
+ * @return The hmtx table.
+ */
+ public HorizontalMetricsTable getHorizontalMetrics()
+ {
+ return (HorizontalMetricsTable)tables.get( HorizontalMetricsTable.TAG );
+ }
+
+ /**
+ * Get the loca table for this TTF.
+ *
+ * @return The loca table.
+ */
+ public IndexToLocationTable getIndexToLocation()
+ {
+ return (IndexToLocationTable)tables.get( IndexToLocationTable.TAG );
+ }
+
+ /**
+ * Get the glyf table for this TTF.
+ *
+ * @return The glyf table.
+ */
+ public GlyphTable getGlyph()
+ {
+ return (GlyphTable)tables.get( GlyphTable.TAG );
+ }
+
+ /**
+ * Get the cmap table for this TTF.
+ *
+ * @return The cmap table.
+ */
+ public CMAPTable getCMAP()
+ {
+ return (CMAPTable)tables.get( CMAPTable.TAG );
+ }
+
+ /**
+ * This permit to get the COSStream of the True Type Font
+ * program representing the stream used to build this
+ * object (normally from the TTFParser object).
+ *
+ * @return COSStream True type font program stream
+ */
+ public PDStream getPDStream()
+ {
+ return data.getPDStream();
+ }
+}
diff --git a/src/main/java/org/pdfbox/ttf/package.html b/src/main/java/org/pdfbox/ttf/package.html
new file mode 100644
index 0000000..55d2af5
--- /dev/null
+++ b/src/main/java/org/pdfbox/ttf/package.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+
+</head>
+<body>
+This package contains classes to parse a TTF file.
+</body>
+</html>