Browse Source

Improved fix for bugzilla#48062

Bug relates to PCL painter thread safetly. Previous fix in rev 895012 worked by synchronizing methods of a static instance of Java2DFontMetrics. This fix uses a unique instance for per thread.


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1161612 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-1_1rc1old
Peter Hancock 12 years ago
parent
commit
355eb32c4a

+ 5
- 5
src/java/org/apache/fop/render/bitmap/BitmapRendererConfigurator.java View File

/** {@inheritDoc} */ /** {@inheritDoc} */
public void setupFontInfo(IFDocumentHandler documentHandler, FontInfo fontInfo) public void setupFontInfo(IFDocumentHandler documentHandler, FontInfo fontInfo)
throws FOPException { throws FOPException {
FontManager fontManager = userAgent.getFactory().getFontManager();
final FontManager fontManager = userAgent.getFactory().getFontManager();


Graphics2D graphics2D = Java2DFontMetrics.createFontMetricsGraphics2D();
final Java2DFontMetrics java2DFontMetrics = new Java2DFontMetrics();


List fontCollections = new java.util.ArrayList();
fontCollections.add(new Base14FontCollection(graphics2D));
fontCollections.add(new InstalledFontCollection(graphics2D));
final List fontCollections = new java.util.ArrayList();
fontCollections.add(new Base14FontCollection(java2DFontMetrics));
fontCollections.add(new InstalledFontCollection(java2DFontMetrics));


Configuration cfg = super.getRendererConfig(documentHandler.getMimeType()); Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
if (cfg != null) { if (cfg != null) {

+ 18
- 17
src/java/org/apache/fop/render/java2d/Base14FontCollection.java View File

*/ */
public class Base14FontCollection implements FontCollection { public class Base14FontCollection implements FontCollection {


private Graphics2D graphics2d = null;
/** required when creating new instances of SystemFontMetricsMapper */
private final Java2DFontMetrics java2DFontMetrics;


/** /**
* Main constructor * Main constructor
* @param graphics2d a graphics 2D
* @param java2DFontMetrics required when creating new instances of SystemFontMetricsMapper
*/ */
public Base14FontCollection(Graphics2D graphics2d) {
this.graphics2d = graphics2d;
public Base14FontCollection(Java2DFontMetrics java2DFontMetrics) {
this.java2DFontMetrics = java2DFontMetrics;
} }


/** /**
final int bolditalic = java.awt.Font.BOLD + java.awt.Font.ITALIC; final int bolditalic = java.awt.Font.BOLD + java.awt.Font.ITALIC;


FontMetricsMapper metric; FontMetricsMapper metric;
metric = new SystemFontMetricsMapper("SansSerif", normal, graphics2d);
metric = new SystemFontMetricsMapper("SansSerif", normal, java2DFontMetrics);
// --> goes to F1 // --> goes to F1
fontInfo.addMetrics("F1", metric); fontInfo.addMetrics("F1", metric);
metric = new SystemFontMetricsMapper("SansSerif", italic, graphics2d);
metric = new SystemFontMetricsMapper("SansSerif", italic, java2DFontMetrics);
// --> goes to F2 // --> goes to F2
fontInfo.addMetrics("F2", metric); fontInfo.addMetrics("F2", metric);
metric = new SystemFontMetricsMapper("SansSerif", bold, graphics2d);
metric = new SystemFontMetricsMapper("SansSerif", bold, java2DFontMetrics);
// --> goes to F3 // --> goes to F3
fontInfo.addMetrics("F3", metric); fontInfo.addMetrics("F3", metric);
metric = new SystemFontMetricsMapper("SansSerif", bolditalic, graphics2d);
metric = new SystemFontMetricsMapper("SansSerif", bolditalic, java2DFontMetrics);
// --> goes to F4 // --> goes to F4
fontInfo.addMetrics("F4", metric); fontInfo.addMetrics("F4", metric);




metric = new SystemFontMetricsMapper("Serif", normal, graphics2d);
metric = new SystemFontMetricsMapper("Serif", normal, java2DFontMetrics);
// --> goes to F5 // --> goes to F5
fontInfo.addMetrics("F5", metric); fontInfo.addMetrics("F5", metric);
metric = new SystemFontMetricsMapper("Serif", italic, graphics2d);
metric = new SystemFontMetricsMapper("Serif", italic, java2DFontMetrics);
// --> goes to F6 // --> goes to F6
fontInfo.addMetrics("F6", metric); fontInfo.addMetrics("F6", metric);
metric = new SystemFontMetricsMapper("Serif", bold, graphics2d);
metric = new SystemFontMetricsMapper("Serif", bold, java2DFontMetrics);
// --> goes to F7 // --> goes to F7
fontInfo.addMetrics("F7", metric); fontInfo.addMetrics("F7", metric);
metric = new SystemFontMetricsMapper("Serif", bolditalic, graphics2d);
metric = new SystemFontMetricsMapper("Serif", bolditalic, java2DFontMetrics);
// --> goes to F8 // --> goes to F8
fontInfo.addMetrics("F8", metric); fontInfo.addMetrics("F8", metric);


metric = new SystemFontMetricsMapper("MonoSpaced", normal, graphics2d);
metric = new SystemFontMetricsMapper("MonoSpaced", normal, java2DFontMetrics);
// --> goes to F9 // --> goes to F9
fontInfo.addMetrics("F9", metric); fontInfo.addMetrics("F9", metric);
metric = new SystemFontMetricsMapper("MonoSpaced", italic, graphics2d);
metric = new SystemFontMetricsMapper("MonoSpaced", italic, java2DFontMetrics);
// --> goes to F10 // --> goes to F10
fontInfo.addMetrics("F10", metric); fontInfo.addMetrics("F10", metric);
metric = new SystemFontMetricsMapper("MonoSpaced", bold, graphics2d);
metric = new SystemFontMetricsMapper("MonoSpaced", bold, java2DFontMetrics);
// --> goes to F11 // --> goes to F11
fontInfo.addMetrics("F11", metric); fontInfo.addMetrics("F11", metric);
metric = new SystemFontMetricsMapper("MonoSpaced", bolditalic, graphics2d);
metric = new SystemFontMetricsMapper("MonoSpaced", bolditalic, java2DFontMetrics);
// --> goes to F12 // --> goes to F12
fontInfo.addMetrics("F12", metric); fontInfo.addMetrics("F12", metric);


metric = new SystemFontMetricsMapper("Serif", normal, graphics2d);
metric = new SystemFontMetricsMapper("Serif", normal, java2DFontMetrics);
//"Symbol" doesn't seem to work here, but "Serif" does the job just fine. *shrug* //"Symbol" doesn't seem to work here, but "Serif" does the job just fine. *shrug*
// --> goes to F13 and F14 // --> goes to F13 and F14
fontInfo.addMetrics("F13", metric); fontInfo.addMetrics("F13", metric);

+ 8
- 7
src/java/org/apache/fop/render/java2d/InstalledFontCollection.java View File

HARDCODED_FONT_NAMES.add("Computer-Modern-Typewriter"); HARDCODED_FONT_NAMES.add("Computer-Modern-Typewriter");
} }


private Graphics2D graphics2D = null;
/** Required by new instances of FontMetricsMapper */
final private Java2DFontMetrics java2DFontMetrics;


/** /**
* Main constructor * Main constructor
* *
* @param graphics2D a graphics 2D
* @param java2DFontMetrics required by new instances of FontMetricsMapper
*/ */
public InstalledFontCollection(Graphics2D graphics2D) {
this.graphics2D = graphics2D;
public InstalledFontCollection(Java2DFontMetrics java2DFontMetrics) {
this.java2DFontMetrics = java2DFontMetrics;
} }


/** /**
num++; num++;
String fontKey = "F" + num; String fontKey = "F" + num;
int style = convertToAWTFontStyle(guessedStyle, guessedWeight); int style = convertToAWTFontStyle(guessedStyle, guessedWeight);
addFontMetricsMapper(fontInfo, f.getName(), fontKey, graphics2D, style);
addFontMetricsMapper(fontInfo, f.getName(), fontKey, java2DFontMetrics, style);


//Register appropriate font triplets matching the font. Two different strategies: //Register appropriate font triplets matching the font. Two different strategies:
//Example: "Arial Bold", normal, normal //Example: "Arial Bold", normal, normal
} }


private static void addFontMetricsMapper(FontInfo fontInfo, String family, String fontKey, private static void addFontMetricsMapper(FontInfo fontInfo, String family, String fontKey,
Graphics2D graphics, int style) {
FontMetricsMapper metric = new SystemFontMetricsMapper(family, style, graphics);
Java2DFontMetrics java2DFontMetrics, int style) {
FontMetricsMapper metric = new SystemFontMetricsMapper(family, style, java2DFontMetrics);
fontInfo.addMetrics(fontKey, metric); fontInfo.addMetrics(fontKey, metric);
} }



+ 13
- 15
src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java View File

/** /**
* Temp graphics object needed to get the font metrics * Temp graphics object needed to get the font metrics
*/ */
private Graphics2D graphics;
private final Graphics2D graphics;


/** /**
* Creates a Graphics2D object for the sole purpose of getting font metrics. * Creates a Graphics2D object for the sole purpose of getting font metrics.
* @return a Graphics2D object * @return a Graphics2D object
*/ */
public static Graphics2D createFontMetricsGraphics2D() {
private static Graphics2D createFontMetricsGraphics2D() {
BufferedImage fontImage = new BufferedImage(100, 100, BufferedImage fontImage = new BufferedImage(100, 100,
BufferedImage.TYPE_INT_RGB); BufferedImage.TYPE_INT_RGB);
Graphics2D graphics2D = fontImage.createGraphics(); Graphics2D graphics2D = fontImage.createGraphics();


/** /**
* Constructs a new Font-metrics. * Constructs a new Font-metrics.
* @param graphics a temp graphics object - this is needed so
* that we can get an instance of java.awt.FontMetrics
*/ */
public Java2DFontMetrics(Graphics2D graphics) {
this.graphics = graphics;
public Java2DFontMetrics() {
this.graphics = createFontMetricsGraphics2D();
} }


/** /**
* @param size font size * @param size font size
* @return ascent in milliponts * @return ascent in milliponts
*/ */
public synchronized int getMaxAscent(String family, int style, int size) {
public int getMaxAscent(String family, int style, int size) {
setFont(family, style, size); setFont(family, style, size);
return Math.round(lineMetrics.getAscent() * FONT_FACTOR); return Math.round(lineMetrics.getAscent() * FONT_FACTOR);
} }
* @param size font size * @param size font size
* @return ascent in milliponts * @return ascent in milliponts
*/ */
public synchronized int getAscender(String family, int style, int size) {
public int getAscender(String family, int style, int size) {
setFont(family, style, size); setFont(family, style, size);
return ascender * 1000; return ascender * 1000;


* @param size font size * @param size font size
* @return capital height in millipoints * @return capital height in millipoints
*/ */
public synchronized int getCapHeight(String family, int style, int size) {
public int getCapHeight(String family, int style, int size) {
// currently just gets Ascent value but maybe should use // currently just gets Ascent value but maybe should use
// getMaxAcent() at some stage // getMaxAcent() at some stage
return getAscender(family, style, size); return getAscender(family, style, size);
* @param size font size * @param size font size
* @return descent in milliponts * @return descent in milliponts
*/ */
public synchronized int getDescender(String family, int style, int size) {
public int getDescender(String family, int style, int size) {
setFont(family, style, size); setFont(family, style, size);
return descender * 1000; return descender * 1000;
} }
* @param size font size * @param size font size
* @return font height in milliponts * @return font height in milliponts
*/ */
public synchronized int getXHeight(String family, int style, int size) {
public int getXHeight(String family, int style, int size) {
setFont(family, style, size); setFont(family, style, size);
return xHeight * 1000; return xHeight * 1000;
} }
* @param size font size * @param size font size
* @return character width in millipoints * @return character width in millipoints
*/ */
public synchronized int width(int i, String family, int style, int size) {
public int width(int i, String family, int style, int size) {
int w; int w;
setFont(family, style, size); setFont(family, style, size);
w = internalCharWidth(i) * 1000; w = internalCharWidth(i) * 1000;
* @param size font size * @param size font size
* @return array of character widths in millipoints * @return array of character widths in millipoints
*/ */
public synchronized int[] getWidths(String family, int style, int size) {
public int[] getWidths(String family, int style, int size) {
int i; int i;


if (width == null) { if (width == null) {
* @param size font size * @param size font size
* @return font with the desired characeristics. * @return font with the desired characeristics.
*/ */
public synchronized java.awt.Font getFont(String family, int style, int size) {
public java.awt.Font getFont(String family, int style, int size) {
setFont(family, style, size); setFont(family, style, size);
return f1; return f1;
/* /*
* @param c the glyph to check * @param c the glyph to check
* @return true if the character is supported * @return true if the character is supported
*/ */
public synchronized boolean hasChar(String family, int style, int size, char c) {
public boolean hasChar(String family, int style, int size, char c) {
setFont(family, style, size); setFont(family, style, size);
return f1.canDisplay(c); return f1.canDisplay(c);
} }

+ 3
- 3
src/java/org/apache/fop/render/java2d/Java2DRenderer.java View File

//Don't call super.setupFontInfo() here! Java2D needs a special font setup //Don't call super.setupFontInfo() here! Java2D needs a special font setup
// create a temp Image to test font metrics on // create a temp Image to test font metrics on
this.fontInfo = inFontInfo; this.fontInfo = inFontInfo;
Graphics2D graphics2D = Java2DFontMetrics.createFontMetricsGraphics2D();
final Java2DFontMetrics java2DFontMetrics = new Java2DFontMetrics();


FontCollection[] fontCollections = new FontCollection[] { FontCollection[] fontCollections = new FontCollection[] {
new Base14FontCollection(graphics2D),
new InstalledFontCollection(graphics2D),
new Base14FontCollection(java2DFontMetrics),
new InstalledFontCollection(java2DFontMetrics),
new ConfiguredFontCollection(getFontResolver(), getFontList()) new ConfiguredFontCollection(getFontResolver(), getFontList())
}; };
userAgent.getFactory().getFontManager().setup( userAgent.getFactory().getFontManager().setup(

+ 3
- 3
src/java/org/apache/fop/render/java2d/Java2DUtil.java View File

*/ */
public static FontInfo buildDefaultJava2DBasedFontInfo( public static FontInfo buildDefaultJava2DBasedFontInfo(
FontInfo fontInfo, FOUserAgent userAgent) { FontInfo fontInfo, FOUserAgent userAgent) {
Graphics2D graphics2D = Java2DFontMetrics.createFontMetricsGraphics2D();
Java2DFontMetrics java2DFontMetrics = new Java2DFontMetrics();


FontManager fontManager = userAgent.getFactory().getFontManager(); FontManager fontManager = userAgent.getFactory().getFontManager();
FontCollection[] fontCollections = new FontCollection[] { FontCollection[] fontCollections = new FontCollection[] {
new org.apache.fop.render.java2d.Base14FontCollection(graphics2D),
new InstalledFontCollection(graphics2D)
new org.apache.fop.render.java2d.Base14FontCollection(java2DFontMetrics),
new InstalledFontCollection(java2DFontMetrics)
}; };


FontInfo fi = (fontInfo != null ? fontInfo : new FontInfo()); FontInfo fi = (fontInfo != null ? fontInfo : new FontInfo());

+ 15
- 16
src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java View File

* This is a Java2DFontMetrics that does the real calculation. * This is a Java2DFontMetrics that does the real calculation.
* It is only one class that dynamically determines the font-size. * It is only one class that dynamically determines the font-size.
*/ */
private static Java2DFontMetrics metric = null;
private final Java2DFontMetrics java2DFontMetrics;


/** /**
* The java name of the font. * The java name of the font.
* Constructs a new Font-metrics. * Constructs a new Font-metrics.
* @param family the family name of the font (java value) * @param family the family name of the font (java value)
* @param style the java type style value of the font * @param style the java type style value of the font
* @param graphics a Graphics2D object - this is needed so
* that we can get an instance of java.awt.FontMetrics
* @param java2DFontMetrics metric calculations delegated to this
*/ */
public SystemFontMetricsMapper(String family, int style, Graphics2D graphics) {
public SystemFontMetricsMapper(String family, int style, Java2DFontMetrics java2DFontMetrics) {
this.family = family; this.family = family;

this.style = style; this.style = style;
if (metric == null) {
metric = new Java2DFontMetrics(graphics);
}

this.java2DFontMetrics = java2DFontMetrics;
} }


/** {@inheritDoc} */ /** {@inheritDoc} */
* {@inheritDoc} * {@inheritDoc}
*/ */
public int getMaxAscent(int size) { public int getMaxAscent(int size) {
return metric.getMaxAscent(family, style, size);
return java2DFontMetrics.getMaxAscent(family, style, size);
} }


/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public int getAscender(int size) { public int getAscender(int size) {
return metric.getAscender(family, style, size);
return java2DFontMetrics.getAscender(family, style, size);
} }


/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public int getCapHeight(int size) { public int getCapHeight(int size) {
return metric.getCapHeight(family, style, size);
return java2DFontMetrics.getCapHeight(family, style, size);
} }


/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public int getDescender(int size) { public int getDescender(int size) {
return metric.getDescender(family, style, size);
return java2DFontMetrics.getDescender(family, style, size);
} }


/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public int getXHeight(int size) { public int getXHeight(int size) {
return metric.getXHeight(family, style, size);
return java2DFontMetrics.getXHeight(family, style, size);
} }


/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public int getWidth(int i, int size) { public int getWidth(int i, int size) {
return metric.width(i, family, style, size);
return java2DFontMetrics.width(i, family, style, size);
} }




* {@inheritDoc} * {@inheritDoc}
*/ */
public int[] getWidths() { public int[] getWidths() {
return metric.getWidths(family, style, Java2DFontMetrics.FONT_SIZE);
return java2DFontMetrics.getWidths(family, style, Java2DFontMetrics.FONT_SIZE);
} }


/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public java.awt.Font getFont(int size) { public java.awt.Font getFont(int size) {
return metric.getFont(family, style, size);
return java2DFontMetrics.getFont(family, style, size);
} }


/** /**


/** {@inheritDoc} */ /** {@inheritDoc} */
public boolean hasChar(char c) { public boolean hasChar(char c) {
return metric.hasChar(family, style, Java2DFontMetrics.FONT_SIZE, c);
return java2DFontMetrics.hasChar(family, style, Java2DFontMetrics.FONT_SIZE, c);
} }


} }

+ 4
- 5
src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java View File

throws FOPException { throws FOPException {
FontManager fontManager = userAgent.getFactory().getFontManager(); FontManager fontManager = userAgent.getFactory().getFontManager();


Graphics2D graphics2D = Java2DFontMetrics.createFontMetricsGraphics2D();

List fontCollections = new java.util.ArrayList();
fontCollections.add(new Base14FontCollection(graphics2D));
fontCollections.add(new InstalledFontCollection(graphics2D));
final Java2DFontMetrics java2DFontMetrics = new Java2DFontMetrics();
final List fontCollections = new java.util.ArrayList();
fontCollections.add(new Base14FontCollection(java2DFontMetrics));
fontCollections.add(new InstalledFontCollection(java2DFontMetrics));


Configuration cfg = super.getRendererConfig(documentHandler.getMimeType()); Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
if (cfg != null) { if (cfg != null) {

+ 5
- 0
status.xml View File

documents. Example: the fix of marks layering will be such a case when it's done. documents. Example: the fix of marks layering will be such a case when it's done.
--> -->
<release version="FOP Trunk" date="TBD"> <release version="FOP Trunk" date="TBD">
<action context="Renderers" dev="PH" type="fix" fixes-bug="48062">
Improved fix of a bug relating to PCL painter thread safetly. Previous fix in rev 895012
worked by synchronizing methods of a static instance of Java2DFontMetrics. This fix uses a
unique instance for per thread.
</action>
<action context="Renderers" dev="PH" type="fix"> <action context="Renderers" dev="PH" type="fix">
Fixed a bug in AFP where an ArrayOutofBoundsException is throwqn when embedding a Page Fixed a bug in AFP where an ArrayOutofBoundsException is throwqn when embedding a Page
Segment. Segment.

Loading…
Cancel
Save