Index: /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java
===================================================================
--- /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java	(revision 631408)
+++ /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java	(working copy)
@@ -78,8 +78,7 @@
     protected static IOFileFilter getFileFilter() {
         return FileFilterUtils.andFileFilter(
                 FileFilterUtils.fileFileFilter(),
-                new WildcardFileFilter(new String[] {"*.ttf", "*.otf", "*.pfb"}, IOCase.INSENSITIVE)
-                //TODO Add *.ttc when support for it has been added to the auto-detection mech.
+                new WildcardFileFilter(new String[] {"*.ttf", "*.otf", "*.pfb", "*.ttc"}, IOCase.INSENSITIVE)
         );
     }
     
Index: /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java
===================================================================
--- /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java	(revision 631408)
+++ /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java	(working copy)
@@ -20,11 +20,14 @@
 package org.apache.fop.fonts.autodetect;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.URL;
 import java.net.URLConnection;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.regex.Pattern;
 
@@ -41,6 +44,9 @@
 import org.apache.fop.fonts.FontResolver;
 import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.fonts.FontUtil;
+import org.apache.fop.fonts.truetype.FontFileReader;
+import org.apache.fop.fonts.truetype.TTFFile;
+import org.apache.fop.fonts.truetype.TTFFontLoader;
 
 /**
  * Attempts to determine correct FontInfo
@@ -133,6 +139,7 @@
         embedUrl = fontUrl.toExternalForm();
         EmbedFontInfo fontInfo = new EmbedFontInfo(null, customFont.isKerningEnabled(),
                 fontTripletList, embedUrl);
+        fontInfo.setPostScriptName(customFont.getFontName());        
         if (fontCache != null) {
             fontCache.addFont(fontInfo);
         }
@@ -145,9 +152,14 @@
      * @param fontUrl font URL. Assumed to be local.
      * @param resolver font resolver used to resolve font
      * @param fontCache font cache (may be null)
-     * @return newly created embed font info
+     * @return list of newly created embed font info.  Generally, this list
+     *         will have only one entry, unless the fontUrl is a TTC
      */
-    public EmbedFontInfo find(URL fontUrl, FontResolver resolver, FontCache fontCache) {
+    public List find(URL fontUrl, FontResolver resolver, FontCache fontCache) {
+    	
+//    	List<EmbedFontInfo> embedFontInfoList = new java.util.ArrayList<EmbedFontInfo>();
+    	List embedFontInfoList = new java.util.ArrayList();
+    	
         String embedUrl = null;
         embedUrl = fontUrl.toExternalForm();
         
@@ -168,13 +180,35 @@
             }
             // firstly try and fetch it from cache before loading/parsing the font file
             if (fontCache.containsFont(embedUrl)) {
-                CachedFontInfo fontInfo = fontCache.getFont(embedUrl);
-                if (fontInfo.lastModified() == fileLastModified) {
-                    return fontInfo;
+                
+                FontCache.CachedFontFile cachedFontInfos =  fontCache.getFontFile(embedUrl);
+                boolean allUpToDate = true; // until proven otherwise
+                
+//                for (CachedFontInfo fontInfo : cachedFontInfos.getFilefontsMap().values()) {
+                
+        		Iterator cachedFontInfosIterator = cachedFontInfos.getFilefontsMap().entrySet().iterator();
+        	    while (cachedFontInfosIterator.hasNext()) {
+        	        Map.Entry pairs = (Map.Entry)cachedFontInfosIterator.next();
+        	        CachedFontInfo fontInfo = (CachedFontInfo)pairs.getValue(); 
+                
+	                if (fontInfo.lastModified() == fileLastModified) {
+	                	embedFontInfoList.add(fontInfo);
+	                } else {
+	                    // out of date cache item
+	                    fontCache.removeFont(embedUrl);
+	                    allUpToDate = false;
+	                    continue;
+	                }
+                }
+                
+                if (allUpToDate) {
+                	return embedFontInfoList;
                 } else {
-                    // out of date cache item
-                    fontCache.removeFont(embedUrl);
+                	// Start again
+//                	embedFontInfoList = new java.util.ArrayList<EmbedFontInfo>();                	
+                	embedFontInfoList = new java.util.ArrayList();                	
                 }
+                
             // is this a previously failed parsed font?
             } else if (fontCache.isFailedFont(embedUrl, fileLastModified)) {
                 if (log.isDebugEnabled()) {
@@ -184,20 +218,81 @@
             }
         }
         
+        
         // try to determine triplet information from font file
         CustomFont customFont = null;
-        try {
-            customFont = FontLoader.loadFont(fontUrl, resolver);
-        } catch (Exception e) {
-            //TODO Too verbose (it's an error but we don't care if some fonts can't be loaded)
-            if (log.isErrorEnabled()) {
-                log.error("Unable to load font file: " + embedUrl + ". Reason: " + e.getMessage());
+        
+        if (fontUrl.toExternalForm().endsWith(".ttc")) {
+        	
+        	// Get a list of the TTC Font names
+//        	List<String> ttcNames = null;
+        	List ttcNames = null;
+        	String fontFileURI = fontUrl.toExternalForm().trim();
+        	TTFFontLoader ttfLoader = new TTFFontLoader(fontFileURI, resolver);
+            InputStream in = null;         	
+            try {
+            	in = FontLoader.openFontUri(resolver, fontFileURI);
+                TTFFile ttf = new TTFFile();
+                FontFileReader reader = new FontFileReader(in);
+                ttcNames = ttf.getTTCnames(reader);
+            } catch (Exception e) {
+            	log.error(e);
+            } finally {
+                IOUtils.closeQuietly(in);
             }
-            if (fontCache != null) {
-                fontCache.registerFailedFont(embedUrl, fileLastModified);
+        	
+        	// For each font name ...
+        	//for (String fontName : ttcNames) {
+
+    		Iterator ttcNamesIterator = ttcNames.iterator();
+    	    while (ttcNamesIterator.hasNext()) {
+    	    	
+    	    	String fontName = (String)ttcNamesIterator.next();        		
+        		
+        		log.debug("Loading " + fontName);
+	            try {
+	            	ttfLoader = new TTFFontLoader(fontFileURI, resolver);
+	                ttfLoader.read(fontName);
+	                customFont = ttfLoader.getFont();
+	            } catch (Exception e) {
+	                //TODO Too verbose (it's an error but we don't care if some fonts can't be loaded)
+	                //if (log.isErrorEnabled()) {
+	                    log.error("Unable to load font file: " + embedUrl + ". Reason: " + e.getMessage());
+	                //}
+	                if (fontCache != null) {
+	                    fontCache.registerFailedFont(embedUrl, fileLastModified);
+	                }
+	                continue;
+	            }
+	            EmbedFontInfo fi = fontInfoFromCustomFont(fontUrl, customFont, fontCache);
+	            if (fi!=null) {
+	            	embedFontInfoList.add(fi);
+	            } 
+        	}
+        	return embedFontInfoList;
+        } else {
+        	// The normal case
+            try {
+                customFont = FontLoader.loadFont(fontUrl, resolver);
+            } catch (Exception e) {
+                //TODO Too verbose (it's an error but we don't care if some fonts can't be loaded)
+                //if (log.isErrorEnabled()) {
+                    log.error("Unable to load font file: " + embedUrl + ". Reason: " + e.getMessage());
+                //}
+                if (fontCache != null) {
+                    fontCache.registerFailedFont(embedUrl, fileLastModified);
+                }
+                return null;
             }
-            return null;
+            EmbedFontInfo fi = fontInfoFromCustomFont(fontUrl, customFont, fontCache);
+            if (fi!=null) {
+            	embedFontInfoList.add(fi);
+                return embedFontInfoList;        	
+            } else {
+            	return null;
+            }        	
         }
-        return fontInfoFromCustomFont(fontUrl, customFont, fontCache);     
+        
+
     }
 }
Index: /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/CachedFontInfo.java
===================================================================
--- /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/CachedFontInfo.java	(revision 631408)
+++ /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/CachedFontInfo.java	(working copy)
@@ -86,6 +86,10 @@
      */
     public CachedFontInfo(EmbedFontInfo fontInfo) {
         super(fontInfo.metricsFile, fontInfo.kerning, fontInfo.fontTriplets, fontInfo.embedFile);
+        
+        // We need to cache our extra stuff as well!
+        setPostScriptName(fontInfo.getPostScriptName());        
+        
         // try and determine modified date
         File fontFile = getFileFromUrls(new String[] {embedFile, metricsFile});
         if (fontFile != null ) {

Index: /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/EmbedFontInfo.java
===================================================================
--- /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/EmbedFontInfo.java	(revision 631408)
+++ /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/EmbedFontInfo.java	(working copy)
@@ -38,6 +38,14 @@
     protected boolean kerning;
     /** the list of associated font triplets */
     protected List fontTriplets;
+        
+	protected String postScriptName = null;
+	public String getPostScriptName() {
+		return postScriptName;
+	}
+	public void setPostScriptName(String postScriptName) {
+		this.postScriptName = postScriptName;
+	}
       
     /**
      * Main constructor
Index: /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/FontCache.java
===================================================================
--- /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/FontCache.java	(revision 631408)
+++ /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/FontCache.java	(working copy)
@@ -27,6 +27,9 @@
 import java.io.OutputStream;
 import java.io.Serializable;
 import java.util.Map;
+import java.util.ArrayList;
+import java.util.List;
+
 
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
@@ -61,11 +64,17 @@
     /** change lock */
     private transient Object changeLock = new Object();
     
-    /** master mapping of font url -> font info */
-    private Map fontMap = new java.util.HashMap();
+    /** master mapping of font url -> font info.  This needs to be
+     *  a list, since a TTC file may contain more than 1 font. */
+//    private Map<String, CachedFontFile> fontfileMap 
+//    			= new java.util.HashMap<String, CachedFontFile>();
+    private Map fontfileMap 
+    			= new java.util.HashMap();
 
     /** mapping of font url -> file modified date */
     private Map failedFontMap = new java.util.HashMap();
+	// Really, its a failed URL map
+
 
     /**
      * Default constructor
@@ -216,7 +225,7 @@
      */
     public boolean containsFont(String embedUrl) {
         if (embedUrl != null) {
-            return fontMap.containsKey(embedUrl);
+            return fontfileMap.containsKey(embedUrl);
         }
         return false;
     }
@@ -228,7 +237,7 @@
      */
     public boolean containsFont(EmbedFontInfo fontInfo) {
         if (fontInfo != null) {
-            return fontMap.containsKey(getCacheKey(fontInfo));
+            return fontfileMap.containsKey(getCacheKey(fontInfo));
         }
         return false;
     }
@@ -240,7 +249,14 @@
     public void addFont(EmbedFontInfo fontInfo) {
         String cacheKey = getCacheKey(fontInfo);
         synchronized (changeLock) {
-            if (!containsFont(cacheKey)) {
+        	CachedFontFile cachedFontFile;
+        	if (containsFont(cacheKey)) {
+        		cachedFontFile = (CachedFontFile)fontfileMap.get(cacheKey);        		
+        		if (!cachedFontFile.containsFont(fontInfo.getPostScriptName() ) ) {
+        			cachedFontFile.put(new CachedFontInfo(fontInfo));	
+        		}        	
+        	} else {
+        		cachedFontFile = new CachedFontFile();
                 if (log.isTraceEnabled()) {
                     log.trace("Font added to cache: " + cacheKey);
                 }
@@ -245,10 +261,11 @@
                     log.trace("Font added to cache: " + cacheKey);
                 }
                 if (fontInfo instanceof CachedFontInfo) {
-                    fontMap.put(cacheKey, fontInfo);
+                	cachedFontFile.put((CachedFontInfo)fontInfo);
                 } else {
-                    fontMap.put(cacheKey, new CachedFontInfo(fontInfo));
+                	cachedFontFile.put(new CachedFontInfo(fontInfo));                	
                 }
+                fontfileMap.put(cacheKey, cachedFontFile);
                 changed = true;
             }
         }
@@ -257,11 +274,11 @@
     /**
      * returns a font from the cache
      * @param embedUrl font info
-     * @return boolean
+     * @return CachedFontFile object 
      */
-    public CachedFontInfo getFont(String embedUrl) {
+    public CachedFontFile getFontFile(String embedUrl) {
         if (containsFont(embedUrl)) {
-            return (CachedFontInfo)fontMap.get(embedUrl);
+            return (CachedFontFile)fontfileMap.get(embedUrl);
         }
         return null;
     }
@@ -276,7 +293,7 @@
                 if (log.isTraceEnabled()) {
                     log.trace("Font removed from cache: " + embedUrl);
                 }
-                fontMap.remove(embedUrl);
+                fontfileMap.remove(embedUrl);
                 changed = true;
             }
         }
@@ -289,6 +306,7 @@
      * @return whether this is a failed font
      */
     public boolean isFailedFont(String embedUrl, long lastModified) {
+    	    	
         if (failedFontMap.containsKey(embedUrl)) {
             synchronized (changeLock) {
                 long failedLastModified = ((Long)failedFontMap.get(embedUrl)).longValue();
@@ -326,7 +344,7 @@
             if (log.isTraceEnabled()) {
                 log.trace("Font cache cleared.");
             }
-            fontMap.clear();
+            fontfileMap.clear();
             failedFontMap.clear();
             changed = true;
         }
@@ -331,4 +349,30 @@
             changed = true;
         }
     }
+    
+    public class CachedFontFile implements Serializable {
+    	
+//        private Map<String, CachedFontInfo> filefontsMap 
+//			= new java.util.HashMap<String, CachedFontInfo>();
+        private Map filefontsMap 
+		= new java.util.HashMap();
+        
+        void put(CachedFontInfo efi) {
+        	filefontsMap.put(efi.getPostScriptName(), efi);
+        }
+    	
+        public boolean containsFont(String fontName) {
+            if (fontName != null) {
+                return filefontsMap.containsKey(fontName);
+            }
+            return false;
+        }
+
+//		public Map<String, CachedFontInfo> getFilefontsMap() {
+		public Map getFilefontsMap() {
+			return filefontsMap;
+		}
+        
+    	
+    }
 }
Index: /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/FontLoader.java
===================================================================
--- /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/FontLoader.java	(revision 631408)
+++ /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/FontLoader.java	(working copy)
@@ -121,7 +121,7 @@
      * @throws IOException In case of an I/O error
      * @throws MalformedURLException If an invalid URL is built
      */
-    protected static InputStream openFontUri(FontResolver resolver, String uri) 
+    public static InputStream openFontUri(FontResolver resolver, String uri) 
                     throws IOException, MalformedURLException {
         InputStream in = null;
         if (resolver != null) {

Index: /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/truetype/TTFFile.java
===================================================================
--- /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/truetype/TTFFile.java	(revision 631408)
+++ /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/truetype/TTFFile.java	(working copy)
@@ -30,6 +30,7 @@
 
 import org.apache.xmlgraphics.fonts.Glyphs;
 
+import org.apache.fop.fonts.EmbedFontInfo;
 import org.apache.fop.fonts.FontUtil;
 
 /**
@@ -988,7 +989,10 @@
         if (dirTabs.get("OS/2") != null) {
             seekTab(in, "OS/2", 2 * 2);
             this.usWeightClass = in.readTTFUShort();
+            
+            // usWidthClass
             in.skip(2);
+            
             int fsType = in.readTTFUShort();
             if (fsType == 2) {
                 isEmbeddable = false;
@@ -1474,6 +1478,68 @@
         }
     }
 
+    /**
+     * Return TTC font names
+     * @param in FontFileReader to read from
+     * @return True if not collection or font name present, false otherwise
+     * @throws IOException In case of an I/O problem
+     */
+    public final List getTTCnames(FontFileReader in) throws IOException {
+//        public final List<String> getTTCnames(FontFileReader in) throws IOException {
+    	
+//    	List<String> fontNames = new java.util.ArrayList<String>();
+    	List fontNames = new java.util.ArrayList();
+    	
+        String tag = in.readTTFString(4);
+
+        if ("ttcf".equals(tag)) {
+            // This is a TrueType Collection
+            in.skip(4);
+
+            // Read directory offsets
+            int numDirectories = (int)in.readTTFULong();
+            // int numDirectories=in.readTTFUShort();
+            long[] dirOffsets = new long[numDirectories];
+            for (int i = 0; i < numDirectories; i++) {
+                dirOffsets[i] = in.readTTFULong();
+            }
+
+            log.info("This is a TrueType collection file with "
+                                   + numDirectories + " fonts");
+            log.info("Containing the following fonts: ");
+            // Read all the directories and name tables to check
+            // If the font exists - this is a bit ugly, but...
+            boolean found = false;
+
+            // Iterate through all name tables even if font
+            // Is found, just to show all the names
+            long dirTabOffset = 0;
+            for (int i = 0; (i < numDirectories); i++) {
+                in.seekSet(dirOffsets[i]);
+                readDirTabs(in);
+
+                readName(in);
+
+                log.info(fullName);
+                fontNames.add(fullName);
+
+                // Reset names
+                notice = "";
+                fullName = "";
+                familyNames.clear();
+                postScriptName = "";
+                subFamilyName = "";
+            }
+
+            in.seekSet(0);
+            return fontNames;
+        } else {
+        	log.error("Not a TTC!");
+        	return null;
+        }
+    }
+    
+    
     /*
      * Helper classes, they are not very efficient, but that really
      * doesn't matter...
Index: /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
===================================================================
--- /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java	(revision 631408)
+++ /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java	(working copy)
@@ -51,6 +51,10 @@
     
     /** {@inheritDoc} */
     protected void read() throws IOException {
+        read(null);
+    }
+
+    public void read(String ttcFontName) throws IOException {
         InputStream in = openFontUri(resolver, this.fontFileURI);
         try {
             TTFFile ttf = new TTFFile();
@@ -55,7 +59,7 @@
         try {
             TTFFile ttf = new TTFFile();
             FontFileReader reader = new FontFileReader(in);
-            boolean supported = ttf.readFont(reader, null);
+            boolean supported = ttf.readFont(reader, ttcFontName);
             if (!supported) {
                 throw new IOException("TrueType font is not supported: " + fontFileURI);
             }
@@ -65,7 +69,8 @@
             IOUtils.closeQuietly(in);
         }
     }
-
+    
+    
     private void buildFont(TTFFile ttf) {
         if (ttf.isCFF()) {
             throw new UnsupportedOperationException(
@@ -91,7 +96,7 @@
         returnFont.setItalicAngle(Integer.parseInt(ttf.getItalicAngle()));
         returnFont.setMissingWidth(0);
         returnFont.setWeight(ttf.getWeightClass());
-        
+                
         multiFont.setCIDType(CIDFontType.CIDTYPE2);
         int[] wx = ttf.getWidths();
         multiFont.setWidthArray(wx);
Index: /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/render/PrintRendererConfigurator.java
===================================================================
--- /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/render/PrintRendererConfigurator.java	(revision 631408)
+++ /home/jharrop/workspace200711/fop-contrib/src/java/org/apache/fop/render/PrintRendererConfigurator.java	(working copy)
@@ -230,10 +230,23 @@
             URL fontUrl = (URL)iter.next();
             // parse font to ascertain font info
             FontInfoFinder finder = new FontInfoFinder();
-            EmbedFontInfo fontInfo = finder.find(fontUrl, resolver, fontCache);
-            if (fontInfo != null) {
-                fontInfoList.add(fontInfo);                
-            }
+            //EmbedFontInfo fontInfo = finder.find(fontUrl, resolver, fontCache);
+            
+//    		List<EmbedFontInfo> embedFontInfoList = finder.find(fontUrl, resolver, fontCache);		
+    		List embedFontInfoList = finder.find(fontUrl, resolver, fontCache);		
+    		
+    		if (embedFontInfoList==null) {
+    			return;
+    		}
+    		
+//    		for ( EmbedFontInfo fontInfo : embedFontInfoList ) {
+    		Iterator fontInfoIterator = embedFontInfoList.iterator();
+    	    while (fontInfoIterator.hasNext()) {
+    	    	EmbedFontInfo fontInfo = (EmbedFontInfo)fontInfoIterator.next();
+	            if (fontInfo != null) {
+	                fontInfoList.add(fontInfo);                
+	            }
+    		}
         }
     }
 
@@ -307,7 +320,10 @@
             }
             if (fontFile != null) {
                 FontInfoFinder finder = new FontInfoFinder();
-                return finder.find(fontUrl, fontResolver, fontCache);
+                return (EmbedFontInfo)finder.find(fontUrl, fontResolver, fontCache).get(0);
+                	// TODO - fixme.  This is a quick hack.  If it is a TTC,
+                	// it will only return the EmbedFontInfo corresponding 
+                	// to the first font.
             } else {
                 return null;
             }
