Author: mehdi
Date: Fri Mar 16 11:44:09 2012
New Revision: 1301445

URL: http://svn.apache.org/viewvc?rev=1301445&view=rev
Log:
Bugzila#52849: SVG font being painted as shapes when font present in the system

Added:
    xmlgraphics/fop/trunk/test/java/org/apache/fop/fonts/svg-fonts.fo
Modified:
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/events/LoggingEventListener.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventAdapter.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventListener.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventProducer.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventProducer.xml
    xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontInfo.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/ACIUtils.java
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/tools/fontlist/FontListMain.java
    xmlgraphics/fop/trunk/status.xml
    
xmlgraphics/fop/trunk/test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/events/LoggingEventListener.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/events/LoggingEventListener.java?rev=1301445&r1=1301444&r2=1301445&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/events/LoggingEventListener.java 
(original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/events/LoggingEventListener.java 
Fri Mar 16 11:44:09 2012
@@ -19,6 +19,9 @@
 
 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;
 
@@ -36,6 +39,8 @@ public class LoggingEventListener implem
     private Log log;
     private boolean skipFatal;
 
+    private final Set<String> loggedMessages = new HashSet<String>();
+
     /**
      * Creates an instance logging to the default log category of this class.
      */
@@ -77,7 +82,20 @@ public class LoggingEventListener implem
         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 (!loggedMessages.contains(msg)) {
+                    loggedMessages.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"));
@@ -96,5 +114,4 @@ public class LoggingEventListener implem
             assert false;
         }
     }
-
 }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventAdapter.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventAdapter.java?rev=1301445&r1=1301444&r2=1301445&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventAdapter.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventAdapter.java 
Fri Mar 16 11:44:09 2012
@@ -66,4 +66,9 @@ public class FontEventAdapter implements
         getEventProducer().fontDirectoryNotFound(source, dir);
     }
 
+    /** {@inheritDoc} */
+    public void svgTextStrokedAsShapes(Object source, String fontFamily) {
+        getEventProducer().svgTextStrokedAsShapes(source, fontFamily);
+    }
+
 }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventListener.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventListener.java?rev=1301445&r1=1301444&r2=1301445&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventListener.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventListener.java 
Fri Mar 16 11:44:09 2012
@@ -54,4 +54,11 @@ public interface FontEventListener {
      * @param dir the directory in the config file
      */
     void fontDirectoryNotFound(Object source, String dir);
+
+    /**
+     * The SVG text will be stroked as shapes.
+     * @param source the event source
+     * @param fontFamily the family name of the font that is being stroked
+     */
+    void svgTextStrokedAsShapes(Object source, String fontFamily);
 }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventProducer.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventProducer.java?rev=1301445&r1=1301444&r2=1301445&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventProducer.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventProducer.java 
Fri Mar 16 11:44:09 2012
@@ -73,10 +73,17 @@ public interface FontEventProducer exten
 
     /**
      * An error occurred trying to find the font directory specified in the 
config file.
-     * @param source the event sourece
+     * @param source the event source
      * @param dir the directory in the config file
      * @event.severity WARN
      */
     void fontDirectoryNotFound(Object source, String dir);
 
+    /**
+     * The SVG text will be stroked as shapes.
+     * @param source the event source
+     * @param fontFamily the family name of the font that is being stroked
+     * @event.severity WARN
+     */
+    void svgTextStrokedAsShapes(Object source, String fontFamily);
 }

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventProducer.xml
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventProducer.xml?rev=1301445&r1=1301444&r2=1301445&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventProducer.xml 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontEventProducer.xml 
Fri Mar 16 11:44:09 2012
@@ -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>

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontInfo.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontInfo.java?rev=1301445&r1=1301444&r2=1301445&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontInfo.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/fonts/FontInfo.java Fri Mar 
16 11:44:09 2012
@@ -22,10 +22,8 @@ package org.apache.fop.fonts;
 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 @@ public class FontInfo {
     /** 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 @@ public class FontInfo {
         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);
         }
     }
 

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/ACIUtils.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/ACIUtils.java?rev=1301445&r1=1301444&r2=1301445&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/ACIUtils.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/ACIUtils.java Fri Mar 16 
11:44:09 2012
@@ -28,13 +28,12 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
 import org.apache.batik.bridge.SVGFontFamily;
 import org.apache.batik.gvt.font.GVTFont;
 import org.apache.batik.gvt.font.GVTFontFamily;
 import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontInfo;
@@ -96,9 +95,10 @@ public final class ACIUtils {
         }
 
         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 +116,14 @@ public final class ACIUtils {
                     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) {

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/tools/fontlist/FontListMain.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/tools/fontlist/FontListMain.java?rev=1301445&r1=1301444&r2=1301445&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/tools/fontlist/FontListMain.java 
(original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/tools/fontlist/FontListMain.java 
Fri Mar 16 11:44:09 2012
@@ -147,6 +147,10 @@ public final class FontListMain {
                 //ignore
             }
 
+            public void svgTextStrokedAsShapes(Object source, String 
fontFamily) {
+                // ignore
+            }
+
         };
 
         FontListGenerator listGenerator = new FontListGenerator();

Modified: xmlgraphics/fop/trunk/status.xml
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/status.xml?rev=1301445&r1=1301444&r2=1301445&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/status.xml (original)
+++ xmlgraphics/fop/trunk/status.xml Fri Mar 16 11:44:09 2012
@@ -62,6 +62,10 @@
       documents. Example: the fix of marks layering will be such a case when 
it's done.
     -->
     <release version="FOP Trunk" date="TBD">
+      <action context="Code" dev="MH" type="fix" fixes-bug="52849" 
due-to="Luis Bernardo">
+        Fixed bug that caused a configured and installed SVG font to stroked,
+        also added an event indicating when fonts are stroked.
+      </action>
       <action context="Code" dev="PH" type="fix">
         Fix of a bug introduced when merging ImproveAccessibility.
       </action>

Modified: 
xmlgraphics/fop/trunk/test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java?rev=1301445&r1=1301444&r2=1301445&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java
 (original)
+++ 
xmlgraphics/fop/trunk/test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java
 Fri Mar 16 11:44:09 2012
@@ -57,4 +57,14 @@ public class FontEventProcessingTestCase
                 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);
+    }
+
 }

Added: xmlgraphics/fop/trunk/test/java/org/apache/fop/fonts/svg-fonts.fo
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/fonts/svg-fonts.fo?rev=1301445&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/test/java/org/apache/fop/fonts/svg-fonts.fo (added)
+++ xmlgraphics/fop/trunk/test/java/org/apache/fop/fonts/svg-fonts.fo Fri Mar 
16 11:44:09 2012
@@ -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>



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to