You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-dev@xmlgraphics.apache.org by Chad Maloney <ch...@peregrine.com> on 2002/04/05 20:35:29 UTC

Multithreading problems with missing glyphs

I'm using Batik's svggen package to draw with java2d
and output an SVG. Everything is going great, but I'm
having problems with missing glyphs in the generated
SVGs at times. This is running in a servlet engine, so
I don't have much control over threading unless I
synchronize things, which I'd rather not do. I am using
SVG Fonts (i.e. I call setEmbeddedFonts(true) on the
SVGGeneratorContext).

I dug into the batik code to see what's up and I believe
the problem is in SVGFont. The fontStringMap (which is
a hashmap) is statically defined. It gets newed at
class load time (there is a = new HashMap() in the
declaration) and is also gets newed in the constructor.
It seems very odd to me to be both using this class as
a static (like in drawString which calls recordFontUsage
statically) and also non-statically (the 
SVGGraphicContextConverter instantiates a new SVGFont and
uses it as a converter to output svg when needed).
The SVGGraphicsContextConverter looks like it's being
instantiated when I make a new SVGGraphics2D.

The fontStringMap really shouldn't be static. If I
instantiate two SVGGraphics2D objects, I'd expect
them to have separate fontStringMaps, so I'd expect
fontStringMap to be somehow associated with the
SVGGraphics2D instance that I called drawString on.

What I did was move the fontStringMap instance 
variable to SVGGraphicsContext and change the call to
recordFontUsage in SVGGraphics2D.drawString to 
call graphicsContext.recordSVGFontUsage, then I 
fixed up SVGFont to take in the Map to record
to in its recordFontUsage and kept it static and
made toSVG use the fontStringMap on the
SVGGraphicsContext.

I did this against 1.1.1 and the diff is below. I
don't have CVS right now, so I didn't make the diff
against the latest code. I also have no idea where the
diff executable I used came from. Hopefully the changes are
appropriate and simple enough to apply to the latest
code easily. This fixed my missing font glyphs for
SVG Fonts.

			- Chad


diff -r -u
\bin\batik-1.1.1-orig\sources\org\apache\batik\svggen\SVGFont.java
.\org\apache\batik\svggen\SVGFont.java
--- \bin\batik-1.1.1-orig\sources\org\apache\batik\svggen\SVGFont.java	Fri
Aug 03 06:21:52 2001
+++ .\org\apache\batik\svggen\SVGFont.java	Fri Apr 05 12:02:00 2002
@@ -135,25 +135,20 @@
     static final int COMMON_FONT_SIZE = 100;
 
     /**
-     * Used to keep track of which characters have been rendered by each
font
-     * used.
-     */
-    static Map fontStringMap = new HashMap();
-
-    /**
      * @param generatorContext used to build Elements
      */
     public SVGFont(SVGGeneratorContext generatorContext) {
         super(generatorContext);
-        fontStringMap = new HashMap();
     }
 
     /**
      * Records that the specified font has been used to draw the text
string.
      * This is so we can keep track of which glyphs are required for each
-     * SVG font that is generated.
+     * SVG font that is generated. The fact is recorded in the
fontStringMap
+     * passed in.
      */
-    public static void recordFontUsage(String string, Font font) {
+    public static void recordFontUsage(Map fontStringMap, String string, 
+                                       Font font) {
 
         Font commonSizeFont = createCommonSizeFont(font);
         String fontKey = commonSizeFont.getFamily() +
commonSizeFont.getStyle();
@@ -215,7 +210,8 @@
         Font commonSizeFont = createCommonSizeFont(font);
         String fontKey = commonSizeFont.getFamily() +
commonSizeFont.getStyle();
 
-        String textUsingFont = (String)fontStringMap.get(fontKey);
+        String textUsingFont = 
+            (String)generatorContext.fontStringMap.get(fontKey);
 
         if (textUsingFont == null) {
             // this font hasn't been used by any text yet,
diff -r -u
\bin\batik-1.1.1-orig\sources\org\apache\batik\svggen\SVGGeneratorContext.ja
va .\org\apache\batik\svggen\SVGGeneratorContext.java
---
\bin\batik-1.1.1-orig\sources\org\apache\batik\svggen\SVGGeneratorContext.ja
va	Fri Nov 02 13:58:30 2001
+++ .\org\apache\batik\svggen\SVGGeneratorContext.java	Fri Apr 05 11:58:04
2002
@@ -18,6 +18,9 @@
 import java.awt.Font;
 import java.awt.Color;
 
+import java.util.Map;
+import java.util.HashMap;
+
 /**
  * This class contains all non graphical contextual information that
  * are needed by the {@link org.apache.batik.svggen.SVGGraphics2D} to
@@ -91,6 +94,12 @@
     GraphicContextDefaults gcDefaults;
 
     /**
+     * Used to keep track of which characters have been rendered by each 
+     * svg font used.
+     */
+    static Map fontStringMap = new HashMap();
+
+    /**
      * Class to describe the GraphicContext defaults to
      * be used. Note that this class does *not* contain
      * a default for the initial transform, as this 
@@ -367,5 +376,14 @@
      */
     final public void setEmbeddedFontsOn(boolean svgFont) {
         this.svgFont = svgFont;
+    }
+
+   /**
+     * Records that the specified font has been used to draw the text
string.
+     * This is so we can keep track of which glyphs are required for each
+     * SVG font that is generated.
+     */
+    public static void recordSVGFontUsage(String string, Font font) {
+        SVGFont.recordFontUsage(fontStringMap, string, font);
     }
 }
diff -r -u
\bin\batik-1.1.1-orig\sources\org\apache\batik\svggen\SVGGraphics2D.java
.\org\apache\batik\svggen\SVGGraphics2D.java
--- \bin\batik-1.1.1-orig\sources\org\apache\batik\svggen\SVGGraphics2D.java
Wed Nov 28 13:49:26 2001
+++ .\org\apache\batik\svggen\SVGGraphics2D.java	Fri Apr 05 11:53:44
2002
@@ -1086,7 +1086,7 @@
                 // record that the font is being used to draw this string,
this is
                 // so that the SVG Font element will only create glyphs for
the
                 // characters that are needed
-                SVGFont.recordFontUsage(s, getFont());
+                generatorCtx.recordSVGFontUsage(s, getFont());
             }
 
             Font font = getFont();

---------------------------------------------------------------------
To unsubscribe, e-mail: batik-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-dev-help@xml.apache.org


RE: Multithreading problems with missing glyphs

Posted by Thierry Kormann <tk...@ilog.fr>.

I enter a bug in bugzilla. Thanks for your feedback.


Thierry.


---------------------------------------------------------------------
To unsubscribe, e-mail: batik-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-dev-help@xml.apache.org