Index: pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java	(revision 1305316)
+++ pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java	(revision )
@@ -16,42 +16,27 @@
  */
 package org.apache.pdfbox.util;
 
-import java.io.IOException;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.Stack;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.pdfbox.cos.COSBase;
 import org.apache.pdfbox.cos.COSObject;
 import org.apache.pdfbox.cos.COSStream;
 import org.apache.pdfbox.exceptions.WrappedIOException;
-
 import org.apache.pdfbox.pdfparser.PDFStreamParser;
 import org.apache.pdfbox.pdmodel.PDPage;
 import org.apache.pdfbox.pdmodel.PDResources;
-
 import org.apache.pdfbox.pdmodel.common.PDMatrix;
 import org.apache.pdfbox.pdmodel.font.PDFont;
 import org.apache.pdfbox.pdmodel.font.PDType3Font;
-
 import org.apache.pdfbox.pdmodel.graphics.PDExtendedGraphicsState;
 import org.apache.pdfbox.pdmodel.graphics.PDGraphicsState;
 import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace;
 import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObject;
-
 import org.apache.pdfbox.util.operator.OperatorProcessor;
 
+import java.io.IOException;
+import java.util.*;
+
 /**
  * This class will run through a PDF content stream and execute certain operations
  * and provide a callback interface for clients that want to do things with the stream.
@@ -398,8 +383,9 @@
                 //maybe a multibyte encoding
                 codeLength++;
                 c = font.encode( string, i, codeLength );
-                codePoints = new int[] {font.getCodeFromArray(string, i, codeLength)};
             }
+
+	        codePoints = new int[] {font.getCodeFromArray(string, i, codeLength)};
 
             // the space width has to be transformed into display units
             float spaceWidthDisp = spaceWidthText * fontSizeText * horizontalScalingText 
Index: pdfbox/src/main/java/org/jpedal/fonts/tt/CFF.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/jpedal/fonts/tt/CFF.java	(revision )
+++ pdfbox/src/main/java/org/jpedal/fonts/tt/CFF.java	(revision )
@@ -0,0 +1,76 @@
+/**
+* ===========================================
+* Java Pdf Extraction Decoding Access Library
+* ===========================================
+*
+* Project Info:  http://www.jpedal.org
+* (C) Copyright 1997-2008, IDRsolutions and Contributors.
+*
+* 	This file is part of JPedal
+*
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+*
+* ---------------
+* CFF.java
+* ---------------
+*/
+package org.jpedal.fonts.tt;
+
+public class CFF extends Table {
+
+//    PdfJavaGlyphs glyphs;
+
+    boolean hasCFFdata=false;
+
+    public CFF(FontFile2 currentFontFile,boolean isCID){
+
+//        glyphs=new T1Glyphs(isCID);
+//        if(isCID)
+//        glyphs.init(65536,true);
+        
+        //move to start and check exists
+		int startPointer=currentFontFile.selectTable(FontFile2.CFF);
+
+        //read 'cff' table
+		if(startPointer!=0){
+
+            try {
+                int length=currentFontFile.getTableSize(FontFile2.CFF);
+
+                byte[] data=currentFontFile.readBytes(startPointer, length) ;
+
+                //initialise glyphs
+//                new Type1C(data,null,glyphs);
+
+                hasCFFdata=true;
+            } catch (Exception e) {
+                e.printStackTrace(); 
+            }
+		}
+    }
+
+    public boolean hasCFFData() {
+        return hasCFFdata;
+    }
+
+
+//    public PdfGlyph getCFFGlyph(GlyphFactory factory,String glyph, float[][] Trm,int rawInt, String displayValue, float currentWidth,String key) {
+//
+//        return glyphs.getEmbeddedGlyph(factory, glyph, Trm, rawInt, displayValue, currentWidth, key);
+//
+//    }
+}
Index: pdfbox/src/main/java/org/jpedal/fonts/tt/Hhea.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/jpedal/fonts/tt/Hhea.java	(revision )
+++ pdfbox/src/main/java/org/jpedal/fonts/tt/Hhea.java	(revision )
@@ -0,0 +1,76 @@
+/**
+* ===========================================
+* Java Pdf Extraction Decoding Access Library
+* ===========================================
+*
+* Project Info:  http://www.jpedal.org
+* (C) Copyright 1997-2008, IDRsolutions and Contributors.
+*
+* 	This file is part of JPedal
+*
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+*
+* ---------------
+* Hhea.java
+* ---------------
+*/
+package org.jpedal.fonts.tt;
+
+
+
+public class Hhea extends Table {
+		
+	private int numberOfHMetrics;
+	
+	public Hhea(FontFile2 currentFontFile){
+	
+		//move to start and check exists
+		int startPointer=currentFontFile.selectTable(FontFile2.HHEA);
+		
+		//read 'head' table
+		if(startPointer!=0){
+			
+            currentFontFile.getNextUint32(); //version 65536
+            currentFontFile.getFWord();//ascender  1972
+            currentFontFile.getFWord();//descender -483
+            currentFontFile.getFWord();//lineGap 0
+            currentFontFile.readUFWord();//advanceWidthMax  2513
+            currentFontFile.getFWord();//minLeftSideBearing  -342
+            currentFontFile.getFWord();//minRightSideBearing  -340
+            currentFontFile.getFWord();//xMaxExtent      2454
+            currentFontFile.getNextInt16();//caretSlopeRise 1
+            currentFontFile.getNextInt16();//caretSlopeRun   0
+            currentFontFile.getFWord();//caretOffset          0
+
+            //reserved values
+            for( int i = 0; i < 4; i++ )
+                currentFontFile.getNextUint16(); //0
+
+            currentFontFile.getNextInt16();//metricDataFormat
+            numberOfHMetrics =currentFontFile.getNextUint16(); //261
+
+		}
+	}
+
+    public Hhea() {
+    }
+
+    public int getNumberOfHMetrics(){
+		return numberOfHMetrics;
+	}
+	
+}
Index: pdfbox/src/main/java/org/jpedal/fonts/tt/Post.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/jpedal/fonts/tt/Post.java	(revision )
+++ pdfbox/src/main/java/org/jpedal/fonts/tt/Post.java	(revision )
@@ -0,0 +1,213 @@
+/**
+* ===========================================
+* Java Pdf Extraction Decoding Access Library
+* ===========================================
+*
+* Project Info:  http://www.jpedal.org
+* (C) Copyright 1997-2008, IDRsolutions and Contributors.
+*
+* 	This file is part of JPedal
+*
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+*
+* ---------------
+* Post.java
+* ---------------
+*/
+package org.jpedal.fonts.tt;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+
+public class Post extends Table {
+	
+	/**map glyphs onto ID values in font*/
+    private Map translateToID=new HashMap();
+	
+	@SuppressWarnings({"FieldCanBeLocal"})
+    final private String[] macEncoding = { ".notdef", ".null",
+			"nonmarkingreturn", "space", "exclam", "quotedbl", "numbersign",
+			"dollar", "percent", "ampersand", "quotesingle", "parenleft",
+			"parenright", "asterisk", "plus", "comma", "hyphen", "period",
+			"slash", "zero", "one", "two", "three", "four", "five", "six",
+			"seven", "eight", "nine", "colon", "semicolon", "less", "equal",
+			"greater", "question", "at", "A", "B", "C", "D", "E", "F", "G",
+			"H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
+			"U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash",
+			"bracketright", "asciicircum", "underscore", "grave", "a", "b",
+			"c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
+			"p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft",
+			"bar", "braceright", "asciitilde", "Adieresis", "Aring",
+			"Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis", "aacute",
+			"agrave", "acircumflex", "adieresis", "atilde", "aring",
+			"ccedilla", "eacute", "egrave", "ecircumflex", "edieresis",
+			"iacute", "igrave", "icircumflex", "idieresis", "ntilde", "oacute",
+			"ograve", "ocircumflex", "odieresis", "otilde", "uacute", "ugrave",
+			"ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling",
+			"section", "bullet", "paragraph", "germandbls", "registered",
+			"copyright", "trademark", "acute", "dieresis", "notequal", "AE",
+			"Oslash", "infinity", "plusminus", "lessequal", "greaterequal",
+			"yen", "mu", "partialdiff", "summation", "product", "pi",
+			"integral", "ordfeminine", "ordmasculine", "Omega", "ae", "oslash",
+			"questiondown", "exclamdown", "logicalnot", "radical", "florin",
+			"approxequal", "Delta", "guillemotleft", "guillemotright",
+			"ellipsis", "nonbreakingspace", "Agrave", "Atilde", "Otilde", "OE",
+			"oe", "endash", "emdash", "quotedblleft", "quotedblright",
+			"quoteleft", "quoteright", "divide", "lozenge", "ydieresis",
+			"Ydieresis", "fraction", "currency", "guilsinglleft",
+			"guilsinglright", "fi", "fl", "daggerdbl", "periodcentered",
+			"quotesinglbase", "quotedblbase", "perthousand", "Acircumflex",
+			"Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute",
+			"Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex",
+			"apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi",
+			"circumflex", "tilde", "macron", "breve", "dotaccent", "ring",
+			"cedilla", "hungarumlaut", "ogonek", "caron", "Lslash", "lslash",
+			"Scaron", "scaron", "Zcaron", "zcaron", "brokenbar", "Eth", "eth",
+			"Yacute", "yacute", "Thorn", "thorn", "minus", "multiply",
+			"onesuperior", "twosuperior", "threesuperior", "onehalf",
+			"onequarter", "threequarters", "franc", "Gbreve", "gbreve",
+			"Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute", "Ccaron",
+			"ccaron", "dcroat" }; 
+	
+	public Post(FontFile2 currentFontFile){
+	
+		//move to start and check exists
+		int startPointer=currentFontFile.selectTable(FontFile2.POST);
+		//System.out.println(startPointer);
+		//read 'head' table
+		if(startPointer==0){
+//			if(LogWriter.isOutput())
+//				LogWriter.writeLog("No Post table found");
+		}else{
+			
+			//read format (actually 1,2,2.5 but multiplied so switch works
+			int id=(int)(10*currentFontFile.getFixed());
+			
+			//System.out.println("id="+id);
+			
+			//for(int i=0;i<)
+			//read rest of table which we ignore
+			currentFontFile.getFixed();// 	italicAngle  	Italic angle in degrees
+			currentFontFile.getFWord();//FWord 	underlinePosition 	Underline position
+			currentFontFile.getFWord();//FWord 	underlineThickness 	Underline thickness
+			currentFontFile.getNextUint16();//uint16 	isFixedPitch 	Font is monospaced; set to 1 if the font is monospaced and 0 otherwise
+			currentFontFile.getNextUint16();//uint16 	reserved 	Reserved, set to 0
+			currentFontFile.getNextUint32();//uint32 	minMemType42 	Minimum memory usage when a TrueType font is downloaded as a Type 42 font
+			currentFontFile.getNextUint32();//uint32 	maxMemType42 	Maximum memory usage when a TrueType font is downloaded as a Type 42 font
+			currentFontFile.getNextUint32();//uint32 	minMemType1 	Minimum memory usage when a TrueType font is downloaded as a Type 1 font
+			currentFontFile.getNextUint32();//uint32 	maxMemType1 	Maximum memory usage when a TrueType font is downloaded as a Type 1 font
+			
+			/**
+			 * create lookup table for mac format
+			 */
+			int numberOfGlyphs;
+
+            //standard mac os table
+			if(id!=30){
+				for(int i=0;i<258;i++)
+					this.translateToID.put(this.macEncoding[i],new Integer(i));
+			}
+			
+			switch(id){
+			
+				case 20:
+					numberOfGlyphs=currentFontFile.getNextUint16();
+					
+					int[] glyphNameIndex=new int[numberOfGlyphs];
+					int numberOfNewGlyphs=0;
+					
+					/**read glyphs and work out how many strings*/
+					for(int i=0;i<numberOfGlyphs;i++){
+						glyphNameIndex[i]=currentFontFile.getNextUint16();
+						if(glyphNameIndex[i]>257 && glyphNameIndex[i]<32768)
+							numberOfNewGlyphs++;
+					}
+					
+					/**now read the strings*/
+					String[] names=new String[numberOfNewGlyphs];
+					for(int i=0;i<numberOfNewGlyphs;i++){
+						names[i]=currentFontFile.getString();
+                        //System.out.println("names["+i+"]="+names[i]);
+                    }
+					/**now add in non-standard strings*/
+					for(int i=0;i<numberOfGlyphs;i++){
+                       // System.out.println("i="+i+"/"+numberOfGlyphs);
+                        if(glyphNameIndex[i]>257 && glyphNameIndex[i]<32768){
+							this.translateToID.put(names[glyphNameIndex[i]-258],new Integer(i));
+                            //System.out.println(i+"="+names[glyphNameIndex[i]-258]);
+                        }
+                    }
+						
+					break;
+					
+				case 25:
+					
+					numberOfGlyphs=currentFontFile.getNextUint16();
+					
+					int[] glyphOffset=new int[numberOfGlyphs];
+					
+					/**read glyphs and work out how many strings*/
+					for(int i=0;i<numberOfGlyphs;i++){
+						glyphOffset[i]=currentFontFile.getNextint8();
+						translateToID.put(macEncoding[glyphOffset[i]+i],new Integer(glyphOffset[i]));
+					}
+					
+					break;
+			}
+		}
+	}
+
+    public Post(){
+
+    }
+
+	/**
+	 * lookup glyph in post table (return -1 if no match
+	 */
+	public int convertGlyphToCharacterCode(String glyph) {
+
+		Integer newID=(Integer) translateToID.get(glyph);
+		
+		if(newID==null)
+			return 0;
+		else
+			return newID.intValue();
+	}
+
+    private static Integer getKey(byte[] raw) {
+
+        int keyStart=0;
+        int keyLength=raw.length;
+
+		//convert token to unique key
+        int id=0,x=0,next;
+
+        for(int i2=keyLength-1;i2>-1;i2--){
+            next=raw[keyStart+i2];
+
+            next=next-48;
+
+            id=id+((next)<<x);
+
+            x=x+8;
+        }
+
+        return new Integer(id);
+	}
+}
Index: pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDSimpleFont.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDSimpleFont.java	(revision 1305316)
+++ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDSimpleFont.java	(revision )
@@ -16,37 +16,26 @@
  */
 package org.apache.pdfbox.pdmodel.font;
 
-import java.awt.Font;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.RenderingHints;
-import java.awt.font.FontRenderContext;
-import java.awt.font.GlyphVector;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
-import java.awt.geom.NoninvertibleTransformException;
-import java.io.IOException;
-
-import java.util.HashMap;
-
-import org.apache.fontbox.afm.FontMetric;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-
-import org.apache.pdfbox.cos.COSArray;
-import org.apache.pdfbox.cos.COSBase;
-import org.apache.pdfbox.cos.COSDictionary;
-import org.apache.pdfbox.cos.COSName;
-import org.apache.pdfbox.cos.COSNumber;
-import org.apache.pdfbox.cos.COSStream;
+import org.apache.fontbox.afm.FontMetric;
+import org.apache.pdfbox.cos.*;
 import org.apache.pdfbox.encoding.DictionaryEncoding;
 import org.apache.pdfbox.encoding.Encoding;
 import org.apache.pdfbox.encoding.EncodingManager;
-
 import org.apache.pdfbox.pdmodel.common.PDRectangle;
 import org.apache.pdfbox.util.ResourceLoader;
+import org.jpedal.fonts.tt.CMAP;
 
+import java.awt.*;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.HashMap;
+
 /**
  * This class contains implementation details of the simple pdf fonts.
  *
@@ -95,7 +84,12 @@
         LOG.error("Not yet implemented:" + getClass().getName() );
         return null;
     }
-    
+
+	public CMAP getFontCmap()
+	{
+		return null;
+	}
+    
     /**
      * {@inheritDoc}
      */
@@ -104,25 +98,46 @@
     {
         Font awtFont = getawtFont();
         FontRenderContext frc = new FontRenderContext(new AffineTransform(), true, true);
-        GlyphVector glyphs = null;
-        boolean useCodepoints = codePoints != null && isType0Font();
-        PDFont descendantFont = useCodepoints ? ((PDType0Font)this).getDescendantFont() : null;
-        // symbolic fonts may trigger the same fontmanager.so/dll error as described below
-        if (useCodepoints && !descendantFont.getFontDescriptor().isSymbolic())
+
+        GlyphVector glyphs;
+        boolean useCodepoints = codePoints != null;
+
+	    if (useCodepoints && isType0Font())
-        {
+	    {
+		    PDFont descendantFont = ((PDType0Font)this).getDescendantFont();
-            PDCIDFontType2Font cid2Font = null;
-            if (descendantFont instanceof PDCIDFontType2Font)
-            {
-                cid2Font = (PDCIDFontType2Font)descendantFont;
-            }
+		    PDCIDFontType2Font cid2Font = null;
+		    if (descendantFont instanceof PDCIDFontType2Font)
+		    {
+			    cid2Font = (PDCIDFontType2Font)descendantFont;
+		    }
+
-            if((cid2Font != null && cid2Font.hasCIDToGIDMap()) || isFontSubstituted)
-            {
-                // we still have to use the string if a CIDToGIDMap is used 
+		    if((cid2Font != null && cid2Font.hasCIDToGIDMap()) || isFontSubstituted)
+		    {
+			    // we still have to use the string if a CIDToGIDMap is used
-                glyphs = awtFont.createGlyphVector(frc, string);
+			    useCodepoints = false;
-            }
+		    }
-            else
+
+		    if (descendantFont.getFontDescriptor().isSymbolic())
-            {
+		    {
+			    // symbolic fonts may trigger the same fontmanager.so/dll error as described below
+			    useCodepoints = false;
+		    }
+	    }
+
+        if (useCodepoints)
+        {
+            CMAP fontCmap = getFontCmap();
+            if (fontCmap == null)
+            {
-                glyphs = awtFont.createGlyphVector(frc, codePoints);
+	            glyphs = awtFont.createGlyphVector(frc, codePoints);
+            }
+            else
+            {
+	            int[] glyphCodes = new int[codePoints.length];
+	            for (int i = 0; i < codePoints.length; i++)
+		            glyphCodes[i] = fontCmap.convertIndexToCharacterCode(null, codePoints[i], false, false, null);
+
+	            glyphs = awtFont.createGlyphVector(frc, glyphCodes);
             }
         }
         else 
Index: pdfbox/src/main/java/org/jpedal/fonts/tt/FontFile2.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/jpedal/fonts/tt/FontFile2.java	(revision )
+++ pdfbox/src/main/java/org/jpedal/fonts/tt/FontFile2.java	(revision )
@@ -0,0 +1,794 @@
+/**
+* ===========================================
+* Java Pdf Extraction Decoding Access Library
+* ===========================================
+*
+* Project Info:  http://www.jpedal.org
+* (C) Copyright 1997-2008, IDRsolutions and Contributors.
+*
+* 	This file is part of JPedal
+*
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+*
+* ---------------
+* FontFile2.java
+* ---------------
+*/
+package org.jpedal.fonts.tt;
+
+import org.jpedal.fonts.objects.FontData;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+
+/**
+ * @author markee
+ *
+ * To change the template for this generated type comment go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+public class FontFile2 implements Serializable{
+	
+	private static final long serialVersionUID = -3097990864237320960L;
+	
+	public final static int HEAD=0;
+	public final static int MAXP =1;
+	public final static int CMAP=2;
+	public final static int LOCA=3;
+	public final static int GLYF=4;
+	public final static int HHEA=5;
+	public final static int HMTX=6;
+	public final static int NAME=7;
+	public final static int POST=8;
+	public final static int CVT=9;
+	public final static int FPGM=10;
+	public final static int HDMX=11;
+	public final static int KERN=12;
+	public final static int OS2=13;
+	public final static int PREP=14;
+	public final static int DSIG=15;
+
+    public final static int CFF=16;
+    public final static int GSUB=17;
+    public final static int BASE=18;
+    public final static int EBDT=19;
+    public final static int EBLC=20;
+    public final static int GASP=21;
+    public final static int VHEA=22;
+    public final static int VMTX=23;
+    public final static int GDEF=24;
+    public final static int JSTF=25;
+    public final static int LTSH=26;
+    public final static int PCLT=27;
+    public final static int VDMX=28;
+    public final static int BSLN=29;
+    public final static int MORT=30;
+    public final static int FDSC=31;
+    public final static int FFTM=32;
+    public final static int GPOS=33;
+    public final static int FEAT=34;
+    public final static int JUST=35;
+    public final static int PROP=36;
+
+    protected int tableCount=37;
+
+    //location of tables
+    protected int checksums[][];
+	protected int tables[][];
+	protected int tableLength[][];
+	
+	/**holds embedded font*/
+	private FontData fontDataAsObject=null;
+	
+	private byte[] fontDataAsArray=null;
+	
+	private boolean useArray=true;
+
+    protected ArrayList tableList=new ArrayList(32);
+	
+	/**current location in fontDataArray*/
+	private int pointer=0;
+
+    public static final int OPENTYPE = 1;
+    public static final int TRUETYPE = 2;
+    public static final int TTC = 3;
+
+    protected int type=TRUETYPE;
+
+    //if several fonts, selects which font
+    public int currentFontID=0;
+    private int fontCount=1;
+
+    //defaults are for OTF write
+    protected int numTables=11,searchRange=128,entrySelector=3,rangeShift=48;
+
+    public FontFile2(FontData data){
+		
+    	useArray=false;
+    	
+		this.fontDataAsObject=data;
+
+        readHeader();
+	}
+    
+    public FontFile2(byte[] data){
+		
+    	useArray=true;
+    	
+		this.fontDataAsArray=data;
+
+        readHeader();
+	}
+    
+    public FontFile2(byte[] data,boolean ignoreHeaders){
+		
+    	useArray=true;
+    	
+		this.fontDataAsArray=data;
+
+		if(!ignoreHeaders)
+        readHeader();
+	}
+
+    public FontFile2() {
+    }
+
+
+    /**
+     * set selected font as a number in TTC
+     * ie if 4 fonts, use 0,1,2,3
+     * if less than fontCount. Otherwise does
+     * nothing 
+     */
+    public void setSelectedFontIndex(int currentFontID) {
+
+        if(currentFontID<fontCount)
+        this.currentFontID = currentFontID;
+    }
+
+    /**read the table offsets*/
+	final private void readHeader(){
+
+		/**code to read the data at start of file*/
+		//scalertype
+		int scalerType=getNextUint32();
+
+        if(scalerType==1330926671)//starts OTTF
+            type=OPENTYPE;
+        else if(scalerType==1953784678)//ttc
+            type= TTC;
+
+        if(type==TTC){
+
+            getNextUint32(); //version
+            fontCount=getNextUint32();
+
+            //location of tables
+            checksums=new int[tableCount][fontCount];
+            tables=new int[tableCount][fontCount];
+            tableLength =new int[tableCount][fontCount];
+
+            int[] fontOffsets=new int[fontCount];
+
+            for(int currentFont=0;currentFont<fontCount;currentFont++){
+
+                currentFontID=currentFont;
+
+                int fontStart=getNextUint32();
+                fontOffsets[currentFont]=fontStart;
+            }
+
+            for(int currentFont=0;currentFont<fontCount;currentFont++){
+
+                currentFontID=currentFont; //choose this font
+
+                this.pointer = fontOffsets[currentFont];
+
+                scalerType=getNextUint32();
+
+                readTablesForFont();
+            }
+
+            //back to default
+            currentFontID=0;
+
+
+        }else{  //otf or ttf
+
+            //location of tables
+            checksums=new int[tableCount][1];
+            tables=new int[tableCount][1];
+            tableLength =new int[tableCount][1];
+
+            readTablesForFont();
+        }
+    }
+
+    private void readTablesForFont() {
+        
+        numTables=getNextUint16();   //tables in the file
+        searchRange=getNextUint16(); //searchRange
+        entrySelector=getNextUint16(); //entrySelector
+        rangeShift=getNextUint16(); //rangeShift
+
+        String tag;
+        int checksum,offset,length,id;
+
+        for(int l=0;l<numTables;l++){
+            //read table
+            tag=getNextUint32AsTag();
+            checksum=getNextUint32(); //checksum
+            offset=getNextUint32();
+            length=getNextUint32();
+
+            tableList.add(tag);
+
+			id = getTableID(tag);
+
+            if(id!=-1){
+                checksums[id][currentFontID]=checksum;
+                tables[id][currentFontID]=offset;
+                tableLength[id][currentFontID]=length;
+            }
+        }
+    }
+
+    protected int getTableID(String tag) {
+
+        int id=-1;
+
+        if(tag.equals("maxp"))
+            id= MAXP;
+        else if(tag.equals("head"))
+            id=HEAD;
+        else if(tag.equals("cmap"))
+            id=CMAP;
+        else if(tag.equals("loca")){
+            id=LOCA;
+        }else if(tag.equals("glyf")){
+            id=GLYF;
+        }else if(tag.equals("hhea")){
+            id=HHEA;
+        }else if(tag.equals("hmtx")){
+            id=HMTX;
+        }else if(tag.equals("name")){
+            id=NAME;
+        }else if(tag.equals("post")){
+            id=POST;
+        }else if(tag.equals("cvt ")){
+            id=CVT;
+        }else if(tag.equals("fpgm")){
+            id=FPGM;
+        }else if(tag.equals("hdmx")){
+            id=HDMX;
+        }else if(tag.equals("kern")){
+            id=KERN;
+        }else if(tag.equals("OS/2")){
+            id=OS2;
+        }else if(tag.equals("prep")){
+            id=PREP;
+        }else if(tag.equals("DSIG")){
+            id=DSIG;
+        }else if(tag.equals("BASE")){
+            id=BASE;
+        }else if(tag.equals("CFF ")){
+            id=CFF;
+        }else if(tag.equals("GSUB")){
+            id=GSUB;
+        }else if(tag.equals("EBDT")){
+            id=EBDT;
+        }else if(tag.equals("EBLC")){
+            id=EBLC;
+        }else if(tag.equals("gasp")){
+            id=GASP;
+        }else if(tag.equals("vhea")){
+            id=VHEA;
+        }else if(tag.equals("vmtx")){
+            id=VMTX;
+        }else if(tag.equals("GDEF")){
+            id=GDEF;
+        }else if(tag.equals("JSTF")){
+            id=JSTF;
+        }else if(tag.equals("LTSH")){
+            id=LTSH;
+        }else if(tag.equals("PCLT")){
+            id=PCLT;
+        }else if(tag.equals("VDMX")){
+            id=VDMX;
+        }else if(tag.equals("mort")){
+            id=MORT;
+        }else if(tag.equals("bsln")){
+            id=BSLN;
+        }else if(tag.equals("fdsc")){
+            id=FDSC;
+        }else if(tag.equals("FFTM")){
+            id=FFTM;
+        }else if(tag.equals("GPOS")){
+            id=GPOS;
+        }else if(tag.equals("feat")){
+            id=FEAT;
+        }else if(tag.equals("just")){
+            id=JUST;
+        }else if(tag.equals("prop")){
+            id=PROP;
+        }else{
+           // System.out.println("No tag for "+tag);
+        }
+        return id;
+    }
+
+    /**choose a table and move to start.
+	 * Return 0 if not present*/
+	public int selectTable(int tableID){
+		pointer=tables[tableID][currentFontID];
+		
+		return pointer;
+	}
+	
+	/**get table size*/
+	public int getTableSize(int tableID){
+		
+		return tableLength[tableID][currentFontID];
+	}
+        
+        /**get table size*/
+	public int getTableStart(int tableID){
+		
+		return tables[tableID][currentFontID];
+	}
+	
+	/**return a uint32*/
+	final public int getNextUint32(){
+		
+		int returnValue=0,nextValue=0;
+
+        for(int i=0;i<4;i++){
+
+            if(useArray){
+                if(pointer<fontDataAsArray.length)
+                    nextValue=fontDataAsArray[pointer] & 255;
+                else
+                    nextValue=0;
+            }else
+				nextValue= fontDataAsObject.getByte(pointer) & 255;
+
+            returnValue=returnValue+((nextValue<<(8*(3-i))));
+            
+            pointer++;
+		}
+
+		return returnValue;
+	}
+	
+	/**return a uint64*/
+	@SuppressWarnings({"UnusedReturnValue"})
+    final public int getNextUint64(){
+		
+		int returnValue=0,nextValue=0;
+		
+		for(int i=0;i<8;i++){
+			
+			if(useArray)
+				nextValue=fontDataAsArray[pointer];
+			else
+				nextValue= fontDataAsObject.getByte(pointer);
+
+			if(nextValue<0)
+				nextValue=256+nextValue;
+			
+			returnValue=returnValue+(nextValue<<(8*(7-i)));
+			
+			pointer++;
+		}
+		
+		return returnValue;
+	}
+	
+	/**set pointer to location in font file*/
+	final public void setPointer(int p){
+		pointer=p;
+	}
+	
+	/**get length of table*/
+	final public int getOffset(int tableID){
+		return tableLength[tableID][currentFontID];
+	}
+	
+	/**get start of table*/
+	final public int getTable(int tableID){
+		return tables[tableID][currentFontID];
+	}
+	
+	/**get pointer to location in font file*/
+	final public int getPointer(){
+		return pointer;
+	}
+	
+	/**return a uint32*/
+	final public String getNextUint32AsTag(){
+		
+		StringBuffer returnValue=new StringBuffer();
+		
+		char c;
+		
+		for(int i=0;i<4;i++){
+			
+			if(useArray)
+				c=(char) fontDataAsArray[pointer];
+			else
+				c=(char) fontDataAsObject.getByte(pointer);
+
+			returnValue.append(c);
+			
+			pointer++;
+		}
+		
+		return returnValue.toString();
+	}
+	
+	/**return a uint16*/
+	final public int getNextUint16(){
+		
+		int returnValue=0,nextValue;
+		
+		for(int i=0;i<2;i++){
+			
+			if(useArray)
+                nextValue=fontDataAsArray[pointer] & 255;
+			else
+				nextValue= fontDataAsObject.getByte(pointer) & 255;
+
+			returnValue=returnValue+(nextValue<<(8*(1-i)));
+			
+			pointer++;
+		}
+		
+		return returnValue;
+	}
+
+	/**return a short*/
+	final public short getShort(){
+		
+		int returnValue=0,nextValue;
+		
+		for(int i=0;i<2;i++){
+			
+			if(useArray)
+				nextValue=fontDataAsArray[pointer];
+			else
+				nextValue= fontDataAsObject.getByte(pointer);
+
+			returnValue=returnValue+(nextValue<<(8*(1-i)));
+			
+			pointer++;
+		}
+		
+		return (short) returnValue;
+	}
+	/**return a uint8*/
+	final public int getNextUint8(){
+		
+		int nextValue;
+		
+		if(useArray)
+			nextValue=fontDataAsArray[pointer] & 255;
+		else
+			nextValue= fontDataAsObject.getByte(pointer) & 255;
+
+		
+		//if(returnValue<0)
+		//	returnValue=256+returnValue;
+		
+		pointer++;
+		
+		return nextValue;
+	}
+
+	/**return a uint8*/
+	final public int getNextint8(){
+		
+		int nextValue;
+		
+		if(useArray)
+			nextValue=fontDataAsArray[pointer];
+		else
+			nextValue= fontDataAsObject.getByte(pointer);
+
+		
+		//if(returnValue<0)
+		//	returnValue=256+returnValue;
+		
+		pointer++;
+		
+		return nextValue;
+	}
+
+	/**
+	 * move forward a certain amount relative
+	 */
+	public void skip(int i) {
+		pointer=pointer+i;
+		
+	}
+
+	/**
+	 * return a short
+	 */
+	public short getFWord() {
+		int returnValue=0,nextValue;
+		
+		for(int i=0;i<2;i++){
+
+			if(useArray)
+				nextValue=fontDataAsArray[pointer] & 255;
+			else
+				nextValue= fontDataAsObject.getByte(pointer) & 255;
+
+			returnValue=returnValue+(nextValue<<(8*(1-i)));
+			
+			pointer++;
+		}
+		
+		return (short) returnValue;
+	}
+	
+	/**
+	 */
+	public short getNextInt16() {
+		int returnValue=0,nextValue;
+		
+		for(int i=0;i<2;i++){
+			
+			if(useArray)
+				nextValue=fontDataAsArray[pointer] & 255;
+			else
+				nextValue= fontDataAsObject.getByte(pointer) & 255;
+
+			returnValue=returnValue+(nextValue<<(8*(1-i)));
+			
+			pointer++;
+		}
+		
+		return (short) returnValue;
+	}
+	
+	
+	/**
+	 */
+	public short getNextSignedInt16() {
+		int returnValue=0,nextValue;
+		
+		for(int i=0;i<2;i++){
+			
+			if(useArray)
+				nextValue=fontDataAsArray[pointer] & 255;
+			else
+				nextValue= fontDataAsObject.getByte(pointer) & 255;
+
+			returnValue=returnValue+(nextValue<<(8*(1-i)));
+			pointer++;
+		}
+		
+		return (short) (returnValue);
+	}
+
+	/**
+	 */
+	@SuppressWarnings({"UnusedReturnValue"})
+    public short readUFWord() {
+		int returnValue=0,nextValue;
+		
+		for(int i=0;i<2;i++){
+			
+			if(useArray)
+				nextValue=fontDataAsArray[pointer] & 255;
+			else
+				nextValue= fontDataAsObject.getByte(pointer) & 255;
+
+			returnValue=returnValue+(nextValue<<(8*(1-i)));
+			
+			pointer++;
+		}
+		
+		return (short) returnValue;
+	}
+
+	/**
+	 * get 16 bit signed fixed point
+	 */
+	public float getFixed() {
+		
+		int number,dec;
+		
+		if(useArray)
+			number=((fontDataAsArray[pointer] & 0xff)*256)+(fontDataAsArray[pointer+1] & 0xff);
+		else
+			number=((fontDataAsObject.getByte(pointer) & 0xff)*256)+(fontDataAsObject.getByte(pointer+1)&0xff);
+
+		
+		if(number>32768)
+			number=number-65536;
+		
+		pointer=pointer+2;
+		
+		if(useArray)
+			dec=((fontDataAsArray[pointer] & 0xff)*256)+(fontDataAsArray[pointer+1] &0xff);
+		else
+			dec=((fontDataAsObject.getByte(pointer) & 0xff)*256)+(fontDataAsObject.getByte(pointer+1)&0xff);
+
+		
+		pointer=pointer+2;
+		
+		return (number+(dec/65536f));
+	}
+
+	/**
+	 * get a pascal string
+	 */
+	public String getString() {
+		int length=0;
+
+        //catch bug in odd file
+        if(useArray && pointer==fontDataAsArray.length)
+        return "";
+        
+        if(useArray)
+			length=fontDataAsArray[pointer] & 255;
+        else
+			length= fontDataAsObject.getByte(pointer) & 255;
+
+        char[] chars=new char[length];
+        //StringBuffer value=new StringBuffer();
+        //value.setLength(length);
+
+		
+		pointer++;
+
+        for(int i=0;i<length;i++){
+			int nextChar;
+			
+			if(useArray)
+				nextChar=fontDataAsArray[pointer] & 255;
+			else
+				nextChar= fontDataAsObject.getByte(pointer) & 255;
+
+			pointer++;
+			
+			//value.append((char)nextChar);
+            //value.setCharAt(i,(char)nextChar);
+            chars[i]=(char)nextChar;
+            //allow for error
+            if(useArray && pointer>=fontDataAsArray.length)
+            i=length;
+
+        }
+        return String.copyValueOf(chars);
+		//return value.toString();
+	}
+
+    /**
+	 * get a pascal string
+	 */
+	public byte[] getStringBytes() {
+		int length=0;
+
+        //catch bug in odd file
+        if(useArray && pointer==fontDataAsArray.length)
+        return new byte[1];
+
+        if(useArray)
+			length=fontDataAsArray[pointer] & 255;
+        else
+			length= fontDataAsObject.getByte(pointer) & 255;
+
+        byte[] value=new byte[length];
+
+		pointer++;
+
+        for(int i=0;i<length;i++){
+			byte nextChar;
+
+			if(useArray)
+				nextChar=fontDataAsArray[pointer];
+			else
+				nextChar= fontDataAsObject.getByte(pointer);
+
+			pointer++;
+
+			//value.append((char)nextChar);
+            value[i]=nextChar;
+
+            //allow for error
+            if(useArray && pointer>=fontDataAsArray.length)
+            i=length;
+
+        }
+		return value;
+	}
+
+	public float getF2Dot14() {
+		
+		int firstValue;
+		
+		if(useArray)
+			firstValue=((fontDataAsArray[pointer] & 0xff)<<8)+(fontDataAsArray[pointer+1] & 0xff);
+		else
+			firstValue=((fontDataAsObject.getByte(pointer) & 0xff)<<8)+(fontDataAsObject.getByte(pointer+1) & 0xff);
+					
+		pointer=pointer+2;
+		
+		if(firstValue==49152){
+			return -1.0f;
+		}else if(firstValue==16384){
+			return 1.0f;
+		}else{
+            return (firstValue - (2 * (firstValue & 32768))) / 16384f;
+		}
+	}
+
+    public byte[] readBytes(int startPointer, int length) {
+
+    	if(useArray){
+    		byte[] block=new byte[length];
+            System.arraycopy(fontDataAsArray,startPointer,block,0,length);
+            return block;
+    	}else
+			return fontDataAsObject.getBytes(startPointer,length);
+
+    }
+
+    public byte[] getTableBytes(int tableID){
+
+        int startPointer=tables[tableID][currentFontID];
+        int length= tableLength[tableID][currentFontID];
+
+        if(useArray){
+    		byte[] block=new byte[length];
+            System.arraycopy(fontDataAsArray,startPointer,block,0,length);
+            return block;
+    	}else
+			return fontDataAsObject.getBytes(startPointer,length);
+
+    }
+    /**
+     * return  fonttype
+    */
+    public int getType(){
+        return type;
+    }
+
+    //number of fonts - 1 for Open/True, can be more for TTC
+    public int getFontCount() {
+        return fontCount;
+    }
+
+    /**
+     * used to test if table too short so need to stop reading
+     * @return
+     */
+    public boolean hasValuesLeft() {
+
+        int size=0;
+        if(useArray)
+            size=fontDataAsArray.length;
+        else
+            size=fontDataAsObject.length();
+
+        return pointer<size;
+
+    }
+}
Index: pdfbox/src/main/java/org/jpedal/fonts/objects/FontData.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/jpedal/fonts/objects/FontData.java	(revision )
+++ pdfbox/src/main/java/org/jpedal/fonts/objects/FontData.java	(revision )
@@ -0,0 +1,200 @@
+/**
+ * ===========================================
+ * Java Pdf Extraction Decoding Access Library
+ * ===========================================
+ *
+ * Project Info:  http://www.jpedal.org
+ * Project Lead:  Mark Stephens (mark@idrsolutions.com)
+ *
+ * (C) Copyright 2006, IDRsolutions and Contributors.
+ *
+ * 	This file is part of JPedal
+ *
+     This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+  *
+  * ---------------
+
+  * FontData.java
+  * ---------------
+  * (C) Copyright 2006, by IDRsolutions and Contributors.
+  *
+  *
+  * --------------------------
+ */
+package org.jpedal.fonts.objects;
+
+import java.io.*;
+
+/**
+ * provides access to font data and caches large objects
+ */
+public class FontData {
+
+    private byte[] fontData;
+
+    /**flag to show if all fontData in memory or just some*/
+    private boolean isInMemory=false;
+
+    /**real size of font object*/
+    private int fullLength=0;
+
+    /**offset to actual block loaded*/
+    private int offset=0;
+
+    /**bytes size of font we keep in memory*/
+    public static int maxSizeAllowedInMemory=-1;
+
+    /**max size of data kept in memory at any one point*/
+    private int blockSize=8192;
+
+    private RandomAccessFile fontFile=null;
+
+    public FontData(byte[] fontData) {
+
+        this.fontData=fontData;
+
+        isInMemory=true;
+
+        fullLength=fontData.length;
+
+    }
+
+    /**
+     * pass in name of temp file on disk so we can just read part at a time -
+     * if not part of PDF user is responsible for deleting
+     * @param cachedFile
+     */
+    public FontData(String cachedFile){//, byte[] stream) {
+
+        try{
+            fontFile = new RandomAccessFile( cachedFile, "r" );
+            fullLength = (int) fontFile.length();
+
+        }catch( Exception e ){
+            e.printStackTrace();
+            //LogWriter.writeLog( "Exception " + e + " accessing file" );
+            //throw new PdfException( "Exception " + e + " accessing file" );
+        }
+
+        //if small read all
+        if(fullLength<maxSizeAllowedInMemory){
+
+            blockSize=maxSizeAllowedInMemory;
+
+            adjustForCache(0);
+
+            isInMemory=true;
+
+        }
+    }
+
+    public byte getByte(int pointer){
+
+    	if(!isInMemory)
+            pointer=adjustForCache(pointer);
+
+       // System.err.println("Now="+pointer+" "+fontData.length+" inMemory="+isInMemory);
+
+        if(pointer>=fontData.length)
+            return 0;
+        else
+            return fontData[pointer];
+    }
+
+    /**
+     * check block in memory, read if not and
+     * adjust pointer
+     * @param pointer
+     * @return
+     */
+    private int adjustForCache(int pointer) {
+
+        //see if in memory and load if not
+        if(fontData==null || pointer<offset || pointer>=(offset+blockSize-1)){
+
+            try {
+
+                fontFile.seek(pointer);
+                fontData=new byte[blockSize];
+
+                fontFile.read(fontData);
+
+            } catch (IOException e) {
+                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+            }
+
+            offset=pointer;
+
+        }
+
+        //subtract offset to make it fall in loaded range
+        return pointer-offset;
+    }
+
+    private int adjustForCache(int pointer,int blockSize) {
+
+        //see if in memory and load if not
+        //if(fontData==null || pointer<offset || pointer>=(offset+blockSize-1)){
+
+            try {
+
+                fontFile.seek(pointer);
+                fontData=new byte[blockSize];
+
+                fontFile.read(fontData);
+
+            } catch (IOException e) {
+                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+            }
+
+            offset=pointer;
+
+        //}
+
+        //subtract offset to make it fall in loaded range
+        return pointer-offset;
+    }
+
+    public byte[] getBytes(int startPointer, int length){
+
+        if(!isInMemory)
+            startPointer=adjustForCache(startPointer,length+1);
+
+        byte[] block=new byte[length];
+        System.arraycopy(fontData,startPointer,block,0,length);
+        return block;
+
+    }
+
+    /**total length of FontData in bytes*/
+    public int length() {
+
+        if(isInMemory)
+            return fontData.length;
+        else
+            return fullLength;
+    }
+    
+    public void close(){
+    	if(fontFile!=null)
+			try {
+				fontFile.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+    }
+}
Index: pdfbox/src/main/java/org/jpedal/fonts/tt/Loca.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/jpedal/fonts/tt/Loca.java	(revision )
+++ pdfbox/src/main/java/org/jpedal/fonts/tt/Loca.java	(revision )
@@ -0,0 +1,93 @@
+/**
+* ===========================================
+* Java Pdf Extraction Decoding Access Library
+* ===========================================
+*
+* Project Info:  http://www.jpedal.org
+* (C) Copyright 1997-2008, IDRsolutions and Contributors.
+*
+* 	This file is part of JPedal
+*
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+*
+* ---------------
+* Loca.java
+* ---------------
+*/
+package org.jpedal.fonts.tt;
+
+
+
+public class Loca extends Table {
+		
+	/**points to location of glyph programs*/
+	int[] glyphIndexStart;
+
+    boolean isCorrupted=false;
+
+	public Loca(FontFile2 currentFontFile,int glyphCount,int format){
+	
+		//LogWriter.writeMethod("{readLocaTable}", 0);
+		
+		//move to start and check exists
+		int startPointer=currentFontFile.selectTable(FontFile2.LOCA);
+		
+		int i=0;
+		
+		int locaLength=currentFontFile.getOffset(FontFile2.LOCA);
+		
+		glyphIndexStart=new int[glyphCount+1];
+
+		//read 'head' table
+		if(startPointer!=0){
+			
+			glyphIndexStart[0]=0;
+			//long version
+			if(format==1){
+//				if(LogWriter.isOutput() && (locaLength/4)!=(glyphCount+1))
+//					LogWriter.writeLog("Incorrect length");
+				
+				for(i=0;i<glyphCount;i++)
+					glyphIndexStart[i]=currentFontFile.getNextUint32();
+				
+			}else{ //short
+				if((locaLength/2)!=(glyphCount+1)){
+					
+//					if(LogWriter.isOutput())
+//					LogWriter.writeLog("Incorrect length");
+
+                    isCorrupted=true;
+				}else{
+					for(i=0;i<glyphCount;i++)
+						glyphIndexStart[i]=(currentFontFile.getNextUint16()*2);
+				
+				}
+			}
+
+            glyphIndexStart[glyphCount]=currentFontFile.getOffset(FontFile2.GLYF);
+		
+		}
+	}
+	
+	public int[] getIndices(){
+		return glyphIndexStart;
+	}
+
+    public boolean isCorrupted(){
+		return isCorrupted;
+	}
+}
Index: pdfbox/src/main/java/org/jpedal/fonts/tt/Head.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/jpedal/fonts/tt/Head.java	(revision )
+++ pdfbox/src/main/java/org/jpedal/fonts/tt/Head.java	(revision )
@@ -0,0 +1,109 @@
+/**
+* ===========================================
+* Java Pdf Extraction Decoding Access Library
+* ===========================================
+*
+* Project Info:  http://www.jpedal.org
+* (C) Copyright 1997-2008, IDRsolutions and Contributors.
+*
+* 	This file is part of JPedal
+*
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+*
+* ---------------
+* Head.java
+* ---------------
+*/
+package org.jpedal.fonts.tt;
+
+
+
+public class Head extends Table {
+	
+	/**format used*/
+    protected int format=0; //default for otf
+	
+	/**bounds on font*/
+    protected float[] FontBBox =new float[4];
+
+	protected int flags=0; //default for otf
+
+	protected int unitsPerEm=1024;  //default for otf
+
+	public Head(FontFile2 currentFontFile){
+	
+		//move to start and check exists
+		int startPointer=currentFontFile.selectTable(FontFile2.HEAD);
+		
+		//read 'head' table
+		if(startPointer==0){
+//			if(LogWriter.isOutput())
+//				LogWriter.writeLog("No head table found");
+		}else{
+			
+			currentFontFile.getNextUint32(); //id
+			
+			//ignore values
+			for(int i=0;i<3;i++)
+				currentFontFile.getNextUint32();
+			
+			flags=currentFontFile.getNextUint16();
+			unitsPerEm=currentFontFile.getNextUint16();
+			
+			//ignore dates
+			for(int i=0;i<2;i++)
+				currentFontFile.getNextUint64();
+			
+			//bounds
+			for(int i=0;i<4;i++)
+                FontBBox[i]=currentFontFile.getNextSignedInt16();
+
+			//ignore more flags
+			for(int i=0;i<3;i++)
+				currentFontFile.getNextUint16();
+			
+			//finally the bit we want indicating size of chunks in mapx
+			format=currentFontFile.getNextUint16();
+			
+		}
+	}
+
+    public Head() {
+    }
+
+    public int getFormat(){
+		return format;
+	}
+
+	public float[] getFontBBox(){
+		return this.FontBBox;
+	}
+	/**
+	 * get flags in Head
+	 */
+	public int getFlags() {
+		return flags;
+	}
+
+	/**
+	 *  Returns the unitsPerEm.
+	 */
+	public int getUnitsPerEm() {
+		return unitsPerEm;
+	}
+
+}
Index: pdfbox/src/main/java/org/jpedal/fonts/JPedalFontCmapReader.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/jpedal/fonts/JPedalFontCmapReader.java	(revision )
+++ pdfbox/src/main/java/org/jpedal/fonts/JPedalFontCmapReader.java	(revision )
@@ -0,0 +1,50 @@
+package org.jpedal.fonts;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jpedal.fonts.tt.*;
+
+/**
+ * User: hamed
+ * Date: 4/3/12
+ * Time: 2:55 PM
+ */
+public class JPedalFontCmapReader
+{
+	//
+	// Static fields
+
+	private static final Log log = LogFactory.getLog(JPedalFontCmapReader.class);
+
+	public static CMAP ReadCmapFromFont(byte[] fontBytes)
+	{
+		FontFile2 currentFontFile;
+
+		currentFontFile = new FontFile2(fontBytes);
+		Head currentHead=new Head(currentFontFile);
+		Post currentPost=new Post(currentFontFile);
+		Maxp currentMaxp = new Maxp(currentFontFile);
+		int glyphCount = currentMaxp.getGlyphCount();
+		Loca currentLoca=new Loca(currentFontFile,glyphCount,currentHead.getFormat());
+		boolean isCorrupted=currentLoca.isCorrupted();
+		Glyf currentGlyf = new Glyf(currentFontFile,glyphCount,currentLoca.getIndices());
+		CFF currentCFF=new CFF(currentFontFile,/* isCID */ true);
+
+		boolean hasCFF=currentCFF.hasCFFData();
+		int type = StandardFonts.TRUETYPE;
+		if(hasCFF)
+			type = StandardFonts.OPENTYPE;
+
+		Hhea currentHhea=new Hhea(currentFontFile);
+		float[] FontBBox=currentHead.getFontBBox();
+		Hmtx currentHmtx=new Hmtx(currentFontFile,glyphCount,currentHhea.getNumberOfHMetrics(),(int)FontBBox[3]);
+
+		int startPointer=currentFontFile.selectTable(FontFile2.CMAP);
+		if(startPointer!=0)
+		{
+			return new CMAP(currentFontFile,startPointer,currentGlyf);
+		}
+
+		return null;
+	}
+}
Index: pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java	(revision 1305316)
+++ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java	(revision )
@@ -98,7 +98,7 @@
         }
         return awtFont;
     }
-    
+
     /**
      * This will get the fonts bounding box.
      *
Index: pdfbox/src/main/java/org/jpedal/fonts/tt/Hmtx.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/jpedal/fonts/tt/Hmtx.java	(revision )
+++ pdfbox/src/main/java/org/jpedal/fonts/tt/Hmtx.java	(revision )
@@ -0,0 +1,142 @@
+/**
+* ===========================================
+* Java Pdf Extraction Decoding Access Library
+* ===========================================
+*
+* Project Info:  http://www.jpedal.org
+* (C) Copyright 1997-2008, IDRsolutions and Contributors.
+*
+* 	This file is part of JPedal
+*
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+*
+* ---------------
+* Hmtx.java
+* ---------------
+*/
+package org.jpedal.fonts.tt;
+
+
+
+public class Hmtx extends Table {
+	
+	private int[] hMetrics;
+	private short[] leftSideBearing;
+    private float scaling=1f/1000f;
+
+    public Hmtx(FontFile2 currentFontFile,int glyphCount,int metricsCount,int maxAdvance){
+
+        scaling=maxAdvance;
+
+        if(metricsCount<0)
+			metricsCount=-metricsCount;
+		
+		//move to start and check exists
+		int startPointer=currentFontFile.selectTable(FontFile2.HMTX);
+		
+		int lsbCount=glyphCount-metricsCount;
+		
+		//System.out.println("start="+Integer.toHexString(startPointer)+" lsbCount="+lsbCount+" glyphCount="+glyphCount+" metricsCount="+metricsCount);
+		
+		hMetrics = new int[glyphCount];
+		leftSideBearing = new short[glyphCount];
+		
+		int currentMetric=0;
+		
+		//read 'head' table
+		if(startPointer==0){
+//			if(LogWriter.isOutput())
+//				LogWriter.writeLog("No Htmx table found");
+		}else if(lsbCount<0){
+//			if(LogWriter.isOutput())
+//				LogWriter.writeLog("Invalid Htmx table found");
+        }else{
+			int i ;
+			for (i = 0; i < metricsCount; i++){
+				currentMetric=currentFontFile.getNextUint16();
+				hMetrics[i] =currentMetric;
+				leftSideBearing[i] = currentFontFile.getNextInt16();
+				//System.out.println(i+"="+hMetrics[i]+" "+leftSideBearing[i]);
+			}
+			
+			//workout actual number of values in table
+			int tableLength=currentFontFile.getTableSize(FontFile2.HMTX);
+			int lsbBytes=tableLength-(i*4); //each entry above used 4 bytes
+			lsbCount=(lsbBytes/2); //each entry contains 2 bytes
+
+			//read additional lsb entries
+			for(int j=i;j<lsbCount;j++){
+
+				hMetrics[j] =currentMetric;
+				leftSideBearing[j] = currentFontFile.getFWord();
+				//System.out.println((j)+" "+leftSideBearing[j]);
+			}
+		}
+		
+	}
+
+    public Hmtx() {
+    }
+
+    //used by OTF code for aligning CFF font data
+    public short getRAWLSB(int i){
+        if(leftSideBearing==null || i>=leftSideBearing.length)
+            return 0;
+        else
+            return leftSideBearing[i];
+    }
+
+    public short getLeftSideBearing(int i) {
+		if (i < hMetrics.length) {
+			return (short)(hMetrics[i] & 0xffff);
+		} else if(leftSideBearing==null){
+			return 0;
+		}else{
+			try{
+				return leftSideBearing[i - hMetrics.length];
+			}catch(Exception e){
+		        return 0;
+			}
+		}
+	}
+	
+	public float getAdvanceWidth(int i) {
+        /**if (i < hMetrics.length) {
+			return hMetrics[i] >> 16;
+		} else {
+			return hMetrics[hMetrics.length - 1] >> 16;
+		}*/
+        return ( (hMetrics[i]-getLeftSideBearing(i))/scaling);
+    }
+
+    public float getWidth(int i) {
+        /**if (i < hMetrics.length) {
+			return hMetrics[i] >> 16;
+		} else {
+			return hMetrics[hMetrics.length - 1] >> 16;
+		}*/
+        float w=hMetrics[i];
+
+        
+        return ( (w)/scaling);
+    }
+    
+    public float getUnscaledWidth(int i) {
+        
+        return hMetrics[i];
+    }
+}
Index: pdfbox/src/main/java/org/jpedal/fonts/tt/Table.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/jpedal/fonts/tt/Table.java	(revision )
+++ pdfbox/src/main/java/org/jpedal/fonts/tt/Table.java	(revision )
@@ -0,0 +1,39 @@
+/**
+* ===========================================
+* Java Pdf Extraction Decoding Access Library
+* ===========================================
+*
+* Project Info:  http://www.jpedal.org
+* (C) Copyright 1997-2008, IDRsolutions and Contributors.
+*
+* 	This file is part of JPedal
+*
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+*
+* ---------------
+* Table.java
+* ---------------
+*/
+package org.jpedal.fonts.tt;
+
+import java.io.Serializable;
+
+/**
+ * generic table class for tables in truetype font */
+public class Table implements Serializable {
+
+}
Index: pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java	(revision 1305316)
+++ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDTrueTypeFont.java	(revision )
@@ -39,6 +39,8 @@
 import org.apache.pdfbox.pdmodel.common.PDStream;
 import org.apache.pdfbox.encoding.WinAnsiEncoding;
 import org.apache.pdfbox.util.ResourceLoader;
+import org.jpedal.fonts.JPedalFontCmapReader;
+import org.jpedal.fonts.tt.CMAP;
 
 import java.awt.Font;
 import java.awt.FontFormatException;
@@ -75,6 +77,8 @@
     public static final String UNKNOWN_FONT = "UNKNOWN_FONT";
 
     private Font awtFont = null;
+	private CMAP fontCmap = null;
+	private boolean cmapExtracted = false;
 
     private static Properties externalFonts = new Properties();
     private static Map<String,TrueTypeFont> loadedExternalFonts = new HashMap<String,TrueTypeFont>();
@@ -434,9 +438,34 @@
             }
         }
         return awtFont;
+    }
+
+	@Override
+	public CMAP getFontCmap()
+	{
+		if (cmapExtracted)
+			return fontCmap;
+
+		cmapExtracted = true;
+
+		try
+		{
+			PDFontDescriptorDictionary fd = (PDFontDescriptorDictionary)getFontDescriptor();
+			PDStream ff2Stream = fd.getFontFile2();
+			if( ff2Stream != null )
+			{
+				fontCmap = JPedalFontCmapReader.ReadCmapFromFont(ff2Stream.getByteArray());
+			}
+		}
+		catch (IOException e)
+		{
+			log.error("Exception occured", e);
+		}
+		
+		return fontCmap;
-    }
+	}
 
-    private InputStream getExternalTTFData() throws IOException
+	private InputStream getExternalTTFData() throws IOException
     {
         String ttfResource = externalFonts.getProperty( UNKNOWN_FONT );
         String baseFont = getBaseFont();
Index: pdfbox/src/main/java/org/jpedal/fonts/tt/Maxp.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/jpedal/fonts/tt/Maxp.java	(revision )
+++ pdfbox/src/main/java/org/jpedal/fonts/tt/Maxp.java	(revision )
@@ -0,0 +1,93 @@
+/**
+* ===========================================
+* Java Pdf Extraction Decoding Access Library
+* ===========================================
+*
+* Project Info:  http://www.jpedal.org
+* (C) Copyright 1997-2008, IDRsolutions and Contributors.
+*
+* 	This file is part of JPedal
+*
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+*
+* ---------------
+* Mapx.java
+* ---------------
+*/
+package org.jpedal.fonts.tt;
+
+public class Maxp extends Table {
+	
+	private int numGlyphs=0, maxPoints=0, maxContours=0, maxComponentPoints=0, maxComponentContours=0, maxZones=0,
+            maxTwilightPoints=0, maxStorage=0, maxFunctionDefs=0, maxInstructionDefs=0, maxStackElements=0,
+            maxSizeOfInstructions=0, maxComponentElements=0, maxComponentDepth=0;
+
+	public Maxp(FontFile2 currentFontFile){
+	
+		//LogWriter.writeMethod("{readMapxTable}", 0);
+        init(currentFontFile);
+
+    }
+
+    public Maxp() {
+    }
+
+    private void init(FontFile2 currentFontFile) {
+        //move to start and check exists
+        int startPointer=currentFontFile.selectTable(FontFile2.MAXP);
+
+        //read 'head' table
+        if(startPointer!=0){
+
+            currentFontFile.getNextUint32(); //id
+            numGlyphs=currentFontFile.getNextUint16();
+            maxPoints=currentFontFile.getNextUint16();
+            maxContours=currentFontFile.getNextUint16();
+            maxComponentPoints=currentFontFile.getNextUint16();
+            maxComponentContours=currentFontFile.getNextUint16();
+            maxZones=currentFontFile.getNextUint16();
+            maxTwilightPoints=currentFontFile.getNextUint16();
+            maxStorage=currentFontFile.getNextUint16();
+            maxFunctionDefs=currentFontFile.getNextUint16();
+            maxInstructionDefs=currentFontFile.getNextUint16();
+            maxStackElements=currentFontFile.getNextUint16();
+            maxSizeOfInstructions=currentFontFile.getNextUint16();
+            maxComponentElements=currentFontFile.getNextUint16();
+            maxComponentDepth=currentFontFile.getNextUint16();
+        }
+    }
+
+    public int getGlyphCount(){
+		return numGlyphs;
+	}
+
+    public int getMaxPoints(){
+        return maxPoints;
+    }
+
+    public int getMaxTwilightPoints(){
+        return maxTwilightPoints;
+    }
+
+    public int getMaxStorage(){
+        return maxStorage;
+    }
+
+    public int getMaxContours(){
+        return maxContours;
+    }
+}
Index: fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java	(revision 1305316)
+++ fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java	(revision )
@@ -16,18 +16,7 @@
  */
 package org.apache.fontbox.cff;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 import org.apache.fontbox.cff.CFFFont.Mapping;
-import org.apache.fontbox.cff.CFFOperator;
 import org.apache.fontbox.cff.charset.CFFCharset;
 import org.apache.fontbox.cff.charset.CFFExpertCharset;
 import org.apache.fontbox.cff.charset.CFFExpertSubsetCharset;
@@ -35,6 +24,9 @@
 import org.apache.fontbox.cff.encoding.CFFEncoding;
 import org.apache.fontbox.cff.encoding.CFFExpertEncoding;
 import org.apache.fontbox.cff.encoding.CFFStandardEncoding;
+
+import java.io.IOException;
+import java.util.*;
 
 /**
  * This class represents a parser for a CFF font. 
\ No newline at end of file
Index: pdfbox/src/main/java/org/jpedal/fonts/tt/Name.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/jpedal/fonts/tt/Name.java	(revision )
+++ pdfbox/src/main/java/org/jpedal/fonts/tt/Name.java	(revision )
@@ -0,0 +1,162 @@
+/**
+* ===========================================
+* Java Pdf Extraction Decoding Access Library
+* ===========================================
+*
+* Project Info:  http://www.jpedal.org
+* (C) Copyright 1997-2008, IDRsolutions and Contributors.
+*
+* 	This file is part of JPedal
+*
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+*
+* ---------------
+* Name.java
+* ---------------
+*/
+package org.jpedal.fonts.tt;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * font strings partially implemented - full spec is at http://www.microsoft.com/OpenType/OTSpec/name.htm
+ */
+public class Name extends Table {
+	
+	/**max number of glyphs*/
+	private int encoding=0;
+
+    private Map strings=new HashMap();
+
+    public static final Integer COPYRIGHT_NOTICE=new Integer(0);
+    public static final Integer FONT_FAMILY_NAME=new Integer(1);
+    public static final Integer FONT_SUBFAMILY_NAME=new Integer(2);
+    public static final Integer UNIQUE_FONT_IDENTIFIER=new Integer(3);
+    public static final Integer FULL_FONT_NAME=new Integer(4);
+    public static final Integer VERSION_STRING=new Integer(5);
+    public static final Integer POSTSCRIPT_NAME=new Integer(6);
+    public static final Integer TRADEMARK=new Integer(7);
+    public static final Integer MANUFACTURER=new Integer(8);
+    public static final Integer DESIGNER=new Integer(9);
+    public static final Integer DESCRIPTION=new Integer(10);
+    public static final Integer VENDOR_URL=new Integer(11);
+    public static final Integer DESIGNER_URL=new Integer(12);
+    public static final Integer LICENSE=new Integer(13);
+    public static final Integer LICENSE_URL=new Integer(14);
+    public static final Integer PREFERRED_FAMILY=new Integer(16);
+    public static final Integer PREFERRED_SUBFAMILY=new Integer(17);
+    public static final Integer COMPATIBLE=new Integer(18);
+    public static final Integer SAMPLE_TEXT=new Integer(19);
+    
+    /**list of Integer values in same order as keys*/
+    public static final String[] stringNames={"COPYRIGHT_NOTICE","FONT_FAMILY_NAME","FONT_SUBFAMILY_NAME",
+    	"UNIQUE_FONT_IDENTIFIER","FULL_FONT_NAME","VERSION_STRING","POSTSCRIPT_NAME",
+    	"TRADEMARK","MANUFACTURER","DESIGNER","DESCRIPTION","VENDOR_URL",
+    	"DESIGNER_URL","LICENSE","LICENSE_URL","PREFERRED_FAMILY",
+    	"PREFERRED_SUBFAMILY","COMPATIBLE","SAMPLE_TEXT"};
+
+    public Name(FontFile2 currentFontFile){
+	
+		//LogWriter.writeMethod("{readMapxTable}", 0);
+		
+		//move to start and check exists
+		int startPointer=currentFontFile.selectTable(FontFile2.NAME);
+
+        //read 'head' table
+		if(startPointer!=0){
+
+            //read global details
+            currentFontFile.getNextUint16();//format
+            int count=currentFontFile.getNextUint16();
+            int offset=currentFontFile.getNextUint16();
+
+            /**
+             * read strings
+             */
+            for(int i=0;i<count;i++){
+
+                //get table values
+                int platformID=currentFontFile.getNextUint16();
+                int platformSpecificID=currentFontFile.getNextUint16();
+                int langID=currentFontFile.getNextUint16();
+                int nameID=currentFontFile.getNextUint16();
+                int length=currentFontFile.getNextUint16();
+                int offset2=currentFontFile.getNextUint16();
+
+                //only these 2 variations at present
+                if((platformID==1 && platformSpecificID==0 && langID==0)||
+                        (platformID==3 && platformSpecificID==0 && langID==1033) ||
+                        (platformID==3 && platformSpecificID==1 && langID==1033)){
+
+                    //read actual string for location, altering/restoring pointers
+                    int oldP=currentFontFile.getPointer();
+
+                    currentFontFile.setPointer(startPointer+offset+offset2);
+
+                    int nextChar;
+
+                    //allow for 2 bytes in char
+                    if(platformID==0 || platformID==3)
+                        length=length/2;
+
+                    StringBuffer s=new StringBuffer();
+                    s.setLength(length);
+
+                    for(int ii=0;ii<length;ii++){
+                        if(platformID==0 || platformID==3)
+                            nextChar=currentFontFile.getNextUint16();
+                        else
+                            nextChar=currentFontFile.getNextUint8();
+
+                        s.setCharAt(ii,(char)nextChar);
+                    }
+
+                    String str=s.toString();
+
+                    if(str!=null)
+                        strings.put(new Integer(nameID),str);
+                    
+                    currentFontFile.setPointer(oldP);
+                }
+            }
+        }
+	}
+
+    public Name() {
+    }
+	
+    /**
+     * get Map of Strings - key is Integer key and String value is in 
+     */
+    public Map getStrings(){
+		return strings;
+	}
+    
+	public int getEncoding(){
+		return encoding;
+	}
+
+    /**
+     * return a String value in font - keys also defined as Integers in NAME class
+     *
+     * not all encodings or ID 20 handled at present
+     */
+    public String getString(Integer id) {
+        return (String) strings.get(id);
+    }
+}
Index: pdfbox/src/main/java/org/jpedal/fonts/StandardFonts.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/jpedal/fonts/StandardFonts.java	(revision )
+++ pdfbox/src/main/java/org/jpedal/fonts/StandardFonts.java	(revision )
@@ -0,0 +1,1142 @@
+/**
+* ===========================================
+* Java Pdf Extraction Decoding Access Library
+* ===========================================
+*
+* Project Info:  http://www.jpedal.org
+* (C) Copyright 1997-2008, IDRsolutions and Contributors.
+*
+* 	This file is part of JPedal
+*
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+*
+* ---------------
+* StandardFonts.java
+* ---------------
+*/
+package org.jpedal.fonts;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+public class StandardFonts {
+	
+	/**holds names of every character*/
+	static private Map unicode_name_mapping_table = new Hashtable();
+	
+	/**holds lookup to map char values for decoding char into name*/
+	private static String[][] unicode_char_decoding_table = new String[7][335];
+	
+	public final static int PDF = 6;
+	
+	/**flag used to identify ZAPF encoding*/
+	public final static int ZAPF = 5;
+	
+	/**flag used to identify Symbol encoding*/
+	public final static int SYMBOL = 4;
+
+	/**flag used to identify MacExpert encoding*/
+	public final static int MACEXPERT = 3;
+	
+	/**flag used to identify WIN encoding*/
+	public final static int WIN = 2;
+
+	/**flag used to identify STD encoding*/
+	public final static int STD = 1;
+
+	/**flag used to identify mac encoding*/
+	public final static int MAC = 0;
+
+    /**mapped onto CID0 or CID2*/
+    final public static int TYPE0=1228944676;
+
+
+    public final static int TYPE1=1228944677;
+	public final static int TRUETYPE=1217103210;
+
+    
+    public final static int TYPE3=1228944679;
+	public final static int CIDTYPE0=-1684566726;
+	public final static int CIDTYPE2=-1684566724;
+
+    public final static int OPENTYPE=6;
+
+    public final static int TRUETYPE_COLLECTION=7;
+    
+    public final static int FONT_UNSUPPORTED=8;
+    
+    /**constant value for ellipsis*/
+    private static String ellipsis= String.valueOf((char) Integer.parseInt("2026", 16));
+    
+    /**must use windows encoding because files were edited on Windows*/
+	private static final String enc = "Cp1252";
+	
+	/**only in 1 encoding*/
+	private static Map uniqueValues=null;
+	
+	/**lookup table to workout index from glyf*/
+	private static Map[] glyphToChar= new Hashtable[7];
+
+	/**holds lookup to map char values for decoding NAME into encoded char*/
+	private static String[] MAC_char_encoding_table;
+	
+	/**holds lookup to map char values for decoding NAME into encoded char*/
+	private static String[] WIN_char_encoding_table;
+	
+	/**holds lookup to map char values for decoding NAME into encoded char*/
+	private static String[] STD_char_encoding_table;
+
+	/**holds lookup to map char values for decoding NAME into encoded char*/
+	private static String[] PDF_char_encoding_table;
+
+	/**holds lookup to map char values for decoding NAME into encoded char*/
+	private static String[] ZAPF_char_encoding_table;
+	
+	/**holds lookup to map char values for decoding NAME into encoded char*/
+	private static String[] SYMBOL_char_encoding_table;
+	
+	/**holds lookup to map char values for decoding NAME into encoded char*/
+	private static String[] MACEXPERT_char_encoding_table;
+	
+	
+	/**loader to load data from jar*/
+	private static ClassLoader loader = StandardFonts.class.getClassLoader();
+	
+	/**list of standard fonts*/
+	private static Hashtable standardFileList=new Hashtable();
+	
+	/**flag if standard font loaded*/
+	private static  Hashtable standardFontLoaded=new Hashtable();
+	
+	/**lookup for standard fonts which we read when object created*/
+	private static Map widthTableStandard = new Hashtable();
+	
+	//@sam - list of CID fonts
+	/**names of CID fonts supplied by Adobe*
+	private static String[] CIDFonts =
+	{
+				"83pv-RKSJ-H",
+						"90msp-RKSJ-H",
+				"90msp-RKSJ-V",
+						"90ms-RKSJ-H",
+				"90ms-RKSJ-UCS2",
+						"90ms-RKSJ-V",
+				"90pv-RKSJ-H",
+						"90pv-RKSJ-UCS2",
+				"90pv-RKSJ-UCS2C",
+						"Add-RKSJ-H",
+				"Add-RKSJ-V",
+						"Adobe-CNS1-3",
+				"Adobe-CNS1-UCS2",
+						"Adobe-GB1-4",
+				"Adobe-GB1-UCS2",
+						"Adobe-Japan1-4",
+				"Adobe-Japan1-UCS2",
+						"Adobe-Korea1-2",
+				"Adobe-Korea1-UCS2",
+						"B5pc-H",
+				"B5pc-UCS2",
+						"B5pc-UCS2C",
+				"B5pc-V",
+						"CNS-EUC-H",
+				"CNS-EUC-V",
+						"ETen-B5-H",
+				"ETen-B5-UCS2",
+						"ETen-B5-V",
+				"euc-h",
+						"euc-v",
+				"Ext-RKSJ-H",
+						"Ext-RKSJ-V",
+				"gb-euc-h",
+						"gb-euc-v",
+				"gbk2k-h",
+						"gbk2k-v",
+				"GBK-EUC-H",
+						"GBK-EUC-UCS2",
+				"GBK-EUC-V",
+						"GBKp-EUC-H",
+				"GBKp-EUC-V",
+						"GBpc-EUC-H",
+				"GBpc-EUC-UCS2",
+						"GBpc-EUC-UCS2C",
+				"GBpc-EUC-V",
+						"GBT-EUC-H",
+				"GBT-EUC-V",
+						"h",
+				"HKscs-B5-H",
+						"HKscs-B5-V",
+				"KSC-EUC-H",
+						"KSC-EUC-V",
+				"KSCms-UHC-H",
+						"KSCms-UHC-HW-H",
+				"KSCms-UHC-HW-V",
+						"KSCms-UHC-UCS2",
+				"KSCms-UHC-V",
+						"KSCpc-EUC-H",
+				"KSCpc-EUC-UCS2",
+						"KSCpc-EUC-UCS2C",
+				"UniCNS-UCS2-H",
+						"UniCNS-UCS2-V",
+				"UniGB-UCS2-H",
+						"UniGB-UCS2-V",
+				"UniJIS-UCS2-H",
+						"UniJIS-UCS2-HW-H",
+				"UniJIS-UCS2-HW-V",
+						"UniJIS-UCS2-V",
+				"UniKS-UCS2-H",
+						"UniKS-UCS2-V",
+	"v" };/**/
+	
+	/**lookup table for java fonts*/
+	protected static Map javaFontList=new Hashtable();
+	
+	/**java font versions of fonts*/
+	protected static String javaFonts[] =
+	{"Courier",
+			"Courier-Bold",
+			"Courier",
+					"Courier-Bold",
+			"Arial",
+					"Arial-Bold",
+			"Arial",
+					"Arial-Italic",
+			"Symbol",
+					"Times New Roman",
+			"Times New Roman",
+					"Times New Roman",
+			"Times New Roman",
+"Wingdings" };
+	
+	/**names of 14 local fonts used in pdf*/
+	protected static String files_names[] =
+	{
+				"Courier",
+						"Courier-Bold",
+				"Courier-BoldOblique",
+						"Courier-Oblique",
+				"Helvetica",
+						"Helvetica-Bold",
+				"Helvetica-BoldOblique",
+						"Helvetica-Oblique",
+				"Symbol",
+						"Times-Bold",
+				"Times-BoldItalic",
+						"Times-Italic",
+				"Times-Roman",
+	"ZapfDingbats" };
+
+	/**alternative names of 14 local fonts used in pdf*/
+	protected static String files_names_bis[] =
+	{
+				"CourierNew",
+						"CourierNew,Bold",
+				"CourierNew,BoldItalic",
+						"CourierNew,Italic",
+				"Arial",
+						"Arial,Bold",
+				"Arial,BoldItalic",
+						"Arial,Italic",
+				"Symbol",
+						"TimesNewRoman,Bold",
+				"TimesNewRoman,BoldItalic",
+						"TimesNewRoman,Italic",
+				"TimesNewRoman",
+	"ZapfDingbats" };
+
+	/**holds lookup values used by truetype font mapping*/
+	private static Hashtable adobeMap=null;
+
+    //hold bounds
+    private static Map fontBounds=new HashMap();
+
+    /**flag if standard_encoding loaded*/
+    public static boolean usesGlyphlist=false;
+
+    public static void dispose(){
+	   
+	   unicode_name_mapping_table =null;
+		
+		unicode_char_decoding_table =null;
+		
+		uniqueValues=null;
+		
+		glyphToChar=null;
+
+		MAC_char_encoding_table=null;
+		
+		WIN_char_encoding_table=null;
+		
+		STD_char_encoding_table=null;
+
+		PDF_char_encoding_table=null;
+
+		ZAPF_char_encoding_table=null;
+		
+		SYMBOL_char_encoding_table=null;
+		
+		MACEXPERT_char_encoding_table=null;
+		
+		
+		loader = null;
+		
+		standardFileList=null;
+		
+		standardFontLoaded=null;
+		
+		widthTableStandard = null;
+		
+		/**names of CID fonts supplied by Adobe*/
+		//CIDFonts =null;
+		
+		/**lookup table for java fonts*/
+		javaFontList=null;
+		
+		/**java font versions of fonts*/
+		javaFonts=null;
+		
+		files_names=null;
+
+		files_names_bis=null;
+
+		adobeMap=null;
+
+	    fontBounds=null;
+   }
+
+    //////////////////////////////////////////////////
+	/**
+	 * create lookup array so we can quickly test if 
+	 * we have one of the 14 fonts so we can test quickly
+	 */
+	static{
+		// loop to read widths from default fonts
+		for (int i = 0; i < files_names.length; i++) {
+			standardFileList.put(files_names_bis[i],new Integer(i));
+			standardFileList.put(files_names[i],new Integer(i));
+		}
+		
+		loadAdobeMap();
+	}
+
+    /**return font type based on file ending or FONT_UNSUPPORTED
+     * if not recognised
+     * @param name
+     * @return int - defined in StandardFonts (no value is FONT_UNSUPPORTED)
+     */
+    public static int getFontType(String name) {
+
+        int type= FONT_UNSUPPORTED;
+
+        if (name.endsWith(".ttf"))
+            type=TRUETYPE;
+        else if(name.endsWith(".otf"))
+            type=OPENTYPE;
+        else if(name.endsWith(".ttc"))
+            type=TRUETYPE_COLLECTION;
+        //else if(name.endsWith(".afm"))
+          //  type=TYPE1;
+        else if(name.endsWith(".pfb"))
+            type=TYPE1;
+
+        return type;
+    }
+
+    /**
+     * get FontBonds set in afm file 
+     */
+    public static float[] getFontBounds(String fontName){
+       return (float[]) fontBounds.get(fontName);
+    }
+    
+
+    public static String getUnicodeName(String key){
+		return (String) unicode_name_mapping_table.get(key);
+	}
+	
+	public static String getUnicodeChar(int i,int key){
+
+        return unicode_char_decoding_table[i][key];
+	}
+
+    public static Map getUniqueMappings(){
+
+    	if(uniqueValues==null){
+    		
+	        uniqueValues=new HashMap();
+	
+	        for(int ii=0;ii<256;ii++){
+	            if(WIN_char_encoding_table[ii]==null && MAC_char_encoding_table[ii]!=null ){
+	                //System.out.println(ii+" MAC only="+MAC_char_encoding_table[ii]);
+	                uniqueValues.put(new Integer(ii), new Integer(1));
+	            }
+	
+	            if(WIN_char_encoding_table[ii]!=null && MAC_char_encoding_table[ii]==null){
+	                //System.out.println(ii+" WIN only="+WIN_char_encoding_table[ii]);
+	                uniqueValues.put(new Integer(ii), new Integer(-1));
+	            }
+	        }
+    	}
+    	
+        return uniqueValues;
+    }
+	
+	public static Float getStandardWidth(String font,String key){
+	    
+	    Object value=widthTableStandard.get(font+key);
+	    if(value==null){
+	        String altfont=font;
+	        int p=altfont.indexOf(',');
+	        if(p!=-1){
+	            altfont=altfont.substring(0,p);
+	            value=widthTableStandard.get(altfont+key);
+	        }
+	    }
+	    
+		return (Float) value;
+	}
+	
+	//////////////////////////////////////////////////////////////////////////
+	/**
+	 * create mapping tables for pdf values
+	 * for Zapf and Symbol (not fully implmented yet)
+	 */
+	final static private void readStandardMappingTable(
+			int key,
+			String file_name){
+		String char_value, NAME, VAL, line = null,hexVal=null;
+		int value = 0;
+		BufferedReader input_stream = null;
+		
+		glyphToChar[key]=new Hashtable();
+		
+		
+		try {
+		
+			
+			input_stream =
+			(file_name.equals("symbol.cfg"))
+			? new BufferedReader(
+					new InputStreamReader(
+							loader.getResourceAsStream(
+									"org/jpedal/res/pdf/" + file_name),
+							enc))
+			: new BufferedReader(
+					new InputStreamReader(
+							loader.getResourceAsStream(
+									"org/jpedal/res/pdf/" + file_name),
+							"UTF-16"));
+
+			// trap problems
+//			if (input_stream == null && LogWriter.isOutput()) {
+//				LogWriter.writeLog("Unable to open "+ file_name+ " to read standard encoding");
+//			}
+			
+
+			//read in lines and place in map tables for fast lookup
+			while (true) {
+				line = input_stream.readLine();
+				if (line == null)
+					break;
+				
+				//write values to table, converting from Octal
+				StringTokenizer values = new StringTokenizer(line);
+				
+				//trap for space and lines which cause problems in Zapf
+				if ((line.indexOf("space") == -1) && (values.countTokens() > 1)) {
+					
+					//ignore first as token but read as char
+					if (values.countTokens() == 3) {
+						char_value = values.nextToken();
+						NAME = values.nextToken();
+						VAL = values.nextToken();
+						
+					}else if (values.countTokens() == 4) {
+						hexVal=values.nextToken();
+						char_value = values.nextToken();
+						NAME = values.nextToken();
+						VAL = values.nextToken();
+						
+						char_value=Character.toString((char)Integer.parseInt(hexVal,16));
+						
+					} else { //zapf values
+						if(values.countTokens()==2){
+							char_value = " ";
+							NAME = values.nextToken();
+							VAL = values.nextToken();
+						}else{
+							char_value = values.nextToken();
+							NAME = values.nextToken();
+							VAL = values.nextToken();
+						}
+					}
+					
+					unicode_name_mapping_table.put(key + NAME, char_value);
+					
+					glyphToChar[key].put(NAME, new Integer(Integer.parseInt(VAL)));
+					
+					//20021104 added to make sure names in list as well
+					//if (file_name.equals("zapf.cfg"))
+						unicode_name_mapping_table.put(NAME, char_value);
+					
+					//convert if there is a value
+					if (Character.isDigit(VAL.charAt(0))) {
+						
+						value = Integer.parseInt(VAL, 8);
+						
+						if(key==ZAPF)
+							ZAPF_char_encoding_table[value] = char_value;
+						else if(key==SYMBOL)
+							SYMBOL_char_encoding_table[value] = char_value;
+						else if(key==MACEXPERT)
+							MACEXPERT_char_encoding_table[value] = char_value;
+						
+						unicode_char_decoding_table[key][value]=NAME;
+						
+					}
+				}
+			}
+		} catch (Exception e) {
+//			if(LogWriter.isOutput())
+//				LogWriter.writeLog("Exception " + e + " reading lookup table for pdf");
+		}
+		
+		if(input_stream!=null){
+			try{
+				input_stream.close();
+			}catch (Exception e) {
+//				if(LogWriter.isOutput())
+//					LogWriter.writeLog("Exception " + e + " reading lookup table for pdf  for abobe map");
+			}		
+		}
+	}
+	//////////////////////////////////////////////
+	/**
+	 * create mapping tables for 'standard' pdf values
+	 * by reading in data from files (which are tables
+	 * taken from Adobe's standard documentation
+	 */
+	final static private void readStandardMappingTable(int idx) {
+
+        String char_value = null, NAME, STD_value, MAC_value, WIN_value,PDF_value,raw;
+		int mac_value = 0, win_value = 0, std_value = 0;
+		String line = null;
+		BufferedReader input_stream = null;
+		
+		//needed for comparison table
+		if(idx==MAC)
+			checkLoaded(WIN);
+		
+		
+		try {
+		
+			//initialise inverse lookup
+			glyphToChar[idx]=new Hashtable();
+			
+			input_stream =
+			new BufferedReader(
+					new InputStreamReader(
+							loader.getResourceAsStream(
+							"org/jpedal/res/pdf/standard_encoding.cfg"),enc));
+
+            usesGlyphlist=true;
+
+			// trap problems
+//			if (input_stream == null && LogWriter.isOutput())
+//				LogWriter.writeLog("Unable to open standard_encoding.cfg from jar");
+			
+			//read in lines and place in map tables for fast lookup
+			while (true) {
+				line = input_stream.readLine();
+				if (line == null)
+					break;
+				
+				//write values to table, converting from Octal
+				StringTokenizer values = new StringTokenizer(line);
+				int count=values.countTokens();
+				
+				//format is NAME, STD,MAC,WIN,PDF, unicode value (as hex) char from PDF reference ignored) or 
+				//NAME, STD,MAC,WIN,PDF,  char (used for fi,fl and other double values)
+				//ignore first as token but read as char
+				
+				NAME = values.nextToken();
+				STD_value = values.nextToken();
+				MAC_value = values.nextToken();
+				WIN_value = values.nextToken();
+				PDF_value =values.nextToken();
+				raw=values.nextToken();
+				
+				if(count==7)				
+					char_value=Character.toString((char)Integer.parseInt(raw,16));					
+				else
+					char_value=raw;
+				
+
+				//convert if possible
+				if((idx==MAC) &&(Character.isDigit(MAC_value.charAt(0)))) {
+					mac_value = Integer.parseInt(MAC_value, 8);
+
+                    //substitute ellipsis
+                    if(mac_value==201)
+                        char_value=ellipsis;
+                    
+					MAC_char_encoding_table[mac_value] =char_value;
+					unicode_char_decoding_table[MAC][mac_value]=NAME;
+					
+					glyphToChar[MAC].put(NAME, new Integer(mac_value));
+					
+					//build a comparison table to test encoding
+					if (Character.isDigit(WIN_value.charAt(0)))
+						win_value = Integer.parseInt(WIN_value, 8);
+					
+				}else if ((idx==STD)&&(Character.isDigit(STD_value.charAt(0)))) {
+					std_value = Integer.parseInt(STD_value, 8);
+
+                    //substitute ellipsis
+                    if(std_value==188)
+                        char_value=ellipsis;
+                    
+					STD_char_encoding_table[std_value] =char_value;
+					unicode_char_decoding_table[STD][std_value]=NAME;
+					
+					glyphToChar[STD].put(NAME, new Integer(std_value));
+				
+				}else if ((idx==PDF)&&(Character.isDigit(PDF_value.charAt(0)))) {
+					std_value = Integer.parseInt(PDF_value, 8);
+
+                    //substitute ellipsis
+                    if(std_value==131)
+                        char_value=ellipsis;
+                    
+					PDF_char_encoding_table[std_value] =char_value;
+					unicode_char_decoding_table[PDF][std_value]=NAME;
+					
+				}else if ((idx== WIN)&&(Character.isDigit(WIN_value.charAt(0)))) {
+					win_value = Integer.parseInt(WIN_value, 8);
+
+                    //substitute ellipsis
+                    if(win_value==133)
+                        char_value=ellipsis;
+                    
+					WIN_char_encoding_table[win_value] =char_value;
+					unicode_char_decoding_table[WIN][win_value]=NAME;
+					
+					glyphToChar[WIN].put(NAME, new Integer(win_value));
+
+
+				}
+				
+				//save details for later
+				unicode_name_mapping_table.put(NAME, char_value);
+				
+			
+			}
+
+            //add in alternative MAC space   312 octal == space
+            if(idx==MAC)
+            MAC_char_encoding_table[202]=" ";
+
+            //add in alternative WIN values
+            if(idx== WIN){
+            	WIN_char_encoding_table[160]=" ";
+            	WIN_char_encoding_table[255]="-";
+            	
+            	unicode_char_decoding_table[WIN][160]="space";
+    			
+            }
+            
+        } catch (Exception e) {
+//        	if(LogWriter.isOutput())
+//        		LogWriter.writeLog("Exception " + e + " reading lookup table for pdf  for "+idx);
+		}
+		
+		if(input_stream!=null){
+			try{
+				input_stream.close();
+			}catch (Exception e) {
+//				if(LogWriter.isOutput())
+//					LogWriter.writeLog("Exception " + e + " reading lookup table for pdf  for abobe map");
+			}		
+		}
+	}
+	
+	/**used internally when we needed to convert bytes to MacROman to build new tables*/
+	/**private static String byteToEncodedString(String value,String enc) throws Exception{
+		
+		String s=null;
+		
+			//Create the encoder and decoder for ISO-8859-1
+	    Charset charset = Charset.forName(enc);
+	    CharsetDecoder decoder = charset.newDecoder();
+	    CharsetEncoder encoder = charset.newEncoder();
+	    
+	        // Convert a string to ISO-LATIN-1 bytes in a ByteBuffer
+	        // The new ByteBuffer is ready to be read.
+	    		java.nio.ByteBuffer bbuf = encoder.encode(CharBuffer.wrap("a"));
+	    		bbuf.clear();
+	        //java.nio.ByteBuffer bbuf=new ByteBuffer();
+	        bbuf.put(0,(byte) Integer.parseInt(value,16));
+	        // Convert ISO-LATIN-1 bytes in a ByteBuffer to a character ByteBuffer and then to a string.
+	        // The new ByteBuffer is ready to be read.
+	        CharBuffer cbuf = decoder.decode(bbuf);
+	        s = cbuf.toString();
+	        
+	        System.out.println(Integer.toHexString((int)s.charAt(0)));
+	   
+	    return s;
+	}*/
+	
+	static public String  getEncodedChar(int font_encoding,int char_int){
+		
+		String return_character=null; 
+		
+		if(font_encoding== WIN)
+			return_character=WIN_char_encoding_table[char_int];
+		else if(font_encoding==STD)
+			return_character=STD_char_encoding_table[char_int];
+		else if(font_encoding==MAC)
+			return_character=MAC_char_encoding_table[char_int];
+		else if(font_encoding==PDF)
+			return_character=PDF_char_encoding_table[char_int];
+		else if(font_encoding==ZAPF)
+			return_character=ZAPF_char_encoding_table[char_int];
+		else if(font_encoding==SYMBOL)
+			return_character=SYMBOL_char_encoding_table[char_int];	
+		else if(font_encoding==MACEXPERT)
+			return_character=MACEXPERT_char_encoding_table[char_int];
+		
+		if (return_character== null)
+			return_character = "&#" + char_int + ';';
+		
+		return return_character;
+	}
+	
+	/**flag fi a valid mac char - must have loaded mac encoding*/
+	public static boolean isValidMacEncoding(int idx){
+		
+		//if(MAC_char_encoding_table[idx]!=null)
+		//	System.out.println("mac="+MAC_char_encoding_table[idx]);
+		
+		return MAC_char_encoding_table[idx]!=null;
+	}
+	
+	/**flag fi a valid win char - must have loaded win encoding*/
+	public static boolean isValidWinEncoding(int idx){
+
+		//if(WIN_char_encoding_table[idx]!=null)
+		//	System.out.println("win="+WIN_char_encoding_table[idx]);
+		
+        return WIN_char_encoding_table[idx]!=null;
+	}
+	
+	/**load required mappings*/
+	public  static void checkLoaded( int enc) {
+		
+		
+		/**load mapping if we need it and initialise storage*/
+		if((enc==MAC)&&(MAC_char_encoding_table==null)){
+			
+			MAC_char_encoding_table = new String[335];
+			readStandardMappingTable(enc);
+			
+		}else if((enc== WIN)&&(WIN_char_encoding_table==null)){
+			
+			WIN_char_encoding_table = new String[335];
+			readStandardMappingTable(enc);
+			
+		}else if((enc==STD)&&(STD_char_encoding_table==null)){
+			
+			STD_char_encoding_table = new String[335];
+			readStandardMappingTable(enc);
+		
+		}else if((enc==PDF)&&(PDF_char_encoding_table==null)){
+			
+			PDF_char_encoding_table = new String[335];
+			readStandardMappingTable(enc);
+		
+		}else if((enc==SYMBOL)&&(SYMBOL_char_encoding_table==null)){
+			
+			SYMBOL_char_encoding_table = new String[335];
+			readStandardMappingTable(SYMBOL, "symbol.cfg");
+			
+		}else if((enc==ZAPF)&&(ZAPF_char_encoding_table==null)){
+			
+			ZAPF_char_encoding_table = new String[335];
+			readStandardMappingTable(ZAPF, "zapf.cfg");
+			
+		}else if((enc==MACEXPERT)&&(MACEXPERT_char_encoding_table==null)){
+			
+			MACEXPERT_char_encoding_table = new String[335];
+			readStandardMappingTable(MACEXPERT, "mac_expert.cfg");
+			
+		}
+	}
+	
+	/////////////////////////////////////////////////////////////////////////
+	/**
+	 * read default widths for 14 standard fonts supplied
+	 * by Adobe
+	 */
+	final private static void loadStandardFont(int i) throws IOException{
+		String line = "", next_command = "", char_name = "";
+		BufferedReader input_stream = null;
+		float width = 200;
+		//int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
+		//int b_x1 = 0, b_y1 = 0, b_x2 = 0, b_y2 = 0;
+
+		// loop to read widths from default fonts
+		{
+			//open the file
+			input_stream =
+			new BufferedReader(
+					new InputStreamReader(
+							loader.getResourceAsStream(
+									"org/jpedal/res/pdf/defaults/"
+									+ files_names[i]
+									+ ".afm"),
+							enc));
+			
+			boolean char_mapping_table = false;
+			//flag if in correct part of file
+			while (true) { //read the lines and extract width info
+				line = input_stream.readLine();
+				
+				if (line == null)
+					break;
+				if (line.startsWith("EndCharMetrics"))
+					char_mapping_table = false;
+
+				//extract bounding box
+				if (line.startsWith("FontBBox")) {
+
+                    float[] fontBBox=new float[4];
+                    StringTokenizer values = new StringTokenizer(line);
+					//drop FontBBox
+                    values.nextToken();
+
+                    for(int a=0;a<4;a++)
+                    fontBBox[a] = Integer.parseInt(values.nextToken());
+
+                    fontBounds.put(files_names[i],fontBBox);
+
+					
+                }
+				
+				if (char_mapping_table == true) { //extract info from the line
+					StringTokenizer values = new StringTokenizer(line, " ;");
+
+					//extract values
+					while (values.hasMoreTokens()) {
+						next_command = values.nextToken();
+						/**
+						if (next_command.equals("C"))
+							char_number = values.nextToken();*/
+						if (next_command.equals("WX"))
+							width = Float.parseFloat(values.nextToken()) / 1000;
+						else if (next_command.equals("N"))
+							char_name = values.nextToken();
+						/**
+						if (next_command.equals("B")) {
+							x1 = Integer.parseInt(values.nextToken());
+							y1 = Integer.parseInt(values.nextToken());
+							x2 = Integer.parseInt(values.nextToken());
+							y2 = Integer.parseInt(values.nextToken());
+						}*/
+					}
+
+					//store width
+					widthTableStandard.put(files_names_bis[i] + char_name,new Float(width));
+					widthTableStandard.put(files_names[i]  + char_name,new Float(width));
+
+				}
+				if (line.startsWith("StartCharMetrics"))
+					char_mapping_table = true;
+			}
+		}
+		
+		if(input_stream!=null){
+			try{
+				input_stream.close();
+			}catch (Exception e) {
+//				if(LogWriter.isOutput())
+//					LogWriter.writeLog("Exception " + e + " reading lookup table for pdf  for abobe map");
+			}		
+		}
+	}
+	
+	/**
+	 * check if one of 14 standard fonts and if so load widths 
+	 */
+	protected static void loadStandardFontWidth(String fontName){
+		
+		//get name of font if standard
+		Integer fileNumber=(Integer) standardFileList.get(fontName);
+
+
+		if( fileNumber!=null && standardFontLoaded.get(fileNumber)==null){
+
+            standardFontLoaded.put(fileNumber,"x");
+			try{
+				loadStandardFont(fileNumber.intValue());
+			} catch (Exception e) {
+//				if(LogWriter.isOutput())
+//					LogWriter.writeLog("[PDF] " + e + " problem reading lookup table for pdf font "+fontName+ ' ' +fontName);
+			}		
+		}
+	}
+
+	/**
+	 * converts glyph into character index
+	 */
+	public static int lookupCharacterIndex(String glyph,int idx) {
+		
+		Object value=glyphToChar[idx].get(glyph);
+		if(value==null)
+			return 0;
+		else
+			return ((Integer)value).intValue();
+	}
+
+	/**
+	 * load the adobe unicode mapping table for truetype fonts
+	 */
+	private static void loadAdobeMap() {
+		
+		BufferedReader input_stream =null;
+		
+		/**load if not already loaded*/
+		if(adobeMap==null){
+			try {
+				//initialise 
+				adobeMap=new Hashtable();
+			
+				input_stream =new BufferedReader(
+						new InputStreamReader(
+								loader.getResourceAsStream(
+								"org/jpedal/res/pdf/glyphlist.cfg"),
+								enc));
+	
+				// trap problems
+//				if (input_stream == null && LogWriter.isOutput())
+//					LogWriter.writeLog("Unable to open glyphlist.cfg from jar");
+				
+				//read in lines and place in map tables for fast lookup
+				while (true) {
+					String line = input_stream.readLine();
+					if (line == null)
+						break;
+					
+					if((!line.startsWith("#"))&&(line.indexOf(';')!=-1)){
+						
+						StringTokenizer vals=new StringTokenizer(line,";");
+						String key=vals.nextToken();
+						String operand=vals.nextToken();
+						int space=operand.indexOf(' ');
+						if(space!=-1)
+							operand=operand.substring(0,space);
+						int opVal=Integer.parseInt(operand,16);
+						adobeMap.put(key,new Integer(opVal));
+						
+						unicode_name_mapping_table.put(key,Character.toString((char)opVal));
+						
+					}
+				}
+			} catch (Exception e) {
+//				if(LogWriter.isOutput())
+//					LogWriter.writeLog("Exception " + e + " reading lookup table for pdf  for abobe map");
+				e.printStackTrace();
+			}
+		}
+		
+		if(input_stream!=null){
+			try{
+				input_stream.close();
+			}catch (Exception e) {
+//				if(LogWriter.isOutput())
+//					LogWriter.writeLog("Exception " + e + " reading lookup table for pdf  for abobe map");
+			}		
+		}
+		
+	}
+	/**
+	 * @return Returns the adobe mapping for truetype case 3,1
+	 */
+	public static int getAdobeMap(String key){
+
+        Object value=adobeMap.get(key);
+        if(value==null)
+            return -1;
+        else
+            return((Integer)value).intValue();
+		
+	}
+
+    /**
+     * @return Returns a boolean if in Adobe map
+     */
+    public static boolean isValidGlyphName(String key){
+
+        if(key==null)
+            return false;
+        else
+            return(adobeMap.get(key)!=null);
+
+    }
+
+
+    /**
+     * see if a standard font (ie Arial, Helvetica)
+     */
+    public static boolean isStandardFont(String fontName, boolean includeWeights) {
+
+        boolean isStandard=(standardFileList.get(fontName)!=null);
+
+        if(!isStandard && includeWeights){
+
+            int ptr=fontName.indexOf("-");
+            if(ptr!=-1){
+                String rawName=fontName.substring(0,ptr);
+                //System.out.println(ptr+"<>"+fontName+"<>"+rawName+"<>"+standardFileList.get(fontName)!=null);
+                isStandard=(standardFileList.get(rawName)!=null);
+            }
+
+        }
+        return isStandard;
+    }
+
+    /**
+     * open font , read postscript, and return Map with font details
+     */
+//    public static Map getFontDetails(int type, String subFont) {
+//
+//    	Map fontDetails=new HashMap();
+//
+//        /**read in font data*/
+//        if(type==TRUETYPE || type==TRUETYPE_COLLECTION){
+//
+//            TTGlyphs currentFont=new TTGlyphs();
+//
+//            //FontData closed in routine
+//            currentFont.addStringValues(new FontData(subFont),fontDetails);
+//
+//        }
+//
+//        return fontDetails;
+//    }
+    
+    /**
+     * open font , read postscript, family or full names and return array
+     */
+//    public static String[] readNamesFromFont(int type, String subFont,int mode) throws Exception {
+//
+//        String[] fontNames=new String[1];
+//        fontNames[0]="";
+//
+//
+//        /**read in font data*/
+//        if(type==TRUETYPE || type==TRUETYPE_COLLECTION){
+//
+//            TTGlyphs currentFont=new TTGlyphs();
+//
+//          //FontData closed in routine
+//            fontNames=currentFont.readFontNames(new FontData(subFont),mode);
+//
+//        }else if(type==TYPE1){
+//
+//            T1Glyphs currentFont=new T1Glyphs();
+//
+//          //FontData closed in routine
+//            fontNames=currentFont.readFontNames(new FontData(subFont),mode);
+//
+//        }
+//
+//        return fontNames;
+//    }
+
+    //allow for number value as well as glyph name (ie 68 rather than D)
+    public static String convertNumberToGlyph(String mappedChar, boolean containsHexNumbers, boolean allowSingleValue) {
+
+    	int charCount=mappedChar.length();
+
+        boolean isNumber=true; //assume true and disprove
+
+        //System.out.println(mappedChar+" "+containsHexNumbers);
+        
+        if(charCount==2 || charCount==3){
+	        for(int ii=0;ii<charCount;ii++){ //test all values to see if number
+	            char c=mappedChar.charAt(ii);
+	            if(c<'0' || c>'9'){  //fail on first and exit loop
+	                isNumber=false;
+	                ii=charCount;
+	            }
+	        }
+
+            if(isNumber)
+                mappedChar= String.valueOf((char) Integer.parseInt(mappedChar));
+        }
+		/**/
+		
+        return mappedChar;
+    }
+
+    /**
+     * turn hashed key value into String
+     */
+    public static String getFontypeAsString(int fontType) {
+        switch(fontType){
+
+            case TRUETYPE:
+                return "TrueType";        
+            case TYPE1:
+                return "Type1";
+            case TYPE3:
+                return "Type3";
+
+            case CIDTYPE0:
+                return "CIDFontType0";
+            case CIDTYPE2:
+                return "CIDFontType2";
+
+            default:
+                return "Unknown";
+        }
+    }
+
+
+    public static int getIDForGlyphName(String name) {
+        int uc = StandardFonts.getAdobeMap(name);
+        if (uc >= 0) {
+            return uc;
+        } else if (name.startsWith("uni")){
+            name = name.substring(3);
+        } else if (name.charAt(0) == 'u' || name.charAt(0) == 'G'){
+            name = name.substring(1);
+        }
+
+        try {
+            int num = Integer.parseInt(name, 16);
+            return num;
+        } catch (NumberFormatException e) {
+            return -1;
+        }
+    }
+
+}
Index: pdfbox/src/main/java/org/jpedal/fonts/tt/CMAP.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/jpedal/fonts/tt/CMAP.java	(revision )
+++ pdfbox/src/main/java/org/jpedal/fonts/tt/CMAP.java	(revision )
@@ -0,0 +1,614 @@
+/**
+* ===========================================
+* Java Pdf Extraction Decoding Access Library
+* ===========================================
+*
+* Project Info:  http://www.jpedal.org
+* (C) Copyright 1997-2008, IDRsolutions and Contributors.
+*
+* 	This file is part of JPedal
+*
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+*
+* ---------------
+* CMAP.java
+* ---------------
+*/
+package org.jpedal.fonts.tt;
+
+import org.jpedal.fonts.StandardFonts;
+
+import java.util.Hashtable;
+
+public class CMAP extends Table {
+
+	protected int[][] glyphIndexToChar;
+
+    private int[] glyphToIndex;
+
+    //flag 6 and use if not able to map elsewhere
+    private boolean hasSix=false;
+
+	/**used to 'guess' wrongly encoded fonts*/
+	private int winScore=0,macScore=0;
+
+	//used by format 4
+    private int segCount=0;
+
+	/**which type of mapping to use*/
+    private int fontMapping=0;
+
+	//used by format 4
+    protected int[] endCode;
+    protected int[] startCode;
+    protected int[] idDelta;
+    protected int[] idRangeOffset;
+    protected int[] glyphIdArray;
+    private int[] f6glyphIdArray;
+    private int[] offset;
+
+	/**CMap format used -1 shows not set*/
+    protected int[] CMAPformats,CMAPlength,CMAPlang,CMAPsegCount,CMAPsearchRange, CMAPentrySelector,CMAPrangeShift,CMAPreserved;
+
+	private boolean maybeWinEncoded=false;
+
+	/**Platform-specific ID list*/
+//	private static String[] PlatformSpecificID={"Roman","Japanese","Traditional Chinese","Korean",
+//			"Arabic","Hebrew","Greek","Russian",
+//			"RSymbol","Devanagari","Gurmukhi","Gujarati",
+//			"Oriya","Bengali","Tamil","Telugu",
+//			"Kannada","Malayalam","Sinhalese","Burmese",
+//			"Khmer","Thai","Laotian","Georgian",
+//			"Armenian","Simplified Chinese","Tibetan","Mongolian",
+//			"Geez","Slavic","Vietnamese","Sindhi","(Uninterpreted)"};
+//
+	/**Platform-specific ID list*/
+	//private static String[] PlatformIDName={"Unicode","Macintosh","Reserved","Microsoft"};
+
+	/**shows which encoding used*/
+    protected int[] platformID;
+
+	private static Hashtable exceptions;
+
+	/**set up differences from Mac Roman*/
+	static {
+
+		exceptions=new Hashtable();
+
+		String[] values={"notequal","173","infinity","176","lessequal","178","greaterequal","179",
+				"partialdiff","182","summation","183","product","184","pi","185",
+				"integral","186","Omega","189","radical","195","approxequal","197",
+				"Delta","198","lozenge","215","Euro","219","apple","240"};
+		for(int i=0;i<values.length;i=i+2)
+			exceptions.put(values[i],values[i+1]);
+
+	}
+
+	/**which CMAP to use to decode the font*/
+	private int formatToUse;
+
+	/**encoding to use resolving tt font - should be MAC but not always*/
+	private int encodingToUse= StandardFonts.MAC;
+
+	private static boolean WINchecked;
+
+    protected int id,numberSubtables;
+
+    protected int[] CMAPsubtables,platformSpecificID;
+
+	public CMAP(FontFile2 currentFontFile,int startPointer, Glyf currentGlyf){
+
+        final boolean debug=false;
+
+        if(debug)
+                System.out.println("CMAP "+this);
+
+		//LogWriter.writeMethod("{readCMAPTable}", 0);
+
+		//read 'cmap' table
+		if(startPointer==0){
+//			if(LogWriter.isOutput())
+//				LogWriter.writeLog("No CMAP table found");
+		}else{
+
+			id=currentFontFile.getNextUint16();//id
+			numberSubtables=currentFontFile.getNextUint16();
+
+			//read the subtables
+			CMAPsubtables=new int[numberSubtables];
+			platformID=new int[numberSubtables];
+			platformSpecificID=new int[numberSubtables];
+			CMAPformats=new int[numberSubtables];
+            CMAPsearchRange=new int[numberSubtables];
+            CMAPentrySelector=new int[numberSubtables];
+            CMAPrangeShift=new int[numberSubtables];
+            CMAPreserved=new int[numberSubtables];
+            CMAPsegCount=new int[numberSubtables];
+            CMAPlength=new int[numberSubtables];
+            CMAPlang=new int[numberSubtables];
+			glyphIndexToChar =new int[numberSubtables][256];
+
+            glyphToIndex=new int[256];
+
+			for(int i=0;i<numberSubtables;i++){
+
+				platformID[i]=currentFontFile.getNextUint16();
+				platformSpecificID[i]=currentFontFile.getNextUint16();
+				CMAPsubtables[i]=currentFontFile.getNextUint32();
+
+                if(debug)
+					System.out.println("IDs platformID="+platformID[i]+" platformSpecificID="+platformSpecificID[i]+" CMAPsubtables="+CMAPsubtables[i]);
+				//System.out.println(PlatformID[platformID[i]]+" "+PlatformSpecificID[platformSpecificID[i]]+CMAPsubtables[i]);
+
+			}
+
+			//now read each subtable
+			for(int j=0;j<numberSubtables;j++){
+                currentFontFile.selectTable(FontFile2.CMAP);
+				currentFontFile.skip(CMAPsubtables[j]);
+
+				//assume 16 bit format to start
+				CMAPformats[j]=currentFontFile.getNextUint16();
+				CMAPlength[j]=currentFontFile.getNextUint16();
+				CMAPlang[j]=currentFontFile.getNextUint16();//lang
+
+                if(debug)
+                        System.out.println(j+" type="+CMAPformats[j]+" length="+CMAPlength[j]+" lang="+CMAPlang[j]);
+				//flag if present
+				if(CMAPformats[j]==6)
+					hasSix=true;
+
+				if(CMAPformats[j]==0 && CMAPlength[j]==262){
+
+					StandardFonts.checkLoaded(StandardFonts.WIN);
+					StandardFonts.checkLoaded(StandardFonts.MAC);
+
+					//populate table and get valid glyphs
+					//Map uniqueFontMappings=StandardFonts.getUniqueMappings(); //win or mac only values we check for
+					//int total=0;
+
+					boolean isValidOnMac,isValidOnWin;
+
+					for(int glyphNum=0;glyphNum<256;glyphNum++){
+
+						int index=currentFontFile.getNextUint8();
+                        glyphIndexToChar[j][glyphNum]=index;
+                        glyphToIndex[index]=glyphNum;
+
+						/**count to try and guess if wrongly encoded*/
+						if(index>0){//&&(currentGlyf.isPresent(index))){
+
+							isValidOnMac=StandardFonts.isValidMacEncoding(glyphNum);
+							isValidOnWin=StandardFonts.isValidWinEncoding(glyphNum);
+
+							//if any different flag it up
+							if(isValidOnMac!=isValidOnWin)
+								maybeWinEncoded=true;
+
+
+							//System.out.println(Integer.toOctalString(index)+" "+glyphNum+" "+StandardFonts.isValidMacEncoding(glyphNum)+" "+StandardFonts.isValidWinEncoding(glyphNum));
+							/**/
+							if(isValidOnMac){
+								macScore++;
+							}//else
+							//	System.out.println(glyphNum+" not MAC");
+
+							if(isValidOnWin){
+								winScore++;
+							}//else
+							//	System.out.println(glyphNum+" now WIN");
+
+							//cumulative WIN or MAC only values found
+//							Object uniqueness=uniqueFontMappings.get(new Integer(glyphNum));
+//							if(uniqueness!=null){// will give a +1 (mac only) or -1 (win only) to total
+//								total=total+((Integer) uniqueness).intValue();
+//								//System.out.println(glyphNum+" >>"+((Integer) uniqueness).intValue());
+//							}
+						}
+					}
+
+					//switch to win only if scored several win only values
+//					System.out.println("total="+total+" macScore="+macScore+" winScore="+winScore);
+//					if(total<-2){
+//						macScore=98;
+//						winScore=99;
+//					}
+
+					//System.out.println("mac="+macScore+" win="+winScore);
+
+				}else if(CMAPformats[j]==4){
+
+					//read values
+					CMAPsegCount[j] = currentFontFile.getNextUint16();
+                    segCount=CMAPsegCount[j]/2;
+					CMAPsearchRange[j]=currentFontFile.getNextUint16(); //searchrange
+					CMAPentrySelector[j]=currentFontFile.getNextUint16();//entrySelector
+					CMAPrangeShift[j]=currentFontFile.getNextUint16();//rangeShift
+
+					//read tables and initialise size of arrays
+					endCode = new int[segCount];
+					for (int i = 0; i < segCount; i++)
+						endCode[i] = currentFontFile.getNextUint16();
+
+					CMAPreserved[j]=currentFontFile.getNextUint16(); //reserved (should be zero)
+
+					startCode = new int[segCount];
+					for (int i = 0; i < segCount; i++)
+						startCode[i] =currentFontFile.getNextUint16();
+
+					idDelta = new int[segCount];
+					for (int i = 0; i < segCount; i++)
+						idDelta[i] = currentFontFile.getNextUint16();
+
+
+					idRangeOffset = new int[segCount];
+					for (int i = 0; i < segCount; i++)
+						idRangeOffset[i] = currentFontFile.getNextUint16();
+
+					/**create offsets*/
+					offset = new int[segCount];
+					int diff,cumulative=0;
+
+					for (int i = 0; i < segCount; i++) {
+
+//                        System.out.println("seg="+i+" cumulative="+cumulative+
+//                                " idDelta[i]="+idDelta[i]+" startCode[i]="+startCode[i]+
+//                        " endCode[i]="+endCode[i]);
+//
+                        if(idDelta[i]==0){// && startCode[i]!=endCode[i]){
+							offset[i]=cumulative;
+							diff=1+endCode[i]-startCode[i];
+
+                            //fixes bug in mapping theSansOffice tff font
+                            if(startCode[i]==endCode[i] && idRangeOffset[i]==0)
+                            diff=0;
+
+                            cumulative=cumulative+diff;
+						}
+					}
+
+					// glyphIdArray at end
+					int count = (CMAPlength[j] -16-(segCount*8)) / 2;
+
+					glyphIdArray = new int[count];
+                    for (int i = 0; i < count; i++){
+						glyphIdArray[i] =currentFontFile.getNextUint16();
+                    }
+
+				}else if(CMAPformats[j]==6){
+					int firstCode=currentFontFile.getNextUint16();
+					int entryCount=currentFontFile.getNextUint16();
+
+					f6glyphIdArray = new int[firstCode+entryCount];
+					for(int jj=0;jj<entryCount;jj++)
+						f6glyphIdArray[jj+firstCode]=currentFontFile.getNextUint16();
+
+				}else{
+					//System.out.println("Unsupported Format "+CMAPformats[j]);
+					//reset to avoid setting
+					CMAPformats[j]=-1;
+
+				}
+
+				//System.out.println(" <> "+platformID[j]);
+				//System.out.println(CMAPformats[j]+" "+platformID[j]+" "+platformSpecificID[j]+" "+PlatformIDName[platformID[j]]);
+
+			}
+		}
+
+		/**validate format zero encoding*/
+		//if(formatFour!=-1)
+		//validateMacEncoding(formatZero,formatFour);
+
+	}
+
+    public CMAP() {
+    }
+
+
+    /**convert raw glyph number to Character code*/
+	public int convertIndexToCharacterCode(String glyph,int index,boolean remapFont,boolean isSubsetted, String[] diffTable){
+
+		int index2=-1, rawIndex=index;
+        int format=CMAPformats[formatToUse];
+
+        final boolean debugMapping=false;//(index==223);
+
+        if(debugMapping)
+        System.out.println(glyph+" fontMapping="+fontMapping+" index="+index+" encodingToUse="+encodingToUse+ ' ' +encodingToUse+" WIN="+StandardFonts.WIN +" MAC="+StandardFonts.MAC);
+
+        /**convert index if needed*/
+		if((fontMapping==1 || (!remapFont &&fontMapping==4))&&(glyph!=null)&&(!glyph.equals("notdef"))){
+
+			index=StandardFonts.getAdobeMap(glyph);
+
+            if(debugMapping)
+            System.out.println("convert index");
+
+
+        }else if (fontMapping==2){
+
+            StandardFonts.checkLoaded(encodingToUse);
+
+			if(encodingToUse==StandardFonts.MAC){
+
+				Object exception=null;
+				if(glyph!=null)
+				    exception=exceptions.get(glyph);
+
+				if(exception==null){
+				    if(glyph!=null && !isSubsetted)
+					index=StandardFonts.lookupCharacterIndex(glyph,encodingToUse);
+				}else if(diffTable==null || diffTable[index]==null){ //not if a diff
+					try{
+					index=Integer.parseInt(((String)exception));
+					}catch(Exception ee){
+					}
+				}
+				//win indexed just incase
+				if(glyph!=null){
+					if(!WINchecked){
+						StandardFonts.checkLoaded(StandardFonts.WIN);
+						WINchecked=true;
+					}
+					index2=StandardFonts.lookupCharacterIndex(glyph,StandardFonts.WIN);
+				}
+			}else if(glyph!=null)
+				index=StandardFonts.lookupCharacterIndex(glyph,encodingToUse);
+		}
+
+        int value=-1;
+
+
+        //remap if flag set
+		if(remapFont && format>0 && format!=6)
+			index=index + 0xf000;
+
+		//if no cmap use identity
+		if(format==0){
+
+			//hack
+			if(index>255)
+				index=0;
+
+			value= glyphIndexToChar[formatToUse][index];
+			if(value==0 && index2!=-1)
+				value= glyphIndexToChar[formatToUse][index2];
+
+            //exception found in Itext
+			if(rawIndex==128 && endCode!=null && glyph.equals("Euro"))
+			    value=getFormat4Value(8364, debugMapping, value);
+                
+
+		}else	if(format==4){
+
+			
+            value = getFormat4Value(index, debugMapping, value);
+
+            //hack for odd value in customer file
+            if(value==-1){
+
+				if(index>0xf000)
+					value = getFormat4Value(index - 0xf000, debugMapping, value);
+				else
+					value = getFormat4Value(index + 0xf000, debugMapping, value);
+
+			}
+        }
+
+		//second attempt if no value found
+		if(value==-1 && hasSix){
+			index=rawIndex;
+			format=6;
+		}
+
+		if(format==6){
+			if(index>=f6glyphIdArray.length)
+				value=0;
+			else
+				value=f6glyphIdArray[index];
+		}
+
+	//	System.out.println(value+" format="+format);
+
+        if(debugMapping)
+        System.out.println("returns "+value+" "+this);
+        
+        return value;
+	}
+
+    private int getFormat4Value(int index, boolean debugMapping, int value) {
+        for (int i = 0; i < segCount; i++) {
+
+            if(debugMapping)
+            System.out.println("Segtable="+i+" start="+startCode[i]+" "+index+
+                    " end="+endCode[i]+" idRangeOffset[i]="+idRangeOffset[i]+
+                    " offset[i]="+offset[i]+" idRangeOffset[i]="+idRangeOffset[i]+" idDelta[i]="+idDelta[i]);
+
+            if (endCode[i] >= index && startCode[i] <= index){
+
+                int idx ;
+                if (idRangeOffset[i] == 0) {
+
+                    if(debugMapping)
+                    System.out.println("xxx="+(idDelta[i] + index));
+
+                    value= (idDelta[i] + index) % 65536;
+
+                    i=segCount;
+                }else{
+
+                    idx= offset[i]+(index - startCode[i]);
+                    value=glyphIdArray[idx];
+
+                    if(debugMapping)
+                    System.out.println("value="+value+" idx="+
+                            idx+" glyphIdArrays="+glyphIdArray[0]+" "+
+                            glyphIdArray[1]+" "+glyphIdArray[2]+" offset[i]="+offset[i]+
+                    " index="+index+" startCode["+i+"]="+startCode[i]+" i="+i);
+
+                    i=segCount;
+
+                }
+            }
+        }
+        
+        return value;
+    }
+
+    /**
+	 * work out correct CMAP table to use.
+	 */
+	public void setEncodingToUse(boolean hasEncoding,int fontEncoding,boolean isSubstituted,boolean isCID) {
+
+        final boolean encodingDebug=false;
+
+        if(encodingDebug)
+        System.out.println(this+ "hasEncoding="+hasEncoding+" fontEncoding="+fontEncoding+" isSubstituted="+isSubstituted+" isCID="+isCID+"  macScore="+macScore);
+
+        formatToUse=-1;
+
+
+        int count=platformID.length;
+
+		//this code changes encoding to WIN if that appears to be encoding used in spite of being MAC
+		if(!isSubstituted && macScore<207){
+			
+			//System.out.println(macScore+" winScore="+winScore+" count="+count+" "+hasEncoding+"  "+fontEncoding+"  "+StandardFonts.WIN);
+
+			if(glyphToIndex!=null && macScore>90 && !maybeWinEncoded){
+                //System.out.println("Its Mac");
+
+			}else if(glyphToIndex!=null && macScore>205 && glyphToIndex[138]!=0 && glyphToIndex[228]==0 ){
+                //System.out.println("Its Mac");
+            }else{
+
+			if(count>0 && winScore>macScore)
+			this.encodingToUse=StandardFonts.WIN;
+
+			if(macScore>80 && hasEncoding && fontEncoding==StandardFonts.WIN && winScore>=macScore)
+				encodingToUse=StandardFonts.WIN;
+			}
+        }
+
+		//System.out.println(isSubstituted+" "+encodingToUse+" WIN="+StandardFonts.WIN+" MAC="+StandardFonts.MAC);
+
+        if(encodingDebug)
+                System.out.println("macScore="+macScore+" winScore="+winScore+" count="+count+" isSubstituted="+isSubstituted);
+
+        /**case 1 */
+        for(int i=0;i<count;i++){
+            if(encodingDebug)
+            System.out.println("Maps="+platformID[i]+" "+CMAPformats[i]);
+            if((platformID[i]==3)&&(CMAPformats[i]==1 || CMAPformats[i]==0)){
+                formatToUse=i;
+                this.fontMapping=1;
+                i=count;
+                //StandardFonts.loadAdobeMap();
+
+                if(encodingDebug)
+                System.out.println("case1");
+                
+            }
+        }
+
+        /**case 2*/
+        boolean wasCase2=false;
+        if(formatToUse==-1 && ((macScore>0 && winScore>0)|| CMAPformats.length==1) && !isCID && (!isSubstituted ||(CMAPformats.length==1 && CMAPformats[0]==0))){
+
+			for(int i=0;i<count;i++){
+				if(platformID[i]==1 && CMAPformats[i]==0){
+					formatToUse=i;
+					if(hasEncoding || fontEncoding==StandardFonts.WIN)
+						fontMapping=2;
+					else
+						fontMapping=3;
+
+					i=count;
+
+					wasCase2=true;
+                }
+			}
+
+            if(encodingDebug)
+                System.out.println("case2 fontMapping="+fontMapping+" "+glyphIndexToChar[formatToUse][175]+" "+glyphIndexToChar[formatToUse][223]);
+        }
+
+        
+        /**case 3 - no MAC cmap in other ranges and substituting font */
+        boolean wasCase3=false;
+        if(formatToUse==-1){
+			for(int i=0;i<count;i++){
+				//if((platformID[i]==1)&&(CMAPformats[i]==6)){ Altered 20050921 to fix problem with Doucsign page
+				if((CMAPformats[i]==6)){
+					formatToUse=i;
+					if((!hasEncoding)&&(fontEncoding==StandardFonts.WIN)){
+						fontMapping=2;
+						StandardFonts.checkLoaded(StandardFonts.MAC);
+					}else
+						fontMapping=6;
+
+                    wasCase3=true;
+                    i=count;
+				}
+			}
+
+            if(encodingDebug)
+                System.out.println("case3");
+        }
+
+        /**case 4 - no simple maps or prefer to last 1*/
+        /**last check uses fl glyph and sticks to case 1 if found*/
+        if((formatToUse==-1) ||  wasCase3 || (wasCase2 && !(glyphIndexToChar[formatToUse][223]!=0 && getFormat4Value(223, false, 0)==0))){// || glyphIndexToChar[formatToUse][223]==0){//&&((!isSubstituted)|(isCID))){
+		//if((formatToUse==-1)){
+			for(int i=0;i<count;i++){
+				if((CMAPformats[i]==4)){
+					formatToUse=i;
+					fontMapping=4;
+					
+					i=count;
+					
+				}
+			}
+
+            if(encodingDebug)
+                System.out.println("case4 fontMapping="+fontMapping+" formatToUse="+formatToUse);
+        }
+
+		//System.out.println(formatToUse+" " +fontMapping);
+
+		if(fontEncoding==StandardFonts.ZAPF){
+			fontMapping=2;
+
+            if(encodingDebug)
+                System.out.println("Zapf");
+        }
+
+		//further tests
+		if(encodingToUse==StandardFonts.WIN && macScore==winScore &&
+				glyphIndexToChar[formatToUse][146]==0 && glyphIndexToChar[formatToUse][213]!=0){ //quoteright
+			encodingToUse=StandardFonts.MAC;
+		}
+
+        //System.out.println("enc="+encodingToUse+" "+glyphIndexToChar[formatToUse][138]+" "+glyphIndexToChar[formatToUse][228]+" mac="+macScore+" win="+winScore);
+
+        if(encodingToUse==StandardFonts.WIN && macScore==winScore &&
+				glyphIndexToChar[formatToUse][228]==0 && glyphIndexToChar[formatToUse][138]!=0){ //adieresis
+			encodingToUse=StandardFonts.MAC;
+		}
+    }
+}
Index: pdfbox/src/main/java/org/jpedal/fonts/tt/Glyf.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pdfbox/src/main/java/org/jpedal/fonts/tt/Glyf.java	(revision )
+++ pdfbox/src/main/java/org/jpedal/fonts/tt/Glyf.java	(revision )
@@ -0,0 +1,106 @@
+/**
+* ===========================================
+* Java Pdf Extraction Decoding Access Library
+* ===========================================
+*
+* Project Info:  http://www.jpedal.org
+* (C) Copyright 1997-2008, IDRsolutions and Contributors.
+*
+* 	This file is part of JPedal
+*
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+*
+* ---------------
+* Glyf.java
+* ---------------
+*/
+package org.jpedal.fonts.tt;
+
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+
+
+public class Glyf extends Table {
+	
+	/**holds mappings for drawing the glpyhs*/
+	private Hashtable charStrings=new Hashtable();
+
+    private int glyfCount=0;
+
+	/**holds list of empty glyphs*/
+	private Map emptyCharStrings=new HashMap();
+    private byte[] glyphTable;
+	
+	public Glyf(FontFile2 currentFontFile,int glyphCount,int[] glyphIndexStart){
+	
+        //save so we can access
+        this.glyfCount=glyphCount;
+
+		//move to start and check exists
+		int startPointer=currentFontFile.selectTable(FontFile2.LOCA);
+		
+		//read  table
+		if(startPointer!=0){
+			
+			//read each gyf
+			for(int i=0;i<glyphCount;i++){
+				
+				//just store in lookup table or flag as zero length
+				if((glyphIndexStart[i]==glyphIndexStart[i+1])){
+					charStrings.put(new Integer(i),new Integer(-1));
+					emptyCharStrings.put(new Integer(i),"x");
+				}else{
+					charStrings.put(new Integer(i),new Integer(glyphIndexStart[i]));
+				}
+			}
+            
+            //read the actual glyph data
+            glyphTable=currentFontFile.getTableBytes(FontFile2.GLYF);
+                    
+		}
+	}
+
+	public boolean isPresent(int glyph){
+		
+		Integer key=new Integer(glyph);
+		
+        Object value=charStrings.get(key);
+
+        return value!=null && emptyCharStrings.get(key)==null;
+	}
+	
+	public int getCharString(int glyph){
+		
+        Object value=charStrings.get(new Integer(glyph));
+
+
+        if(value==null)
+			return glyph;
+		else
+			return ((Integer) value).intValue();
+	}
+	
+    public byte[] getTableData() {
+        return glyphTable;
+    }
+
+    public int getGlypfCount() {
+        return glyfCount;
+    }
+}
