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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]