Index: src/java/org/apache/fop/events/LoggingEventListener.java
===================================================================
--- src/java/org/apache/fop/events/LoggingEventListener.java	(revision 1300166)
+++ src/java/org/apache/fop/events/LoggingEventListener.java	(working copy)
@@ -19,9 +19,11 @@
 
 package org.apache.fop.events;
 
+import java.util.HashSet;
+import java.util.Set;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-
 import org.apache.fop.events.model.EventSeverity;
 
 /**
@@ -36,6 +38,8 @@
     private Log log;
     private boolean skipFatal;
 
+    private Set<String> loggedMessages;
+
     /**
      * Creates an instance logging to the default log category of this class.
      */
@@ -77,7 +81,20 @@
         if (severity == EventSeverity.INFO) {
             log.info(msg);
         } else if (severity == EventSeverity.WARN) {
-            log.warn(msg);
+            // we want to prevent logging of duplicate messages in situations where they are likely to occur;
+            // for instance, warning related to layout do not repeat (since line number will be different) and
+            // as such we do not try to filter them here; on the other hand, font related warnings are very
+            // likely to repeat and we try to filter them out here; the same may happen with missing images
+            // (but not implemented yet).
+            String eventGroupID = event.getEventGroupID();
+            if (eventGroupID.equals("org.apache.fop.fonts.FontEventProducer")) {
+                if (!getLoggedMessages().contains(msg)) {
+                    getLoggedMessages().add(msg);
+                    log.warn(msg);
+                }
+            } else {
+                log.warn(msg);
+            }
         } else if (severity == EventSeverity.ERROR) {
             if (event.getParam("e") != null) {
                 log.error(msg, (Throwable)event.getParam("e"));
@@ -97,4 +114,11 @@
         }
     }
 
+    private Set<String> getLoggedMessages() {
+        if (loggedMessages == null) {
+            loggedMessages = new HashSet<String>();
+        }
+        return loggedMessages;
+    }
+
 }
Index: src/java/org/apache/fop/fonts/FontEventProducer.java
===================================================================
--- src/java/org/apache/fop/fonts/FontEventProducer.java	(revision 1300166)
+++ src/java/org/apache/fop/fonts/FontEventProducer.java	(working copy)
@@ -79,4 +79,11 @@
      */
     void fontDirectoryNotFound(Object source, String dir);
 
+    /**
+     * The SVG text will be stroked as shapes.
+     * @param source
+     * @param fontFamily
+     * @event.severity WARN
+     */
+    void svgTextStrokedAsShapes(Object source, String fontFamily);
 }
Index: src/java/org/apache/fop/fonts/FontEventProducer.xml
===================================================================
--- src/java/org/apache/fop/fonts/FontEventProducer.xml	(revision 1300166)
+++ src/java/org/apache/fop/fonts/FontEventProducer.xml	(working copy)
@@ -20,5 +20,6 @@
   <message key="fontSubstituted">Font "{requested}" not found. Substituting with "{effective}".</message>
   <message key="fontLoadingErrorAtAutoDetection">Unable to load font file: {fontURL}.[ Reason: {e}]</message>
   <message key="glyphNotAvailable">Glyph "{ch}" (0x{ch,hex}[, {ch,glyph-name}]) not available in font "{fontName}".</message>
-  <message key="fontDirectoryNotFound">'{dir}' does not exist or is not a directory.</message>
+  <message key="fontDirectoryNotFound">The font directory {dir} could not be found.</message>
+  <message key="svgTextStrokedAsShapes">The SVG text for font {fontFamily} will be stroked as shapes.</message>
 </catalogue>
Index: src/java/org/apache/fop/fonts/FontEventListener.java
===================================================================
--- src/java/org/apache/fop/fonts/FontEventListener.java	(revision 1300166)
+++ src/java/org/apache/fop/fonts/FontEventListener.java	(working copy)
@@ -54,4 +54,11 @@
      * @param dir the directory in the config file
      */
     void fontDirectoryNotFound(Object source, String dir);
+
+    /**
+     * The SVG text will be stroked as shapes.
+     * @param source
+     * @param fontFamily
+     */
+    void svgTextStrokedAsShapes(Object source, String fontFamily);
 }
Index: src/java/org/apache/fop/fonts/FontInfo.java
===================================================================
--- src/java/org/apache/fop/fonts/FontInfo.java	(revision 1300166)
+++ src/java/org/apache/fop/fonts/FontInfo.java	(working copy)
@@ -22,10 +22,8 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
@@ -59,12 +57,6 @@
     /** look up a font-name to get a font (that implements FontMetrics at least) */
     private Map<String, Typeface> fonts = null; //(String = font key)
 
-    /**
-     *  a collection of missing fonts; used to make sure the user gets
-     *  a warning for a missing font only once (not every time the font is used)
-     */
-    private Set<FontTriplet> loggedFontKeys = null;
-
     /** Cache for Font instances. */
     private Map<FontTriplet, Map<Integer, Font>> fontInstanceCache = null;
 
@@ -453,22 +445,19 @@
         return fontTriplets;
     }
 
-    private Set<FontTriplet> getLoggedFontKeys() {
-        if (loggedFontKeys == null) {
-            loggedFontKeys = new HashSet<FontTriplet>();
+    private void notifyFontReplacement(FontTriplet replacedKey, FontTriplet newKey) {
+        if (this.eventListener != null) {
+            this.eventListener.fontSubstituted(this, replacedKey, newKey);
         }
-        return loggedFontKeys;
     }
 
-    private void notifyFontReplacement(FontTriplet replacedKey, FontTriplet newKey) {
-        if (!getLoggedFontKeys().contains(replacedKey)) {
-            getLoggedFontKeys().add(replacedKey);
-            if (this.eventListener != null) {
-                this.eventListener.fontSubstituted(this, replacedKey, newKey);
-            } else {
-                log.warn("Font '" + replacedKey + "' not found. "
-                        + "Substituting with '" + newKey + "'.");
-            }
+    /**
+     * Notify listeners that the SVG text for the given font will be stroked as shapes.
+     * @param fontFamily a SVG font family
+     */
+    public void notifyStrokingSVGTextAsShapes(String fontFamily) {
+        if (this.eventListener != null) {
+            this.eventListener.svgTextStrokedAsShapes(this, fontFamily);
         }
     }
 
Index: src/java/org/apache/fop/fonts/FontEventAdapter.java
===================================================================
--- src/java/org/apache/fop/fonts/FontEventAdapter.java	(revision 1300166)
+++ src/java/org/apache/fop/fonts/FontEventAdapter.java	(working copy)
@@ -66,4 +66,9 @@
         getEventProducer().fontDirectoryNotFound(source, dir);
     }
 
+    /** {@inheritDoc} */
+    public void svgTextStrokedAsShapes(Object source, String fontFamily) {
+        getEventProducer().svgTextStrokedAsShapes(source, fontFamily);
+    }
+
 }
Index: src/java/org/apache/fop/tools/fontlist/FontListMain.java
===================================================================
--- src/java/org/apache/fop/tools/fontlist/FontListMain.java	(revision 1300166)
+++ src/java/org/apache/fop/tools/fontlist/FontListMain.java	(working copy)
@@ -147,6 +147,10 @@
                 //ignore
             }
 
+            public void svgTextStrokedAsShapes(Object source, String fontFamily) {
+                // ignore
+            }
+
         };
 
         FontListGenerator listGenerator = new FontListGenerator();
Index: src/java/org/apache/fop/svg/ACIUtils.java
===================================================================
--- src/java/org/apache/fop/svg/ACIUtils.java	(revision 1300166)
+++ src/java/org/apache/fop/svg/ACIUtils.java	(working copy)
@@ -96,9 +96,10 @@
         }
 
         if (gvtFonts != null) {
+            boolean haveInstanceOfSVGFontFamily = false;
             for (GVTFontFamily fam : gvtFonts) {
                 if (fam instanceof SVGFontFamily) {
-                    return null; //Let Batik paint this text!
+                    haveInstanceOfSVGFontFamily = true;
                 }
                 String fontFamily = fam.getFamilyName();
                 if (fontInfo.hasFont(fontFamily, style, weight)) {
@@ -116,6 +117,13 @@
                     firstFontFamily = fontFamily;
                 }
             }
+            // SVG fonts are embedded fonts in the SVG document and are rarely used; however if they are used
+            // but the fonts also exists in the system and are known to FOP then FOP should use them; then the
+            // decision whether Batik should stroke the text should be made after no matching fonts are found
+            if (fonts.isEmpty() && haveInstanceOfSVGFontFamily) {
+                fontInfo.notifyStrokingSVGTextAsShapes(firstFontFamily);
+                return null; // Let Batik paint this text!
+            }
         }
         if (fonts.isEmpty()) {
             if (firstFontFamily == null) {
Index: test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java
===================================================================
--- test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java	(revision 1300166)
+++ test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java	(working copy)
@@ -57,4 +57,14 @@
                 MimeConstants.MIME_PDF);
     }
 
+    @Test
+    public void testSVGFontStrokedAsShapes() throws FOPException, TransformerException, IOException,
+            SAXException {
+        // svg-fonts.fo embeds two fonts; one that is present in the system and the other is not; the
+        // missing font is stroked as shapes while the fonts that exists is stroked as text
+        InputStream inStream = getClass().getResourceAsStream("svg-fonts.fo");
+        eventsTests.doTest(inStream, null, FontEventProducer.class.getName() + ".svgTextStrokedAsShapes",
+                MimeConstants.MIME_PDF);
+    }
+
 }
Index: test/java/org/apache/fop/fonts/svg-fonts.fo
===================================================================
--- test/java/org/apache/fop/fonts/svg-fonts.fo	(revision 0)
+++ test/java/org/apache/fop/fonts/svg-fonts.fo	(revision 0)
@@ -0,0 +1,37 @@
+<?xml version="1.0" standalone="no"?>
+<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
+  <fo:layout-master-set>
+    <fo:simple-page-master master-name="page">
+      <fo:region-body />
+    </fo:simple-page-master>
+  </fo:layout-master-set>
+  <fo:page-sequence master-reference="page">
+    <fo:flow flow-name="xsl-region-body">
+      <fo:block>
+        <fo:instream-foreign-object>
+          <svg:svg width="250" height="50">
+            <svg:font horiz-adv-x="1000">
+              <svg:font-face font-family="Missing" units-per-em="1000" underline-position="-100"
+                underline-thickness="50" />
+              <svg:glyph unicode="A" horiz-adv-x="686" d="M162,186l362,0l78,-186l84,0l-308,708l-70,0l-308,-708l84,0M343,624l153,-372l-307,0z" />
+              <svg:glyph unicode="C" horiz-adv-x="704" d="M620,154C567,72 491,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C492,660 571,613 599,567l63,47C600,693 505,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C534,-18 632,39 679,112z" />
+              <svg:glyph unicode="F" horiz-adv-x="556" d="M168,335l330,0l0,66l-330,0l0,241l355,0l0,66l-427,0l0,-708l72,0z" />
+              <svg:glyph unicode="G" horiz-adv-x="778" d="M673,631C610,694 529,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C503,-18 606,7 685,54l0,347l-241,0l0,-66l169,0l0,-237C560,68 490,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C504,660 571,629 619,578z" />
+            </svg:font>
+            <svg:font horiz-adv-x="1000">
+              <!-- this is not Helvetica but it is here to increase coverage and show the code takes expected path -->
+              <svg:font-face font-family="Helvetica" units-per-em="1000" underline-position="-100"
+                underline-thickness="50" />
+              <svg:glyph unicode="A" horiz-adv-x="686" d="M162,186l362,0l78,-186l84,0l-308,708l-70,0l-308,-708l84,0M343,624l153,-372l-307,0z" />
+              <svg:glyph unicode="C" horiz-adv-x="704" d="M620,154C567,72 491,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C492,660 571,613 599,567l63,47C600,693 505,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C534,-18 632,39 679,112z" />
+              <svg:glyph unicode="F" horiz-adv-x="556" d="M168,335l330,0l0,66l-330,0l0,241l355,0l0,66l-427,0l0,-708l72,0z" />
+              <svg:glyph unicode="G" horiz-adv-x="778" d="M673,631C610,694 529,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C503,-18 606,7 685,54l0,347l-241,0l0,-66l169,0l0,-237C560,68 490,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C504,660 571,629 619,578z" />
+            </svg:font>
+            <svg:text x="20" y="20" font-family="Missing" font-size="12">ACFG</svg:text>
+            <svg:text x="20" y="40" font-family="Helvetica" font-size="12">ACFG</svg:text>
+          </svg:svg>
+        </fo:instream-foreign-object>
+      </fo:block>
+    </fo:flow>
+  </fo:page-sequence>
+</fo:root>
