Index: src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java
===================================================================
--- src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java	(revision 652071)
+++ src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java	(working copy)
@@ -223,7 +223,8 @@
                     log.debug("Loading " + fontName);
                 }
                 try {
-                    TTFFontLoader ttfLoader = new TTFFontLoader(fontFileURI, fontName, resolver);
+                    TTFFontLoader ttfLoader = new TTFFontLoader(
+                            fontFileURI, fontName, true, resolver);
                     customFont = ttfLoader.getFont();
                     if (this.eventListener != null) {
                         customFont.setEventListener(this.eventListener);
@@ -247,7 +248,7 @@
         } else {
             // The normal case
             try {
-                customFont = FontLoader.loadFont(fontUrl, null, resolver);
+                customFont = FontLoader.loadFont(fontUrl, null, true, resolver);
                 if (this.eventListener != null) {
                     customFont.setEventListener(this.eventListener);
                 }
Index: src/java/org/apache/fop/fonts/EmbedFontInfo.java
===================================================================
--- src/java/org/apache/fop/fonts/EmbedFontInfo.java	(revision 652071)
+++ src/java/org/apache/fop/fonts/EmbedFontInfo.java	(working copy)
@@ -19,6 +19,7 @@
  
 package org.apache.fop.fonts;
 
+import java.io.IOException;
 import java.io.Serializable;
 import java.util.List;
 
@@ -44,6 +45,8 @@
     /** the sub-fontname of the font (used for TrueType Collections, null otherwise) */
     protected String subFontName = null;
 
+    private transient boolean embedded = true;
+    
     /**
      * Main constructor
      * @param metricsFile Path to the xml file containing font metrics
@@ -118,10 +121,38 @@
         this.postScriptName = postScriptName;
     }
     
+    /**
+     * Indicates whether the font is only referenced rather than embedded.
+     * @return true if the font is embedded, false if it is referenced.
+     */
+    public boolean isEmbedded() {
+        if (metricsFile != null && embedFile == null) {
+            return false;
+        } else {
+            return this.embedded;
+        }
+    }
+    
+    /**
+     * Defines whether the font is embedded or not.
+     * @param value true to embed the font, false to reference it
+     */
+    public void setEmbedded(boolean value) {
+        this.embedded = value;
+    }
+    
+    private void readObject(java.io.ObjectInputStream in)
+                throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+        this.embedded = true;
+    }
+    
     /** {@inheritDoc} */
     public String toString() {
         return "metrics-url=" + metricsFile + ",embed-url=" + embedFile
             + ", kerning=" + kerning + ", font-triplet=" + fontTriplets
-            + (getSubFontName() != null ? ", sub-font=" + getSubFontName() : ""); 
+            + (getSubFontName() != null ? ", sub-font=" + getSubFontName() : "")
+            + (isEmbedded() ? "" : ", NOT embedded"); 
     }
+
 }
Index: src/java/org/apache/fop/fonts/FontLoader.java
===================================================================
--- src/java/org/apache/fop/fonts/FontLoader.java	(revision 652071)
+++ src/java/org/apache/fop/fonts/FontLoader.java	(working copy)
@@ -39,9 +39,7 @@
  */
 public abstract class FontLoader {
 
-    /**
-     * logging instance
-     */
+    /** logging instance */
     protected static Log log = LogFactory.getLog(FontLoader.class);
 
     /** URI representing the font file */
@@ -53,14 +51,18 @@
 
     /** true if the font has been loaded */
     protected boolean loaded = false;
+    /** true if the font will be embedded, false if it will be referenced only. */
+    protected boolean embedded = true;
 
     /**
      * Default constructor.
      * @param fontFileURI the URI to the PFB file of a Type 1 font
+     * @param embedded indicates whether the font is embedded or referenced
      * @param resolver the font resolver used to resolve URIs
      */
-    public FontLoader(String fontFileURI, FontResolver resolver) {
+    public FontLoader(String fontFileURI, boolean embedded, FontResolver resolver) {
         this.fontFileURI = fontFileURI;
+        this.embedded = embedded;
         this.resolver = resolver;
     }
 
@@ -72,46 +74,48 @@
      * Loads a custom font from a File. In the case of Type 1 fonts, the PFB file must be specified.
      * @param fontFile the File representation of the font
      * @param subFontName the sub-fontname of a font (for TrueType Collections, null otherwise)
+     * @param embedded indicates whether the font is embedded or referenced
      * @param resolver the font resolver to use when resolving URIs
      * @return the newly loaded font
      * @throws IOException In case of an I/O error
      */
-    public static CustomFont loadFont(File fontFile, String subFontName, FontResolver resolver)
-                throws IOException {
-        return loadFont(fontFile.getAbsolutePath(), subFontName, resolver);
+    public static CustomFont loadFont(File fontFile, String subFontName,
+            boolean embedded, FontResolver resolver) throws IOException {
+        return loadFont(fontFile.getAbsolutePath(), subFontName, embedded, resolver);
     }
 
     /**
      * Loads a custom font from an URL. In the case of Type 1 fonts, the PFB file must be specified.
      * @param fontUrl the URL representation of the font
      * @param subFontName the sub-fontname of a font (for TrueType Collections, null otherwise)
+     * @param embedded indicates whether the font is embedded or referenced
      * @param resolver the font resolver to use when resolving URIs
      * @return the newly loaded font
      * @throws IOException In case of an I/O error
      */
-    public static CustomFont loadFont(URL fontUrl, String subFontName, FontResolver resolver)
-                throws IOException {
-        return loadFont(fontUrl.toExternalForm(), subFontName, resolver);
+    public static CustomFont loadFont(URL fontUrl, String subFontName,
+            boolean embedded, FontResolver resolver) throws IOException {
+        return loadFont(fontUrl.toExternalForm(), subFontName, embedded, resolver);
     }
     
-    
     /**
      * Loads a custom font from a URI. In the case of Type 1 fonts, the PFB file must be specified.
      * @param fontFileURI the URI to the font
      * @param subFontName the sub-fontname of a font (for TrueType Collections, null otherwise)
+     * @param embedded indicates whether the font is embedded or referenced
      * @param resolver the font resolver to use when resolving URIs
      * @return the newly loaded font
      * @throws IOException In case of an I/O error
      */
-    public static CustomFont loadFont(String fontFileURI, String subFontName, FontResolver resolver)
-                throws IOException {
+    public static CustomFont loadFont(String fontFileURI, String subFontName,
+            boolean embedded, FontResolver resolver) throws IOException {
         fontFileURI = fontFileURI.trim();
         boolean type1 = isType1(fontFileURI);
         FontLoader loader;
         if (type1) {
-            loader = new Type1FontLoader(fontFileURI, resolver);
+            loader = new Type1FontLoader(fontFileURI, embedded, resolver);
         } else {
-            loader = new TTFFontLoader(fontFileURI, subFontName, resolver);
+            loader = new TTFFontLoader(fontFileURI, subFontName, embedded, resolver);
         }
         return loader.getFont();
     }
Index: src/java/org/apache/fop/fonts/FontTriplet.java
===================================================================
--- src/java/org/apache/fop/fonts/FontTriplet.java	(revision 652071)
+++ src/java/org/apache/fop/fonts/FontTriplet.java	(working copy)
@@ -121,5 +121,18 @@
         return getKey();
     }
 
+    /**
+     * Matcher interface for {@link FontTriplet}.
+     */
+    public interface Matcher {
+        
+        /**
+         * Indicates whether the given {@link FontTriplet} matches a particular criterium.
+         * @param triplet the font triplet
+         * @return true if the font triplet is a match
+         */
+        boolean matches(FontTriplet triplet);
+    }
+    
 }
 
Index: src/java/org/apache/fop/fonts/LazyFont.java
===================================================================
--- src/java/org/apache/fop/fonts/LazyFont.java	(revision 652071)
+++ src/java/org/apache/fop/fonts/LazyFont.java	(working copy)
@@ -44,6 +44,7 @@
     private String metricsFileName = null;
     private String fontEmbedPath = null;
     private boolean useKerning = false;
+    private boolean embedded = true;
     private String subFontName = null;
 
     private boolean isMetricsLoaded = false;
@@ -63,6 +64,7 @@
         this.fontEmbedPath = fontInfo.getEmbedFile();
         this.useKerning = fontInfo.getKerning();
         this.subFontName = fontInfo.getSubFontName();
+        this.embedded = fontInfo.isEmbedded();
         this.resolver = resolver;
     }
 
@@ -118,14 +120,17 @@
                                     new URL(metricsFileName).openStream()));
                     }
                     reader.setKerningEnabled(useKerning);
-                    reader.setFontEmbedPath(fontEmbedPath);
+                    if (this.embedded) {
+                        reader.setFontEmbedPath(fontEmbedPath);
+                    }
                     reader.setResolver(resolver);
                     realFont = reader.getFont();
                 } else {
                     if (fontEmbedPath == null) {
                         throw new RuntimeException("Cannot load font. No font URIs available.");
                     }
-                    realFont = FontLoader.loadFont(fontEmbedPath, this.subFontName, resolver);
+                    realFont = FontLoader.loadFont(fontEmbedPath, this.subFontName,
+                            this.embedded, resolver);
                 }
                 if (realFont instanceof FontDescriptor) {
                     realFontDescriptor = (FontDescriptor) realFont;
Index: src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
===================================================================
--- src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java	(revision 652071)
+++ src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java	(working copy)
@@ -27,11 +27,16 @@
 
 import org.apache.commons.io.IOUtils;
 
+import org.apache.xmlgraphics.fonts.Glyphs;
+
 import org.apache.fop.fonts.BFEntry;
 import org.apache.fop.fonts.CIDFontType;
 import org.apache.fop.fonts.FontLoader;
 import org.apache.fop.fonts.FontResolver;
+import org.apache.fop.fonts.FontType;
 import org.apache.fop.fonts.MultiByteFont;
+import org.apache.fop.fonts.NamedCharacter;
+import org.apache.fop.fonts.SingleByteFont;
 
 /**
  * Loads a TrueType font into memory directly from the original font file.
@@ -39,6 +44,7 @@
 public class TTFFontLoader extends FontLoader {
 
     private MultiByteFont multiFont;
+    private SingleByteFont singleFont;
     private String subFontName;
     
     /**
@@ -47,7 +53,7 @@
      * @param resolver the FontResolver for font URI resolution
      */
     public TTFFontLoader(String fontFileURI, FontResolver resolver) {
-        this(fontFileURI, null, resolver);
+        this(fontFileURI, null, true, resolver);
     }
     
     /**
@@ -55,10 +61,12 @@
      * @param fontFileURI the URI representing the font file
      * @param subFontName the sub-fontname of a font in a TrueType Collection (or null for normal
      *          TrueType fonts)
+     * @param embedded indicates whether the font is embedded or referenced
      * @param resolver the FontResolver for font URI resolution
      */
-    public TTFFontLoader(String fontFileURI, String subFontName, FontResolver resolver) {
-        super(fontFileURI, resolver);
+    public TTFFontLoader(String fontFileURI, String subFontName,
+                boolean embedded, FontResolver resolver) {
+        super(fontFileURI, embedded, resolver);
         this.subFontName = subFontName;
     }
     
@@ -95,43 +103,86 @@
             throw new UnsupportedOperationException(
                     "OpenType fonts with CFF data are not supported, yet");
         }
-        multiFont = new MultiByteFont();
-        multiFont.setResolver(this.resolver);
-        returnFont = multiFont;
+        
+        boolean isCid = this.embedded;
+        
+        if (isCid) {
+            multiFont = new MultiByteFont();
+            returnFont = multiFont;
+            multiFont.setTTCName(ttcFontName);
+        } else {
+            singleFont = new SingleByteFont();
+            returnFont = singleFont;
+        }
+        returnFont.setResolver(resolver);
 
         returnFont.setFontName(ttf.getPostScriptName());
         returnFont.setFullName(ttf.getFullName());
         returnFont.setFamilyNames(ttf.getFamilyNames());
         returnFont.setFontSubFamilyName(ttf.getSubFamilyName());
-        multiFont.setTTCName(ttcFontName);
         returnFont.setCapHeight(ttf.getCapHeight());
         returnFont.setXHeight(ttf.getXHeight());
         returnFont.setAscender(ttf.getLowerCaseAscent());
         returnFont.setDescender(ttf.getLowerCaseDescent());
         returnFont.setFontBBox(ttf.getFontBBox());
-        //returnFont.setFirstChar(ttf.getFirstChar();)
         returnFont.setFlags(ttf.getFlags());
         returnFont.setStemV(Integer.parseInt(ttf.getStemV())); //not used for TTF
         returnFont.setItalicAngle(Integer.parseInt(ttf.getItalicAngle()));
         returnFont.setMissingWidth(0);
         returnFont.setWeight(ttf.getWeightClass());
-                
-        multiFont.setCIDType(CIDFontType.CIDTYPE2);
+
+        if (isCid) {
+            multiFont.setCIDType(CIDFontType.CIDTYPE2);
+            int[] wx = ttf.getWidths();
+            multiFont.setWidthArray(wx);
+            List entries = ttf.getCMaps();
+            BFEntry[] bfentries = new BFEntry[entries.size()];
+            int pos = 0;
+            Iterator iter = ttf.getCMaps().listIterator();
+            while (iter.hasNext()) {
+                TTFCmapEntry ce = (TTFCmapEntry)iter.next();
+                bfentries[pos] = new BFEntry(ce.getUnicodeStart(), ce.getUnicodeEnd(),
+                        ce.getGlyphStartIndex());
+                pos++;
+            }
+            multiFont.setBFEntries(bfentries);
+        } else {
+            singleFont.setFontType(FontType.TRUETYPE);
+            singleFont.setEncoding(ttf.getCharSetName());
+            returnFont.setFirstChar(ttf.getFirstChar());
+            returnFont.setLastChar(ttf.getLastChar());
+            copyWidthsSingleByte(ttf);
+        }
+        
+        copyKerning(ttf, isCid);
+        if (this.embedded && ttf.isEmbeddable()) {
+            multiFont.setEmbedFileName(this.fontFileURI);
+        }
+    }
+
+    private void copyWidthsSingleByte(TTFFile ttf) {
         int[] wx = ttf.getWidths();
-        multiFont.setWidthArray(wx);
-        List entries = ttf.getCMaps();
-        BFEntry[] bfentries = new BFEntry[entries.size()];
-        int pos = 0;
+        for (int i = singleFont.getFirstChar(); i <= singleFont.getLastChar(); i++) {
+            singleFont.setWidth(i, ttf.getCharWidth(i));
+        }
         Iterator iter = ttf.getCMaps().listIterator();
         while (iter.hasNext()) {
             TTFCmapEntry ce = (TTFCmapEntry)iter.next();
-            bfentries[pos] = new BFEntry(ce.getUnicodeStart(), ce.getUnicodeEnd(),
-                    ce.getGlyphStartIndex());
-            pos++;
+            if (ce.getUnicodeStart() < 0xFFFE) {
+                for (char u = (char)ce.getUnicodeStart(); u <= ce.getUnicodeEnd(); u++) {
+                    int codePoint = singleFont.getEncoding().mapChar(u);
+                    if (codePoint <= 0) {
+                        String unicode = Character.toString(u);
+                        String charName = Glyphs.stringToGlyph(unicode);
+                        if (charName.length() > 0) {
+                            NamedCharacter nc = new NamedCharacter(charName, unicode);
+                            int glyphIndex = ce.getGlyphStartIndex() + u - ce.getUnicodeStart();
+                            singleFont.addUnencodedCharacter(nc, wx[glyphIndex]);
+                        }
+                    }
+                }
+            }
         }
-        multiFont.setBFEntries(bfentries);
-        copyKerning(ttf, true);
-        multiFont.setEmbedFileName(this.fontFileURI);
     }
     
     /**
Index: src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
===================================================================
--- src/java/org/apache/fop/fonts/type1/Type1FontLoader.java	(revision 652071)
+++ src/java/org/apache/fop/fonts/type1/Type1FontLoader.java	(working copy)
@@ -44,12 +44,13 @@
     /**
      * Constructs a new Type 1 font loader.
      * @param fontFileURI the URI to the PFB file of a Type 1 font
+     * @param embedded indicates whether the font is embedded or referenced
      * @param resolver the font resolver used to resolve URIs
      * @throws IOException In case of an I/O error
      */
-    public Type1FontLoader(String fontFileURI, FontResolver resolver) 
+    public Type1FontLoader(String fontFileURI, boolean embedded, FontResolver resolver) 
                 throws IOException {
-        super(fontFileURI, resolver);
+        super(fontFileURI, embedded, resolver);
     }
 
     private String getPFMURI(String pfbURI) {
@@ -119,7 +120,9 @@
         singleFont = new SingleByteFont();
         singleFont.setFontType(FontType.TYPE1);
         singleFont.setResolver(this.resolver);
-        singleFont.setEmbedFileName(this.fontFileURI);
+        if (this.embedded) {
+            singleFont.setEmbedFileName(this.fontFileURI);
+        }
         returnFont = singleFont;
         
         handleEncoding(afm, pfm);
Index: src/java/org/apache/fop/render/java2d/FontSetup.java
===================================================================
--- src/java/org/apache/fop/render/java2d/FontSetup.java	(revision 652071)
+++ src/java/org/apache/fop/render/java2d/FontSetup.java	(working copy)
@@ -304,7 +304,7 @@
                     Source fontSource = resolver.resolve(configFontInfo.getEmbedFile());
                     font = new CustomFontMetricsMapper(fontMetrics, fontSource);
                 } else {
-                    CustomFont fontMetrics = FontLoader.loadFont(fontFile, null, resolver);
+                    CustomFont fontMetrics = FontLoader.loadFont(fontFile, null, true, resolver);
                     font = new CustomFontMetricsMapper(fontMetrics);
                 }
 
Index: src/java/org/apache/fop/render/PrintRendererConfigurator.java
===================================================================
--- src/java/org/apache/fop/render/PrintRendererConfigurator.java	(revision 652071)
+++ src/java/org/apache/fop/render/PrintRendererConfigurator.java	(working copy)
@@ -25,6 +25,7 @@
 import java.net.URL;
 import java.util.Iterator;
 import java.util.List;
+import java.util.regex.Pattern;
 
 import javax.xml.transform.Source;
 import javax.xml.transform.stream.StreamSource;
@@ -210,6 +211,13 @@
                     fontInfoList.add(fontInfo);
                 }
             }
+
+            // Determine referenced fonts (fonts which are not to be embedded)
+            Configuration referencedFonts = fonts.getChild("referenced-fonts", false);
+            if (referencedFonts != null) {
+                processReferencedFonts(referencedFonts, fontInfoList, strict);
+            }
+
             if (log.isDebugEnabled()) {
                 log.debug("Finished font configuration in " 
                         + (System.currentTimeMillis() - start) + "ms");
@@ -218,6 +226,71 @@
         return fontInfoList;
     }
 
+    private static void processReferencedFonts(Configuration fonts, List fontInfoList,
+            boolean strict) throws FOPException {
+        List matcherList = new java.util.ArrayList();
+        Configuration[] matches = fonts.getChildren("match");
+        for (int i = 0; i < matches.length; i++) {
+            try {
+                matcherList.add(new FontFamilyRegExFontTripletMatcher(
+                        matches[i].getAttribute("font-family")));
+            } catch (ConfigurationException ce) {
+                LogUtil.handleException(log, ce, strict);
+                continue;
+            }
+        }
+        FontTriplet.Matcher orMatcher = new OrFontTripletMatcher(
+                (FontTriplet.Matcher[])matcherList.toArray(
+                        new FontTriplet.Matcher[matcherList.size()]));
+        Iterator iter = fontInfoList.iterator();
+        while (iter.hasNext()) {
+            EmbedFontInfo fontInfo = (EmbedFontInfo)iter.next();
+            Iterator triplets = fontInfo.getFontTriplets().iterator();
+            while (triplets.hasNext()) {
+                FontTriplet triplet = (FontTriplet)triplets.next();
+                if (orMatcher.matches(triplet)) {
+                    fontInfo.setEmbedded(false);
+                    break;
+                }
+            }
+        }
+    }
+
+    private static class OrFontTripletMatcher implements FontTriplet.Matcher {
+
+        private FontTriplet.Matcher[] matchers;
+        
+        public OrFontTripletMatcher(FontTriplet.Matcher[] matchers) {
+            this.matchers = matchers;
+        }
+        
+        /** {@inheritDoc} */
+        public boolean matches(FontTriplet triplet) {
+            for (int i = 0, c = matchers.length; i < c; i++) {
+                if (matchers[i].matches(triplet)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        
+    }
+    
+    private static class FontFamilyRegExFontTripletMatcher implements FontTriplet.Matcher {
+
+        private Pattern regex;
+        
+        public FontFamilyRegExFontTripletMatcher(String regex) {
+            this.regex = Pattern.compile(regex);
+        }
+        
+        /** {@inheritDoc} */
+        public boolean matches(FontTriplet triplet) {
+            return regex.matcher(triplet.getName()).matches();
+        }
+        
+    }
+    
     /**
      * Iterates over font file list adding font info to list
      * @param fontFileList font file list
