jeremias 02/05/19 14:05:04 Modified: src/org/apache/fop/render/awt Tag: fop-0_20_2-maintain AWTRenderer.java Log: Patch by Ralph LaChance works around a bug in JDK 1.3.0.* and 1.4 to improve text output. I've added support for overline, line-through and text-decoration on inline spaces. Made graphics variable protected to faciliate subclassing. Submitted by: Ralph LaChance <[EMAIL PROTECTED]> Revision Changes Path No revision No revision 1.38.2.3 +110 -26 xml-fop/src/org/apache/fop/render/awt/AWTRenderer.java Index: AWTRenderer.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/render/awt/AWTRenderer.java,v retrieving revision 1.38.2.2 retrieving revision 1.38.2.3 diff -u -r1.38.2.2 -r1.38.2.3 --- AWTRenderer.java 23 Apr 2002 22:33:39 -0000 1.38.2.2 +++ AWTRenderer.java 19 May 2002 21:05:04 -0000 1.38.2.3 @@ -1,5 +1,5 @@ /* - * $Id: AWTRenderer.java,v 1.38.2.2 2002/04/23 22:33:39 arved Exp $ + * $Id: AWTRenderer.java,v 1.38.2.3 2002/05/19 21:05:04 jeremias Exp $ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. * For details on use and redistribution please refer to the * LICENSE file included with these sources. @@ -79,7 +79,7 @@ * object that is contained withing the Image Object. */ private BufferedImage pageImage = null; - private Graphics2D graphics = null; + protected Graphics2D graphics = null; /** * The current (internal) font name @@ -99,6 +99,13 @@ protected float currentBlue = 0; /** + * Used to make the last font and color available to + * renderInlineSpace() to render text decorations. + */ + protected java.awt.Font lastFont = null; + protected Color lastColor = null; + + /** * The parent component, used to set up the font. * This is needed as FontSetup needs a live AWT component * in order to generate valid font measures. @@ -484,7 +491,7 @@ * Renders an image, scaling it to the given width and height. * If the scaled width and height is the same intrinsic size * of the image, the image is not scaled. - * + * * @param x the x position of left edge in millipoints * @param y the y position of top edge in millipoints * @param w the width in millipoints @@ -498,10 +505,10 @@ FontState fs) { // XXX: implement this } - + /** - * Renders an image, clipping it as specified. - * + * Renders an image, clipping it as specified. + * * @param x the x position of left edge in millipoints. * @param y the y position of top edge in millipoints. * @param clipX the left edge of the clip in millipoints @@ -597,13 +604,13 @@ this.currentXPosition += area.getContentWidth(); } + public void renderWordArea(WordArea area) { char ch; StringBuffer pdf = new StringBuffer(); - String name = area.getFontState().getFontName(); + String fontname = area.getFontState().getFontName(); int size = area.getFontState().getFontSize(); - boolean underlined = area.getUnderlined(); float red = area.getRed(); float green = area.getGreen(); @@ -612,15 +619,15 @@ FontMetricsMapper mapper; try { mapper = - (FontMetricsMapper)area.getFontState().getFontInfo().getMetricsFor(name); + (FontMetricsMapper)area.getFontState().getFontInfo().getMetricsFor(fontname); } catch (FOPException iox) { mapper = new FontMetricsMapper("MonoSpaced", java.awt.Font.PLAIN, graphics); } - if ((!name.equals(this.currentFontName)) + if ((!fontname.equals(this.currentFontName)) || (size != this.currentFontSize)) { - this.currentFontName = name; + this.currentFontName = fontname; this.currentFontSize = size; } @@ -635,7 +642,7 @@ int bl = this.currentYPosition; - String s; // = area.getText(); + String s; if (area.getPageNumberID() != null) { // this text is a page number, so resolve it s = idReferences.getPageNumber(area.getPageNumberID()); @@ -660,28 +667,105 @@ } graphics.setColor(saveColor); - AttributedString ats = new AttributedString(s); - ats.addAttribute(TextAttribute.FONT, f); - if (underlined) { - ats.addAttribute(TextAttribute.UNDERLINE, - TextAttribute.UNDERLINE_ON); - } - AttributedCharacterIterator iter = ats.getIterator(); - - // correct integer roundoff - // graphics.drawString(iter, rx / 1000f, - // (int)(pageHeight - bl / 1000f)); - - graphics.drawString(iter, (rx + 500) / 1000, - (int)(pageHeight - (bl + 500) / 1000)); + // Ralph LaChance (May 16, 2002) + // AttributedString mechanism removed because of + // rendering bug in both jdk 1.3.0_x and 1.4. + // see bug parade 4650042 and others + // + graphics.setFont(f); + + // correct starting location for integer roundoff + int newx = (int)(rx + 500) / 1000; + int newy = (int)(pageHeight - (bl + 500) / 1000); + + // draw text, corrected for integer roundoff + graphics.drawString(s, newx, newy); + + FontMetrics fm = graphics.getFontMetrics(f); + int tdwidth = (int)fm.getStringBounds(s, graphics).getWidth(); + + // text decorations + renderTextDecoration(rx, bl, tdwidth, f, " ", + area.getUnderlined(), + area.getOverlined(), + area.getLineThrough()); + + // remember last font and color for possible inline spaces + // (especially for text decorations) + this.lastFont = graphics.getFont(); + this.lastColor = graphics.getColor(); + graphics.setFont(oldFont); graphics.setColor(oldColor); + this.currentXPosition += area.getContentWidth(); } + public void renderInlineSpace(InlineSpace space) { + if (space.getUnderlined() || space.getOverlined() || space.getLineThrough()) { + int rx = this.currentXPosition; + int bl = this.currentYPosition; + + java.awt.Font oldFont = graphics.getFont(); + if (this.lastFont != null) { + graphics.setFont(this.lastFont); + } + Color oldColor = graphics.getColor(); + if (this.lastColor != null) { + graphics.setColor(this.lastColor); + } + + int width = (int)(space.getSize() + 500) / 1000; + renderTextDecoration(rx, bl, width, graphics.getFont(), " ", + space.getUnderlined(), + space.getOverlined(), + space.getLineThrough()); + + graphics.setFont(oldFont); + graphics.setColor(oldColor); + } + this.currentXPosition += space.getSize(); } + + + protected void renderTextDecoration(int x, int bl, int width, + java.awt.Font font, String text, + boolean underline, + boolean overline, + boolean linethrough) { + if (!(underline || overline || linethrough)) return; + int newx = (int)(x + 500) / 1000; + int newy = (int)(pageHeight - (bl + 500) / 1000); + + // text decorations + FontMetrics fm = graphics.getFontMetrics(font); + LineMetrics lm = fm.getLineMetrics(text, graphics); + + int ulthick = (int)lm.getUnderlineThickness(); + if (ulthick < 1) + ulthick = 1; // don't allow it to disappear + if (underline) { + // nothing in awt specifies underline location, + // descent/2 seems to match my word processor + int deltay = fm.getDescent() / 2; + graphics.fillRect(newx, newy + deltay, width, ulthick); + } + if (overline) { + // todo: maybe improve positioning of overline + int deltay = -(int)(lm.getAscent() * 0.8); + graphics.fillRect(newx, newy + deltay, width, ulthick); + } + if (linethrough) { + int ltthick = (int)lm.getStrikethroughThickness(); + if (ltthick < 1) + ltthick = 1; // don't allow it to disappear + int deltay = (int)lm.getStrikethroughOffset(); + graphics.fillRect(newx, newy + deltay, width, ltthick); + } + } + /** * render leader area into AWT
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]